From e310a96db7039063e26e8c57e2c68f5689432816 Mon Sep 17 00:00:00 2001 From: Tim Uebelhoer <tim.uebelhoer@rwth-aachen.de> Date: Mon, 18 Dec 2017 12:06:28 +0100 Subject: [PATCH] Finished the unmanaged interface and the Managed wrapper class --- ModeliRpc.capnp | 6 +- ModeliRpc/ModeliRpcCLR/ModeliRpc.cpp | 127 +++++++++++++++--- ModeliRpc/ModeliRpcCLR/ModeliRpc.h | 23 ++++ ModeliRpc/ModeliRpcCLR/ModeliRpcCLR.vcxproj | 2 + .../ModeliRpcCLR/ModeliRpcCLR.vcxproj.filters | 6 + ModeliRpc/ModeliRpcCLR/NewValuesEventArgs.h | 2 +- ModeliRpc/ModeliRpcCLR/RpcChannelLink.cpp | 7 + ModeliRpc/ModeliRpcCLR/RpcChannelLink.h | 14 ++ ModeliRpc/ModeliRpcNative/CapnConverter.cpp | 2 +- ModeliRpc/ModeliRpcNative/IRpcFrontend.h | 6 +- ModeliRpc/ModeliRpcNative/ModeliRpc.capnp.c++ | 33 ++++- ModeliRpc/ModeliRpcNative/ModeliRpc.capnp.h | 63 ++++++--- ModeliRpc/ModeliRpcNative/RpcFrontend.cpp | 16 ++- ModeliRpc/ModeliRpcNative/RpcFrontend.h | 3 +- 14 files changed, 255 insertions(+), 55 deletions(-) create mode 100644 ModeliRpc/ModeliRpcCLR/RpcChannelLink.cpp create mode 100644 ModeliRpc/ModeliRpcCLR/RpcChannelLink.h diff --git a/ModeliRpc.capnp b/ModeliRpc.capnp index 98df47b..c399418 100644 --- a/ModeliRpc.capnp +++ b/ModeliRpc.capnp @@ -8,7 +8,7 @@ interface ModeliBackend { # Start Simulation play @0 () -> (result : Int16); # Simulate as quick as possible - playFast @1 () -> (result : Int16); + playFast @1 (timeToPlay : Float64) -> (result : Int16); # Pause simulation pause @2 (); # Stop and reset simulation @@ -54,8 +54,8 @@ struct Values { integerValues @2 : List(Int32); realValueRefs @3 : List(UInt32); realValues @4 : List(Float64); - boolValueRefs @5 : List(UInt32); - boolValues @6 : List(Bool); + boolValueRefs @5 : List(UInt32); # fmi2Bool is an int (0 = false, 1 = true) + boolValues @6 : List(Int32); stringValueRefs @7 : List(UInt32); stringValues @8 : List(Text); } \ No newline at end of file diff --git a/ModeliRpc/ModeliRpcCLR/ModeliRpc.cpp b/ModeliRpc/ModeliRpcCLR/ModeliRpc.cpp index 883e035..5076e49 100644 --- a/ModeliRpc/ModeliRpcCLR/ModeliRpc.cpp +++ b/ModeliRpc/ModeliRpcCLR/ModeliRpc.cpp @@ -31,7 +31,6 @@ namespace ModeliRpc static_cast<LogCallback>(Marshal::GetFunctionPointerForDelegate(_log).ToPointer())); // Connect _rpcFrontend->connect(marshal_as<std::string>(address), port); - } FrontendRpc::~FrontendRpc() @@ -52,40 +51,136 @@ namespace ModeliRpc } } + int FrontendRpc::Play() + { + return _rpcFrontend->play(); + } + + int FrontendRpc::PlayFast(double timeToPlay) + { + return _rpcFrontend->playFast(timeToPlay); + } + + void FrontendRpc::Pause() + { + _rpcFrontend->pause(); + } + + int FrontendRpc::Stop() + { + return _rpcFrontend->stop(); + } + + bool FrontendRpc::AddFmu(String ^ instanceName, array<Byte>^ fmuFileBuffer) + { + // Prevent GC from moving the memory + pin_ptr<unsigned char> pin = &fmuFileBuffer[0]; + unsigned char* src = pin; + std::vector<unsigned char> buffer(src, src + fmuFileBuffer->Length); + return _rpcFrontend->addFmu(marshal_as<std::string>(instanceName), buffer); + } + + bool FrontendRpc::RemoveFmu(String ^ instanceName) + { + return _rpcFrontend->removeFmu(marshal_as<std::string>(instanceName)); + } + + bool FrontendRpc::AddChannelLink(RpcChannelLink ^ channelLink) + { + // Native struct + ChannelLink nativeLink = {}; + nativeLink.masterInstanceName = marshal_as<std::string>(channelLink->MasterInstanceName); + nativeLink.slaveInstanceName = marshal_as<std::string>(channelLink->SlaveInstanceName); + nativeLink.masterValueRef = channelLink->MasterValueRef; + nativeLink.slaveValueRef = channelLink->SlaveValueRef; + nativeLink.factor = channelLink->Factor; + nativeLink.offset = channelLink->Offset; + return _rpcFrontend->addChannelLink(nativeLink); + } + + bool FrontendRpc::RemoveChannelLink(RpcChannelLink ^ channelLink) + { + // Native struct + ChannelLink nativeLink = {}; + nativeLink.masterInstanceName = marshal_as<std::string>(channelLink->MasterInstanceName); + nativeLink.slaveInstanceName = marshal_as<std::string>(channelLink->SlaveInstanceName); + nativeLink.masterValueRef = channelLink->MasterValueRef; + nativeLink.slaveValueRef = channelLink->SlaveValueRef; + nativeLink.factor = channelLink->Factor; + nativeLink.offset = channelLink->Offset; + return _rpcFrontend->removeChannelink(nativeLink); + } + + int FrontendRpc::SetValues(String^ instanceName, array<unsigned int>^ intVRs, array<int>^ intValues, array<unsigned int>^ realVRs, array<double>^ realValues, array<unsigned int>^ boolVRs, array<int>^ boolValues, array<unsigned int>^ stringVRs, array<String^>^ stringValues) + { + ValuesStruct values = {}; + values.instanceName = marshal_as<std::string>(instanceName); + // Int + pin_ptr<uint32_t> pinIntVrs = &intVRs[0]; + uint32_t* srcIntVrs = pinIntVrs; + values.integerValueRefs.assign(srcIntVrs, srcIntVrs + intVRs->Length); + pin_ptr<int32_t> pinIntValues = &intValues[0]; + int32_t* srcIntValues = pinIntValues; + values.integerValues.assign(srcIntValues, srcIntValues + intValues->Length); + // Real + pin_ptr<uint32_t> pinRealVrs = &realVRs[0]; + uint32_t* srcRealVrs = pinRealVrs; + values.realValueRefs.assign(srcRealVrs, srcRealVrs + realVRs->Length); + pin_ptr<double> pinRealValues = &realValues[0]; + double* srcRealValues = pinRealValues; + values.realValues.assign(srcRealValues, srcRealValues + realValues->Length); + // Bool + pin_ptr<uint32_t> pinBoolVrs = &boolVRs[0]; + uint32_t* srcBoolVrs = pinBoolVrs; + values.boolValueRefs.assign(srcBoolVrs, srcBoolVrs + boolVRs->Length); + pin_ptr<int32_t> pinBoolValues = &boolValues[0]; + int32_t* srcBoolValues = pinBoolValues; + values.boolValues.assign(srcBoolValues, srcBoolValues + boolValues->Length); + // String + pin_ptr<uint32_t> pinStringVrs = &stringVRs[0]; + uint32_t* srcStringVrs = pinStringVrs; + values.stringValueRefs.assign(srcStringVrs, srcStringVrs + stringVRs->Length); + for (int i = 0; i < stringValues->Length; i++) + { + auto temp = stringValues[i]; // I dont know why marshal_as doesnt take stringValues[i] + values.stringValues.push_back(marshal_as<std::string>(temp)); + } + // RPC call + return _rpcFrontend->setValues(values); + } + void FrontendRpc::onNewValues(double timestamp, ValuesStruct values) { // Copy data into the EventArgs auto args = gcnew NewValuesEventArgs(); args->Timestamp = timestamp; - args->InstanceName = marshal_as<String^> (values.instanceName); + args->InstanceName = marshal_as<String^>(values.instanceName); // Int - args->IntegerValueRefs = gcnew array<unsigned int>(values.integerValueRefs.size()); + args->IntegerValueRefs = gcnew array<unsigned int>(static_cast<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()); + args->IntegerValues = gcnew array<int>(static_cast<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()); + args->RealValueRefs = gcnew array<unsigned int>(static_cast<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()); + args->RealValues = gcnew array<double>(static_cast<int>(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()); + args->BoolValueRefs = gcnew array<unsigned int>(static_cast<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 - args->StringValueRefs = gcnew array<unsigned int>(values.stringValueRefs.size()); + args->BoolValues = gcnew array<int>(static_cast<int>(values.boolValues.size())); + pin_ptr<int> pinBoolValues = &args->BoolValues[0]; + memcpy_s(pinBoolValues, args->BoolValueRefs->Length, values.boolValues.data(), values.boolValues.size()); + // String no memcpy possible because each string needs to be marshalled + args->StringValueRefs = gcnew array<unsigned int>(static_cast<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()); + args->StringValues = gcnew array<String^>(static_cast<int>(values.stringValues.size())); for (int i = 0; i < args->StringValues->Length; i++) { args->StringValues[i] = marshal_as<String^>(values.stringValues[i]); @@ -93,7 +188,7 @@ namespace ModeliRpc // Fire! NewValuesArrived(this, args); } - + void FrontendRpc::onLog(std::string instanceName, int status, std::string message) { auto args = gcnew LogEventArgs(); diff --git a/ModeliRpc/ModeliRpcCLR/ModeliRpc.h b/ModeliRpc/ModeliRpcCLR/ModeliRpc.h index ce5677b..76fcddf 100644 --- a/ModeliRpc/ModeliRpcCLR/ModeliRpc.h +++ b/ModeliRpc/ModeliRpcCLR/ModeliRpc.h @@ -8,6 +8,7 @@ #include <string> #include "NewValuesEventArgs.h" #include "LogEventArgs.h" +#include "RpcChannelLink.h" using namespace System; @@ -48,5 +49,27 @@ namespace ModeliRpc event EventHandler<NewValuesEventArgs^>^ NewValuesArrived; /// Gets fired when logging messages arrive from the backend. event EventHandler<LogEventArgs^>^ LogArrived; + /// Play the simulation, returns a fmi2Status + int Play(); + /// Fast forward the simulation, returns a fmi2Status + int PlayFast(double timeToPlay); + /// Pause the simulation without resetting it + void Pause(); + /// Stop & reset the simulation, returns a fmi2Status + int Stop(); + /// Add a fmu to the simulation, returns false on fail + bool AddFmu(String^ instanceName, array<Byte>^ fmuFileBuffer); + /// Remove a fmu to the simulation, returns false on fail + bool RemoveFmu(String^ instanceName); + /// Add a ChannelLink to the simulation, returns false on fail + bool AddChannelLink(RpcChannelLink^ channelLink); + /// Remove a ChannelLink from the simulation, returns false on fail + bool RemoveChannelLink(RpcChannelLink^ channelLink); + /// Set values in the simulation, retruns a fmi2Status + int SetValues(String^ instanceName, + array<unsigned int>^ intVRs, array<int>^ intValues, + array<unsigned int>^ realVRs, array<double>^ realValues, + array<unsigned int>^ boolVRs, array<int>^ boolValues, // Fmi2Bool = int + array<unsigned int>^ stringVRs, array<String^>^ stringValues); }; } \ No newline at end of file diff --git a/ModeliRpc/ModeliRpcCLR/ModeliRpcCLR.vcxproj b/ModeliRpc/ModeliRpcCLR/ModeliRpcCLR.vcxproj index 75e5902..3aff032 100644 --- a/ModeliRpc/ModeliRpcCLR/ModeliRpcCLR.vcxproj +++ b/ModeliRpc/ModeliRpcCLR/ModeliRpcCLR.vcxproj @@ -148,6 +148,7 @@ <ClInclude Include="ModeliRpc.h" /> <ClInclude Include="NewValuesEventArgs.h" /> <ClInclude Include="resource.h" /> + <ClInclude Include="RpcChannelLink.h" /> <ClInclude Include="Stdafx.h" /> </ItemGroup> <ItemGroup> @@ -155,6 +156,7 @@ <ClCompile Include="LogEventArgs.cpp" /> <ClCompile Include="ModeliRpc.cpp" /> <ClCompile Include="NewValuesEventArgs.cpp" /> + <ClCompile Include="RpcChannelLink.cpp" /> <ClCompile Include="Stdafx.cpp"> <PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">Create</PrecompiledHeader> <PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">Create</PrecompiledHeader> diff --git a/ModeliRpc/ModeliRpcCLR/ModeliRpcCLR.vcxproj.filters b/ModeliRpc/ModeliRpcCLR/ModeliRpcCLR.vcxproj.filters index d71ba5a..9476f3c 100644 --- a/ModeliRpc/ModeliRpcCLR/ModeliRpcCLR.vcxproj.filters +++ b/ModeliRpc/ModeliRpcCLR/ModeliRpcCLR.vcxproj.filters @@ -30,6 +30,9 @@ <ClInclude Include="LogEventArgs.h"> <Filter>Header Files</Filter> </ClInclude> + <ClInclude Include="RpcChannelLink.h"> + <Filter>Header Files</Filter> + </ClInclude> </ItemGroup> <ItemGroup> <ClCompile Include="AssemblyInfo.cpp"> @@ -47,6 +50,9 @@ <ClCompile Include="LogEventArgs.cpp"> <Filter>Source Files</Filter> </ClCompile> + <ClCompile Include="RpcChannelLink.cpp"> + <Filter>Source Files</Filter> + </ClCompile> </ItemGroup> <ItemGroup> <Text Include="ReadMe.txt" /> diff --git a/ModeliRpc/ModeliRpcCLR/NewValuesEventArgs.h b/ModeliRpc/ModeliRpcCLR/NewValuesEventArgs.h index cfe4f75..8472511 100644 --- a/ModeliRpc/ModeliRpcCLR/NewValuesEventArgs.h +++ b/ModeliRpc/ModeliRpcCLR/NewValuesEventArgs.h @@ -12,7 +12,7 @@ public: property array<unsigned int>^ RealValueRefs; property array<double>^ RealValues; property array<unsigned int>^ BoolValueRefs; - property array<bool>^ BoolValues; + property array<int>^ BoolValues; property array<unsigned int>^ StringValueRefs; property array<String^>^ StringValues; }; diff --git a/ModeliRpc/ModeliRpcCLR/RpcChannelLink.cpp b/ModeliRpc/ModeliRpcCLR/RpcChannelLink.cpp new file mode 100644 index 0000000..3331ab8 --- /dev/null +++ b/ModeliRpc/ModeliRpcCLR/RpcChannelLink.cpp @@ -0,0 +1,7 @@ +#include "stdafx.h" +#include "RpcChannelLink.h" + + +RpcChannelLink::RpcChannelLink() +{ +} diff --git a/ModeliRpc/ModeliRpcCLR/RpcChannelLink.h b/ModeliRpc/ModeliRpcCLR/RpcChannelLink.h new file mode 100644 index 0000000..a3354ea --- /dev/null +++ b/ModeliRpc/ModeliRpcCLR/RpcChannelLink.h @@ -0,0 +1,14 @@ +#pragma once +using namespace System; +ref class RpcChannelLink +{ +public: + RpcChannelLink(); + property String^ MasterInstanceName; + property String^ SlaveInstanceName; + property unsigned int MasterValueRef; + property unsigned int SlaveValueRef; + property double Factor; + property double Offset; +}; + diff --git a/ModeliRpc/ModeliRpcNative/CapnConverter.cpp b/ModeliRpc/ModeliRpcNative/CapnConverter.cpp index fa6ef93..4db9419 100644 --- a/ModeliRpc/ModeliRpcNative/CapnConverter.cpp +++ b/ModeliRpc/ModeliRpcNative/CapnConverter.cpp @@ -44,7 +44,7 @@ ValuesStruct CapnConverter::convertValues(Values::Reader reader) { boolVrs.push_back(element); } - std::vector<bool> boolValues; + std::vector<int32_t> boolValues; for (auto element : reader.getBoolValues()) { boolValues.push_back(element); diff --git a/ModeliRpc/ModeliRpcNative/IRpcFrontend.h b/ModeliRpc/ModeliRpcNative/IRpcFrontend.h index adf9824..e859903 100644 --- a/ModeliRpc/ModeliRpcNative/IRpcFrontend.h +++ b/ModeliRpc/ModeliRpcNative/IRpcFrontend.h @@ -11,7 +11,7 @@ struct ValuesStruct std::vector<uint32_t> realValueRefs; std::vector<double> realValues; std::vector<uint32_t> boolValueRefs; - std::vector<bool> boolValues; + std::vector<int32_t> boolValues; std::vector<uint32_t> stringValueRefs; std::vector<std::string> stringValues; }; @@ -38,10 +38,12 @@ class IRpcFrontend { public: virtual void destroy() = 0; - virtual void connect(std::string address, int port) = 0; + virtual void connect(std::string address, unsigned int port) = 0; virtual void registerCallbacks(NewValuesCallback newValuesCallback, LogCallback logCallback) = 0; /// Returns fmi2Status virtual int play() = 0; + /// Returns fmi2Status + virtual int playFast(double timeToPlay) = 0; virtual void pause() = 0; /// Returns fmi2Status virtual int stop() = 0; diff --git a/ModeliRpc/ModeliRpcNative/ModeliRpc.capnp.c++ b/ModeliRpc/ModeliRpcNative/ModeliRpc.capnp.c++ index d483ef7..7b9a27e 100644 --- a/ModeliRpc/ModeliRpcNative/ModeliRpc.capnp.c++ +++ b/ModeliRpc/ModeliRpcNative/ModeliRpc.capnp.c++ @@ -367,17 +367,17 @@ const ::capnp::_::RawSchema s_935c832cec2e072f = { 0, 1, i_935c832cec2e072f, nullptr, nullptr, { &s_935c832cec2e072f, nullptr, nullptr, 0, 0, nullptr } }; #endif // !CAPNP_LITE -static const ::capnp::_::AlignedData<18> b_92d58775d6d1f6fe = { +static const ::capnp::_::AlignedData<35> b_92d58775d6d1f6fe = { { 0, 0, 0, 0, 5, 0, 6, 0, 254, 246, 209, 214, 117, 135, 213, 146, - 30, 0, 0, 0, 1, 0, 0, 0, + 30, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 21, 0, 0, 0, 114, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, + 33, 0, 0, 0, 63, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 77, 111, 100, 101, 108, 105, 82, 112, @@ -385,13 +385,32 @@ static const ::capnp::_::AlignedData<18> b_92d58775d6d1f6fe = { 77, 111, 100, 101, 108, 105, 66, 97, 99, 107, 101, 110, 100, 46, 112, 108, 97, 121, 70, 97, 115, 116, 36, 80, - 97, 114, 97, 109, 115, 0, 0, 0, } + 97, 114, 97, 109, 115, 0, 0, 0, + 4, 0, 0, 0, 3, 0, 4, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 1, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 13, 0, 0, 0, 90, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 12, 0, 0, 0, 3, 0, 1, 0, + 24, 0, 0, 0, 2, 0, 1, 0, + 116, 105, 109, 101, 84, 111, 80, 108, + 97, 121, 0, 0, 0, 0, 0, 0, + 11, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 11, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, } }; ::capnp::word const* const bp_92d58775d6d1f6fe = b_92d58775d6d1f6fe.words; #if !CAPNP_LITE +static const uint16_t m_92d58775d6d1f6fe[] = {0}; +static const uint16_t i_92d58775d6d1f6fe[] = {0}; const ::capnp::_::RawSchema s_92d58775d6d1f6fe = { - 0x92d58775d6d1f6fe, b_92d58775d6d1f6fe.words, 18, nullptr, nullptr, - 0, 0, nullptr, nullptr, nullptr, { &s_92d58775d6d1f6fe, nullptr, nullptr, 0, 0, nullptr } + 0x92d58775d6d1f6fe, b_92d58775d6d1f6fe.words, 35, nullptr, m_92d58775d6d1f6fe, + 0, 1, i_92d58775d6d1f6fe, nullptr, nullptr, { &s_92d58775d6d1f6fe, nullptr, nullptr, 0, 0, nullptr } }; #endif // !CAPNP_LITE static const ::capnp::_::AlignedData<34> b_dce78f15ea9b3d58 = { @@ -1538,7 +1557,7 @@ static const ::capnp::_::AlignedData<194> b_a43101940a8689a5 = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 1, 0, - 1, 0, 0, 0, 0, 0, 0, 0, + 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, diff --git a/ModeliRpc/ModeliRpcNative/ModeliRpc.capnp.h b/ModeliRpc/ModeliRpcNative/ModeliRpc.capnp.h index 5342c7c..1f36039 100644 --- a/ModeliRpc/ModeliRpcNative/ModeliRpc.capnp.h +++ b/ModeliRpc/ModeliRpcNative/ModeliRpc.capnp.h @@ -141,7 +141,7 @@ struct ModeliBackend::PlayFastParams { class Pipeline; struct _capnpPrivate { - CAPNP_DECLARE_STRUCT_HEADER(92d58775d6d1f6fe, 0, 0) + CAPNP_DECLARE_STRUCT_HEADER(92d58775d6d1f6fe, 1, 0) #if !CAPNP_LITE static constexpr ::capnp::_::RawBrandedSchema const* brand() { return &schema->defaultBrand; } #endif // !CAPNP_LITE @@ -881,6 +881,8 @@ public: } #endif // !CAPNP_LITE + inline double getTimeToPlay() const; + private: ::capnp::_::StructReader _reader; template <typename, ::capnp::Kind> @@ -909,6 +911,9 @@ public: inline ::kj::StringTree toString() const { return asReader().toString(); } #endif // !CAPNP_LITE + inline double getTimeToPlay(); + inline void setTimeToPlay(double value); + private: ::capnp::_::StructBuilder _builder; template <typename, ::capnp::Kind> @@ -2673,7 +2678,7 @@ public: inline ::capnp::List< ::uint32_t>::Reader getBoolValueRefs() const; inline bool hasBoolValues() const; - inline ::capnp::List<bool>::Reader getBoolValues() const; + inline ::capnp::List< ::int32_t>::Reader getBoolValues() const; inline bool hasStringValueRefs() const; inline ::capnp::List< ::uint32_t>::Reader getStringValueRefs() const; @@ -2757,12 +2762,12 @@ public: inline ::capnp::Orphan< ::capnp::List< ::uint32_t>> disownBoolValueRefs(); inline bool hasBoolValues(); - inline ::capnp::List<bool>::Builder getBoolValues(); - inline void setBoolValues( ::capnp::List<bool>::Reader value); - inline void setBoolValues(::kj::ArrayPtr<const bool> value); - inline ::capnp::List<bool>::Builder initBoolValues(unsigned int size); - inline void adoptBoolValues(::capnp::Orphan< ::capnp::List<bool>>&& value); - inline ::capnp::Orphan< ::capnp::List<bool>> disownBoolValues(); + inline ::capnp::List< ::int32_t>::Builder getBoolValues(); + inline void setBoolValues( ::capnp::List< ::int32_t>::Reader value); + inline void setBoolValues(::kj::ArrayPtr<const ::int32_t> value); + inline ::capnp::List< ::int32_t>::Builder initBoolValues(unsigned int size); + inline void adoptBoolValues(::capnp::Orphan< ::capnp::List< ::int32_t>>&& value); + inline ::capnp::Orphan< ::capnp::List< ::int32_t>> disownBoolValues(); inline bool hasStringValueRefs(); inline ::capnp::List< ::uint32_t>::Builder getStringValueRefs(); @@ -2970,6 +2975,20 @@ inline void ModeliBackend::PlayResults::Builder::setResult( ::int16_t value) { ::capnp::bounded<0>() * ::capnp::ELEMENTS, value); } +inline double ModeliBackend::PlayFastParams::Reader::getTimeToPlay() const { + return _reader.getDataField<double>( + ::capnp::bounded<0>() * ::capnp::ELEMENTS); +} + +inline double ModeliBackend::PlayFastParams::Builder::getTimeToPlay() { + return _builder.getDataField<double>( + ::capnp::bounded<0>() * ::capnp::ELEMENTS); +} +inline void ModeliBackend::PlayFastParams::Builder::setTimeToPlay(double value) { + _builder.setDataField<double>( + ::capnp::bounded<0>() * ::capnp::ELEMENTS, value); +} + inline ::int16_t ModeliBackend::PlayFastResults::Reader::getResult() const { return _reader.getDataField< ::int16_t>( ::capnp::bounded<0>() * ::capnp::ELEMENTS); @@ -3717,33 +3736,33 @@ inline bool Values::Builder::hasBoolValues() { return !_builder.getPointerField( ::capnp::bounded<6>() * ::capnp::POINTERS).isNull(); } -inline ::capnp::List<bool>::Reader Values::Reader::getBoolValues() const { - return ::capnp::_::PointerHelpers< ::capnp::List<bool>>::get(_reader.getPointerField( +inline ::capnp::List< ::int32_t>::Reader Values::Reader::getBoolValues() const { + return ::capnp::_::PointerHelpers< ::capnp::List< ::int32_t>>::get(_reader.getPointerField( ::capnp::bounded<6>() * ::capnp::POINTERS)); } -inline ::capnp::List<bool>::Builder Values::Builder::getBoolValues() { - return ::capnp::_::PointerHelpers< ::capnp::List<bool>>::get(_builder.getPointerField( +inline ::capnp::List< ::int32_t>::Builder Values::Builder::getBoolValues() { + return ::capnp::_::PointerHelpers< ::capnp::List< ::int32_t>>::get(_builder.getPointerField( ::capnp::bounded<6>() * ::capnp::POINTERS)); } -inline void Values::Builder::setBoolValues( ::capnp::List<bool>::Reader value) { - ::capnp::_::PointerHelpers< ::capnp::List<bool>>::set(_builder.getPointerField( +inline void Values::Builder::setBoolValues( ::capnp::List< ::int32_t>::Reader value) { + ::capnp::_::PointerHelpers< ::capnp::List< ::int32_t>>::set(_builder.getPointerField( ::capnp::bounded<6>() * ::capnp::POINTERS), value); } -inline void Values::Builder::setBoolValues(::kj::ArrayPtr<const bool> value) { - ::capnp::_::PointerHelpers< ::capnp::List<bool>>::set(_builder.getPointerField( +inline void Values::Builder::setBoolValues(::kj::ArrayPtr<const ::int32_t> value) { + ::capnp::_::PointerHelpers< ::capnp::List< ::int32_t>>::set(_builder.getPointerField( ::capnp::bounded<6>() * ::capnp::POINTERS), value); } -inline ::capnp::List<bool>::Builder Values::Builder::initBoolValues(unsigned int size) { - return ::capnp::_::PointerHelpers< ::capnp::List<bool>>::init(_builder.getPointerField( +inline ::capnp::List< ::int32_t>::Builder Values::Builder::initBoolValues(unsigned int size) { + return ::capnp::_::PointerHelpers< ::capnp::List< ::int32_t>>::init(_builder.getPointerField( ::capnp::bounded<6>() * ::capnp::POINTERS), size); } inline void Values::Builder::adoptBoolValues( - ::capnp::Orphan< ::capnp::List<bool>>&& value) { - ::capnp::_::PointerHelpers< ::capnp::List<bool>>::adopt(_builder.getPointerField( + ::capnp::Orphan< ::capnp::List< ::int32_t>>&& value) { + ::capnp::_::PointerHelpers< ::capnp::List< ::int32_t>>::adopt(_builder.getPointerField( ::capnp::bounded<6>() * ::capnp::POINTERS), kj::mv(value)); } -inline ::capnp::Orphan< ::capnp::List<bool>> Values::Builder::disownBoolValues() { - return ::capnp::_::PointerHelpers< ::capnp::List<bool>>::disown(_builder.getPointerField( +inline ::capnp::Orphan< ::capnp::List< ::int32_t>> Values::Builder::disownBoolValues() { + return ::capnp::_::PointerHelpers< ::capnp::List< ::int32_t>>::disown(_builder.getPointerField( ::capnp::bounded<6>() * ::capnp::POINTERS)); } diff --git a/ModeliRpc/ModeliRpcNative/RpcFrontend.cpp b/ModeliRpc/ModeliRpcNative/RpcFrontend.cpp index 0fc8546..f7d0021 100644 --- a/ModeliRpc/ModeliRpcNative/RpcFrontend.cpp +++ b/ModeliRpc/ModeliRpcNative/RpcFrontend.cpp @@ -18,7 +18,7 @@ void RpcFrontend::destroy() delete(this); } -void RpcFrontend::connect(std::string address, int port) +void RpcFrontend::connect(std::string address, unsigned int port) { _client = std::make_unique<capnp::EzRpcClient>(address, port); } @@ -46,6 +46,18 @@ int RpcFrontend::play() return backend.playRequest().send().wait(_client->getWaitScope()).getResult(); } +int RpcFrontend::playFast(double timeToPlay) +{ + if (!_client) + { + return FMI2_ERROR; + } + auto backend = _client->getMain<ModeliBackend>(); + auto request = backend.playFastRequest(); + request.setTimeToPlay(timeToPlay); + request.send().wait(_client->getWaitScope()).getResult(); +} + void RpcFrontend::pause() { if (!_client) @@ -128,4 +140,4 @@ int RpcFrontend::setValues(ValuesStruct values) auto request = backend.setValuesRequest(); request.setValues(CapnConverter::convertValues(values)); return request.send().wait(_client->getWaitScope()).getResult(); -} \ No newline at end of file +} diff --git a/ModeliRpc/ModeliRpcNative/RpcFrontend.h b/ModeliRpc/ModeliRpcNative/RpcFrontend.h index e4e1e54..d81fe70 100644 --- a/ModeliRpc/ModeliRpcNative/RpcFrontend.h +++ b/ModeliRpc/ModeliRpcNative/RpcFrontend.h @@ -19,9 +19,10 @@ private: // Inherited via IModeliFrontend void destroy() override; - void connect(std::string address, int port) override; + void connect(std::string address, unsigned int port) override; void registerCallbacks(NewValuesCallback newValuesCallback, LogCallback logCallback) override; int play() override; + int playFast(double timeToPlay) override; void pause() override; int stop() override; bool addFmu(std::string instanceName, std::vector<unsigned char> fmuFile) override; -- GitLab