Skip to content
Snippets Groups Projects
Commit fa8dcbda authored by Tim Übelhör's avatar Tim Übelhör
Browse files

Added events for callbacks

parent bc308732
No related branches found
No related tags found
No related merge requests found
#include "stdafx.h"
#include "LogEventArgs.h"
LogEventArgs::LogEventArgs()
{
}
#pragma once
using namespace System;
ref class LogEventArgs : public EventArgs
{
public:
LogEventArgs();
property String^ InstanceName;
property int Status;
property String^ Message;
};
...@@ -5,13 +5,13 @@ ...@@ -5,13 +5,13 @@
using namespace msclr::interop; using namespace msclr::interop;
using namespace System::Runtime::InteropServices; using namespace System::Runtime::InteropServices;
namespace ModeliRpcImpl namespace ModeliRpc
{ {
ModeliRpcImpl::ModeliRpcImpl(String^ address, int port) FrontendRpc::FrontendRpc(String^ address, int port)
{ {
// Managed callbacks // Managed callbacks
_newValues = gcnew NewValuesDelegate(this, &ModeliRpcImpl::onNewValues); _newValues = gcnew NewValuesDelegate(this, &FrontendRpc::onNewValues);
_log = gcnew LogDelegate(this, &ModeliRpcImpl::onLog); _log = gcnew LogDelegate(this, &FrontendRpc::onLog);
// Load the unmanged instance // Load the unmanged instance
HINSTANCE _rpcDll = LoadLibrary("ModeliRpcNative.dll"); HINSTANCE _rpcDll = LoadLibrary("ModeliRpcNative.dll");
if (!_rpcDll) if (!_rpcDll)
...@@ -34,12 +34,12 @@ namespace ModeliRpcImpl ...@@ -34,12 +34,12 @@ namespace ModeliRpcImpl
} }
ModeliRpcImpl::~ModeliRpcImpl() FrontendRpc::~FrontendRpc()
{ {
// Call the finalizer // Call the finalizer
this->!ModeliRpcImpl(); this->!FrontendRpc();
} }
ModeliRpcImpl::!ModeliRpcImpl() FrontendRpc::!FrontendRpc()
{ {
// Clear all unmanaged resources // Clear all unmanaged resources
if (_rpcFrontend) if (_rpcFrontend)
...@@ -52,16 +52,54 @@ namespace ModeliRpcImpl ...@@ -52,16 +52,54 @@ namespace ModeliRpcImpl
} }
} }
void ModeliRpcImpl::onNewValues(double timestamp, ValuesStruct values) void FrontendRpc::onNewValues(double timestamp, ValuesStruct values)
{ {
throw gcnew System::NotImplementedException(); // Copy data into the EventArgs
auto args = gcnew NewValuesEventArgs();
args->Timestamp = timestamp;
args->InstanceName = marshal_as<String^> (values.instanceName);
// Int
args->IntegerValueRefs = gcnew array<unsigned int>(values.integerValueRefs.size());
pin_ptr<unsigned int> pinIntegerVrs = &args->IntegerValueRefs[0];
memcpy_s(pinIntegerVrs, args->IntegerValueRefs->Length, values.integerValueRefs.data(), values.integerValueRefs.size());
args->IntegerValues = gcnew array<int>(values.integerValues.size());
pin_ptr<int> pinIntegerValues = &args->IntegerValues[0];
memcpy_s(pinIntegerValues, args->IntegerValues->Length, values.integerValues.data(), values.integerValues.size());
// Real
args->RealValueRefs = gcnew array<unsigned int>(values.realValueRefs.size());
pin_ptr<unsigned int> pinRealVrs = &args->RealValueRefs[0];
memcpy_s(pinRealVrs, args->RealValueRefs->Length, values.realValueRefs.data(), values.realValueRefs.size());
args->RealValues = gcnew array<double>(values.realValues.size());
pin_ptr<double> pinRealValues = &args->RealValues[0];
memcpy_s(pinIntegerValues, args->RealValues->Length, values.realValues.data(), values.realValues.size());
// Bool
args->BoolValueRefs = gcnew array<unsigned int>(values.boolValueRefs.size());
pin_ptr<unsigned int> pinBoolVrs = &args->BoolValueRefs[0];
memcpy_s(pinBoolVrs, args->BoolValueRefs->Length, values.boolValueRefs.data(), values.boolValueRefs.size());
args->BoolValues = gcnew array<bool>(values.boolValues.size());
for (int i = 0; i < args->BoolValues->Length; i++)
{
args->BoolValues[i] = values.boolValues[i];
} }
// String
void ModeliRpcImpl::onLog(std::string instanceName, fmi2Status status, std::string message) args->StringValueRefs = gcnew array<unsigned int>(values.stringValueRefs.size());
pin_ptr<unsigned int> pinStringVrs = &args->StringValueRefs[0];
memcpy_s(pinStringVrs, args->StringValueRefs->Length, values.stringValueRefs.data(), values.stringValueRefs.size());
args->StringValues = gcnew array<String^>(values.stringValues.size());
for (int i = 0; i < args->StringValues->Length; i++)
{ {
throw gcnew System::NotImplementedException(); args->StringValues[i] = marshal_as<String^>(values.stringValues[i]);
}
// Fire!
NewValuesArrived(this, args);
} }
void FrontendRpc::onLog(std::string instanceName, int status, std::string message)
{
auto args = gcnew LogEventArgs();
args->InstanceName = marshal_as<String^>(instanceName);
args->Status = status;
args->Message = marshal_as<String^>(message);
LogArrived(this, args);
}
} }
\ No newline at end of file
#pragma once #pragma once
#include"../ModeliRpcNative/IRpcFrontend.h" // Faster build by not incuding all of windows
#include <string>
#ifndef VC_EXTRALEAN #ifndef VC_EXTRALEAN
#define VC_EXTRALEAN #define VC_EXTRALEAN
#endif #endif
#include <windows.h> #include <windows.h> // Always on top otherwise build fails (IServicProvider CLI issue)
#include "../ModeliRpcNative/IRpcFrontend.h"
#include <string>
#include "NewValuesEventArgs.h"
#include "LogEventArgs.h"
using namespace System; using namespace System;
...@@ -15,9 +18,9 @@ namespace capnp ...@@ -15,9 +18,9 @@ namespace capnp
class EzRpcClient; class EzRpcClient;
} }
namespace ModeliRpcImpl namespace ModeliRpc
{ {
ref class ModeliRpcImpl ref class FrontendRpc
{ {
private: private:
// Unmanaged rpc interface // Unmanaged rpc interface
...@@ -27,17 +30,23 @@ namespace ModeliRpcImpl ...@@ -27,17 +30,23 @@ namespace ModeliRpcImpl
// Delegates for callbacks // Delegates for callbacks
delegate void NewValuesDelegate(double timestamp, ValuesStruct values); delegate void NewValuesDelegate(double timestamp, ValuesStruct values);
delegate void LogDelegate(std::string instanceName, fmi2Status status, std::string message); delegate void LogDelegate(std::string instanceName, int status, std::string message);
NewValuesDelegate^ _newValues; NewValuesDelegate^ _newValues;
LogDelegate^ _log; LogDelegate^ _log;
// Functions for the delegates // Functions for the delegates
void onNewValues(double timestamp, ValuesStruct values); void onNewValues(double timestamp, ValuesStruct values);
void onLog(std::string instanceName, fmi2Status status, std::string message); void onLog(std::string instanceName, int status, std::string message);
public: public:
ModeliRpcImpl(String^ address, int port); /// Create a new managed instance for RPCs to the ModeliBackend.
~ModeliRpcImpl(); // Destructor (IDisposable) FrontendRpc(String^ address, int port);
!ModeliRpcImpl(); // Finalizer ~FrontendRpc(); // Destructor (IDisposable)
!FrontendRpc(); // Finalizer
/// Gets fired when new values arrived from the backend.
event EventHandler<NewValuesEventArgs^>^ NewValuesArrived;
/// Gets fired when logging messages arrive from the backend.
event EventHandler<LogEventArgs^>^ LogArrived;
}; };
} }
\ No newline at end of file
...@@ -21,7 +21,7 @@ ...@@ -21,7 +21,7 @@
<PropertyGroup Label="Globals"> <PropertyGroup Label="Globals">
<VCProjectVersion>15.0</VCProjectVersion> <VCProjectVersion>15.0</VCProjectVersion>
<ProjectGuid>{A8187A41-1D24-438F-9B5D-0F7BF270130E}</ProjectGuid> <ProjectGuid>{A8187A41-1D24-438F-9B5D-0F7BF270130E}</ProjectGuid>
<TargetFrameworkVersion>v4.6.1</TargetFrameworkVersion> <TargetFrameworkVersion>v4.7</TargetFrameworkVersion>
<Keyword>ManagedCProj</Keyword> <Keyword>ManagedCProj</Keyword>
<RootNamespace>ModeliRpcCLR</RootNamespace> <RootNamespace>ModeliRpcCLR</RootNamespace>
<WindowsTargetPlatformVersion>10.0.16299.0</WindowsTargetPlatformVersion> <WindowsTargetPlatformVersion>10.0.16299.0</WindowsTargetPlatformVersion>
...@@ -144,13 +144,17 @@ ...@@ -144,13 +144,17 @@
<Reference Include="System.Xml" /> <Reference Include="System.Xml" />
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<ClInclude Include="LogEventArgs.h" />
<ClInclude Include="ModeliRpc.h" /> <ClInclude Include="ModeliRpc.h" />
<ClInclude Include="NewValuesEventArgs.h" />
<ClInclude Include="resource.h" /> <ClInclude Include="resource.h" />
<ClInclude Include="Stdafx.h" /> <ClInclude Include="Stdafx.h" />
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<ClCompile Include="AssemblyInfo.cpp" /> <ClCompile Include="AssemblyInfo.cpp" />
<ClCompile Include="LogEventArgs.cpp" />
<ClCompile Include="ModeliRpc.cpp" /> <ClCompile Include="ModeliRpc.cpp" />
<ClCompile Include="NewValuesEventArgs.cpp" />
<ClCompile Include="Stdafx.cpp"> <ClCompile Include="Stdafx.cpp">
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">Create</PrecompiledHeader> <PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">Create</PrecompiledHeader>
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">Create</PrecompiledHeader> <PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">Create</PrecompiledHeader>
...@@ -167,11 +171,6 @@ ...@@ -167,11 +171,6 @@
<ItemGroup> <ItemGroup>
<Image Include="app.ico" /> <Image Include="app.ico" />
</ItemGroup> </ItemGroup>
<ItemGroup>
<ProjectReference Include="..\ModeliRpcNative\ModeliRpcNative.vcxproj">
<Project>{171ed599-c0c6-4342-8328-e7abe7f7feaa}</Project>
</ProjectReference>
</ItemGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" /> <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
<ImportGroup Label="ExtensionTargets"> <ImportGroup Label="ExtensionTargets">
</ImportGroup> </ImportGroup>
......
...@@ -24,6 +24,12 @@ ...@@ -24,6 +24,12 @@
<ClInclude Include="ModeliRpc.h"> <ClInclude Include="ModeliRpc.h">
<Filter>Header Files</Filter> <Filter>Header Files</Filter>
</ClInclude> </ClInclude>
<ClInclude Include="NewValuesEventArgs.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="LogEventArgs.h">
<Filter>Header Files</Filter>
</ClInclude>
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<ClCompile Include="AssemblyInfo.cpp"> <ClCompile Include="AssemblyInfo.cpp">
...@@ -35,6 +41,12 @@ ...@@ -35,6 +41,12 @@
<ClCompile Include="ModeliRpc.cpp"> <ClCompile Include="ModeliRpc.cpp">
<Filter>Source Files</Filter> <Filter>Source Files</Filter>
</ClCompile> </ClCompile>
<ClCompile Include="NewValuesEventArgs.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="LogEventArgs.cpp">
<Filter>Source Files</Filter>
</ClCompile>
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<Text Include="ReadMe.txt" /> <Text Include="ReadMe.txt" />
......
#include "stdafx.h"
#include "NewValuesEventArgs.h"
NewValuesEventArgs::NewValuesEventArgs()
{
}
#pragma once
using namespace System;
ref class NewValuesEventArgs: EventArgs
{
public:
NewValuesEventArgs();
property double Timestamp;
property String^ InstanceName;
property array<unsigned int>^ IntegerValueRefs;
property array<int>^ IntegerValues;
property array<unsigned int>^ RealValueRefs;
property array<double>^ RealValues;
property array<unsigned int>^ BoolValueRefs;
property array<bool>^ BoolValues;
property array<unsigned int>^ StringValueRefs;
property array<String^>^ StringValues;
};
...@@ -2,16 +2,6 @@ ...@@ -2,16 +2,6 @@
#include <string> #include <string>
#include <vector> #include <vector>
enum fmi2Status
{
fmi2OK,
fmi2Warning,
fmi2Discard,
fmi2Error,
fmi2Fatal,
fmi2Pending
};
// Struct that will be used for the NewValues callback // Struct that will be used for the NewValues callback
struct ValuesStruct struct ValuesStruct
{ {
...@@ -50,14 +40,17 @@ public: ...@@ -50,14 +40,17 @@ public:
virtual void destroy() = 0; virtual void destroy() = 0;
virtual void connect(std::string address, int port) = 0; virtual void connect(std::string address, int port) = 0;
virtual void registerCallbacks(NewValuesCallback newValuesCallback, LogCallback logCallback) = 0; virtual void registerCallbacks(NewValuesCallback newValuesCallback, LogCallback logCallback) = 0;
virtual fmi2Status play() = 0; /// Returns fmi2Status
virtual int play() = 0;
virtual void pause() = 0; virtual void pause() = 0;
virtual fmi2Status stop() = 0; /// Returns fmi2Status
virtual int stop() = 0;
virtual bool addFmu(std::string instanceName, std::vector<unsigned char> fmuFile) = 0; virtual bool addFmu(std::string instanceName, std::vector<unsigned char> fmuFile) = 0;
virtual bool removeFmu(std::string instanceName) = 0; virtual bool removeFmu(std::string instanceName) = 0;
virtual bool addChannelLink(ChannelLink channelLink) = 0; virtual bool addChannelLink(ChannelLink channelLink) = 0;
virtual bool removeChannelink(ChannelLink channelLink) = 0; virtual bool removeChannelink(ChannelLink channelLink) = 0;
virtual fmi2Status setValues(ValuesStruct values) = 0; /// Returns fmi2Status
virtual int setValues(ValuesStruct values) = 0;
}; };
// Factory signature // Factory signature
extern "C" __declspec(dllexport) IRpcFrontend* createRpcFrontend(); extern "C" __declspec(dllexport) IRpcFrontend* createRpcFrontend();
\ No newline at end of file
...@@ -36,14 +36,14 @@ void RpcFrontend::registerCallbacks(NewValuesCallback newValuesCallback, LogCall ...@@ -36,14 +36,14 @@ void RpcFrontend::registerCallbacks(NewValuesCallback newValuesCallback, LogCall
} }
fmi2Status RpcFrontend::play() int RpcFrontend::play()
{ {
if (!_client) if (!_client)
{ {
return fmi2Error; return FMI2_ERROR;
} }
auto backend = _client->getMain<ModeliBackend>(); auto backend = _client->getMain<ModeliBackend>();
return static_cast<fmi2Status>(backend.playRequest().send().wait(_client->getWaitScope()).getResult()); return backend.playRequest().send().wait(_client->getWaitScope()).getResult();
} }
void RpcFrontend::pause() void RpcFrontend::pause()
...@@ -56,14 +56,14 @@ void RpcFrontend::pause() ...@@ -56,14 +56,14 @@ void RpcFrontend::pause()
backend.pauseRequest().send().wait(_client->getWaitScope()); backend.pauseRequest().send().wait(_client->getWaitScope());
} }
fmi2Status RpcFrontend::stop() int RpcFrontend::stop()
{ {
if (!_client) if (!_client)
{ {
return fmi2Error; return FMI2_ERROR;
} }
auto backend = _client->getMain<ModeliBackend>(); auto backend = _client->getMain<ModeliBackend>();
return static_cast<fmi2Status>(backend.stopRequest().send().wait(_client->getWaitScope()).getResult()); return backend.stopRequest().send().wait(_client->getWaitScope()).getResult();
} }
bool RpcFrontend::addFmu(std::string instanceName, std::vector<unsigned char> fmuFile) bool RpcFrontend::addFmu(std::string instanceName, std::vector<unsigned char> fmuFile)
...@@ -117,15 +117,15 @@ bool RpcFrontend::removeChannelink(ChannelLink channelLink) ...@@ -117,15 +117,15 @@ bool RpcFrontend::removeChannelink(ChannelLink channelLink)
return request.send().wait(_client->getWaitScope()).getResult(); return request.send().wait(_client->getWaitScope()).getResult();
} }
fmi2Status RpcFrontend::setValues(ValuesStruct values) int RpcFrontend::setValues(ValuesStruct values)
{ {
if (!_client) if (!_client)
{ {
return fmi2Error; return FMI2_ERROR;
} }
// Send request // Send request
auto backend = _client->getMain<ModeliBackend>(); auto backend = _client->getMain<ModeliBackend>();
auto request = backend.setValuesRequest(); auto request = backend.setValuesRequest();
request.setValues(CapnConverter::convertValues(values)); request.setValues(CapnConverter::convertValues(values));
return static_cast<fmi2Status>(request.send().wait(_client->getWaitScope()).getResult()); return request.send().wait(_client->getWaitScope()).getResult();
} }
\ No newline at end of file
...@@ -15,19 +15,20 @@ public: ...@@ -15,19 +15,20 @@ public:
~RpcFrontend(); ~RpcFrontend();
private: private:
std::unique_ptr<capnp::EzRpcClient> _client; std::unique_ptr<capnp::EzRpcClient> _client;
const int FMI2_ERROR = 3;
// Inherited via IModeliFrontend // Inherited via IModeliFrontend
void destroy() override; void destroy() override;
void connect(std::string address, int port) override; void connect(std::string address, int port) override;
void registerCallbacks(NewValuesCallback newValuesCallback, LogCallback logCallback) override; void registerCallbacks(NewValuesCallback newValuesCallback, LogCallback logCallback) override;
fmi2Status play() override; int play() override;
void pause() override; void pause() override;
fmi2Status stop() override; int stop() override;
bool addFmu(std::string instanceName, std::vector<unsigned char> fmuFile) override; bool addFmu(std::string instanceName, std::vector<unsigned char> fmuFile) override;
bool removeFmu(std::string instanceName) override; bool removeFmu(std::string instanceName) override;
bool addChannelLink(ChannelLink channelLink) override; bool addChannelLink(ChannelLink channelLink) override;
bool removeChannelink(ChannelLink channelLink) override; bool removeChannelink(ChannelLink channelLink) override;
fmi2Status setValues(ValuesStruct values) override; int setValues(ValuesStruct values) override;
}; };
/// Factory method that returns an implementation of IRpcFrontend. /// Factory method that returns an implementation of IRpcFrontend.
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment