From db4e95639eb7a274f433134fd3888e13eb2afbd9 Mon Sep 17 00:00:00 2001
From: Tim Uebelhoer <tim.uebelhoer@rwth-aachen.de>
Date: Tue, 2 Jan 2018 15:25:45 +0100
Subject: [PATCH] Grpc now with generated files from the vcpkg. The
 waitable_queue is unit tested.

---
 BackendTests/BackendTests.vcxproj             | 24 +++--
 BackendTests/BackendTests.vcxproj.filters     |  3 +
 BackendTests/SimulatorTest.cpp                |  2 +-
 BackendTests/WaitableQueueTest.cpp            | 53 +++++++++++
 CreatedGrpc/CreatedGrpc.vcxitems              |  8 +-
 {Network => CreatedGrpc}/ModeliRpc.grpc.pb.cc |  0
 {Network => CreatedGrpc}/ModeliRpc.grpc.pb.h  |  0
 {Network => CreatedGrpc}/ModeliRpc.pb.cc      |  0
 {Network => CreatedGrpc}/ModeliRpc.pb.h       |  0
 MC_BackEnd.sln                                | 10 +-
 MC_Backend_Linux/MC_Backend_Linux.vcxproj     | 14 +--
 MC_Backend_Win/MC_Backend_Win.vcxproj         | 10 +-
 Main/main.cpp                                 |  4 +-
 Network/ModeliGrpcServer.cpp                  | 52 ++---------
 Network/ModeliGrpcServer.h                    | 24 ++---
 Network/Network.vcxitems                      |  4 -
 Network/Network.vcxitems.filters              | 12 ---
 Simulation/{FMUEngine.cpp => Simulation.cpp}  | 91 ++++++++++---------
 Simulation/{FmuEngine.hpp => Simulation.hpp}  |  6 +-
 Simulation/Simulation.vcxitems                |  4 +-
 Simulation/Simulation.vcxitems.filters        |  6 +-
 UtilityClasses/UtilityClasses.vcxitems        | 20 ++++
 UtilityClasses/WaitableQueue.h                | 79 ++++++++++++++++
 23 files changed, 272 insertions(+), 154 deletions(-)
 create mode 100644 BackendTests/WaitableQueueTest.cpp
 rename {Network => CreatedGrpc}/ModeliRpc.grpc.pb.cc (100%)
 rename {Network => CreatedGrpc}/ModeliRpc.grpc.pb.h (100%)
 rename {Network => CreatedGrpc}/ModeliRpc.pb.cc (100%)
 rename {Network => CreatedGrpc}/ModeliRpc.pb.h (100%)
 rename Simulation/{FMUEngine.cpp => Simulation.cpp} (79%)
 rename Simulation/{FmuEngine.hpp => Simulation.hpp} (98%)
 create mode 100644 UtilityClasses/UtilityClasses.vcxitems
 create mode 100644 UtilityClasses/WaitableQueue.h

diff --git a/BackendTests/BackendTests.vcxproj b/BackendTests/BackendTests.vcxproj
index ee75574..dd7738f 100644
--- a/BackendTests/BackendTests.vcxproj
+++ b/BackendTests/BackendTests.vcxproj
@@ -63,9 +63,8 @@
   <ImportGroup Label="Shared">
     <Import Project="..\Simulation\Simulation.vcxitems" Label="Shared" />
     <Import Project="..\Files\Files.vcxitems" Label="Shared" />
-    <Import Project="..\Main\Main.vcxitems" Label="Shared" />
     <Import Project="..\FMU-Core\NativeFmuShared\NativeFmuShared.vcxitems" Label="Shared" />
-    <Import Project="..\Network\Network.vcxitems" Label="Shared" />
+    <Import Project="..\UtilityClasses\UtilityClasses.vcxitems" Label="Shared" />
   </ImportGroup>
   <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
     <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
@@ -99,17 +98,17 @@
       <Optimization>MaxSpeed</Optimization>
       <FunctionLevelLinking>true</FunctionLevelLinking>
       <IntrinsicFunctions>true</IntrinsicFunctions>
-      <AdditionalIncludeDirectories>../AdditionalIncludes/flatbuffers;../AdditionalIncludes/MC_Protocol;C:\boost_1_65_1;$(VCInstallDir)UnitTest\include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+      <AdditionalIncludeDirectories>$(VCInstallDir)UnitTest\include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
       <PreprocessorDefinitions>NDEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
       <UseFullPaths>true</UseFullPaths>
-      <AdditionalOptions>-DBOOST_DATE_TIME_NO_LIB -DBOOST_REGEX_NO_LIB %(AdditionalOptions)</AdditionalOptions>
+      <AdditionalOptions>-DBOOST_DATE_TIME_NO_LIB -DBOOST_REGEX_NO_LIB -D_WIN32_WINNT=0x0A00 %(AdditionalOptions)</AdditionalOptions>
     </ClCompile>
     <Link>
       <SubSystem>Windows</SubSystem>
       <EnableCOMDATFolding>true</EnableCOMDATFolding>
       <OptimizeReferences>true</OptimizeReferences>
       <AdditionalLibraryDirectories>C:\boost_1_65_1\stage\lib;$(VCInstallDir)UnitTest\lib;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
-      <AdditionalDependencies>Winmm.lib;kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies)</AdditionalDependencies>
+      <AdditionalDependencies>Winmm.lib;%(AdditionalDependencies)</AdditionalDependencies>
     </Link>
   </ItemDefinitionGroup>
   <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
@@ -117,13 +116,15 @@
       <PrecompiledHeader>NotUsing</PrecompiledHeader>
       <WarningLevel>Level3</WarningLevel>
       <Optimization>Disabled</Optimization>
-      <AdditionalIncludeDirectories>../AdditionalIncludes/flatbuffers;../AdditionalIncludes/MC_Protocol;C:\boost_1_65_1;$(VCInstallDir)UnitTest\include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+      <AdditionalIncludeDirectories>$(VCInstallDir)UnitTest\include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
       <PreprocessorDefinitions>WIN32;_DEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
       <UseFullPaths>true</UseFullPaths>
+      <AdditionalOptions>-DBOOST_DATE_TIME_NO_LIB -DBOOST_REGEX_NO_LIB -D_WIN32_WINNT=0x0A00 %(AdditionalOptions)</AdditionalOptions>
     </ClCompile>
     <Link>
       <SubSystem>Windows</SubSystem>
       <AdditionalLibraryDirectories>$(VCInstallDir)UnitTest\lib;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
+      <AdditionalDependencies>Winmm.lib;%(AdditionalDependencies)</AdditionalDependencies>
     </Link>
   </ItemDefinitionGroup>
   <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
@@ -131,15 +132,15 @@
       <PrecompiledHeader>NotUsing</PrecompiledHeader>
       <WarningLevel>Level3</WarningLevel>
       <Optimization>Disabled</Optimization>
-      <AdditionalIncludeDirectories>../AdditionalIncludes/flatbuffers;../AdditionalIncludes/MC_Protocol;C:\boost_1_65_1;$(VCInstallDir)UnitTest\include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+      <AdditionalIncludeDirectories>$(VCInstallDir)UnitTest\include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
       <PreprocessorDefinitions>_DEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
       <UseFullPaths>true</UseFullPaths>
-      <AdditionalOptions>-DBOOST_DATE_TIME_NO_LIB -DBOOST_REGEX_NO_LIB %(AdditionalOptions)</AdditionalOptions>
+      <AdditionalOptions>-DBOOST_DATE_TIME_NO_LIB -DBOOST_REGEX_NO_LIB -D_WIN32_WINNT=0x0A00 %(AdditionalOptions)</AdditionalOptions>
     </ClCompile>
     <Link>
       <SubSystem>Windows</SubSystem>
       <AdditionalLibraryDirectories>C:\boost_1_65_1\stage\lib;$(VCInstallDir)UnitTest\lib;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
-      <AdditionalDependencies>Winmm.lib;kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies)</AdditionalDependencies>
+      <AdditionalDependencies>Winmm.lib;%(AdditionalDependencies)</AdditionalDependencies>
     </Link>
   </ItemDefinitionGroup>
   <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
@@ -149,15 +150,17 @@
       <Optimization>MaxSpeed</Optimization>
       <FunctionLevelLinking>true</FunctionLevelLinking>
       <IntrinsicFunctions>true</IntrinsicFunctions>
-      <AdditionalIncludeDirectories>../AdditionalIncludes/flatbuffers;../AdditionalIncludes/MC_Protocol;C:\boost_1_65_1;$(VCInstallDir)UnitTest\include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+      <AdditionalIncludeDirectories>$(VCInstallDir)UnitTest\include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
       <PreprocessorDefinitions>WIN32;NDEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
       <UseFullPaths>true</UseFullPaths>
+      <AdditionalOptions>-DBOOST_DATE_TIME_NO_LIB -DBOOST_REGEX_NO_LIB -D_WIN32_WINNT=0x0A00 %(AdditionalOptions)</AdditionalOptions>
     </ClCompile>
     <Link>
       <SubSystem>Windows</SubSystem>
       <EnableCOMDATFolding>true</EnableCOMDATFolding>
       <OptimizeReferences>true</OptimizeReferences>
       <AdditionalLibraryDirectories>$(VCInstallDir)UnitTest\lib;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
+      <AdditionalDependencies>Winmm.lib;%(AdditionalDependencies)</AdditionalDependencies>
     </Link>
   </ItemDefinitionGroup>
   <ItemGroup>
@@ -174,6 +177,7 @@
       <PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">Create</PrecompiledHeader>
     </ClCompile>
     <ClCompile Include="SimulatorTest.cpp" />
+    <ClCompile Include="WaitableQueueTest.cpp" />
   </ItemGroup>
   <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
   <ImportGroup Label="ExtensionTargets">
diff --git a/BackendTests/BackendTests.vcxproj.filters b/BackendTests/BackendTests.vcxproj.filters
index daf54bf..de4ac7c 100644
--- a/BackendTests/BackendTests.vcxproj.filters
+++ b/BackendTests/BackendTests.vcxproj.filters
@@ -35,5 +35,8 @@
     <ClCompile Include="EngineObserver.cpp">
       <Filter>Quelldateien</Filter>
     </ClCompile>
+    <ClCompile Include="WaitableQueueTest.cpp">
+      <Filter>Quelldateien</Filter>
+    </ClCompile>
   </ItemGroup>
 </Project>
\ No newline at end of file
diff --git a/BackendTests/SimulatorTest.cpp b/BackendTests/SimulatorTest.cpp
index 9cecf3f..07c631e 100644
--- a/BackendTests/SimulatorTest.cpp
+++ b/BackendTests/SimulatorTest.cpp
@@ -15,7 +15,7 @@ namespace BackendTests
 		TEST_METHOD(TestFmuEngine)
 		{
 			// Basic setup
-			FmuEngine fmuEngine("TestID");
+			Simulation fmuEngine("TestID");
 			auto observer = std::make_shared<EngineObserver>();
 			// Add & remove observer
 			fmuEngine.AddObserver(observer);
diff --git a/BackendTests/WaitableQueueTest.cpp b/BackendTests/WaitableQueueTest.cpp
new file mode 100644
index 0000000..9c6519f
--- /dev/null
+++ b/BackendTests/WaitableQueueTest.cpp
@@ -0,0 +1,53 @@
+#include "stdafx.h"
+#include "CppUnitTest.h"
+#include "WaitableQueue.h"
+
+using namespace Microsoft::VisualStudio::CppUnitTestFramework;
+
+namespace BackendTests
+{
+    TEST_CLASS(WaitableQueueTest)
+    {
+    private:
+        Utility::WaitableQueue<int> _queue;
+    public:
+
+        TEST_METHOD_INITIALIZE(TestWaitableQueueInitialize)
+        {
+            // Boost none is expected
+            Assert::IsTrue(!_queue.pop());
+        }
+
+        void produce(int n)
+        {
+            for (int i = 0; i < n; i++)
+            {
+                _queue.push(i);
+            }
+        }
+
+        void consume(int n)
+        {
+            for (int i = 0; i < n; i++)
+            {
+                Assert::AreEqual(i, _queue.wait_and_pop());
+            }
+        }
+
+        TEST_METHOD(TestWaitableQueuePush_n_Pop)
+        {
+            const int COUNT = 10000;
+            // Produce one more than consuming
+            std::thread consumer(std::bind(&WaitableQueueTest::consume, this, COUNT));
+            std::thread producer(std::bind(&WaitableQueueTest::produce, this, COUNT + 1));
+            // Wait for the threads
+            producer.join();
+            consumer.join();
+            // One more availabe to test regular pop
+            Assert::AreEqual(COUNT, _queue.pop().get());
+            // Nothing available
+            Assert::IsTrue(!_queue.pop());
+        }
+
+    };
+}
\ No newline at end of file
diff --git a/CreatedGrpc/CreatedGrpc.vcxitems b/CreatedGrpc/CreatedGrpc.vcxitems
index e8b0d21..2a02ca3 100644
--- a/CreatedGrpc/CreatedGrpc.vcxitems
+++ b/CreatedGrpc/CreatedGrpc.vcxitems
@@ -14,11 +14,11 @@
     <ProjectCapability Include="SourceItemsFromImports" />
   </ItemGroup>
   <ItemGroup>
-    <ClCompile Include="$(MSBuildThisFileDirectory)..\ModeliProtocol\ModeliRpc_Cpp\ModeliRpc.grpc.pb.cc" />
-    <ClCompile Include="$(MSBuildThisFileDirectory)..\ModeliProtocol\ModeliRpc_Cpp\ModeliRpc.pb.cc" />
+    <ClInclude Include="$(MSBuildThisFileDirectory)ModeliRpc.grpc.pb.h" />
+    <ClInclude Include="$(MSBuildThisFileDirectory)ModeliRpc.pb.h" />
   </ItemGroup>
   <ItemGroup>
-    <ClInclude Include="$(MSBuildThisFileDirectory)..\ModeliProtocol\ModeliRpc_Cpp\ModeliRpc.grpc.pb.h" />
-    <ClInclude Include="$(MSBuildThisFileDirectory)..\ModeliProtocol\ModeliRpc_Cpp\ModeliRpc.pb.h" />
+    <ClCompile Include="$(MSBuildThisFileDirectory)ModeliRpc.grpc.pb.cc" />
+    <ClCompile Include="$(MSBuildThisFileDirectory)ModeliRpc.pb.cc" />
   </ItemGroup>
 </Project>
\ No newline at end of file
diff --git a/Network/ModeliRpc.grpc.pb.cc b/CreatedGrpc/ModeliRpc.grpc.pb.cc
similarity index 100%
rename from Network/ModeliRpc.grpc.pb.cc
rename to CreatedGrpc/ModeliRpc.grpc.pb.cc
diff --git a/Network/ModeliRpc.grpc.pb.h b/CreatedGrpc/ModeliRpc.grpc.pb.h
similarity index 100%
rename from Network/ModeliRpc.grpc.pb.h
rename to CreatedGrpc/ModeliRpc.grpc.pb.h
diff --git a/Network/ModeliRpc.pb.cc b/CreatedGrpc/ModeliRpc.pb.cc
similarity index 100%
rename from Network/ModeliRpc.pb.cc
rename to CreatedGrpc/ModeliRpc.pb.cc
diff --git a/Network/ModeliRpc.pb.h b/CreatedGrpc/ModeliRpc.pb.h
similarity index 100%
rename from Network/ModeliRpc.pb.h
rename to CreatedGrpc/ModeliRpc.pb.h
diff --git a/MC_BackEnd.sln b/MC_BackEnd.sln
index a8dee85..94bdcbd 100644
--- a/MC_BackEnd.sln
+++ b/MC_BackEnd.sln
@@ -22,30 +22,36 @@ Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "BackendTests", "BackendTest
 EndProject
 Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "CreatedGrpc", "CreatedGrpc\CreatedGrpc.vcxitems", "{9C78546C-04B5-45BB-99C4-9FFBAF846BFE}"
 EndProject
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "Utility", "UtilityClasses\UtilityClasses.vcxitems", "{FD95EBAC-8E33-43D3-88BA-04A2B02D7D9E}"
+EndProject
 Global
 	GlobalSection(SharedMSBuildProjectFiles) = preSolution
 		Network\Network.vcxitems*{059b87b7-3153-4b08-b4db-12f671328ebb}*SharedItemsImports = 9
 		Files\Files.vcxitems*{500f1104-28c6-4be4-a180-8028843972ac}*SharedItemsImports = 4
 		FMU-Core\NativeFmuShared\NativeFmuShared.vcxitems*{500f1104-28c6-4be4-a180-8028843972ac}*SharedItemsImports = 4
-		Main\Main.vcxitems*{500f1104-28c6-4be4-a180-8028843972ac}*SharedItemsImports = 4
-		Network\Network.vcxitems*{500f1104-28c6-4be4-a180-8028843972ac}*SharedItemsImports = 4
 		Simulation\Simulation.vcxitems*{500f1104-28c6-4be4-a180-8028843972ac}*SharedItemsImports = 4
+		UtilityClasses\UtilityClasses.vcxitems*{500f1104-28c6-4be4-a180-8028843972ac}*SharedItemsImports = 4
 		Files\Files.vcxitems*{600c8d4e-39a2-40dd-b779-ac823cd2f5cc}*SharedItemsImports = 9
+		CreatedGrpc\CreatedGrpc.vcxitems*{661905ce-1efd-4d2b-8cc8-0a8bafb5242f}*SharedItemsImports = 4
 		Files\Files.vcxitems*{661905ce-1efd-4d2b-8cc8-0a8bafb5242f}*SharedItemsImports = 4
 		FMU-Core\NativeFmuShared\NativeFmuShared.vcxitems*{661905ce-1efd-4d2b-8cc8-0a8bafb5242f}*SharedItemsImports = 4
 		Main\Main.vcxitems*{661905ce-1efd-4d2b-8cc8-0a8bafb5242f}*SharedItemsImports = 4
 		Network\Network.vcxitems*{661905ce-1efd-4d2b-8cc8-0a8bafb5242f}*SharedItemsImports = 4
 		Simulation\Simulation.vcxitems*{661905ce-1efd-4d2b-8cc8-0a8bafb5242f}*SharedItemsImports = 4
+		UtilityClasses\UtilityClasses.vcxitems*{661905ce-1efd-4d2b-8cc8-0a8bafb5242f}*SharedItemsImports = 4
 		Simulation\Simulation.vcxitems*{8510328c-8540-419b-96d9-1e5ff396366f}*SharedItemsImports = 9
+		CreatedGrpc\CreatedGrpc.vcxitems*{87f7a408-7c05-47a8-a1d7-4a53ca350666}*SharedItemsImports = 4
 		Files\Files.vcxitems*{87f7a408-7c05-47a8-a1d7-4a53ca350666}*SharedItemsImports = 4
 		FMU-Core\NativeFmuShared\NativeFmuShared.vcxitems*{87f7a408-7c05-47a8-a1d7-4a53ca350666}*SharedItemsImports = 4
 		Main\Main.vcxitems*{87f7a408-7c05-47a8-a1d7-4a53ca350666}*SharedItemsImports = 4
 		Network\Network.vcxitems*{87f7a408-7c05-47a8-a1d7-4a53ca350666}*SharedItemsImports = 4
 		Simulation\Simulation.vcxitems*{87f7a408-7c05-47a8-a1d7-4a53ca350666}*SharedItemsImports = 4
+		UtilityClasses\UtilityClasses.vcxitems*{87f7a408-7c05-47a8-a1d7-4a53ca350666}*SharedItemsImports = 4
 		CreatedGrpc\CreatedGrpc.vcxitems*{9c78546c-04b5-45bb-99c4-9ffbaf846bfe}*SharedItemsImports = 9
 		FMU-Core\NativeFmuShared\NativeFmuShared.vcxitems*{b23eb13a-9d85-4f36-8327-543fa7b6a01e}*SharedItemsImports = 9
 		Main\Main.vcxitems*{de14bb19-25d6-4ec9-8878-d5fc8ec737bb}*SharedItemsImports = 9
 		FMU-Core\NativeFmuShared\NativeFmuShared.vcxitems*{f31eeb13-5399-4e96-af1f-b0bcf3119b5f}*SharedItemsImports = 4
+		UtilityClasses\UtilityClasses.vcxitems*{fd95ebac-8e33-43d3-88ba-04a2b02d7d9e}*SharedItemsImports = 9
 	EndGlobalSection
 	GlobalSection(SolutionConfigurationPlatforms) = preSolution
 		Debug|ARM = Debug|ARM
diff --git a/MC_Backend_Linux/MC_Backend_Linux.vcxproj b/MC_Backend_Linux/MC_Backend_Linux.vcxproj
index 865f522..b2d681c 100644
--- a/MC_Backend_Linux/MC_Backend_Linux.vcxproj
+++ b/MC_Backend_Linux/MC_Backend_Linux.vcxproj
@@ -69,6 +69,8 @@
     <Import Project="..\Network\Network.vcxitems" Label="Shared" />
     <Import Project="..\Simulation\Simulation.vcxitems" Label="Shared" />
     <Import Project="..\Main\Main.vcxitems" Label="Shared" />
+    <Import Project="..\UtilityClasses\UtilityClasses.vcxitems" Label="Shared" />
+    <Import Project="..\CreatedGrpc\CreatedGrpc.vcxitems" Label="Shared" />
   </ImportGroup>
   <ImportGroup Label="PropertySheets" />
   <PropertyGroup Label="UserMacros" />
@@ -105,7 +107,7 @@
       <SharedLibrarySearchPath>%(SharedLibrarySearchPath)</SharedLibrarySearchPath>
     </Link>
     <ClCompile>
-      <AdditionalIncludeDirectories>../FMU-Core/NativeFmuShared;../Network;../Files;../Simulation;../AdditionalIncludes/flatbuffers;../AdditionalIncludes/MC_Protocol;</AdditionalIncludeDirectories>
+      <AdditionalIncludeDirectories>../FMU-Core/NativeFmuShared;../Network;../Files;../Simulation</AdditionalIncludeDirectories>
       <AdditionalOptions>-DBOOST_DATE_TIME_NO_LIB -DBOOST_REGEX_NO_LIB </AdditionalOptions>
       <CppLanguageStandard>c++1y</CppLanguageStandard>
     </ClCompile>
@@ -119,7 +121,7 @@
       <SharedLibrarySearchPath>%(SharedLibrarySearchPath)</SharedLibrarySearchPath>
     </Link>
     <ClCompile>
-      <AdditionalIncludeDirectories>../FMU-Core/NativeFmuShared;../Network;../Files;../Simulation;../AdditionalIncludes/flatbuffers;../AdditionalIncludes/MC_Protocol;</AdditionalIncludeDirectories>
+      <AdditionalIncludeDirectories>../FMU-Core/NativeFmuShared;../Network;../Files;../Simulation</AdditionalIncludeDirectories>
       <AdditionalOptions>-DBOOST_DATE_TIME_NO_LIB -DBOOST_REGEX_NO_LIB </AdditionalOptions>
       <CppLanguageStandard>c++1y</CppLanguageStandard>
     </ClCompile>
@@ -133,7 +135,7 @@
       <SharedLibrarySearchPath>%(SharedLibrarySearchPath)</SharedLibrarySearchPath>
     </Link>
     <ClCompile>
-      <AdditionalIncludeDirectories>../FMU-Core/NativeFmuShared;../Network;../Files;../Simulation;../AdditionalIncludes/flatbuffers;../AdditionalIncludes/MC_Protocol;</AdditionalIncludeDirectories>
+      <AdditionalIncludeDirectories>../FMU-Core/NativeFmuShared;../Network;../Files;../Simulation</AdditionalIncludeDirectories>
       <AdditionalOptions>-DBOOST_DATE_TIME_NO_LIB -DBOOST_REGEX_NO_LIB</AdditionalOptions>
       <CppLanguageStandard>c++1y</CppLanguageStandard>
     </ClCompile>
@@ -151,7 +153,7 @@
       <SharedLibrarySearchPath>%(SharedLibrarySearchPath)</SharedLibrarySearchPath>
     </Link>
     <ClCompile>
-      <AdditionalIncludeDirectories>../FMU-Core/NativeFmuShared;../Network;../Files;../Simulation;../AdditionalIncludes/flatbuffers;../AdditionalIncludes/MC_Protocol;</AdditionalIncludeDirectories>
+      <AdditionalIncludeDirectories>../FMU-Core/NativeFmuShared;../Network;../Files;../Simulation</AdditionalIncludeDirectories>
       <AdditionalOptions>-DBOOST_DATE_TIME_NO_LIB -DBOOST_REGEX_NO_LIB</AdditionalOptions>
       <CppLanguageStandard>c++1y</CppLanguageStandard>
     </ClCompile>
@@ -169,7 +171,7 @@
       <SharedLibrarySearchPath>%(SharedLibrarySearchPath)</SharedLibrarySearchPath>
     </Link>
     <ClCompile>
-      <AdditionalIncludeDirectories>../FMU-Core/NativeFmuShared;../Network;../Files;../Simulation;../AdditionalIncludes/flatbuffers;../AdditionalIncludes/MC_Protocol;</AdditionalIncludeDirectories>
+      <AdditionalIncludeDirectories>../FMU-Core/NativeFmuShared;../Network;../Files;../Simulation</AdditionalIncludeDirectories>
       <AdditionalOptions>-DBOOST_DATE_TIME_NO_LIB -DBOOST_REGEX_NO_LIB</AdditionalOptions>
       <CppLanguageStandard>c++1y</CppLanguageStandard>
     </ClCompile>
@@ -183,7 +185,7 @@
       <SharedLibrarySearchPath>%(SharedLibrarySearchPath)</SharedLibrarySearchPath>
     </Link>
     <ClCompile>
-      <AdditionalIncludeDirectories>../FMU-Core/NativeFmuShared;../Network;../Files;../Simulation;../AdditionalIncludes/flatbuffers;../AdditionalIncludes/MC_Protocol;</AdditionalIncludeDirectories>
+      <AdditionalIncludeDirectories>../FMU-Core/NativeFmuShared;../Network;../Files;../Simulation</AdditionalIncludeDirectories>
       <AdditionalOptions>-DBOOST_DATE_TIME_NO_LIB -DBOOST_REGEX_NO_LIB</AdditionalOptions>
       <CppLanguageStandard>c++1y</CppLanguageStandard>
     </ClCompile>
diff --git a/MC_Backend_Win/MC_Backend_Win.vcxproj b/MC_Backend_Win/MC_Backend_Win.vcxproj
index 9e62d32..f2fe9b3 100644
--- a/MC_Backend_Win/MC_Backend_Win.vcxproj
+++ b/MC_Backend_Win/MC_Backend_Win.vcxproj
@@ -61,6 +61,8 @@
     <Import Project="..\Network\Network.vcxitems" Label="Shared" />
     <Import Project="..\Simulation\Simulation.vcxitems" Label="Shared" />
     <Import Project="..\Main\Main.vcxitems" Label="Shared" />
+    <Import Project="..\UtilityClasses\UtilityClasses.vcxitems" Label="Shared" />
+    <Import Project="..\CreatedGrpc\CreatedGrpc.vcxitems" Label="Shared" />
   </ImportGroup>
   <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
     <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
@@ -107,7 +109,7 @@
     </ClCompile>
     <Link>
       <SubSystem>Console</SubSystem>
-      <AdditionalDependencies>Winmm.lib;ws2_32.lib;gpr.lib;grpc.lib;grpc++.lib;grpc_unsecure.lib;grpc++_unsecure.lib;libprotobuf.lib;%(AdditionalDependencies)</AdditionalDependencies>
+      <AdditionalDependencies>Winmm.lib;ws2_32.lib;%(AdditionalDependencies)</AdditionalDependencies>
       <AdditionalLibraryDirectories>
       </AdditionalLibraryDirectories>
     </Link>
@@ -124,7 +126,7 @@
     </ClCompile>
     <Link>
       <SubSystem>Console</SubSystem>
-      <AdditionalDependencies>Winmm.lib;ws2_32.lib;gpr.lib;grpc.lib;grpc++.lib;grpc_unsecure.lib;grpc++_unsecure.lib;libprotobuf.lib;%(AdditionalDependencies)</AdditionalDependencies>
+      <AdditionalDependencies>Winmm.lib;ws2_32.lib;%(AdditionalDependencies)</AdditionalDependencies>
       <AdditionalLibraryDirectories>
       </AdditionalLibraryDirectories>
     </Link>
@@ -145,7 +147,7 @@
       <SubSystem>Console</SubSystem>
       <EnableCOMDATFolding>true</EnableCOMDATFolding>
       <OptimizeReferences>true</OptimizeReferences>
-      <AdditionalDependencies>Winmm.lib;ws2_32.lib;gpr.lib;grpc.lib;grpc++.lib;grpc_unsecure.lib;grpc++_unsecure.lib;libprotobuf.lib;%(AdditionalDependencies)</AdditionalDependencies>
+      <AdditionalDependencies>Winmm.lib;ws2_32.lib;%(AdditionalDependencies)</AdditionalDependencies>
       <AdditionalLibraryDirectories>
       </AdditionalLibraryDirectories>
     </Link>
@@ -166,7 +168,7 @@
       <SubSystem>Console</SubSystem>
       <EnableCOMDATFolding>true</EnableCOMDATFolding>
       <OptimizeReferences>true</OptimizeReferences>
-      <AdditionalDependencies>Winmm.lib;ws2_32.lib;gpr.lib;grpc.lib;grpc++.lib;grpc_unsecure.lib;grpc++_unsecure.lib;libprotobuf.lib;%(AdditionalDependencies)</AdditionalDependencies>
+      <AdditionalDependencies>Winmm.lib;ws2_32.lib;%(AdditionalDependencies)</AdditionalDependencies>
       <AdditionalLibraryDirectories>
       </AdditionalLibraryDirectories>
     </Link>
diff --git a/Main/main.cpp b/Main/main.cpp
index 36106d7..e7c086f 100644
--- a/Main/main.cpp
+++ b/Main/main.cpp
@@ -1,5 +1,5 @@
 #include "ModeliFile.hpp"
-#include "FmuEngine.hpp"
+#include "Simulation.hpp"
 #include "ModeliGrpcServer.h"
 #include "grpc++/grpc++.h"
 #include <chrono>
@@ -42,7 +42,7 @@ int main(int argc, char *argv[])
             {
                 port = vm["port"].as<unsigned short>();
             }
-            auto fmuEngine = std::make_shared<Simulation::FmuEngine>(std::to_string(port));
+            auto fmuEngine = std::make_shared<Simulation::Simulation>(std::to_string(port));
             // Load the modeli file into the engine
             if (vm.count("modeli"))
             {
diff --git a/Network/ModeliGrpcServer.cpp b/Network/ModeliGrpcServer.cpp
index ae7acc6..e963665 100644
--- a/Network/ModeliGrpcServer.cpp
+++ b/Network/ModeliGrpcServer.cpp
@@ -1,10 +1,10 @@
 #include "ModeliGrpcServer.h"
-#include "FmuEngine.hpp"
+#include "Simulation.hpp"
 #include "CoSimFmu.h"
 
 using ModeliRpc::Fmi2Status;
 
-ModeliGrpcServer::ModeliGrpcServer(std::shared_ptr<FmuEngine> fmuEngine) :_fmuEngine(fmuEngine)
+ModeliGrpcServer::ModeliGrpcServer(std::shared_ptr<Simulation> fmuEngine) :_fmuEngine(fmuEngine)
 {
 }
 
@@ -163,25 +163,9 @@ Status ModeliGrpcServer::NewValues(ServerContext * context, const::ModeliRpc::Ne
 {
     bool streamOpen = true;
     // Write to the stream until it is closed by the frontend
-    while (streamOpen)
+    while (writer->Write(_newValues.wait_and_pop()))
     {
-        std::unique_lock<std::mutex> lock(_newValuesMutex);
-        // While waiting we release the lock for the producer
-        _newValuesCv.wait(lock);
-        // We can access the queue savely
-        while (streamOpen && !_newValues.empty())
-        {
-            if (writer->Write(_newValues.front()))
-            {
-                _newValues.pop();
-            }
-            else
-            {
-                // Stop writing
-                streamOpen = false;
-            }
-        }
-        // Lock goes out of scope, the producer can add data to the queue
+        ;   // Do nothing
     }
     return Status::OK;
 }
@@ -190,25 +174,9 @@ Status ModeliGrpcServer::Log(ServerContext * context, const::ModeliRpc::LogReque
 {
     bool streamOpen = true;
     // Write to the stream until it is closed by the frontend
-    while (streamOpen)
+    while (writer->Write(_logs.wait_and_pop()))
     {
-        std::unique_lock<std::mutex> lock(_logMutex);
-        // While waiting we release the lock for the producer
-        _logCv.wait(lock);
-        // We can access the queue savely
-        while (streamOpen && !_logs.empty())
-        {
-            if (writer->Write(_logs.front()))
-            {
-                _logs.pop();
-            }
-            else
-            {
-                // Stop writing
-                streamOpen = false;
-            }
-        }
-        // Lock goes out of scope, the producer can add data to the queue
+        ;   // Do nothing
     }
     return Status::OK;
 }
@@ -247,11 +215,8 @@ void ModeliGrpcServer::ValuesArrived(const std::string instanceName, double time
         added->set_value_ref(stringVrs[i]);
         added->set_value(stringValues[i]);
     }
-    // Now safe to modify the queue
-    std::unique_lock<std::mutex> lock(_newValuesMutex);
+    // Thread safe modification & notification
     _newValues.push(response);
-    // Let the consumer do its work
-    _newValuesCv.notify_all();
 }
 
 void ModeliGrpcServer::LogArrived(std::string instanceName, int status, std::string category, std::string message)
@@ -259,5 +224,6 @@ void ModeliGrpcServer::LogArrived(std::string instanceName, int status, std::str
     ModeliRpc::LogResponse response;
     response.set_instance_name(instanceName);
     response.set_status(static_cast<Fmi2Status>(status));
-
+    // Threadsafe modification & notification
+    _logs.push(response);
 }
diff --git a/Network/ModeliGrpcServer.h b/Network/ModeliGrpcServer.h
index ce71994..d704768 100644
--- a/Network/ModeliGrpcServer.h
+++ b/Network/ModeliGrpcServer.h
@@ -1,15 +1,13 @@
 #pragma once
 #include "ModeliRpc.grpc.pb.h"
+#include "WaitableQueue.h"
 #include "IEngineObserver.hpp"
-#include <memory>
-#include <condition_variable>
-#include <queue>
 
 namespace Simulation
 {
-    class FmuEngine;
+    class Simulation;
 }
-using Simulation::FmuEngine;
+using Simulation::Simulation;
 using grpc::Status;
 using grpc::ServerContext;
 using grpc::ServerWriter;
@@ -18,7 +16,7 @@ using grpc::ServerReader;
 class ModeliGrpcServer final : public ModeliRpc::ModeliBackend::Service, Simulation::IEngineObserver
 {
 public:
-    ModeliGrpcServer(std::shared_ptr<FmuEngine> fmuEngine);
+    ModeliGrpcServer(std::shared_ptr<Simulation> fmuEngine);
 
     // Play the simulation infinetly in realtime
     Status Play(ServerContext* context, const ModeliRpc::PlayRequest* request, ModeliRpc::PlayResponse* response);
@@ -49,7 +47,7 @@ public:
     // Stream log messages to the client
     Status Log(ServerContext* context, const ModeliRpc::LogRequest* request, ServerWriter<ModeliRpc::LogResponse>* writer);
 
-    /// Observer of the simulation
+    /// Observer callback
     virtual void ValuesArrived(
         std::string instanceName,	///< The instanceName of the FMU
         double timestamp,	///< Timestamp (current time)
@@ -62,7 +60,7 @@ public:
         std::vector<unsigned int> stringVrs,
         std::vector<const char*> stringValues);
 
-    /// Observer of the simulation
+    /// Observer callback
     virtual void LogArrived(
         std::string instanceName,	///< The instanceName of the FMU
         int status,	///< Fmi2Status of the message
@@ -71,15 +69,11 @@ public:
     );
 private:
     // Execue the simulation commands
-    std::shared_ptr<FmuEngine> _fmuEngine;
+    std::shared_ptr<Simulation> _fmuEngine;
     // Wait for logs to arrive
-    std::mutex _logMutex;
-    std::condition_variable _logCv;
-    std::queue<ModeliRpc::LogResponse> _logs;
+    Utility::WaitableQueue<ModeliRpc::LogResponse> _logs;
     // Wait for values to arrive
-    std::mutex _newValuesMutex;
-    std::condition_variable _newValuesCv;
-    std::queue<ModeliRpc::NewValuesResponse> _newValues;
+    Utility::WaitableQueue<ModeliRpc::NewValuesResponse> _newValues;
 
 
 };
diff --git a/Network/Network.vcxitems b/Network/Network.vcxitems
index 8bc7e13..7d769a1 100644
--- a/Network/Network.vcxitems
+++ b/Network/Network.vcxitems
@@ -16,12 +16,8 @@
   </ItemGroup>
   <ItemGroup>
     <ClInclude Include="$(MSBuildThisFileDirectory)ModeliGrpcServer.h" />
-    <ClInclude Include="$(MSBuildThisFileDirectory)ModeliRpc.grpc.pb.h" />
-    <ClInclude Include="$(MSBuildThisFileDirectory)ModeliRpc.pb.h" />
   </ItemGroup>
   <ItemGroup>
     <ClCompile Include="$(MSBuildThisFileDirectory)ModeliGrpcServer.cpp" />
-    <ClCompile Include="$(MSBuildThisFileDirectory)ModeliRpc.grpc.pb.cc" />
-    <ClCompile Include="$(MSBuildThisFileDirectory)ModeliRpc.pb.cc" />
   </ItemGroup>
 </Project>
\ No newline at end of file
diff --git a/Network/Network.vcxitems.filters b/Network/Network.vcxitems.filters
index 58153b3..0e5934b 100644
--- a/Network/Network.vcxitems.filters
+++ b/Network/Network.vcxitems.filters
@@ -14,22 +14,10 @@
     <ClCompile Include="$(MSBuildThisFileDirectory)ModeliGrpcServer.cpp">
       <Filter>Source</Filter>
     </ClCompile>
-    <ClCompile Include="$(MSBuildThisFileDirectory)ModeliRpc.grpc.pb.cc">
-      <Filter>Source</Filter>
-    </ClCompile>
-    <ClCompile Include="$(MSBuildThisFileDirectory)ModeliRpc.pb.cc">
-      <Filter>Source</Filter>
-    </ClCompile>
   </ItemGroup>
   <ItemGroup>
     <ClInclude Include="$(MSBuildThisFileDirectory)ModeliGrpcServer.h">
       <Filter>Header</Filter>
     </ClInclude>
-    <ClInclude Include="$(MSBuildThisFileDirectory)ModeliRpc.grpc.pb.h">
-      <Filter>Header</Filter>
-    </ClInclude>
-    <ClInclude Include="$(MSBuildThisFileDirectory)ModeliRpc.pb.h">
-      <Filter>Header</Filter>
-    </ClInclude>
   </ItemGroup>
 </Project>
\ No newline at end of file
diff --git a/Simulation/FMUEngine.cpp b/Simulation/Simulation.cpp
similarity index 79%
rename from Simulation/FMUEngine.cpp
rename to Simulation/Simulation.cpp
index f0e8924..b38644c 100644
--- a/Simulation/FMUEngine.cpp
+++ b/Simulation/Simulation.cpp
@@ -1,5 +1,5 @@
 #include "FmuFile.hpp"
-#include "FmuEngine.hpp"
+#include "Simulation.hpp"
 #include "CoSimFmu.h"
 // std
 #include <iostream>
@@ -20,13 +20,13 @@ using NativeFmu::CoSimFmu;
 
 namespace Simulation
 {
-    FmuEngine::FmuEngine(std::string id) :
+    Simulation::Simulation(std::string id) :
         _controllerId(id)
     {
         _simulating = false;
     }
 
-    void  FmuEngine::simulate()
+    void  Simulation::simulate()
     {
         using std::chrono::high_resolution_clock;
         // Remember current time as oldDuration (continuing from pause)
@@ -77,7 +77,7 @@ namespace Simulation
                     fmi2False);
                 if (status == fmi2Error || status == fmi2Fatal)
                 {
-                    onLog(pair.first, status, "FmuEngine", "Error on DoStep. Cannot continue the simulation!");
+                    onLog(pair.first, status, "Simulation", "Error on DoStep. Cannot continue the simulation!");
                     return;	// Simulation no longer possible
                 }
             }
@@ -92,7 +92,8 @@ namespace Simulation
         // Let the CPU cool down
         SetProcessAsLowPrecision();
     }
-    void FmuEngine::calculateChannelLinks()
+  
+    void Simulation::calculateChannelLinks()
     {
         // Perform each link
         for (ChannelLink link : _channelLinks)
@@ -101,7 +102,7 @@ namespace Simulation
             auto masterFmuInstance = FindFmu(link.MasterInstanceName);
             if (!masterFmuInstance)
             {
-                onLog("FmuEngine", fmi2Warning, "FmuEngine",
+                onLog("Simulation", fmi2Warning, "Simulation",
                       "Failed ChannelLink: " +
                       link.MasterInstanceName + ": " + std::to_string(link.MasterValueRef)
                       + "-> " + link.SlaveInstanceName + ": " + std::to_string(link.SlaveValueRef) +
@@ -111,7 +112,7 @@ namespace Simulation
             auto slaveFmuInstance = FindFmu(link.SlaveInstanceName);
             if (!slaveFmuInstance)
             {
-                onLog("FmuEngine", fmi2Warning, "FmuEngine",
+                onLog("Simulation", fmi2Warning, "Simulation",
                       "Failed ChannelLink: " + link.MasterInstanceName + ": " + std::to_string(link.MasterValueRef)
                       + "-> " + link.SlaveInstanceName + ": " + std::to_string(link.SlaveValueRef) +
                       " SlaveChannel fmu instance does not exist.");
@@ -124,7 +125,7 @@ namespace Simulation
             if (res != fmi2OK)
             {
                 // The fmu will send an error itself but send soe additional info here
-                onLog("FmuEngine", fmi2Warning, "FmuEngine",
+                onLog("Simulation", fmi2Warning, "Simulation",
                       "Failed ChannelLink: " + link.MasterInstanceName + ": " + std::to_string(link.MasterValueRef)
                       + "-> " + link.SlaveInstanceName + ": " + std::to_string(link.SlaveValueRef) +
                       ", could not perform GetReal.");
@@ -140,7 +141,7 @@ namespace Simulation
             if (res != fmi2OK)
             {
                 // The fmu will send an error itself but send soe additional info here
-                onLog("FmuEngine", fmi2Warning, "FmuEngine",
+                onLog("Simulation", fmi2Warning, "Simulation",
                       "Failed ChannelLink: " + link.MasterInstanceName + ": " + std::to_string(link.MasterValueRef)
                       + "-> " + link.SlaveInstanceName + ": " + std::to_string(link.SlaveValueRef) +
                       ", could not perform SetReal.");
@@ -149,7 +150,8 @@ namespace Simulation
             }
         }
     }
-    void FmuEngine::sendValues()
+    
+    void Simulation::sendValues()
     {
         for (auto &pair : _fmus)
         {
@@ -158,25 +160,25 @@ namespace Simulation
             auto intRes = fmu->GetInteger();
             if (intRes.first != fmi2OK)
             {
-                onLog(fmu->GetInstanceName(), intRes.first, "FmuEngine", "GetInteger failed.");
+                onLog(fmu->GetInstanceName(), intRes.first, "Simulation", "GetInteger failed.");
             }
             // Real
             auto realRes = fmu->GetReal();
             if (realRes.first != fmi2OK)
             {
-                onLog(fmu->GetInstanceName(), realRes.first, "FmuEngine", "GetReal failed.");
+                onLog(fmu->GetInstanceName(), realRes.first, "Simulation", "GetReal failed.");
             }
             // Bool
             auto boolRes = fmu->GetBoolean();
             if (boolRes.first != fmi2OK)
             {
-                onLog(fmu->GetInstanceName(), boolRes.first, "FmuEngine", "GetBoolean failed.");
+                onLog(fmu->GetInstanceName(), boolRes.first, "Simulation", "GetBoolean failed.");
             }
             // String
             auto stringRes = fmu->GetString();
             if (stringRes.first != fmi2OK)
             {
-                onLog(fmu->GetInstanceName(), stringRes.first, "FmuEngine", "GetString failed.");
+                onLog(fmu->GetInstanceName(), stringRes.first, "Simulation", "GetString failed.");
             }
 
             // Send the values			
@@ -190,14 +192,14 @@ namespace Simulation
         }
     }
 
-    double FmuEngine::getSeconds(std::chrono::milliseconds duration)
+    double Simulation::getSeconds(std::chrono::milliseconds duration)
     {
         // seconds as double
         typedef std::chrono::duration<double> double_seconds;
         return std::chrono::duration_cast<double_seconds>(duration).count();
     }
 
-    int FmuEngine::startSimulation()
+    int Simulation::startSimulation()
     {
         // Play from initialized or stopped state
         if (!_simulating)
@@ -210,30 +212,30 @@ namespace Simulation
                 int status = fmu->ExitInitializationMode();
                 if (!(status == fmi2OK || status == fmi2Warning))
                 {
-                    onLog(fmu->GetInstanceName(), status, "FmuEngine", "ExitInitializationMode failed");
+                    onLog(fmu->GetInstanceName(), status, "Simulation", "ExitInitializationMode failed");
                     return status;
                 }
             }
             // Start simulating
             _simulating = true;
             // Create new thread for the simulation
-            _simThread = std::thread(&FmuEngine::simulate, this);
+            _simThread = std::thread(&Simulation::simulate, this);
         }
         return fmi2OK;
     }
 
-    void FmuEngine::AddObserver(std::shared_ptr<IEngineObserver> observer)
+    void Simulation::AddObserver(std::shared_ptr<IEngineObserver> observer)
     {
         _observers.push_back(observer);
     }
 
-    void FmuEngine::RemoveObserver(std::shared_ptr<IEngineObserver> observer)
+    void Simulation::RemoveObserver(std::shared_ptr<IEngineObserver> observer)
     {
         // Guarenteed not to throw
         _observers.remove(observer);
     }
 
-    int FmuEngine::Play()
+    int Simulation::Play()
     {
         // Play infinite
         _endDuration = std::chrono::milliseconds(0);
@@ -241,7 +243,8 @@ namespace Simulation
         _playFast = false;
         return startSimulation();
     }
-    int FmuEngine::PlayFast(double endTime_sec)
+   
+    int Simulation::PlayFast(double endTime_sec)
     {
         // Update the _endTime
         _endDuration = std::chrono::milliseconds(static_cast<unsigned long>(endTime_sec * 1000));
@@ -249,16 +252,18 @@ namespace Simulation
         _playFast = true;
         return startSimulation();
     }
+  
     // Stop the simulation thread
-    void FmuEngine::Pause()
+    void Simulation::Pause()
     {
         // Only try to obtain ownership over the thread without blocking the current thread
         _simulating = false;
         // Wait until the current run has finished
         _simThread.join();
     }
+  
     // Stop the thread and reset the simulation
-    int FmuEngine::Stop()
+    int Simulation::Stop()
     {
         // Stop simulation
         _simulating = false;
@@ -301,7 +306,7 @@ namespace Simulation
         return fmi2OK;
     }
 
-    int FmuEngine::initializeFmu(std::shared_ptr<CoSimFmu> fmu)
+    int Simulation::initializeFmu(std::shared_ptr<CoSimFmu> fmu)
     {
         // No error estimation and no pre-defined stoptime -> 10.0 is meaningless
         int status = fmu->SetupExperiment(fmi2False, 0, 0, fmi2False, 0);
@@ -313,7 +318,7 @@ namespace Simulation
         return fmu->EnterInitializationMode();
     }
 
-    void FmuEngine::onValuesArrived(const std::string instanceName, double timestamp, const std::vector<unsigned int> intVrs, const std::vector<int> intValues, const std::vector<unsigned int> realVrs, const std::vector<double> realValues, const std::vector<unsigned int> boolVrs, const std::vector<int> boolValues, const std::vector<unsigned int> stringVrs, const std::vector<const char*> stringValues)
+    void Simulation::onValuesArrived(const std::string instanceName, double timestamp, const std::vector<unsigned int> intVrs, const std::vector<int> intValues, const std::vector<unsigned int> realVrs, const std::vector<double> realValues, const std::vector<unsigned int> boolVrs, const std::vector<int> boolValues, const std::vector<unsigned int> stringVrs, const std::vector<const char*> stringValues)
     {
         // Invoke each observer
         for (auto observer : _observers)
@@ -327,7 +332,7 @@ namespace Simulation
         }
     }
 
-    void FmuEngine::onLog(std::string instanceName, int status, std::string category, std::string message)
+    void Simulation::onLog(std::string instanceName, int status, std::string category, std::string message)
     {
         // Invoke each observer
         for (auto observer : _observers)
@@ -336,18 +341,18 @@ namespace Simulation
         }
     }
 
-    bool FmuEngine::AddChannelLink(ChannelLink channelLink)
+    bool Simulation::AddChannelLink(ChannelLink channelLink)
     {
         // Check existance of instances
         if (!FindFmu(channelLink.MasterInstanceName))
         {
-            onLog("FmuEngine", fmi2Warning, "FmuEngine",
+            onLog("Simulation", fmi2Warning, "Simulation",
                   "MasterInstanceName of ChannelLink not found: " + channelLink.MasterInstanceName);
             return false;
         }
         if (!FindFmu(channelLink.SlaveInstanceName))
         {
-            onLog("FmuEngine", fmi2Warning, "FmuEngine",
+            onLog("Simulation", fmi2Warning, "Simulation",
                   "SlaveInstanceName of ChannelLink not found: " + channelLink.SlaveInstanceName);
             return false;
         }
@@ -357,13 +362,13 @@ namespace Simulation
         return true;
     }
 
-    bool FmuEngine::RemoveChannelLink(ChannelLink channelLink)
+    bool Simulation::RemoveChannelLink(ChannelLink channelLink)
     {
         _channelLinks.remove(channelLink);
         return true;
     }
 
-    bool FmuEngine::AddChannelLink(const std::string& masterInstanceName, const std::string& slaveInstanceName,
+    bool Simulation::AddChannelLink(const std::string& masterInstanceName, const std::string& slaveInstanceName,
                                    unsigned int masterValueRef, unsigned int slaveValueRef, double factor, double shift)
     {
         // Create the channelLink
@@ -377,7 +382,7 @@ namespace Simulation
         // Add it!
         return AddChannelLink(channelLink);
     }
-    bool FmuEngine::RemoveChannelLink(const std::string& masterInstanceName, const std::string& slaveInstanceName,
+    bool Simulation::RemoveChannelLink(const std::string& masterInstanceName, const std::string& slaveInstanceName,
                                       unsigned int masterValueRef, unsigned int slaveValueRef)
     {
         // Create the channelLink
@@ -390,13 +395,13 @@ namespace Simulation
         return RemoveChannelLink(channelLink);
     }
 
-    bool FmuEngine::AddFmu(std::shared_ptr<FmuFile> fmuFile)
+    bool Simulation::AddFmu(std::shared_ptr<FmuFile> fmuFile)
     {
         // Check if the instanceName is in use
         if (FindFmu(fmuFile->GetInstanceName()))
         {
             // Error: The element has been found but we can not have two identical instances
-            onLog(fmuFile->GetInstanceName(), fmi2Warning, "FmuEngine", "The instanceName already exists.");
+            onLog(fmuFile->GetInstanceName(), fmi2Warning, "Simulation", "The instanceName already exists.");
             return false;
         }
 
@@ -405,17 +410,17 @@ namespace Simulation
         std::pair<bool, std::string> loadDllRes = coSimFmu->LoadDll(fmuFile->GetBinaryPath());
         if (!loadDllRes.first)
         {
-            onLog(fmuFile->GetInstanceName(), fmi2Warning, "FmuEngine", "Failed LoadLibrary, Error: " + loadDllRes.second);
+            onLog(fmuFile->GetInstanceName(), fmi2Warning, "Simulation", "Failed LoadLibrary, Error: " + loadDllRes.second);
             return false;
         }
 
         // Setup callbacks and parameters
         namespace ph = std::placeholders;
-        coSimFmu->SetLoggerCallback(std::bind(&FmuEngine::onLog, this, ph::_1, ph::_2, ph::_3, ph::_4));
+        coSimFmu->SetLoggerCallback(std::bind(&Simulation::onLog, this, ph::_1, ph::_2, ph::_3, ph::_4));
         // Instantiate
         if (!coSimFmu->Instantiate(fmuFile->GetInstanceName(), fmuFile->GetGUID(), fmuFile->GetResourceUri()))
         {
-            onLog(fmuFile->GetInstanceName(), fmi2Warning, "FmuEngine", "Instantiation failed for instance: " + fmuFile->GetInstanceName());
+            onLog(fmuFile->GetInstanceName(), fmi2Warning, "Simulation", "Instantiation failed for instance: " + fmuFile->GetInstanceName());
             return false;
         }
 
@@ -430,19 +435,19 @@ namespace Simulation
         return true;
     }
 
-    bool FmuEngine::AddFmu(std::string instanceName, std::string path)
+    bool Simulation::AddFmu(std::string instanceName, std::string path)
     {
         // Add the fmu from file
         return AddFmu(std::make_shared<FmuFile>(path, _controllerId, instanceName));
     }
 
-    bool FmuEngine::AddFmu(std::string instanceName, const std::vector<unsigned char> &bytes)
+    bool Simulation::AddFmu(std::string instanceName, const std::vector<unsigned char> &bytes)
     {
         // Add the fmu from file
         return AddFmu(std::make_shared<FmuFile>(bytes, _controllerId, instanceName));
     }
 
-    bool FmuEngine::RemoveFMU(std::string instanceName)
+    bool Simulation::RemoveFMU(std::string instanceName)
     {
         // Make sure we stopped the simulation
         Stop();
@@ -455,12 +460,12 @@ namespace Simulation
         }
         else
         {
-            onLog(instanceName, fmi2Warning, "FmuEngine", "Instance can not be removed, it does not exist: " + instanceName);
+            onLog(instanceName, fmi2Warning, "Simulation", "Instance can not be removed, it does not exist: " + instanceName);
             return false;
         }
     }
 
-    boost::optional<FmuFilePair> FmuEngine::FindFmu(std::string instanceName)
+    boost::optional<FmuFilePair> Simulation::FindFmu(std::string instanceName)
     {
         auto iter = _fmus.find(instanceName);
         if (iter == _fmus.end())
diff --git a/Simulation/FmuEngine.hpp b/Simulation/Simulation.hpp
similarity index 98%
rename from Simulation/FmuEngine.hpp
rename to Simulation/Simulation.hpp
index 4cc0386..d1726cb 100644
--- a/Simulation/FmuEngine.hpp
+++ b/Simulation/Simulation.hpp
@@ -35,11 +35,11 @@ namespace Simulation
 		std::shared_ptr<FmuFile> File;
 	};
 
-	class FmuEngine
+	class Simulation
 	{
 	public:
-		///< Creates a new instance of the FmuEngine
-		FmuEngine(
+		///< Creates a new instance of the Simulation
+		Simulation(
 			std::string id	///< A unique identification, used to create a dir where the models will be stored
 		);
 
diff --git a/Simulation/Simulation.vcxitems b/Simulation/Simulation.vcxitems
index a22d006..d941352 100644
--- a/Simulation/Simulation.vcxitems
+++ b/Simulation/Simulation.vcxitems
@@ -17,11 +17,11 @@
     <ClInclude Include="$(MSBuildThisFileDirectory)ChannelLink.h" />
     <ClInclude Include="$(MSBuildThisFileDirectory)fmi2FunctionTypes.h" />
     <ClInclude Include="$(MSBuildThisFileDirectory)fmi2TypesPlatform.h" />
-    <ClInclude Include="$(MSBuildThisFileDirectory)FmuEngine.hpp" />
+    <ClInclude Include="$(MSBuildThisFileDirectory)Simulation.hpp" />
     <ClInclude Include="$(MSBuildThisFileDirectory)IEngineObserver.hpp" />
   </ItemGroup>
   <ItemGroup>
     <ClCompile Include="$(MSBuildThisFileDirectory)ChannelLink.cpp" />
-    <ClCompile Include="$(MSBuildThisFileDirectory)FMUEngine.cpp" />
+    <ClCompile Include="$(MSBuildThisFileDirectory)Simulation.cpp" />
   </ItemGroup>
 </Project>
\ No newline at end of file
diff --git a/Simulation/Simulation.vcxitems.filters b/Simulation/Simulation.vcxitems.filters
index 535ee7b..2d58f89 100644
--- a/Simulation/Simulation.vcxitems.filters
+++ b/Simulation/Simulation.vcxitems.filters
@@ -20,10 +20,10 @@
     <ClInclude Include="$(MSBuildThisFileDirectory)fmi2TypesPlatform.h">
       <Filter>Header</Filter>
     </ClInclude>
-    <ClInclude Include="$(MSBuildThisFileDirectory)FmuEngine.hpp">
+    <ClInclude Include="$(MSBuildThisFileDirectory)IEngineObserver.hpp">
       <Filter>Header</Filter>
     </ClInclude>
-    <ClInclude Include="$(MSBuildThisFileDirectory)IEngineObserver.hpp">
+    <ClInclude Include="C:\Users\alldocube\Documents\GitRepo\MC_BackEnd\Simulation\Simulation.hpp">
       <Filter>Header</Filter>
     </ClInclude>
   </ItemGroup>
@@ -31,7 +31,7 @@
     <ClCompile Include="$(MSBuildThisFileDirectory)ChannelLink.cpp">
       <Filter>Source</Filter>
     </ClCompile>
-    <ClCompile Include="$(MSBuildThisFileDirectory)FMUEngine.cpp">
+    <ClCompile Include="C:\Users\alldocube\Documents\GitRepo\MC_BackEnd\Simulation\Simulation.cpp">
       <Filter>Source</Filter>
     </ClCompile>
   </ItemGroup>
diff --git a/UtilityClasses/UtilityClasses.vcxitems b/UtilityClasses/UtilityClasses.vcxitems
new file mode 100644
index 0000000..358818e
--- /dev/null
+++ b/UtilityClasses/UtilityClasses.vcxitems
@@ -0,0 +1,20 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+  <PropertyGroup Label="Globals">
+    <MSBuildAllProjects>$(MSBuildAllProjects);$(MSBuildThisFileFullPath)</MSBuildAllProjects>
+    <HasSharedItems>true</HasSharedItems>
+    <ItemsProjectGuid>{fd95ebac-8e33-43d3-88ba-04a2b02d7d9e}</ItemsProjectGuid>
+    <ItemsProjectName>Utility</ItemsProjectName>
+  </PropertyGroup>
+  <ItemDefinitionGroup>
+    <ClCompile>
+      <AdditionalIncludeDirectories>%(AdditionalIncludeDirectories);$(MSBuildThisFileDirectory)</AdditionalIncludeDirectories>
+    </ClCompile>
+  </ItemDefinitionGroup>
+  <ItemGroup>
+    <ProjectCapability Include="SourceItemsFromImports" />
+  </ItemGroup>
+  <ItemGroup>
+    <ClInclude Include="$(MSBuildThisFileDirectory)WaitableQueue.h" />
+  </ItemGroup>
+</Project>
\ No newline at end of file
diff --git a/UtilityClasses/WaitableQueue.h b/UtilityClasses/WaitableQueue.h
new file mode 100644
index 0000000..cf5cf87
--- /dev/null
+++ b/UtilityClasses/WaitableQueue.h
@@ -0,0 +1,79 @@
+#pragma once
+#include "boost/optional.hpp"
+#include <functional>
+#include <queue>
+#include <mutex>
+
+namespace Utility
+{
+    /// This class enables thread safe access to the queue.
+    /// It uses conditional variables to for efficient waiting.
+    /// No hard exception safety for better interface.
+    template <typename T>
+    class WaitableQueue
+    {
+    private:
+        std::queue<T> _queue;
+        std::mutex _mutex;
+        std::condition_variable _cond_var;
+
+        // Functional style for boilerplate
+        /// Locks the mutex before executing the action.
+        /// After the execution has finished the conditional variable will be notified.
+        void executeAndNotify(std::function<void()> action)
+        {
+            std::unique_lock<std::mutex> lock(_mutex);
+            action();
+            lock.unlock();
+            _cond_var.notify_one();
+        }
+
+    public:
+        /// Immediately returns the item from the front (or boost::none).
+        boost::optional<T> pop()
+        {
+            std::unique_lock<std::mutex> lock(_mutex);
+            if (_queue.empty())
+            {
+                return boost::none;
+            }
+            else
+            {
+                auto item = _queue.front();
+                _queue.pop();
+                return item;
+            }
+        }
+        /// Waits for data to become available and returns the first element.
+        T wait_and_pop()
+        {
+            // Wait for signal
+            std::unique_lock<std::mutex> lock(_mutex);
+            // Prevent spurious wakeups by checking the queue
+            _cond_var.wait(lock, [&]()
+            {
+                return !_queue.empty();
+            });
+            // Return the front
+            auto item = _queue.front();
+            _queue.pop();
+            return item;
+        }
+        /// Add an item to the end of the queue
+        void push(const T& item)
+        {
+            executeAndNotify([&]()
+            {
+                _queue.push(item);
+            });
+        }
+        /// Add an item to the end of the queue
+        void push(T&& item)
+        {
+            executeAndNotify([&]()
+            {
+                _queue.push(std::move(item));
+            });
+        }
+    };
+}
-- 
GitLab