@@ -0,0 +1,34 @@ | |||
CONFIG -= qt | |||
TEMPLATE = lib | |||
CONFIG += staticlib | |||
CONFIG += c++17 | |||
INCLUDEPATH += ../EasyLoggingPP | |||
unix: CONFIG += link_pkgconfig | |||
unix: PKGCONFIG += libasio | |||
SOURCES += \ | |||
LIBS += -pthread | |||
HEADERS += \ | |||
net_server_client.h \ | |||
src/net_client.h \ | |||
src/net_common.h \ | |||
src/net_connection.h \ | |||
src/net_dequeue_ts.h \ | |||
src/net_message.h \ | |||
src/net_message_types.h \ | |||
src/net_server.h | |||
# Default rules for deployment. | |||
unix { | |||
target.path = $$[QT_INSTALL_PLUGINS]/generic | |||
} | |||
!isEmpty(target.path): INSTALLS += target |
@@ -0,0 +1,355 @@ | |||
<?xml version="1.0" encoding="UTF-8"?> | |||
<!DOCTYPE QtCreatorProject> | |||
<!-- Written by QtCreator 4.13.3, 2021-07-30T10:52:14. --> | |||
<qtcreator> | |||
<data> | |||
<variable>EnvironmentId</variable> | |||
<value type="QByteArray">{5a632e4a-e744-412b-acc7-3b951573dab3}</value> | |||
</data> | |||
<data> | |||
<variable>ProjectExplorer.Project.ActiveTarget</variable> | |||
<value type="int">0</value> | |||
</data> | |||
<data> | |||
<variable>ProjectExplorer.Project.EditorSettings</variable> | |||
<valuemap type="QVariantMap"> | |||
<value type="bool" key="EditorConfiguration.AutoIndent">true</value> | |||
<value type="bool" key="EditorConfiguration.AutoSpacesForTabs">false</value> | |||
<value type="bool" key="EditorConfiguration.CamelCaseNavigation">true</value> | |||
<valuemap type="QVariantMap" key="EditorConfiguration.CodeStyle.0"> | |||
<value type="QString" key="language">Cpp</value> | |||
<valuemap type="QVariantMap" key="value"> | |||
<value type="QByteArray" key="CurrentPreferences">CppGlobal</value> | |||
</valuemap> | |||
</valuemap> | |||
<valuemap type="QVariantMap" key="EditorConfiguration.CodeStyle.1"> | |||
<value type="QString" key="language">QmlJS</value> | |||
<valuemap type="QVariantMap" key="value"> | |||
<value type="QByteArray" key="CurrentPreferences">QmlJSGlobal</value> | |||
</valuemap> | |||
</valuemap> | |||
<value type="int" key="EditorConfiguration.CodeStyle.Count">2</value> | |||
<value type="QByteArray" key="EditorConfiguration.Codec">UTF-8</value> | |||
<value type="bool" key="EditorConfiguration.ConstrainTooltips">false</value> | |||
<value type="int" key="EditorConfiguration.IndentSize">4</value> | |||
<value type="bool" key="EditorConfiguration.KeyboardTooltips">false</value> | |||
<value type="int" key="EditorConfiguration.MarginColumn">80</value> | |||
<value type="bool" key="EditorConfiguration.MouseHiding">true</value> | |||
<value type="bool" key="EditorConfiguration.MouseNavigation">true</value> | |||
<value type="int" key="EditorConfiguration.PaddingMode">1</value> | |||
<value type="bool" key="EditorConfiguration.ScrollWheelZooming">true</value> | |||
<value type="bool" key="EditorConfiguration.ShowMargin">false</value> | |||
<value type="int" key="EditorConfiguration.SmartBackspaceBehavior">0</value> | |||
<value type="bool" key="EditorConfiguration.SmartSelectionChanging">true</value> | |||
<value type="bool" key="EditorConfiguration.SpacesForTabs">true</value> | |||
<value type="int" key="EditorConfiguration.TabKeyBehavior">0</value> | |||
<value type="int" key="EditorConfiguration.TabSize">8</value> | |||
<value type="bool" key="EditorConfiguration.UseGlobal">true</value> | |||
<value type="int" key="EditorConfiguration.Utf8BomBehavior">1</value> | |||
<value type="bool" key="EditorConfiguration.addFinalNewLine">true</value> | |||
<value type="bool" key="EditorConfiguration.cleanIndentation">true</value> | |||
<value type="bool" key="EditorConfiguration.cleanWhitespace">true</value> | |||
<value type="QString" key="EditorConfiguration.ignoreFileTypes">*.md, *.MD, Makefile</value> | |||
<value type="bool" key="EditorConfiguration.inEntireDocument">false</value> | |||
<value type="bool" key="EditorConfiguration.skipTrailingWhitespace">true</value> | |||
</valuemap> | |||
</data> | |||
<data> | |||
<variable>ProjectExplorer.Project.PluginSettings</variable> | |||
<valuemap type="QVariantMap"> | |||
<valuemap type="QVariantMap" key="AutoTest.ActiveFrameworks"> | |||
<value type="bool" key="AutoTest.Framework.Boost">true</value> | |||
<value type="bool" key="AutoTest.Framework.Catch">true</value> | |||
<value type="bool" key="AutoTest.Framework.GTest">true</value> | |||
<value type="bool" key="AutoTest.Framework.QtQuickTest">true</value> | |||
<value type="bool" key="AutoTest.Framework.QtTest">true</value> | |||
</valuemap> | |||
<valuemap type="QVariantMap" key="AutoTest.CheckStates"/> | |||
<value type="int" key="AutoTest.RunAfterBuild">0</value> | |||
<value type="bool" key="AutoTest.UseGlobal">true</value> | |||
<valuelist type="QVariantList" key="ClangCodeModel.CustomCommandLineKey"/> | |||
<value type="bool" key="ClangCodeModel.UseGlobalConfig">true</value> | |||
<value type="QString" key="ClangCodeModel.WarningConfigId">Builtin.Questionable</value> | |||
<valuemap type="QVariantMap" key="ClangTools"> | |||
<value type="bool" key="ClangTools.BuildBeforeAnalysis">true</value> | |||
<value type="QString" key="ClangTools.DiagnosticConfig">Builtin.DefaultTidyAndClazy</value> | |||
<value type="int" key="ClangTools.ParallelJobs">1</value> | |||
<valuelist type="QVariantList" key="ClangTools.SelectedDirs"/> | |||
<valuelist type="QVariantList" key="ClangTools.SelectedFiles"/> | |||
<valuelist type="QVariantList" key="ClangTools.SuppressedDiagnostics"/> | |||
<value type="bool" key="ClangTools.UseGlobalSettings">true</value> | |||
</valuemap> | |||
</valuemap> | |||
</data> | |||
<data> | |||
<variable>ProjectExplorer.Project.Target.0</variable> | |||
<valuemap type="QVariantMap"> | |||
<value type="QString" key="DeviceType">Desktop</value> | |||
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">Desktop Qt 5.15.1 GCC 64bit</value> | |||
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName">Desktop Qt 5.15.1 GCC 64bit</value> | |||
<value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">qt.qt5.5151.gcc_64_kit</value> | |||
<value type="int" key="ProjectExplorer.Target.ActiveBuildConfiguration">0</value> | |||
<value type="int" key="ProjectExplorer.Target.ActiveDeployConfiguration">0</value> | |||
<value type="int" key="ProjectExplorer.Target.ActiveRunConfiguration">0</value> | |||
<valuemap type="QVariantMap" key="ProjectExplorer.Target.BuildConfiguration.0"> | |||
<value type="bool">true</value> | |||
<value type="int" key="EnableQmlDebugging">0</value> | |||
<value type="QString" key="ProjectExplorer.BuildConfiguration.BuildDirectory">/home/michael/baConditionMonitoring/AsioNetClientServer/debug</value> | |||
<value type="QString" key="ProjectExplorer.BuildConfiguration.BuildDirectory.shadowDir">/home/michael/baConditionMonitoring/AsioNetClientServer/debug</value> | |||
<valuemap type="QVariantMap" key="ProjectExplorer.BuildConfiguration.BuildStepList.0"> | |||
<valuemap type="QVariantMap" key="ProjectExplorer.BuildStepList.Step.0"> | |||
<value type="bool" key="ProjectExplorer.BuildStep.Enabled">true</value> | |||
<value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">QtProjectManager.QMakeBuildStep</value> | |||
<value type="QString" key="QtProjectManager.QMakeBuildStep.QMakeArguments"></value> | |||
<value type="bool" key="QtProjectManager.QMakeBuildStep.QMakeForced">false</value> | |||
<valuelist type="QVariantList" key="QtProjectManager.QMakeBuildStep.SelectedAbis"/> | |||
</valuemap> | |||
<valuemap type="QVariantMap" key="ProjectExplorer.BuildStepList.Step.1"> | |||
<value type="bool" key="ProjectExplorer.BuildStep.Enabled">true</value> | |||
<value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">Qt4ProjectManager.MakeStep</value> | |||
<valuelist type="QVariantList" key="Qt4ProjectManager.MakeStep.BuildTargets"/> | |||
<value type="bool" key="Qt4ProjectManager.MakeStep.Clean">false</value> | |||
<value type="QString" key="Qt4ProjectManager.MakeStep.MakeArguments"></value> | |||
<value type="QString" key="Qt4ProjectManager.MakeStep.MakeCommand"></value> | |||
<value type="bool" key="Qt4ProjectManager.MakeStep.OverrideMakeflags">false</value> | |||
</valuemap> | |||
<value type="int" key="ProjectExplorer.BuildStepList.StepsCount">2</value> | |||
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">Build</value> | |||
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName">Build</value> | |||
<value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">ProjectExplorer.BuildSteps.Build</value> | |||
</valuemap> | |||
<valuemap type="QVariantMap" key="ProjectExplorer.BuildConfiguration.BuildStepList.1"> | |||
<valuemap type="QVariantMap" key="ProjectExplorer.BuildStepList.Step.0"> | |||
<value type="bool" key="ProjectExplorer.BuildStep.Enabled">true</value> | |||
<value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">Qt4ProjectManager.MakeStep</value> | |||
<valuelist type="QVariantList" key="Qt4ProjectManager.MakeStep.BuildTargets"/> | |||
<value type="bool" key="Qt4ProjectManager.MakeStep.Clean">true</value> | |||
<value type="QString" key="Qt4ProjectManager.MakeStep.MakeArguments">clean</value> | |||
<value type="QString" key="Qt4ProjectManager.MakeStep.MakeCommand"></value> | |||
<value type="bool" key="Qt4ProjectManager.MakeStep.OverrideMakeflags">false</value> | |||
</valuemap> | |||
<value type="int" key="ProjectExplorer.BuildStepList.StepsCount">1</value> | |||
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">Clean</value> | |||
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName">Clean</value> | |||
<value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">ProjectExplorer.BuildSteps.Clean</value> | |||
</valuemap> | |||
<value type="int" key="ProjectExplorer.BuildConfiguration.BuildStepListCount">2</value> | |||
<value type="bool" key="ProjectExplorer.BuildConfiguration.ClearSystemEnvironment">false</value> | |||
<valuelist type="QVariantList" key="ProjectExplorer.BuildConfiguration.CustomParsers"/> | |||
<valuelist type="QVariantList" key="ProjectExplorer.BuildConfiguration.UserEnvironmentChanges"/> | |||
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName">Debug</value> | |||
<value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">Qt4ProjectManager.Qt4BuildConfiguration</value> | |||
<value type="int" key="Qt4ProjectManager.Qt4BuildConfiguration.BuildConfiguration">2</value> | |||
<value type="int" key="QtQuickCompiler">2</value> | |||
<value type="int" key="SeparateDebugInfo">2</value> | |||
</valuemap> | |||
<valuemap type="QVariantMap" key="ProjectExplorer.Target.BuildConfiguration.1"> | |||
<value type="bool">true</value> | |||
<value type="int" key="EnableQmlDebugging">2</value> | |||
<value type="QString" key="ProjectExplorer.BuildConfiguration.BuildDirectory">/home/michael/baConditionMonitoring/build-asio_inet_client_server-Desktop_Qt_5_15_1_GCC_64bit-Release</value> | |||
<value type="QString" key="ProjectExplorer.BuildConfiguration.BuildDirectory.shadowDir">/home/michael/baConditionMonitoring/build-asio_inet_client_server-Desktop_Qt_5_15_1_GCC_64bit-Release</value> | |||
<valuemap type="QVariantMap" key="ProjectExplorer.BuildConfiguration.BuildStepList.0"> | |||
<valuemap type="QVariantMap" key="ProjectExplorer.BuildStepList.Step.0"> | |||
<value type="bool" key="ProjectExplorer.BuildStep.Enabled">true</value> | |||
<value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">QtProjectManager.QMakeBuildStep</value> | |||
<value type="QString" key="QtProjectManager.QMakeBuildStep.QMakeArguments"></value> | |||
<value type="bool" key="QtProjectManager.QMakeBuildStep.QMakeForced">false</value> | |||
<valuelist type="QVariantList" key="QtProjectManager.QMakeBuildStep.SelectedAbis"/> | |||
</valuemap> | |||
<valuemap type="QVariantMap" key="ProjectExplorer.BuildStepList.Step.1"> | |||
<value type="bool" key="ProjectExplorer.BuildStep.Enabled">true</value> | |||
<value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">Qt4ProjectManager.MakeStep</value> | |||
<valuelist type="QVariantList" key="Qt4ProjectManager.MakeStep.BuildTargets"/> | |||
<value type="bool" key="Qt4ProjectManager.MakeStep.Clean">false</value> | |||
<value type="QString" key="Qt4ProjectManager.MakeStep.MakeArguments"></value> | |||
<value type="QString" key="Qt4ProjectManager.MakeStep.MakeCommand"></value> | |||
<value type="bool" key="Qt4ProjectManager.MakeStep.OverrideMakeflags">false</value> | |||
</valuemap> | |||
<value type="int" key="ProjectExplorer.BuildStepList.StepsCount">2</value> | |||
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">Build</value> | |||
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName">Build</value> | |||
<value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">ProjectExplorer.BuildSteps.Build</value> | |||
</valuemap> | |||
<valuemap type="QVariantMap" key="ProjectExplorer.BuildConfiguration.BuildStepList.1"> | |||
<valuemap type="QVariantMap" key="ProjectExplorer.BuildStepList.Step.0"> | |||
<value type="bool" key="ProjectExplorer.BuildStep.Enabled">true</value> | |||
<value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">Qt4ProjectManager.MakeStep</value> | |||
<valuelist type="QVariantList" key="Qt4ProjectManager.MakeStep.BuildTargets"/> | |||
<value type="bool" key="Qt4ProjectManager.MakeStep.Clean">true</value> | |||
<value type="QString" key="Qt4ProjectManager.MakeStep.MakeArguments">clean</value> | |||
<value type="QString" key="Qt4ProjectManager.MakeStep.MakeCommand"></value> | |||
<value type="bool" key="Qt4ProjectManager.MakeStep.OverrideMakeflags">false</value> | |||
</valuemap> | |||
<value type="int" key="ProjectExplorer.BuildStepList.StepsCount">1</value> | |||
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">Clean</value> | |||
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName">Clean</value> | |||
<value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">ProjectExplorer.BuildSteps.Clean</value> | |||
</valuemap> | |||
<value type="int" key="ProjectExplorer.BuildConfiguration.BuildStepListCount">2</value> | |||
<value type="bool" key="ProjectExplorer.BuildConfiguration.ClearSystemEnvironment">false</value> | |||
<valuelist type="QVariantList" key="ProjectExplorer.BuildConfiguration.CustomParsers"/> | |||
<valuelist type="QVariantList" key="ProjectExplorer.BuildConfiguration.UserEnvironmentChanges"/> | |||
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName">Release</value> | |||
<value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">Qt4ProjectManager.Qt4BuildConfiguration</value> | |||
<value type="int" key="Qt4ProjectManager.Qt4BuildConfiguration.BuildConfiguration">0</value> | |||
<value type="int" key="QtQuickCompiler">0</value> | |||
<value type="int" key="SeparateDebugInfo">2</value> | |||
</valuemap> | |||
<valuemap type="QVariantMap" key="ProjectExplorer.Target.BuildConfiguration.2"> | |||
<value type="bool">true</value> | |||
<value type="int" key="EnableQmlDebugging">0</value> | |||
<value type="QString" key="ProjectExplorer.BuildConfiguration.BuildDirectory">/home/michael/baConditionMonitoring/build-asio_inet_client_server-Desktop_Qt_5_15_1_GCC_64bit-Profile</value> | |||
<value type="QString" key="ProjectExplorer.BuildConfiguration.BuildDirectory.shadowDir">/home/michael/baConditionMonitoring/build-asio_inet_client_server-Desktop_Qt_5_15_1_GCC_64bit-Profile</value> | |||
<valuemap type="QVariantMap" key="ProjectExplorer.BuildConfiguration.BuildStepList.0"> | |||
<valuemap type="QVariantMap" key="ProjectExplorer.BuildStepList.Step.0"> | |||
<value type="bool" key="ProjectExplorer.BuildStep.Enabled">true</value> | |||
<value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">QtProjectManager.QMakeBuildStep</value> | |||
<value type="QString" key="QtProjectManager.QMakeBuildStep.QMakeArguments"></value> | |||
<value type="bool" key="QtProjectManager.QMakeBuildStep.QMakeForced">false</value> | |||
<valuelist type="QVariantList" key="QtProjectManager.QMakeBuildStep.SelectedAbis"/> | |||
</valuemap> | |||
<valuemap type="QVariantMap" key="ProjectExplorer.BuildStepList.Step.1"> | |||
<value type="bool" key="ProjectExplorer.BuildStep.Enabled">true</value> | |||
<value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">Qt4ProjectManager.MakeStep</value> | |||
<valuelist type="QVariantList" key="Qt4ProjectManager.MakeStep.BuildTargets"/> | |||
<value type="bool" key="Qt4ProjectManager.MakeStep.Clean">false</value> | |||
<value type="QString" key="Qt4ProjectManager.MakeStep.MakeArguments"></value> | |||
<value type="QString" key="Qt4ProjectManager.MakeStep.MakeCommand"></value> | |||
<value type="bool" key="Qt4ProjectManager.MakeStep.OverrideMakeflags">false</value> | |||
</valuemap> | |||
<value type="int" key="ProjectExplorer.BuildStepList.StepsCount">2</value> | |||
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">Build</value> | |||
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName">Build</value> | |||
<value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">ProjectExplorer.BuildSteps.Build</value> | |||
</valuemap> | |||
<valuemap type="QVariantMap" key="ProjectExplorer.BuildConfiguration.BuildStepList.1"> | |||
<valuemap type="QVariantMap" key="ProjectExplorer.BuildStepList.Step.0"> | |||
<value type="bool" key="ProjectExplorer.BuildStep.Enabled">true</value> | |||
<value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">Qt4ProjectManager.MakeStep</value> | |||
<valuelist type="QVariantList" key="Qt4ProjectManager.MakeStep.BuildTargets"/> | |||
<value type="bool" key="Qt4ProjectManager.MakeStep.Clean">true</value> | |||
<value type="QString" key="Qt4ProjectManager.MakeStep.MakeArguments">clean</value> | |||
<value type="QString" key="Qt4ProjectManager.MakeStep.MakeCommand"></value> | |||
<value type="bool" key="Qt4ProjectManager.MakeStep.OverrideMakeflags">false</value> | |||
</valuemap> | |||
<value type="int" key="ProjectExplorer.BuildStepList.StepsCount">1</value> | |||
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">Clean</value> | |||
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName">Clean</value> | |||
<value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">ProjectExplorer.BuildSteps.Clean</value> | |||
</valuemap> | |||
<value type="int" key="ProjectExplorer.BuildConfiguration.BuildStepListCount">2</value> | |||
<value type="bool" key="ProjectExplorer.BuildConfiguration.ClearSystemEnvironment">false</value> | |||
<valuelist type="QVariantList" key="ProjectExplorer.BuildConfiguration.CustomParsers"/> | |||
<valuelist type="QVariantList" key="ProjectExplorer.BuildConfiguration.UserEnvironmentChanges"/> | |||
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName">Profile</value> | |||
<value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">Qt4ProjectManager.Qt4BuildConfiguration</value> | |||
<value type="int" key="Qt4ProjectManager.Qt4BuildConfiguration.BuildConfiguration">0</value> | |||
<value type="int" key="QtQuickCompiler">0</value> | |||
<value type="int" key="SeparateDebugInfo">0</value> | |||
</valuemap> | |||
<value type="int" key="ProjectExplorer.Target.BuildConfigurationCount">3</value> | |||
<valuemap type="QVariantMap" key="ProjectExplorer.Target.DeployConfiguration.0"> | |||
<valuemap type="QVariantMap" key="ProjectExplorer.BuildConfiguration.BuildStepList.0"> | |||
<value type="int" key="ProjectExplorer.BuildStepList.StepsCount">0</value> | |||
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">Deploy</value> | |||
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName">Deploy</value> | |||
<value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">ProjectExplorer.BuildSteps.Deploy</value> | |||
</valuemap> | |||
<value type="int" key="ProjectExplorer.BuildConfiguration.BuildStepListCount">1</value> | |||
<valuemap type="QVariantMap" key="ProjectExplorer.DeployConfiguration.CustomData"/> | |||
<value type="bool" key="ProjectExplorer.DeployConfiguration.CustomDataEnabled">false</value> | |||
<value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">ProjectExplorer.DefaultDeployConfiguration</value> | |||
</valuemap> | |||
<value type="int" key="ProjectExplorer.Target.DeployConfigurationCount">1</value> | |||
<valuemap type="QVariantMap" key="ProjectExplorer.Target.PluginSettings"/> | |||
<valuemap type="QVariantMap" key="ProjectExplorer.Target.RunConfiguration.0"> | |||
<value type="QString" key="Analyzer.Perf.CallgraphMode">dwarf</value> | |||
<valuelist type="QVariantList" key="Analyzer.Perf.Events"> | |||
<value type="QString">cpu-cycles</value> | |||
</valuelist> | |||
<valuelist type="QVariantList" key="Analyzer.Perf.ExtraArguments"/> | |||
<value type="int" key="Analyzer.Perf.Frequency">250</value> | |||
<valuelist type="QVariantList" key="Analyzer.Perf.RecordArguments"> | |||
<value type="QString">-e</value> | |||
<value type="QString">cpu-cycles</value> | |||
<value type="QString">--call-graph</value> | |||
<value type="QString">dwarf,4096</value> | |||
<value type="QString">-F</value> | |||
<value type="QString">250</value> | |||
</valuelist> | |||
<value type="QString" key="Analyzer.Perf.SampleMode">-F</value> | |||
<value type="bool" key="Analyzer.Perf.Settings.UseGlobalSettings">true</value> | |||
<value type="int" key="Analyzer.Perf.StackSize">4096</value> | |||
<value type="bool" key="Analyzer.QmlProfiler.AggregateTraces">false</value> | |||
<value type="bool" key="Analyzer.QmlProfiler.FlushEnabled">false</value> | |||
<value type="uint" key="Analyzer.QmlProfiler.FlushInterval">1000</value> | |||
<value type="QString" key="Analyzer.QmlProfiler.LastTraceFile"></value> | |||
<value type="bool" key="Analyzer.QmlProfiler.Settings.UseGlobalSettings">true</value> | |||
<valuelist type="QVariantList" key="Analyzer.Valgrind.AddedSuppressionFiles"/> | |||
<value type="bool" key="Analyzer.Valgrind.Callgrind.CollectBusEvents">false</value> | |||
<value type="bool" key="Analyzer.Valgrind.Callgrind.CollectSystime">false</value> | |||
<value type="bool" key="Analyzer.Valgrind.Callgrind.EnableBranchSim">false</value> | |||
<value type="bool" key="Analyzer.Valgrind.Callgrind.EnableCacheSim">false</value> | |||
<value type="bool" key="Analyzer.Valgrind.Callgrind.EnableEventToolTips">true</value> | |||
<value type="double" key="Analyzer.Valgrind.Callgrind.MinimumCostRatio">0.01</value> | |||
<value type="double" key="Analyzer.Valgrind.Callgrind.VisualisationMinimumCostRatio">10</value> | |||
<value type="bool" key="Analyzer.Valgrind.FilterExternalIssues">true</value> | |||
<value type="QString" key="Analyzer.Valgrind.KCachegrindExecutable">kcachegrind</value> | |||
<value type="int" key="Analyzer.Valgrind.LeakCheckOnFinish">1</value> | |||
<value type="int" key="Analyzer.Valgrind.NumCallers">25</value> | |||
<valuelist type="QVariantList" key="Analyzer.Valgrind.RemovedSuppressionFiles"/> | |||
<value type="int" key="Analyzer.Valgrind.SelfModifyingCodeDetection">1</value> | |||
<value type="bool" key="Analyzer.Valgrind.Settings.UseGlobalSettings">true</value> | |||
<value type="bool" key="Analyzer.Valgrind.ShowReachable">false</value> | |||
<value type="bool" key="Analyzer.Valgrind.TrackOrigins">true</value> | |||
<value type="QString" key="Analyzer.Valgrind.ValgrindExecutable">valgrind</value> | |||
<valuelist type="QVariantList" key="Analyzer.Valgrind.VisibleErrorKinds"> | |||
<value type="int">0</value> | |||
<value type="int">1</value> | |||
<value type="int">2</value> | |||
<value type="int">3</value> | |||
<value type="int">4</value> | |||
<value type="int">5</value> | |||
<value type="int">6</value> | |||
<value type="int">7</value> | |||
<value type="int">8</value> | |||
<value type="int">9</value> | |||
<value type="int">10</value> | |||
<value type="int">11</value> | |||
<value type="int">12</value> | |||
<value type="int">13</value> | |||
<value type="int">14</value> | |||
</valuelist> | |||
<valuelist type="QVariantList" key="CustomOutputParsers"/> | |||
<value type="int" key="PE.EnvironmentAspect.Base">2</value> | |||
<valuelist type="QVariantList" key="PE.EnvironmentAspect.Changes"/> | |||
<value type="QString" key="ProjectExplorer.CustomExecutableRunConfiguration.Executable"></value> | |||
<value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">ProjectExplorer.CustomExecutableRunConfiguration</value> | |||
<value type="QString" key="ProjectExplorer.RunConfiguration.BuildKey"></value> | |||
<value type="QString" key="RunConfiguration.Arguments"></value> | |||
<value type="bool" key="RunConfiguration.Arguments.multi">false</value> | |||
<value type="QString" key="RunConfiguration.OverrideDebuggerStartup"></value> | |||
<value type="bool" key="RunConfiguration.UseCppDebugger">false</value> | |||
<value type="bool" key="RunConfiguration.UseCppDebuggerAuto">true</value> | |||
<value type="bool" key="RunConfiguration.UseMultiProcess">false</value> | |||
<value type="bool" key="RunConfiguration.UseQmlDebugger">false</value> | |||
<value type="bool" key="RunConfiguration.UseQmlDebuggerAuto">true</value> | |||
<value type="QString" key="RunConfiguration.WorkingDirectory"></value> | |||
<value type="QString" key="RunConfiguration.WorkingDirectory.default"></value> | |||
</valuemap> | |||
<value type="int" key="ProjectExplorer.Target.RunConfigurationCount">1</value> | |||
</valuemap> | |||
</data> | |||
<data> | |||
<variable>ProjectExplorer.Project.TargetCount</variable> | |||
<value type="int">1</value> | |||
</data> | |||
<data> | |||
<variable>ProjectExplorer.Project.Updater.FileVersion</variable> | |||
<value type="int">22</value> | |||
</data> | |||
<data> | |||
<variable>Version</variable> | |||
<value type="int">22</value> | |||
</data> | |||
</qtcreator> |
@@ -0,0 +1,317 @@ | |||
<?xml version="1.0" encoding="UTF-8"?> | |||
<!DOCTYPE QtCreatorProject> | |||
<!-- Written by QtCreator 4.15.1, 2021-07-23T08:11:18. --> | |||
<qtcreator> | |||
<data> | |||
<variable>EnvironmentId</variable> | |||
<value type="QByteArray">{eac5e3ee-8a8a-4d3e-ba79-20701eff322a}</value> | |||
</data> | |||
<data> | |||
<variable>ProjectExplorer.Project.ActiveTarget</variable> | |||
<value type="int">0</value> | |||
</data> | |||
<data> | |||
<variable>ProjectExplorer.Project.EditorSettings</variable> | |||
<valuemap type="QVariantMap"> | |||
<value type="bool" key="EditorConfiguration.AutoIndent">true</value> | |||
<value type="bool" key="EditorConfiguration.AutoSpacesForTabs">false</value> | |||
<value type="bool" key="EditorConfiguration.CamelCaseNavigation">true</value> | |||
<valuemap type="QVariantMap" key="EditorConfiguration.CodeStyle.0"> | |||
<value type="QString" key="language">Cpp</value> | |||
<valuemap type="QVariantMap" key="value"> | |||
<value type="QByteArray" key="CurrentPreferences">CppGlobal</value> | |||
</valuemap> | |||
</valuemap> | |||
<valuemap type="QVariantMap" key="EditorConfiguration.CodeStyle.1"> | |||
<value type="QString" key="language">QmlJS</value> | |||
<valuemap type="QVariantMap" key="value"> | |||
<value type="QByteArray" key="CurrentPreferences">QmlJSGlobal</value> | |||
</valuemap> | |||
</valuemap> | |||
<value type="int" key="EditorConfiguration.CodeStyle.Count">2</value> | |||
<value type="QByteArray" key="EditorConfiguration.Codec">UTF-8</value> | |||
<value type="bool" key="EditorConfiguration.ConstrainTooltips">false</value> | |||
<value type="int" key="EditorConfiguration.IndentSize">4</value> | |||
<value type="bool" key="EditorConfiguration.KeyboardTooltips">false</value> | |||
<value type="int" key="EditorConfiguration.MarginColumn">80</value> | |||
<value type="bool" key="EditorConfiguration.MouseHiding">true</value> | |||
<value type="bool" key="EditorConfiguration.MouseNavigation">true</value> | |||
<value type="int" key="EditorConfiguration.PaddingMode">1</value> | |||
<value type="bool" key="EditorConfiguration.PreferSingleLineComments">false</value> | |||
<value type="bool" key="EditorConfiguration.ScrollWheelZooming">true</value> | |||
<value type="bool" key="EditorConfiguration.ShowMargin">false</value> | |||
<value type="int" key="EditorConfiguration.SmartBackspaceBehavior">0</value> | |||
<value type="bool" key="EditorConfiguration.SmartSelectionChanging">true</value> | |||
<value type="bool" key="EditorConfiguration.SpacesForTabs">true</value> | |||
<value type="int" key="EditorConfiguration.TabKeyBehavior">0</value> | |||
<value type="int" key="EditorConfiguration.TabSize">8</value> | |||
<value type="bool" key="EditorConfiguration.UseGlobal">true</value> | |||
<value type="bool" key="EditorConfiguration.UseIndenter">false</value> | |||
<value type="int" key="EditorConfiguration.Utf8BomBehavior">1</value> | |||
<value type="bool" key="EditorConfiguration.addFinalNewLine">true</value> | |||
<value type="bool" key="EditorConfiguration.cleanIndentation">true</value> | |||
<value type="bool" key="EditorConfiguration.cleanWhitespace">true</value> | |||
<value type="QString" key="EditorConfiguration.ignoreFileTypes">*.md, *.MD, Makefile</value> | |||
<value type="bool" key="EditorConfiguration.inEntireDocument">false</value> | |||
<value type="bool" key="EditorConfiguration.skipTrailingWhitespace">true</value> | |||
</valuemap> | |||
</data> | |||
<data> | |||
<variable>ProjectExplorer.Project.PluginSettings</variable> | |||
<valuemap type="QVariantMap"> | |||
<valuemap type="QVariantMap" key="AutoTest.ActiveFrameworks"> | |||
<value type="bool" key="AutoTest.Framework.Boost">true</value> | |||
<value type="bool" key="AutoTest.Framework.CTest">false</value> | |||
<value type="bool" key="AutoTest.Framework.Catch">true</value> | |||
<value type="bool" key="AutoTest.Framework.GTest">true</value> | |||
<value type="bool" key="AutoTest.Framework.QtQuickTest">true</value> | |||
<value type="bool" key="AutoTest.Framework.QtTest">true</value> | |||
</valuemap> | |||
<valuemap type="QVariantMap" key="AutoTest.CheckStates"/> | |||
<value type="int" key="AutoTest.RunAfterBuild">0</value> | |||
<value type="bool" key="AutoTest.UseGlobal">true</value> | |||
<valuelist type="QVariantList" key="ClangCodeModel.CustomCommandLineKey"/> | |||
<value type="bool" key="ClangCodeModel.UseGlobalConfig">true</value> | |||
<value type="QString" key="ClangCodeModel.WarningConfigId">Builtin.BuildSystem</value> | |||
<valuemap type="QVariantMap" key="ClangTools"> | |||
<value type="bool" key="ClangTools.AnalyzeOpenFiles">true</value> | |||
<value type="bool" key="ClangTools.BuildBeforeAnalysis">true</value> | |||
<value type="QString" key="ClangTools.DiagnosticConfig">Builtin.DefaultTidyAndClazy</value> | |||
<value type="int" key="ClangTools.ParallelJobs">1</value> | |||
<valuelist type="QVariantList" key="ClangTools.SelectedDirs"/> | |||
<valuelist type="QVariantList" key="ClangTools.SelectedFiles"/> | |||
<valuelist type="QVariantList" key="ClangTools.SuppressedDiagnostics"/> | |||
<value type="bool" key="ClangTools.UseGlobalSettings">true</value> | |||
</valuemap> | |||
</valuemap> | |||
</data> | |||
<data> | |||
<variable>ProjectExplorer.Project.Target.0</variable> | |||
<valuemap type="QVariantMap"> | |||
<value type="QString" key="DeviceType">Desktop</value> | |||
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">Desktop Qt 6.1.1 GCC 64bit</value> | |||
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName">Desktop Qt 6.1.1 GCC 64bit</value> | |||
<value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">qt.qt6.611.gcc_64_kit</value> | |||
<value type="int" key="ProjectExplorer.Target.ActiveBuildConfiguration">1</value> | |||
<value type="int" key="ProjectExplorer.Target.ActiveDeployConfiguration">0</value> | |||
<value type="int" key="ProjectExplorer.Target.ActiveRunConfiguration">0</value> | |||
<valuemap type="QVariantMap" key="ProjectExplorer.Target.BuildConfiguration.0"> | |||
<value type="int" key="EnableQmlDebugging">0</value> | |||
<value type="QString" key="ProjectExplorer.BuildConfiguration.BuildDirectory">/home/michael/baConditionMonitoring/AsioNetClientServer/build-asio_inet_client_server-Desktop_Qt_6_1_1_GCC_64bit-Debug</value> | |||
<value type="QString" key="ProjectExplorer.BuildConfiguration.BuildDirectory.shadowDir">/home/michael/baConditionMonitoring/AsioNetClientServer/build-asio_inet_client_server-Desktop_Qt_6_1_1_GCC_64bit-Debug</value> | |||
<valuemap type="QVariantMap" key="ProjectExplorer.BuildConfiguration.BuildStepList.0"> | |||
<valuemap type="QVariantMap" key="ProjectExplorer.BuildStepList.Step.0"> | |||
<value type="bool" key="ProjectExplorer.BuildStep.Enabled">true</value> | |||
<value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">QtProjectManager.QMakeBuildStep</value> | |||
<value type="bool" key="QtProjectManager.QMakeBuildStep.QMakeForced">false</value> | |||
<valuelist type="QVariantList" key="QtProjectManager.QMakeBuildStep.SelectedAbis"/> | |||
</valuemap> | |||
<valuemap type="QVariantMap" key="ProjectExplorer.BuildStepList.Step.1"> | |||
<value type="bool" key="ProjectExplorer.BuildStep.Enabled">true</value> | |||
<value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">Qt4ProjectManager.MakeStep</value> | |||
</valuemap> | |||
<value type="int" key="ProjectExplorer.BuildStepList.StepsCount">2</value> | |||
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">Build</value> | |||
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName">Build</value> | |||
<value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">ProjectExplorer.BuildSteps.Build</value> | |||
</valuemap> | |||
<valuemap type="QVariantMap" key="ProjectExplorer.BuildConfiguration.BuildStepList.1"> | |||
<valuemap type="QVariantMap" key="ProjectExplorer.BuildStepList.Step.0"> | |||
<value type="bool" key="ProjectExplorer.BuildStep.Enabled">true</value> | |||
<value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">Qt4ProjectManager.MakeStep</value> | |||
<value type="QString" key="Qt4ProjectManager.MakeStep.MakeArguments">clean</value> | |||
</valuemap> | |||
<value type="int" key="ProjectExplorer.BuildStepList.StepsCount">1</value> | |||
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">Clean</value> | |||
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName">Clean</value> | |||
<value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">ProjectExplorer.BuildSteps.Clean</value> | |||
</valuemap> | |||
<value type="int" key="ProjectExplorer.BuildConfiguration.BuildStepListCount">2</value> | |||
<value type="bool" key="ProjectExplorer.BuildConfiguration.ClearSystemEnvironment">false</value> | |||
<valuelist type="QVariantList" key="ProjectExplorer.BuildConfiguration.CustomParsers"/> | |||
<valuelist type="QVariantList" key="ProjectExplorer.BuildConfiguration.UserEnvironmentChanges"/> | |||
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName">Debug</value> | |||
<value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">Qt4ProjectManager.Qt4BuildConfiguration</value> | |||
<value type="int" key="Qt4ProjectManager.Qt4BuildConfiguration.BuildConfiguration">2</value> | |||
</valuemap> | |||
<valuemap type="QVariantMap" key="ProjectExplorer.Target.BuildConfiguration.1"> | |||
<value type="QString" key="ProjectExplorer.BuildConfiguration.BuildDirectory">debug</value> | |||
<value type="QString" key="ProjectExplorer.BuildConfiguration.BuildDirectory.shadowDir">debug</value> | |||
<valuemap type="QVariantMap" key="ProjectExplorer.BuildConfiguration.BuildStepList.0"> | |||
<valuemap type="QVariantMap" key="ProjectExplorer.BuildStepList.Step.0"> | |||
<value type="bool" key="ProjectExplorer.BuildStep.Enabled">true</value> | |||
<value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">QtProjectManager.QMakeBuildStep</value> | |||
<value type="bool" key="QtProjectManager.QMakeBuildStep.QMakeForced">false</value> | |||
<valuelist type="QVariantList" key="QtProjectManager.QMakeBuildStep.SelectedAbis"/> | |||
</valuemap> | |||
<valuemap type="QVariantMap" key="ProjectExplorer.BuildStepList.Step.1"> | |||
<value type="bool" key="ProjectExplorer.BuildStep.Enabled">true</value> | |||
<value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">Qt4ProjectManager.MakeStep</value> | |||
</valuemap> | |||
<value type="int" key="ProjectExplorer.BuildStepList.StepsCount">2</value> | |||
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">Build</value> | |||
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName">Build</value> | |||
<value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">ProjectExplorer.BuildSteps.Build</value> | |||
</valuemap> | |||
<valuemap type="QVariantMap" key="ProjectExplorer.BuildConfiguration.BuildStepList.1"> | |||
<valuemap type="QVariantMap" key="ProjectExplorer.BuildStepList.Step.0"> | |||
<value type="bool" key="ProjectExplorer.BuildStep.Enabled">true</value> | |||
<value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">Qt4ProjectManager.MakeStep</value> | |||
<value type="QString" key="Qt4ProjectManager.MakeStep.MakeArguments">clean</value> | |||
</valuemap> | |||
<value type="int" key="ProjectExplorer.BuildStepList.StepsCount">1</value> | |||
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">Clean</value> | |||
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName">Clean</value> | |||
<value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">ProjectExplorer.BuildSteps.Clean</value> | |||
</valuemap> | |||
<value type="int" key="ProjectExplorer.BuildConfiguration.BuildStepListCount">2</value> | |||
<value type="bool" key="ProjectExplorer.BuildConfiguration.ClearSystemEnvironment">false</value> | |||
<valuelist type="QVariantList" key="ProjectExplorer.BuildConfiguration.CustomParsers"/> | |||
<valuelist type="QVariantList" key="ProjectExplorer.BuildConfiguration.UserEnvironmentChanges"/> | |||
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName">Release</value> | |||
<value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">Qt4ProjectManager.Qt4BuildConfiguration</value> | |||
<value type="int" key="Qt4ProjectManager.Qt4BuildConfiguration.BuildConfiguration">0</value> | |||
<value type="int" key="QtQuickCompiler">0</value> | |||
</valuemap> | |||
<valuemap type="QVariantMap" key="ProjectExplorer.Target.BuildConfiguration.2"> | |||
<value type="int" key="EnableQmlDebugging">0</value> | |||
<value type="QString" key="ProjectExplorer.BuildConfiguration.BuildDirectory">/home/michael/baConditionMonitoring/AsioNetClientServer/build-asio_inet_client_server-Desktop_Qt_6_1_1_GCC_64bit-Profile</value> | |||
<value type="QString" key="ProjectExplorer.BuildConfiguration.BuildDirectory.shadowDir">/home/michael/baConditionMonitoring/AsioNetClientServer/build-asio_inet_client_server-Desktop_Qt_6_1_1_GCC_64bit-Profile</value> | |||
<valuemap type="QVariantMap" key="ProjectExplorer.BuildConfiguration.BuildStepList.0"> | |||
<valuemap type="QVariantMap" key="ProjectExplorer.BuildStepList.Step.0"> | |||
<value type="bool" key="ProjectExplorer.BuildStep.Enabled">true</value> | |||
<value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">QtProjectManager.QMakeBuildStep</value> | |||
<value type="bool" key="QtProjectManager.QMakeBuildStep.QMakeForced">false</value> | |||
<valuelist type="QVariantList" key="QtProjectManager.QMakeBuildStep.SelectedAbis"/> | |||
</valuemap> | |||
<valuemap type="QVariantMap" key="ProjectExplorer.BuildStepList.Step.1"> | |||
<value type="bool" key="ProjectExplorer.BuildStep.Enabled">true</value> | |||
<value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">Qt4ProjectManager.MakeStep</value> | |||
</valuemap> | |||
<value type="int" key="ProjectExplorer.BuildStepList.StepsCount">2</value> | |||
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">Build</value> | |||
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName">Build</value> | |||
<value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">ProjectExplorer.BuildSteps.Build</value> | |||
</valuemap> | |||
<valuemap type="QVariantMap" key="ProjectExplorer.BuildConfiguration.BuildStepList.1"> | |||
<valuemap type="QVariantMap" key="ProjectExplorer.BuildStepList.Step.0"> | |||
<value type="bool" key="ProjectExplorer.BuildStep.Enabled">true</value> | |||
<value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">Qt4ProjectManager.MakeStep</value> | |||
<value type="QString" key="Qt4ProjectManager.MakeStep.MakeArguments">clean</value> | |||
</valuemap> | |||
<value type="int" key="ProjectExplorer.BuildStepList.StepsCount">1</value> | |||
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">Clean</value> | |||
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName">Clean</value> | |||
<value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">ProjectExplorer.BuildSteps.Clean</value> | |||
</valuemap> | |||
<value type="int" key="ProjectExplorer.BuildConfiguration.BuildStepListCount">2</value> | |||
<value type="bool" key="ProjectExplorer.BuildConfiguration.ClearSystemEnvironment">false</value> | |||
<valuelist type="QVariantList" key="ProjectExplorer.BuildConfiguration.CustomParsers"/> | |||
<valuelist type="QVariantList" key="ProjectExplorer.BuildConfiguration.UserEnvironmentChanges"/> | |||
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName">Profile</value> | |||
<value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">Qt4ProjectManager.Qt4BuildConfiguration</value> | |||
<value type="int" key="Qt4ProjectManager.Qt4BuildConfiguration.BuildConfiguration">0</value> | |||
<value type="int" key="QtQuickCompiler">0</value> | |||
<value type="int" key="SeparateDebugInfo">0</value> | |||
</valuemap> | |||
<value type="int" key="ProjectExplorer.Target.BuildConfigurationCount">3</value> | |||
<valuemap type="QVariantMap" key="ProjectExplorer.Target.DeployConfiguration.0"> | |||
<valuemap type="QVariantMap" key="ProjectExplorer.BuildConfiguration.BuildStepList.0"> | |||
<value type="int" key="ProjectExplorer.BuildStepList.StepsCount">0</value> | |||
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">Deploy</value> | |||
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName">Deploy</value> | |||
<value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">ProjectExplorer.BuildSteps.Deploy</value> | |||
</valuemap> | |||
<value type="int" key="ProjectExplorer.BuildConfiguration.BuildStepListCount">1</value> | |||
<valuemap type="QVariantMap" key="ProjectExplorer.DeployConfiguration.CustomData"/> | |||
<value type="bool" key="ProjectExplorer.DeployConfiguration.CustomDataEnabled">false</value> | |||
<value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">ProjectExplorer.DefaultDeployConfiguration</value> | |||
</valuemap> | |||
<value type="int" key="ProjectExplorer.Target.DeployConfigurationCount">1</value> | |||
<valuemap type="QVariantMap" key="ProjectExplorer.Target.RunConfiguration.0"> | |||
<value type="QString" key="Analyzer.Perf.CallgraphMode">dwarf</value> | |||
<valuelist type="QVariantList" key="Analyzer.Perf.Events"> | |||
<value type="QString">cpu-cycles</value> | |||
</valuelist> | |||
<valuelist type="QVariantList" key="Analyzer.Perf.ExtraArguments"/> | |||
<value type="int" key="Analyzer.Perf.Frequency">250</value> | |||
<valuelist type="QVariantList" key="Analyzer.Perf.RecordArguments"> | |||
<value type="QString">-e</value> | |||
<value type="QString">cpu-cycles</value> | |||
<value type="QString">--call-graph</value> | |||
<value type="QString">dwarf,4096</value> | |||
<value type="QString">-F</value> | |||
<value type="QString">250</value> | |||
</valuelist> | |||
<value type="QString" key="Analyzer.Perf.SampleMode">-F</value> | |||
<value type="bool" key="Analyzer.Perf.Settings.UseGlobalSettings">true</value> | |||
<value type="int" key="Analyzer.Perf.StackSize">4096</value> | |||
<value type="bool" key="Analyzer.QmlProfiler.AggregateTraces">false</value> | |||
<value type="bool" key="Analyzer.QmlProfiler.FlushEnabled">false</value> | |||
<value type="uint" key="Analyzer.QmlProfiler.FlushInterval">1000</value> | |||
<value type="QString" key="Analyzer.QmlProfiler.LastTraceFile"></value> | |||
<value type="bool" key="Analyzer.QmlProfiler.Settings.UseGlobalSettings">true</value> | |||
<valuelist type="QVariantList" key="Analyzer.Valgrind.AddedSuppressionFiles"/> | |||
<value type="QString" key="Analyzer.Valgrind.Callgrind.Arguments"></value> | |||
<value type="bool" key="Analyzer.Valgrind.Callgrind.CollectBusEvents">false</value> | |||
<value type="bool" key="Analyzer.Valgrind.Callgrind.CollectSystime">false</value> | |||
<value type="bool" key="Analyzer.Valgrind.Callgrind.EnableBranchSim">false</value> | |||
<value type="bool" key="Analyzer.Valgrind.Callgrind.EnableCacheSim">false</value> | |||
<value type="bool" key="Analyzer.Valgrind.Callgrind.EnableEventToolTips">true</value> | |||
<value type="double" key="Analyzer.Valgrind.Callgrind.MinimumCostRatio">0.01</value> | |||
<value type="double" key="Analyzer.Valgrind.Callgrind.VisualisationMinimumCostRatio">10</value> | |||
<value type="bool" key="Analyzer.Valgrind.FilterExternalIssues">true</value> | |||
<value type="QString" key="Analyzer.Valgrind.KCachegrindExecutable">kcachegrind</value> | |||
<value type="int" key="Analyzer.Valgrind.LeakCheckOnFinish">1</value> | |||
<value type="QString" key="Analyzer.Valgrind.Memcheck.Arguments"></value> | |||
<value type="int" key="Analyzer.Valgrind.NumCallers">25</value> | |||
<valuelist type="QVariantList" key="Analyzer.Valgrind.RemovedSuppressionFiles"/> | |||
<value type="int" key="Analyzer.Valgrind.SelfModifyingCodeDetection">1</value> | |||
<value type="bool" key="Analyzer.Valgrind.Settings.UseGlobalSettings">true</value> | |||
<value type="bool" key="Analyzer.Valgrind.ShowReachable">false</value> | |||
<value type="bool" key="Analyzer.Valgrind.TrackOrigins">true</value> | |||
<value type="QString" key="Analyzer.Valgrind.ValgrindArguments"></value> | |||
<value type="QString" key="Analyzer.Valgrind.ValgrindExecutable">valgrind</value> | |||
<valuelist type="QVariantList" key="Analyzer.Valgrind.VisibleErrorKinds"> | |||
<value type="int">0</value> | |||
<value type="int">1</value> | |||
<value type="int">2</value> | |||
<value type="int">3</value> | |||
<value type="int">4</value> | |||
<value type="int">5</value> | |||
<value type="int">6</value> | |||
<value type="int">7</value> | |||
<value type="int">8</value> | |||
<value type="int">9</value> | |||
<value type="int">10</value> | |||
<value type="int">11</value> | |||
<value type="int">12</value> | |||
<value type="int">13</value> | |||
<value type="int">14</value> | |||
</valuelist> | |||
<valuelist type="QVariantList" key="CustomOutputParsers"/> | |||
<value type="int" key="PE.EnvironmentAspect.Base">2</value> | |||
<valuelist type="QVariantList" key="PE.EnvironmentAspect.Changes"/> | |||
<value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">ProjectExplorer.CustomExecutableRunConfiguration</value> | |||
<value type="QString" key="ProjectExplorer.RunConfiguration.BuildKey"></value> | |||
<value type="bool" key="RunConfiguration.UseCppDebugger">false</value> | |||
<value type="bool" key="RunConfiguration.UseCppDebuggerAuto">true</value> | |||
<value type="bool" key="RunConfiguration.UseQmlDebugger">false</value> | |||
<value type="bool" key="RunConfiguration.UseQmlDebuggerAuto">true</value> | |||
</valuemap> | |||
<value type="int" key="ProjectExplorer.Target.RunConfigurationCount">1</value> | |||
</valuemap> | |||
</data> | |||
<data> | |||
<variable>ProjectExplorer.Project.TargetCount</variable> | |||
<value type="int">1</value> | |||
</data> | |||
<data> | |||
<variable>ProjectExplorer.Project.Updater.FileVersion</variable> | |||
<value type="int">22</value> | |||
</data> | |||
<data> | |||
<variable>Version</variable> | |||
<value type="int">22</value> | |||
</data> | |||
</qtcreator> |
@@ -0,0 +1,64 @@ | |||
/* | |||
MMO Client/Server Framework using ASIO | |||
"Happy Birthday Mrs Javidx9!" - javidx9 | |||
Videos: | |||
Part #1: https://youtu.be/2hNdkYInj4g | |||
Part #2: https://youtu.be/UbjxGvrDrbw | |||
License (OLC-3) | |||
~~~~~~~~~~~~~~~ | |||
Copyright 2018 - 2020 OneLoneCoder.com | |||
Redistribution and use in source and binary forms, with or without | |||
modification, are permitted provided that the following conditions | |||
are met: | |||
1. Redistributions or derivations of source code must retain the above | |||
copyright notice, this list of conditions and the following disclaimer. | |||
2. Redistributions or derivative works in binary form must reproduce | |||
the above copyright notice. This list of conditions and the following | |||
disclaimer must be reproduced in the documentation and/or other | |||
materials provided with the distribution. | |||
3. Neither the name of the copyright holder nor the names of its | |||
contributors may be used to endorse or promote products derived | |||
from this software without specific prior written permission. | |||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS | |||
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT | |||
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR | |||
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT | |||
HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, | |||
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT | |||
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, | |||
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY | |||
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT | |||
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE | |||
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | |||
Links | |||
~~~~~ | |||
YouTube: https://www.youtube.com/javidx9 | |||
Discord: https://discord.gg/WhwHUMV | |||
Twitter: https://www.twitter.com/javidx9 | |||
Twitch: https://www.twitch.tv/javidx9 | |||
GitHub: https://www.github.com/onelonecoder | |||
Homepage: https://www.onelonecoder.com | |||
Author | |||
~~~~~~ | |||
David Barr, aka javidx9, ©OneLoneCoder 2019, 2020 | |||
*/ | |||
#pragma once | |||
#include "src/net_common.h" | |||
#include "src/net_dequeue_ts.h" | |||
#include "src/net_message.h" | |||
#include "src/net_client.h" | |||
#include "src/net_server.h" | |||
#include "src/net_connection.h" |
@@ -0,0 +1,157 @@ | |||
/* | |||
MMO Client/Server Framework using ASIO | |||
"Happy Birthday Mrs Javidx9!" - javidx9 | |||
Videos: | |||
Part #1: https://youtu.be/2hNdkYInj4g | |||
Part #2: https://youtu.be/UbjxGvrDrbw | |||
License (OLC-3) | |||
~~~~~~~~~~~~~~~ | |||
Copyright 2018 - 2020 OneLoneCoder.com | |||
Redistribution and use in source and binary forms, with or without | |||
modification, are permitted provided that the following conditions | |||
are met: | |||
1. Redistributions or derivations of source code must retain the above | |||
copyright notice, this list of conditions and the following disclaimer. | |||
2. Redistributions or derivative works in binary form must reproduce | |||
the above copyright notice. This list of conditions and the following | |||
disclaimer must be reproduced in the documentation and/or other | |||
materials provided with the distribution. | |||
3. Neither the name of the copyright holder nor the names of its | |||
contributors may be used to endorse or promote products derived | |||
from this software without specific prior written permission. | |||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS | |||
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT | |||
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR | |||
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT | |||
HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, | |||
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT | |||
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, | |||
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY | |||
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT | |||
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE | |||
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | |||
Links | |||
~~~~~ | |||
YouTube: https://www.youtube.com/javidx9 | |||
Discord: https://discord.gg/WhwHUMV | |||
Twitter: https://www.twitter.com/javidx9 | |||
Twitch: https://www.twitch.tv/javidx9 | |||
GitHub: https://www.github.com/onelonecoder | |||
Homepage: https://www.onelonecoder.com | |||
Author | |||
~~~~~~ | |||
David Barr, aka javidx9, ©OneLoneCoder 2019, 2020 | |||
*/ | |||
#pragma once | |||
#include "net_common.h" | |||
#include "net_connection.h" | |||
namespace net | |||
{ | |||
template <typename T> | |||
class ClientInterface | |||
{ | |||
public: | |||
ClientInterface() | |||
{} | |||
virtual ~ClientInterface() | |||
{ | |||
// If the client is destroyed, always try and disconnect from server | |||
Disconnect(); | |||
} | |||
public: | |||
// Connect to server with hostname/ip-address and port | |||
bool Connect(const std::string& host, const uint16_t port) | |||
{ | |||
try | |||
{ | |||
// Resolve hostname/ip-address into tangiable physical address | |||
asio::ip::tcp::resolver resolver(m_context); | |||
asio::ip::tcp::resolver::results_type endpoints = resolver.resolve(host, std::to_string(port)); | |||
// Create connection | |||
m_connection = std::make_unique<Connection<T>>(Connection<T>::Owner::CLIENT, m_context, asio::ip::tcp::socket(m_context), m_qMessagesIn); | |||
// Tell the connection object to connect to server | |||
m_connection->ConnectToServer(endpoints); | |||
// Start Context Thread | |||
thrContext = std::thread([this]() { m_context.run(); }); | |||
} | |||
catch (std::exception& e) | |||
{ | |||
std::cerr << "Client Exception: " << e.what() << "\n"; | |||
return false; | |||
} | |||
return true; | |||
} | |||
// Disconnect from server | |||
void Disconnect() | |||
{ | |||
// If connection exists, and it's connected then... | |||
if(IsConnected()) | |||
{ | |||
// ...disconnect from server gracefully | |||
m_connection->Disconnect(); | |||
} | |||
// Either way, we're also done with the asio context... | |||
m_context.stop(); | |||
// ...and its thread | |||
if (thrContext.joinable()) | |||
thrContext.join(); | |||
// Destroy the connection object | |||
m_connection.release(); | |||
} | |||
// Check if client is actually connected to a server | |||
bool IsConnected() | |||
{ | |||
if (m_connection) | |||
return m_connection->IsConnected(); | |||
else | |||
return false; | |||
} | |||
public: | |||
// Send message to server | |||
void Send(const Message<T>& msg) | |||
{ | |||
if (IsConnected()) | |||
m_connection->Send(msg); | |||
} | |||
// Retrieve queue of messages from server | |||
net::ts_dequeue<OwnedMessage<T>>& Incoming() | |||
{ | |||
return m_qMessagesIn; | |||
} | |||
protected: | |||
// asio context handles the data transfer... | |||
asio::io_context m_context; | |||
// ...but needs a thread of its own to execute its work commands | |||
std::thread thrContext; | |||
// The client has a single instance of a "connection" object, which handles data transfer | |||
std::unique_ptr<Connection<T>> m_connection; | |||
private: | |||
// This is the thread safe queue of incoming messages from server | |||
net::ts_dequeue<OwnedMessage<T>> m_qMessagesIn; | |||
}; | |||
} |
@@ -0,0 +1,76 @@ | |||
/* | |||
MMO Client/Server Framework using ASIO | |||
"Happy Birthday Mrs Javidx9!" - javidx9 | |||
Videos: | |||
Part #1: https://youtu.be/2hNdkYInj4g | |||
Part #2: https://youtu.be/UbjxGvrDrbw | |||
License (OLC-3) | |||
~~~~~~~~~~~~~~~ | |||
Copyright 2018 - 2020 OneLoneCoder.com | |||
Redistribution and use in source and binary forms, with or without | |||
modification, are permitted provided that the following conditions | |||
are met: | |||
1. Redistributions or derivations of source code must retain the above | |||
copyright notice, this list of conditions and the following disclaimer. | |||
2. Redistributions or derivative works in binary form must reproduce | |||
the above copyright notice. This list of conditions and the following | |||
disclaimer must be reproduced in the documentation and/or other | |||
materials provided with the distribution. | |||
3. Neither the name of the copyright holder nor the names of its | |||
contributors may be used to endorse or promote products derived | |||
from this software without specific prior written permission. | |||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS | |||
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT | |||
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR | |||
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT | |||
HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, | |||
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT | |||
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, | |||
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY | |||
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT | |||
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE | |||
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | |||
Links | |||
~~~~~ | |||
YouTube: https://www.youtube.com/javidx9 | |||
Discord: https://discord.gg/WhwHUMV | |||
Twitter: https://www.twitter.com/javidx9 | |||
Twitch: https://www.twitch.tv/javidx9 | |||
GitHub: https://www.github.com/onelonecoder | |||
Homepage: https://www.onelonecoder.com | |||
Author | |||
~~~~~~ | |||
David Barr, aka javidx9, ©OneLoneCoder 2019, 2020 | |||
*/ | |||
#pragma once | |||
#include <memory> | |||
#include <thread> | |||
#include <mutex> | |||
#include <deque> | |||
#include <optional> | |||
#include <vector> | |||
#include <iostream> | |||
#include <algorithm> | |||
#include <chrono> | |||
#include <cstdint> | |||
#ifdef _WIN32 | |||
#define _WIN32_WINNT 0x0A00 | |||
#endif | |||
#define ASIO_STANDALONE | |||
#include <asio.hpp> | |||
#include <asio/ts/buffer.hpp> | |||
#include <asio/ts/internet.hpp> |
@@ -0,0 +1,343 @@ | |||
/* | |||
MMO Client/Server Framework using ASIO | |||
"Happy Birthday Mrs Javidx9!" - javidx9 | |||
Videos: | |||
Part #1: https://youtu.be/2hNdkYInj4g | |||
Part #2: https://youtu.be/UbjxGvrDrbw | |||
License (OLC-3) | |||
~~~~~~~~~~~~~~~ | |||
Copyright 2018 - 2020 OneLoneCoder.com | |||
Redistribution and use in source and binary forms, with or without | |||
modification, are permitted provided that the following conditions | |||
are met: | |||
1. Redistributions or derivations of source code must retain the above | |||
copyright notice, this list of conditions and the following disclaimer. | |||
2. Redistributions or derivative works in binary form must reproduce | |||
the above copyright notice. This list of conditions and the following | |||
disclaimer must be reproduced in the documentation and/or other | |||
materials provided with the distribution. | |||
3. Neither the name of the copyright holder nor the names of its | |||
contributors may be used to endorse or promote products derived | |||
from this software without specific prior written permission. | |||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS | |||
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT | |||
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR | |||
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT | |||
HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, | |||
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT | |||
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, | |||
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY | |||
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT | |||
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE | |||
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | |||
Links | |||
~~~~~ | |||
YouTube: https://www.youtube.com/javidx9 | |||
Discord: https://discord.gg/WhwHUMV | |||
Twitter: https://www.twitter.com/javidx9 | |||
Twitch: https://www.twitch.tv/javidx9 | |||
GitHub: https://www.github.com/onelonecoder | |||
Homepage: https://www.onelonecoder.com | |||
Author | |||
~~~~~~ | |||
David Barr, aka javidx9, ©OneLoneCoder 2019, 2020 | |||
*/ | |||
#pragma once | |||
#include "net_common.h" | |||
#include "net_dequeue_ts.h" | |||
#include "net_message.h" | |||
namespace net | |||
{ | |||
template<typename T> | |||
class Connection : public std::enable_shared_from_this<Connection<T>> | |||
{ | |||
public: | |||
// A connection is "owned" by either a server or a client, and its | |||
// behaviour is slightly different bewteen the two. | |||
enum class Owner | |||
{ | |||
SERVER, | |||
CLIENT | |||
}; | |||
public: | |||
// Constructor: Specify Owner, connect to context, transfer the socket | |||
// Provide reference to incoming message queue | |||
Connection(Owner parent, asio::io_context& asioContext, asio::ip::tcp::socket socket, ts_dequeue<OwnedMessage<T>>& qIn) | |||
: m_socket(std::move(socket)), m_asioContext(asioContext), m_qMessagesIn(qIn) | |||
{ | |||
m_nOwnerType = parent; | |||
} | |||
virtual ~Connection() | |||
{} | |||
// This ID is used system wide - its how clients will understand other clients | |||
// exist across the whole system. | |||
uint32_t GetID() const | |||
{ | |||
return id; | |||
} | |||
public: | |||
void ConnectToClient(uint32_t uid = 0) | |||
{ | |||
if (m_nOwnerType == Owner::SERVER) | |||
{ | |||
if (m_socket.is_open()) | |||
{ | |||
id = uid; | |||
ReadHeader(); | |||
} | |||
} | |||
} | |||
void ConnectToServer(const asio::ip::tcp::resolver::results_type& endpoints) | |||
{ | |||
// Only clients can connect to servers | |||
if (m_nOwnerType == Owner::CLIENT) | |||
{ | |||
// Request asio attempts to connect to an endpoint | |||
asio::async_connect(m_socket, endpoints, | |||
[this](std::error_code ec, asio::ip::tcp::endpoint endpoint) | |||
{ | |||
if (!ec) | |||
{ | |||
ReadHeader(); | |||
} | |||
}); | |||
} | |||
} | |||
void Disconnect() | |||
{ | |||
if (IsConnected()) | |||
asio::post(m_asioContext, [this]() { m_socket.close(); }); | |||
} | |||
bool IsConnected() const | |||
{ | |||
return m_socket.is_open(); | |||
} | |||
// Prime the connection to wait for incoming messages | |||
void StartListening() | |||
{ | |||
} | |||
public: | |||
// ASYNC - Send a message, connections are one-to-one so no need to specifiy | |||
// the target, for a client, the target is the server and vice versa | |||
void Send(const Message<T>& msg) | |||
{ | |||
asio::post(m_asioContext, | |||
[this, msg]() | |||
{ | |||
// If the queue has a message in it, then we must | |||
// assume that it is in the process of asynchronously being written. | |||
// Either way add the message to the queue to be output. If no messages | |||
// were available to be written, then start the process of writing the | |||
// message at the front of the queue. | |||
bool bWritingMessage = !m_qMessagesOut.empty(); | |||
m_qMessagesOut.push_back(msg); | |||
if (!bWritingMessage) | |||
{ | |||
WriteHeader(); | |||
} | |||
}); | |||
} | |||
private: | |||
// ASYNC - Prime context to write a message header | |||
void WriteHeader() | |||
{ | |||
// If this function is called, we know the outgoing message queue must have | |||
// at least one message to send. So allocate a transmission buffer to hold | |||
// the message, and issue the work - asio, send these bytes | |||
asio::async_write(m_socket, asio::buffer(&m_qMessagesOut.front().header, sizeof(MessageHeader<T>)), | |||
[this](std::error_code ec, std::size_t length) | |||
{ | |||
// asio has now sent the bytes - if there was a problem | |||
// an error would be available... | |||
if (!ec) | |||
{ | |||
// ... no error, so check if the message header just sent also | |||
// has a message body... | |||
if (m_qMessagesOut.front().body.size() > 0) | |||
{ | |||
// ...it does, so issue the task to write the body bytes | |||
WriteBody(); | |||
} | |||
else | |||
{ | |||
// ...it didnt, so we are done with this message. Remove it from | |||
// the outgoing message queue | |||
m_qMessagesOut.pop_front(); | |||
// If the queue is not empty, there are more messages to send, so | |||
// make this happen by issuing the task to send the next header. | |||
if (!m_qMessagesOut.empty()) | |||
{ | |||
WriteHeader(); | |||
} | |||
} | |||
} | |||
else | |||
{ | |||
// ...asio failed to write the message, we could analyse why but | |||
// for now simply assume the connection has died by closing the | |||
// socket. When a future attempt to write to this client fails due | |||
// to the closed socket, it will be tidied up. | |||
std::cout << "[" << id << "] Write Header Fail.\n"; | |||
m_socket.close(); | |||
} | |||
}); | |||
} | |||
// ASYNC - Prime context to write a message body | |||
void WriteBody() | |||
{ | |||
// If this function is called, a header has just been sent, and that header | |||
// indicated a body existed for this message. Fill a transmission buffer | |||
// with the body data, and send it! | |||
asio::async_write(m_socket, asio::buffer(m_qMessagesOut.front().body.data(), m_qMessagesOut.front().body.size()), | |||
[this](std::error_code ec, std::size_t length) | |||
{ | |||
if (!ec) | |||
{ | |||
// Sending was successful, so we are done with the message | |||
// and remove it from the queue | |||
m_qMessagesOut.pop_front(); | |||
// If the queue still has messages in it, then issue the task to | |||
// send the next messages' header. | |||
if (!m_qMessagesOut.empty()) | |||
{ | |||
WriteHeader(); | |||
} | |||
} | |||
else | |||
{ | |||
// Sending failed, see WriteHeader() equivalent for description :P | |||
std::cout << "[" << id << "] Write Body Fail.\n"; | |||
m_socket.close(); | |||
} | |||
}); | |||
} | |||
// ASYNC - Prime context ready to read a message header | |||
void ReadHeader() | |||
{ | |||
// asio to waits until it receives | |||
// enough bytes to form a header of a message. We know the headers are a fixed | |||
// size, so allocate a transmission buffer large enough to store it. | |||
//Call this function to set up an asynchronous listener for a certain Connection | |||
asio::async_read(m_socket, asio::buffer(&m_msgTemporaryIn.header, sizeof(MessageHeader<T>)), | |||
[this](std::error_code ec, std::size_t length) | |||
{ | |||
if (!ec) | |||
{ | |||
//Full header readed | |||
//Check for message body | |||
if (m_msgTemporaryIn.header.size > 0) | |||
{ | |||
//Allocate storage | |||
m_msgTemporaryIn.body.resize(m_msgTemporaryIn.header.size); | |||
//Read if available | |||
ReadBody(); | |||
} | |||
else | |||
{ | |||
//Bodyless message, add to queue | |||
AddToIncomingMessageQueue(); | |||
} | |||
} | |||
else | |||
{ | |||
//Failure, probably a disconnection | |||
std::cout << "[" << id << "] Error: " << ec.message() << std::endl; | |||
m_socket.close(); | |||
} | |||
}); | |||
} | |||
// ASYNC - Prime context to read a message body | |||
void ReadBody() | |||
{ | |||
//Called after header has been read successfully | |||
//Read the body in the pre allocated storage | |||
asio::async_read(m_socket, asio::buffer(m_msgTemporaryIn.body.data(), m_msgTemporaryIn.body.size()), | |||
[this](std::error_code ec, std::size_t length) | |||
{ | |||
if (!ec) | |||
{ | |||
// Complete message, add to queue | |||
AddToIncomingMessageQueue(); | |||
} | |||
else | |||
{ | |||
//Failure, probably a disconnection | |||
std::cout << "[" << id << "] Error reading body: " << ec.message() << std::endl; | |||
m_socket.close(); | |||
} | |||
}); | |||
} | |||
// Add a complete message to the incoming queue, with or without body | |||
void AddToIncomingMessageQueue() | |||
{ | |||
//Put it in the queue, put a owner to the object to let the server know who send the message (which connection) | |||
if(m_nOwnerType == Owner::SERVER) | |||
m_qMessagesIn.push_back({ this->shared_from_this(), m_msgTemporaryIn }); | |||
else | |||
m_qMessagesIn.push_back({ nullptr, m_msgTemporaryIn }); | |||
//Done queueing the message, now initialize a new async read to wait for next message | |||
ReadHeader(); | |||
} | |||
protected: | |||
// unique socket to a remote | |||
asio::ip::tcp::socket m_socket; | |||
// This context is shared with the whole asio instance | |||
asio::io_context& m_asioContext; | |||
// This queue holds all messages to be sent to the remote side | |||
// of this connection | |||
ts_dequeue<Message<T>> m_qMessagesOut; | |||
// This references the incoming queue of the parent object | |||
ts_dequeue<OwnedMessage<T>>& m_qMessagesIn; | |||
// Incoming messages are constructed asynchronously, so we will | |||
// store the part assembled message here, until it is ready | |||
Message<T> m_msgTemporaryIn; | |||
// The "owner" decides how some of the connection behaves | |||
Owner m_nOwnerType = Owner::SERVER; | |||
uint32_t id = 0; | |||
}; | |||
} |
@@ -0,0 +1,161 @@ | |||
/* | |||
MMO Client/Server Framework using ASIO | |||
"Happy Birthday Mrs Javidx9!" - javidx9 | |||
Videos: | |||
Part #1: https://youtu.be/2hNdkYInj4g | |||
Part #2: https://youtu.be/UbjxGvrDrbw | |||
License (OLC-3) | |||
~~~~~~~~~~~~~~~ | |||
Copyright 2018 - 2020 OneLoneCoder.com | |||
Redistribution and use in source and binary forms, with or without | |||
modification, are permitted provided that the following conditions | |||
are met: | |||
1. Redistributions or derivations of source code must retain the above | |||
copyright notice, this list of conditions and the following disclaimer. | |||
2. Redistributions or derivative works in binary form must reproduce | |||
the above copyright notice. This list of conditions and the following | |||
disclaimer must be reproduced in the documentation and/or other | |||
materials provided with the distribution. | |||
3. Neither the name of the copyright holder nor the names of its | |||
contributors may be used to endorse or promote products derived | |||
from this software without specific prior written permission. | |||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS | |||
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT | |||
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR | |||
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT | |||
HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, | |||
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT | |||
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, | |||
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY | |||
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT | |||
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE | |||
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | |||
Links | |||
~~~~~ | |||
YouTube: https://www.youtube.com/javidx9 | |||
Discord: https://discord.gg/WhwHUMV | |||
Twitter: https://www.twitter.com/javidx9 | |||
Twitch: https://www.twitch.tv/javidx9 | |||
GitHub: https://www.github.com/onelonecoder | |||
Homepage: https://www.onelonecoder.com | |||
Author | |||
~~~~~~ | |||
David Barr, aka javidx9, ©OneLoneCoder 2019, 2020 | |||
*/ | |||
#pragma once | |||
#include "net_common.h" | |||
namespace net | |||
{ | |||
template<typename T> | |||
class ts_dequeue | |||
{ | |||
public: | |||
ts_dequeue() = default; | |||
ts_dequeue(const ts_dequeue<T>&) = delete; | |||
virtual ~ts_dequeue() { clear(); } | |||
public: | |||
// Returns and maintains item at front of Queue | |||
const T& front() | |||
{ | |||
std::scoped_lock lock(muxQueue); | |||
return deqQueue.front(); | |||
} | |||
// Returns and maintains item at back of Queue | |||
const T& back() | |||
{ | |||
std::scoped_lock lock(muxQueue); | |||
return deqQueue.back(); | |||
} | |||
// Removes and returns item from front of Queue | |||
T pop_front() | |||
{ | |||
std::scoped_lock lock(muxQueue); | |||
auto t = std::move(deqQueue.front()); | |||
deqQueue.pop_front(); | |||
return t; | |||
} | |||
// Removes and returns item from back of Queue | |||
T pop_back() | |||
{ | |||
std::scoped_lock lock(muxQueue); | |||
auto t = std::move(deqQueue.back()); | |||
deqQueue.pop_back(); | |||
return t; | |||
} | |||
// Adds an item to back of Queue | |||
void push_back(const T& item) | |||
{ | |||
std::scoped_lock lock(muxQueue); | |||
deqQueue.emplace_back(std::move(item)); | |||
std::unique_lock<std::mutex> ul(muxBlocking); | |||
cvBlocking.notify_one(); | |||
} | |||
// Adds an item to front of Queue | |||
void push_front(const T& item) | |||
{ | |||
std::scoped_lock lock(muxQueue); | |||
deqQueue.emplace_front(std::move(item)); | |||
std::unique_lock<std::mutex> ul(muxBlocking); | |||
cvBlocking.notify_one(); | |||
} | |||
// Returns true if Queue has no items | |||
bool empty() | |||
{ | |||
std::scoped_lock lock(muxQueue); | |||
return deqQueue.empty(); | |||
} | |||
// Returns number of items in Queue | |||
size_t count() | |||
{ | |||
std::scoped_lock lock(muxQueue); | |||
return deqQueue.size(); | |||
} | |||
// Clears Queue | |||
void clear() | |||
{ | |||
std::scoped_lock lock(muxQueue); | |||
deqQueue.clear(); | |||
} | |||
void wait() | |||
{ | |||
while (empty()) | |||
{ | |||
std::unique_lock<std::mutex> ul(muxBlocking); | |||
cvBlocking.wait(ul); | |||
} | |||
} | |||
protected: | |||
std::mutex muxQueue; | |||
std::deque<T> deqQueue; | |||
std::condition_variable cvBlocking; | |||
std::mutex muxBlocking; | |||
}; | |||
} |
@@ -0,0 +1,214 @@ | |||
/* | |||
MMO Client/Server Framework using ASIO | |||
"Happy Birthday Mrs Javidx9!" - javidx9 | |||
Videos: | |||
Part #1: https://youtu.be/2hNdkYInj4g | |||
Part #2: https://youtu.be/UbjxGvrDrbw | |||
License (OLC-3) | |||
~~~~~~~~~~~~~~~ | |||
Copyright 2018 - 2020 OneLoneCoder.com | |||
Redistribution and use in source and binary forms, with or without | |||
modification, are permitted provided that the following conditions | |||
are met: | |||
1. Redistributions or derivations of source code must retain the above | |||
copyright notice, this list of conditions and the following disclaimer. | |||
2. Redistributions or derivative works in binary form must reproduce | |||
the above copyright notice. This list of conditions and the following | |||
disclaimer must be reproduced in the documentation and/or other | |||
materials provided with the distribution. | |||
3. Neither the name of the copyright holder nor the names of its | |||
contributors may be used to endorse or promote products derived | |||
from this software without specific prior written permission. | |||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS | |||
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT | |||
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR | |||
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT | |||
HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, | |||
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT | |||
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, | |||
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY | |||
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT | |||
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE | |||
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | |||
Links | |||
~~~~~ | |||
YouTube: https://www.youtube.com/javidx9 | |||
Discord: https://discord.gg/WhwHUMV | |||
Twitter: https://www.twitter.com/javidx9 | |||
Twitch: https://www.twitch.tv/javidx9 | |||
GitHub: https://www.github.com/onelonecoder | |||
Homepage: https://www.onelonecoder.com | |||
Author | |||
~~~~~~ | |||
David Barr, aka javidx9, �OneLoneCoder 2019, 2020 | |||
*/ | |||
#pragma once | |||
#include "net_common.h" | |||
#include <string> | |||
namespace net | |||
{ | |||
///[OLC_HEADERIFYIER] START "MESSAGE" | |||
// Message Header is sent at start of all messages. The template allows us | |||
// to use "enum class" to ensure that the messages are valid at compile time | |||
template <typename T> | |||
struct MessageHeader | |||
{ | |||
T id{}; | |||
uint32_t size = 0; | |||
}; | |||
// Message Body contains a header and a std::vector, containing raw bytes | |||
// of infomation. This way the message can be variable length, but the size | |||
// in the header must be updated. | |||
template <typename T> | |||
struct Message | |||
{ | |||
// Header & Body vector | |||
MessageHeader<T> header{}; | |||
std::vector<uint8_t> body; | |||
// returns size of entire message packet in bytes | |||
size_t size() const | |||
{ | |||
return body.size(); | |||
} | |||
// Override for std::cout compatibility - produces friendly description of message | |||
friend std::ostream& operator << (std::ostream& os, const Message<T>& msg) | |||
{ | |||
os << "ID:" << int(msg.header.id) << " Size:" << msg.header.size; | |||
return os; | |||
} | |||
// Convenience Operator overloads - These allow us to add and remove stuff from | |||
// the body vector as if it were a stack, so First in, Last Out. These are a | |||
// template in itself, because we dont know what data type the user is pushing or | |||
// popping, so lets allow them all. NOTE: It assumes the data type is fundamentally | |||
// Plain Old Data (POD). TLDR: Serialise & Deserialise into/from a vector | |||
// Pushes any POD-like data into the message buffer | |||
template<typename DataType> | |||
friend Message<T>& operator << (Message<T>& msg, const DataType& data) | |||
{ | |||
// Check that the type of the data being pushed is trivially copyable | |||
static_assert(std::is_standard_layout<DataType>::value, "Data is too complex to be pushed into vector"); | |||
// Cache current size of vector, as this will be the point we insert the data | |||
size_t i = msg.body.size(); | |||
// Resize the vector by the size of the data being pushed | |||
msg.body.resize(i + sizeof(DataType)); | |||
// Physically copy the data into the newly allocated vector space | |||
std::memcpy(msg.body.data() + i, &data, sizeof(DataType)); | |||
// Recalculate the message size | |||
msg.header.size = msg.size(); | |||
// Return the target message so it can be "chained" | |||
return msg; | |||
} | |||
//Specified template to write string | |||
friend Message<T>& operator << (Message<T>& msg, const std::string& data) | |||
{ | |||
// Cache current size of vector, as this will be the point we insert the data | |||
size_t i = msg.body.size(); | |||
// Resize the vector by the size of the data being pushed | |||
//msg.body.resize(i + sizeof(data)); | |||
// Physically copy the data of the string character by character | |||
msg.body.resize(i + data.size()); | |||
for (size_t index = 0; index < data.size(); index++) { | |||
msg.body[i+index] = data.at(index); | |||
//std::memcpy(msg.body.data() + i, &c, sizeof(uint8_t)); | |||
} | |||
// Recalculate the message size | |||
msg.header.size = (uint32_t)msg.size(); | |||
// Return the target message so it can be "chained" | |||
return msg; | |||
} | |||
// Pulls any POD-like data form the message buffer | |||
template<typename DataType> | |||
friend Message<T>& operator >> (Message<T>& msg, DataType& data) | |||
{ | |||
// Check that the type of the data being pushed is trivially copyable | |||
static_assert(std::is_standard_layout<DataType>::value, "Data is too complex to be pulled from vector"); | |||
// Cache the location towards the end of the vector where the pulled data starts | |||
size_t i = msg.body.size() - sizeof(DataType); | |||
// Physically copy the data from the vector into the user variable | |||
std::memcpy(&data, msg.body.data() + i, sizeof(DataType)); | |||
// Shrink the vector to remove read bytes, and reset end position | |||
msg.body.resize(i); | |||
// Recalculate the message size | |||
msg.header.size = msg.size(); | |||
// Return the target message so it can be "chained" | |||
return msg; | |||
} | |||
//Specified template to read string | |||
friend Message<T>& operator >> (Message<T>& msg, std::string& data) | |||
{ | |||
// Cache the location towards the end of the vector where the pulled data starts | |||
size_t i = 0; | |||
// Physically copy the data from the vector into the user variable | |||
std::memcpy(&data, msg.body.data(), msg.body.size()); | |||
// Shrink the vector to remove read bytes, and reset end position | |||
msg.body.resize(i); | |||
// Return the target message so it can be "chained" | |||
return msg; | |||
} | |||
}; | |||
// An "owned" message is identical to a regular message, but it is associated with | |||
// a connection. On a server, the owner would be the client that sent the message, | |||
// on a client the owner would be the server. | |||
// Forward declare the connection | |||
template <typename T> | |||
class Connection; | |||
template <typename T> | |||
struct OwnedMessage | |||
{ | |||
std::shared_ptr<Connection<T>> remote = nullptr; | |||
Message<T> msg; | |||
// Again, a friendly string maker | |||
friend std::ostream& operator<<(std::ostream& os, const OwnedMessage<T>& msg) | |||
{ | |||
os << msg.msg; | |||
return os; | |||
} | |||
}; | |||
} |
@@ -0,0 +1,279 @@ | |||
/* | |||
MMO Client/Server Framework using ASIO | |||
"Happy Birthday Mrs Javidx9!" - javidx9 | |||
Videos: | |||
Part #1: https://youtu.be/2hNdkYInj4g | |||
Part #2: https://youtu.be/UbjxGvrDrbw | |||
License (OLC-3) | |||
~~~~~~~~~~~~~~~ | |||
Copyright 2018 - 2020 OneLoneCoder.com | |||
Redistribution and use in source and binary forms, with or without | |||
modification, are permitted provided that the following conditions | |||
are met: | |||
1. Redistributions or derivations of source code must retain the above | |||
copyright notice, this list of conditions and the following disclaimer. | |||
2. Redistributions or derivative works in binary form must reproduce | |||
the above copyright notice. This list of conditions and the following | |||
disclaimer must be reproduced in the documentation and/or other | |||
materials provided with the distribution. | |||
3. Neither the name of the copyright holder nor the names of its | |||
contributors may be used to endorse or promote products derived | |||
from this software without specific prior written permission. | |||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS | |||
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT | |||
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR | |||
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT | |||
HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, | |||
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT | |||
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, | |||
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY | |||
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT | |||
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE | |||
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | |||
Links | |||
~~~~~ | |||
YouTube: https://www.youtube.com/javidx9 | |||
Discord: https://discord.gg/WhwHUMV | |||
Twitter: https://www.twitter.com/javidx9 | |||
Twitch: https://www.twitch.tv/javidx9 | |||
GitHub: https://www.github.com/onelonecoder | |||
Homepage: https://www.onelonecoder.com | |||
Author | |||
~~~~~~ | |||
David Barr, aka javidx9, ?OneLoneCoder 2019, 2020 | |||
*/ | |||
#pragma once | |||
#include "net_dequeue_ts.h" | |||
#include "net_common.h" | |||
#include "net_message.h" | |||
#include "net_connection.h" | |||
#include "easylogging++.h" | |||
namespace net | |||
{ | |||
template<typename T> | |||
class ServerInterface | |||
{ | |||
public: // Create a server, ready to listen on specified port | |||
ServerInterface(uint16_t port) | |||
: m_asioAcceptor(m_asioContext, asio::ip::tcp::endpoint(asio::ip::tcp::v4(), port)) { } | |||
virtual ~ServerInterface() { Stop(); } | |||
// Starts the server | |||
virtual bool Start() | |||
{ | |||
try | |||
{ | |||
// Issue a task to the asio context - This is important | |||
// as it will prime the context with "work", and stop it | |||
// from exiting immediately. Since this is a server, we | |||
// want it primed ready to handle clients trying to | |||
// connect. | |||
WaitForClientConnection(); | |||
// Launch the asio context in its own thread | |||
m_threadContext = std::thread([this]() { m_asioContext.run(); }); | |||
} | |||
catch (std::exception& e) | |||
{ | |||
// Something prohibited the server from listening | |||
std::cerr << "[SERVER] Exception: " << e.what() << "\n"; | |||
return false; | |||
} | |||
LOG(INFO) << "[SERVER] Started\n"; | |||
return true; | |||
} | |||
bool isStopped()const { | |||
return m_asioContext.stopped(); | |||
} | |||
// Stops the server! | |||
virtual void Stop() | |||
{ | |||
// Request the context to close | |||
m_asioContext.stop(); | |||
// Tidy up the context thread | |||
if (m_threadContext.joinable()) m_threadContext.join(); | |||
// Inform someone, anybody, if they care... | |||
LOG(INFO) << "[SERVER] Stopped!\n"; | |||
} | |||
// ASYNC - Instruct asio to wait for connection | |||
void WaitForClientConnection() | |||
{ | |||
// Prime context with an instruction to wait until a socket connects. This | |||
// is the purpose of an "acceptor" object. It will provide a unique socket | |||
// for each incoming connection attempt | |||
m_asioAcceptor.async_accept( | |||
[this](std::error_code ec, asio::ip::tcp::socket socket) | |||
{ | |||
// Triggered by incoming connection request | |||
if (!ec) | |||
{ | |||
LOG(INFO) << "[SERVER] New Connection: " << socket.remote_endpoint(); | |||
// Create a new connection to handle this client | |||
std::shared_ptr<Connection<T>> newconn = | |||
std::make_shared<Connection<T>>(Connection<T>::Owner::SERVER, | |||
m_asioContext, std::move(socket), m_qMessagesIn); | |||
// Give the user server a chance to deny connection | |||
if (OnClientConnect(newconn)) | |||
{ | |||
// Connection allowed, so add to container of new connections | |||
m_deqConnections.push_back(std::move(newconn)); | |||
// Issue a task to the connection's | |||
// asio context to sit and wait for bytes to arrive! | |||
m_deqConnections.back()->ConnectToClient(nIDCounter++); | |||
LOG(INFO) << "[" << m_deqConnections.back()->GetID() << "] Connection Approved\n"; | |||
} | |||
else | |||
{ | |||
LOG(INFO) << "[SERVER] Connection Denied"; | |||
// Connection will go out of scope with no pending tasks, so will | |||
// get destroyed automatically (smart pointer) | |||
} | |||
} | |||
else | |||
{ | |||
// Error has occurred during acceptance | |||
LOG(INFO) << "[SERVER] New Connection Error: " << ec.message(); | |||
} | |||
// Prime the asio context with more work - again simply wait for | |||
// another connection... | |||
WaitForClientConnection(); | |||
}); | |||
} | |||
// Send a message to a specific client | |||
void MessageClient(std::shared_ptr<Connection<T>> client, const Message<T>& msg) | |||
{ | |||
// Check client is legitimate... | |||
if (client && client->IsConnected()) | |||
{ | |||
// ...and post the message via the connection | |||
client->Send(msg); | |||
} | |||
else | |||
{ | |||
// If we cant communicate with client then we may as | |||
// well remove the client - let the server know, it may | |||
// be tracking it somehow | |||
OnClientDisconnect(client); | |||
// Off you go now, bye bye! | |||
client.reset(); | |||
// Then physically remove it from the container | |||
m_deqConnections.erase( | |||
std::remove(m_deqConnections.begin(), m_deqConnections.end(), client), m_deqConnections.end()); | |||
} | |||
} | |||
// Send message to all clients | |||
void MessageAllClients(const Message<T>& msg, std::shared_ptr<Connection<T>> pIgnoreClient = nullptr) | |||
{ | |||
bool bInvalidClientExists = false; | |||
// Iterate through all clients in container | |||
for (auto& client : m_deqConnections) | |||
{ | |||
// Check client is connected... | |||
if (client && client->IsConnected()) | |||
{ | |||
// ..it is! | |||
if(client != pIgnoreClient) | |||
client->Send(msg); | |||
} | |||
else | |||
{ | |||
// The client couldnt be contacted, so assume it has | |||
// disconnected. | |||
OnClientDisconnect(client); | |||
client.reset(); | |||
// Set this flag to then remove dead clients from container | |||
bInvalidClientExists = true; | |||
} | |||
} | |||
// Remove dead clients, all in one go - this way, we dont invalidate the | |||
// container as we iterated through it. | |||
if (bInvalidClientExists) | |||
m_deqConnections.erase( | |||
std::remove(m_deqConnections.begin(), m_deqConnections.end(), nullptr), m_deqConnections.end()); | |||
} | |||
// Force server to respond to incoming messages | |||
// size_t nmaxMessages: Assign -1 to unsigned to unspecify max message count | |||
// bool bWait: if queue is empty, wait synchronously until message arrives | |||
void Update(size_t nMaxMessages = -1, bool bWait = false) | |||
{ | |||
if (bWait) m_qMessagesIn.wait(); | |||
// Process as many messages as you can up to the value | |||
// specified | |||
size_t nMessageCount = 0; | |||
while (nMessageCount < nMaxMessages && !m_qMessagesIn.empty()) | |||
{ | |||
// Grab the front message | |||
auto msg = m_qMessagesIn.pop_front(); | |||
// Pass to message handler | |||
OnMessage(msg.remote, msg.msg); | |||
nMessageCount++; | |||
} | |||
} | |||
protected: | |||
//Overwritable functions to customize server behaviour | |||
// Called when a client connects, you can veto the connection by returning false | |||
virtual bool OnClientConnect(std::shared_ptr<Connection<T>> client) = 0; | |||
// Called when a client appears to have disconnected | |||
virtual void OnClientDisconnect(std::shared_ptr<Connection<T>> client) = 0; | |||
// Called when a message arrives | |||
virtual void OnMessage(std::shared_ptr<Connection<T>> client, Message<T>& msg) = 0; | |||
protected: | |||
// Thread Safe Queue for incoming message packets | |||
ts_dequeue<OwnedMessage<T>> m_qMessagesIn; | |||
// Container of active validated connections | |||
std::deque<std::shared_ptr<Connection<T>>> m_deqConnections; | |||
// Order of declaration is important - it is also the order of initialisation | |||
asio::io_context m_asioContext; | |||
std::thread m_threadContext; | |||
// These things need an asio context | |||
asio::ip::tcp::acceptor m_asioAcceptor; // Handles new incoming connection attempts... | |||
// Clients will be identified in the "wider system" via an ID | |||
uint32_t nIDCounter = 100; | |||
}; | |||
} |
@@ -0,0 +1,34 @@ | |||
CONFIG -= qt | |||
TEMPLATE = lib | |||
CONFIG += staticlib | |||
CONFIG += c++17 | |||
INCLUDEPATH += ../EasyLoggingPP | |||
unix: CONFIG += link_pkgconfig | |||
unix: PKGCONFIG += libasio | |||
SOURCES += \ | |||
LIBS += -pthread | |||
HEADERS += \ | |||
net_server_client.h \ | |||
src/net_client.h \ | |||
src/net_common.h \ | |||
src/net_connection.h \ | |||
src/net_dequeue_ts.h \ | |||
src/net_message.h \ | |||
src/net_message_types.h \ | |||
src/net_server.h | |||
# Default rules for deployment. | |||
unix { | |||
target.path = $$[QT_INSTALL_PLUGINS]/generic | |||
} | |||
!isEmpty(target.path): INSTALLS += target |
@@ -0,0 +1,355 @@ | |||
<?xml version="1.0" encoding="UTF-8"?> | |||
<!DOCTYPE QtCreatorProject> | |||
<!-- Written by QtCreator 4.13.3, 2021-07-30T10:52:14. --> | |||
<qtcreator> | |||
<data> | |||
<variable>EnvironmentId</variable> | |||
<value type="QByteArray">{5a632e4a-e744-412b-acc7-3b951573dab3}</value> | |||
</data> | |||
<data> | |||
<variable>ProjectExplorer.Project.ActiveTarget</variable> | |||
<value type="int">0</value> | |||
</data> | |||
<data> | |||
<variable>ProjectExplorer.Project.EditorSettings</variable> | |||
<valuemap type="QVariantMap"> | |||
<value type="bool" key="EditorConfiguration.AutoIndent">true</value> | |||
<value type="bool" key="EditorConfiguration.AutoSpacesForTabs">false</value> | |||
<value type="bool" key="EditorConfiguration.CamelCaseNavigation">true</value> | |||
<valuemap type="QVariantMap" key="EditorConfiguration.CodeStyle.0"> | |||
<value type="QString" key="language">Cpp</value> | |||
<valuemap type="QVariantMap" key="value"> | |||
<value type="QByteArray" key="CurrentPreferences">CppGlobal</value> | |||
</valuemap> | |||
</valuemap> | |||
<valuemap type="QVariantMap" key="EditorConfiguration.CodeStyle.1"> | |||
<value type="QString" key="language">QmlJS</value> | |||
<valuemap type="QVariantMap" key="value"> | |||
<value type="QByteArray" key="CurrentPreferences">QmlJSGlobal</value> | |||
</valuemap> | |||
</valuemap> | |||
<value type="int" key="EditorConfiguration.CodeStyle.Count">2</value> | |||
<value type="QByteArray" key="EditorConfiguration.Codec">UTF-8</value> | |||
<value type="bool" key="EditorConfiguration.ConstrainTooltips">false</value> | |||
<value type="int" key="EditorConfiguration.IndentSize">4</value> | |||
<value type="bool" key="EditorConfiguration.KeyboardTooltips">false</value> | |||
<value type="int" key="EditorConfiguration.MarginColumn">80</value> | |||
<value type="bool" key="EditorConfiguration.MouseHiding">true</value> | |||
<value type="bool" key="EditorConfiguration.MouseNavigation">true</value> | |||
<value type="int" key="EditorConfiguration.PaddingMode">1</value> | |||
<value type="bool" key="EditorConfiguration.ScrollWheelZooming">true</value> | |||
<value type="bool" key="EditorConfiguration.ShowMargin">false</value> | |||
<value type="int" key="EditorConfiguration.SmartBackspaceBehavior">0</value> | |||
<value type="bool" key="EditorConfiguration.SmartSelectionChanging">true</value> | |||
<value type="bool" key="EditorConfiguration.SpacesForTabs">true</value> | |||
<value type="int" key="EditorConfiguration.TabKeyBehavior">0</value> | |||
<value type="int" key="EditorConfiguration.TabSize">8</value> | |||
<value type="bool" key="EditorConfiguration.UseGlobal">true</value> | |||
<value type="int" key="EditorConfiguration.Utf8BomBehavior">1</value> | |||
<value type="bool" key="EditorConfiguration.addFinalNewLine">true</value> | |||
<value type="bool" key="EditorConfiguration.cleanIndentation">true</value> | |||
<value type="bool" key="EditorConfiguration.cleanWhitespace">true</value> | |||
<value type="QString" key="EditorConfiguration.ignoreFileTypes">*.md, *.MD, Makefile</value> | |||
<value type="bool" key="EditorConfiguration.inEntireDocument">false</value> | |||
<value type="bool" key="EditorConfiguration.skipTrailingWhitespace">true</value> | |||
</valuemap> | |||
</data> | |||
<data> | |||
<variable>ProjectExplorer.Project.PluginSettings</variable> | |||
<valuemap type="QVariantMap"> | |||
<valuemap type="QVariantMap" key="AutoTest.ActiveFrameworks"> | |||
<value type="bool" key="AutoTest.Framework.Boost">true</value> | |||
<value type="bool" key="AutoTest.Framework.Catch">true</value> | |||
<value type="bool" key="AutoTest.Framework.GTest">true</value> | |||
<value type="bool" key="AutoTest.Framework.QtQuickTest">true</value> | |||
<value type="bool" key="AutoTest.Framework.QtTest">true</value> | |||
</valuemap> | |||
<valuemap type="QVariantMap" key="AutoTest.CheckStates"/> | |||
<value type="int" key="AutoTest.RunAfterBuild">0</value> | |||
<value type="bool" key="AutoTest.UseGlobal">true</value> | |||
<valuelist type="QVariantList" key="ClangCodeModel.CustomCommandLineKey"/> | |||
<value type="bool" key="ClangCodeModel.UseGlobalConfig">true</value> | |||
<value type="QString" key="ClangCodeModel.WarningConfigId">Builtin.Questionable</value> | |||
<valuemap type="QVariantMap" key="ClangTools"> | |||
<value type="bool" key="ClangTools.BuildBeforeAnalysis">true</value> | |||
<value type="QString" key="ClangTools.DiagnosticConfig">Builtin.DefaultTidyAndClazy</value> | |||
<value type="int" key="ClangTools.ParallelJobs">1</value> | |||
<valuelist type="QVariantList" key="ClangTools.SelectedDirs"/> | |||
<valuelist type="QVariantList" key="ClangTools.SelectedFiles"/> | |||
<valuelist type="QVariantList" key="ClangTools.SuppressedDiagnostics"/> | |||
<value type="bool" key="ClangTools.UseGlobalSettings">true</value> | |||
</valuemap> | |||
</valuemap> | |||
</data> | |||
<data> | |||
<variable>ProjectExplorer.Project.Target.0</variable> | |||
<valuemap type="QVariantMap"> | |||
<value type="QString" key="DeviceType">Desktop</value> | |||
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">Desktop Qt 5.15.1 GCC 64bit</value> | |||
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName">Desktop Qt 5.15.1 GCC 64bit</value> | |||
<value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">qt.qt5.5151.gcc_64_kit</value> | |||
<value type="int" key="ProjectExplorer.Target.ActiveBuildConfiguration">0</value> | |||
<value type="int" key="ProjectExplorer.Target.ActiveDeployConfiguration">0</value> | |||
<value type="int" key="ProjectExplorer.Target.ActiveRunConfiguration">0</value> | |||
<valuemap type="QVariantMap" key="ProjectExplorer.Target.BuildConfiguration.0"> | |||
<value type="bool">true</value> | |||
<value type="int" key="EnableQmlDebugging">0</value> | |||
<value type="QString" key="ProjectExplorer.BuildConfiguration.BuildDirectory">/home/michael/baConditionMonitoring/AsioNetClientServer/debug</value> | |||
<value type="QString" key="ProjectExplorer.BuildConfiguration.BuildDirectory.shadowDir">/home/michael/baConditionMonitoring/AsioNetClientServer/debug</value> | |||
<valuemap type="QVariantMap" key="ProjectExplorer.BuildConfiguration.BuildStepList.0"> | |||
<valuemap type="QVariantMap" key="ProjectExplorer.BuildStepList.Step.0"> | |||
<value type="bool" key="ProjectExplorer.BuildStep.Enabled">true</value> | |||
<value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">QtProjectManager.QMakeBuildStep</value> | |||
<value type="QString" key="QtProjectManager.QMakeBuildStep.QMakeArguments"></value> | |||
<value type="bool" key="QtProjectManager.QMakeBuildStep.QMakeForced">false</value> | |||
<valuelist type="QVariantList" key="QtProjectManager.QMakeBuildStep.SelectedAbis"/> | |||
</valuemap> | |||
<valuemap type="QVariantMap" key="ProjectExplorer.BuildStepList.Step.1"> | |||
<value type="bool" key="ProjectExplorer.BuildStep.Enabled">true</value> | |||
<value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">Qt4ProjectManager.MakeStep</value> | |||
<valuelist type="QVariantList" key="Qt4ProjectManager.MakeStep.BuildTargets"/> | |||
<value type="bool" key="Qt4ProjectManager.MakeStep.Clean">false</value> | |||
<value type="QString" key="Qt4ProjectManager.MakeStep.MakeArguments"></value> | |||
<value type="QString" key="Qt4ProjectManager.MakeStep.MakeCommand"></value> | |||
<value type="bool" key="Qt4ProjectManager.MakeStep.OverrideMakeflags">false</value> | |||
</valuemap> | |||
<value type="int" key="ProjectExplorer.BuildStepList.StepsCount">2</value> | |||
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">Build</value> | |||
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName">Build</value> | |||
<value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">ProjectExplorer.BuildSteps.Build</value> | |||
</valuemap> | |||
<valuemap type="QVariantMap" key="ProjectExplorer.BuildConfiguration.BuildStepList.1"> | |||
<valuemap type="QVariantMap" key="ProjectExplorer.BuildStepList.Step.0"> | |||
<value type="bool" key="ProjectExplorer.BuildStep.Enabled">true</value> | |||
<value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">Qt4ProjectManager.MakeStep</value> | |||
<valuelist type="QVariantList" key="Qt4ProjectManager.MakeStep.BuildTargets"/> | |||
<value type="bool" key="Qt4ProjectManager.MakeStep.Clean">true</value> | |||
<value type="QString" key="Qt4ProjectManager.MakeStep.MakeArguments">clean</value> | |||
<value type="QString" key="Qt4ProjectManager.MakeStep.MakeCommand"></value> | |||
<value type="bool" key="Qt4ProjectManager.MakeStep.OverrideMakeflags">false</value> | |||
</valuemap> | |||
<value type="int" key="ProjectExplorer.BuildStepList.StepsCount">1</value> | |||
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">Clean</value> | |||
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName">Clean</value> | |||
<value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">ProjectExplorer.BuildSteps.Clean</value> | |||
</valuemap> | |||
<value type="int" key="ProjectExplorer.BuildConfiguration.BuildStepListCount">2</value> | |||
<value type="bool" key="ProjectExplorer.BuildConfiguration.ClearSystemEnvironment">false</value> | |||
<valuelist type="QVariantList" key="ProjectExplorer.BuildConfiguration.CustomParsers"/> | |||
<valuelist type="QVariantList" key="ProjectExplorer.BuildConfiguration.UserEnvironmentChanges"/> | |||
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName">Debug</value> | |||
<value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">Qt4ProjectManager.Qt4BuildConfiguration</value> | |||
<value type="int" key="Qt4ProjectManager.Qt4BuildConfiguration.BuildConfiguration">2</value> | |||
<value type="int" key="QtQuickCompiler">2</value> | |||
<value type="int" key="SeparateDebugInfo">2</value> | |||
</valuemap> | |||
<valuemap type="QVariantMap" key="ProjectExplorer.Target.BuildConfiguration.1"> | |||
<value type="bool">true</value> | |||
<value type="int" key="EnableQmlDebugging">2</value> | |||
<value type="QString" key="ProjectExplorer.BuildConfiguration.BuildDirectory">/home/michael/baConditionMonitoring/build-asio_inet_client_server-Desktop_Qt_5_15_1_GCC_64bit-Release</value> | |||
<value type="QString" key="ProjectExplorer.BuildConfiguration.BuildDirectory.shadowDir">/home/michael/baConditionMonitoring/build-asio_inet_client_server-Desktop_Qt_5_15_1_GCC_64bit-Release</value> | |||
<valuemap type="QVariantMap" key="ProjectExplorer.BuildConfiguration.BuildStepList.0"> | |||
<valuemap type="QVariantMap" key="ProjectExplorer.BuildStepList.Step.0"> | |||
<value type="bool" key="ProjectExplorer.BuildStep.Enabled">true</value> | |||
<value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">QtProjectManager.QMakeBuildStep</value> | |||
<value type="QString" key="QtProjectManager.QMakeBuildStep.QMakeArguments"></value> | |||
<value type="bool" key="QtProjectManager.QMakeBuildStep.QMakeForced">false</value> | |||
<valuelist type="QVariantList" key="QtProjectManager.QMakeBuildStep.SelectedAbis"/> | |||
</valuemap> | |||
<valuemap type="QVariantMap" key="ProjectExplorer.BuildStepList.Step.1"> | |||
<value type="bool" key="ProjectExplorer.BuildStep.Enabled">true</value> | |||
<value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">Qt4ProjectManager.MakeStep</value> | |||
<valuelist type="QVariantList" key="Qt4ProjectManager.MakeStep.BuildTargets"/> | |||
<value type="bool" key="Qt4ProjectManager.MakeStep.Clean">false</value> | |||
<value type="QString" key="Qt4ProjectManager.MakeStep.MakeArguments"></value> | |||
<value type="QString" key="Qt4ProjectManager.MakeStep.MakeCommand"></value> | |||
<value type="bool" key="Qt4ProjectManager.MakeStep.OverrideMakeflags">false</value> | |||
</valuemap> | |||
<value type="int" key="ProjectExplorer.BuildStepList.StepsCount">2</value> | |||
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">Build</value> | |||
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName">Build</value> | |||
<value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">ProjectExplorer.BuildSteps.Build</value> | |||
</valuemap> | |||
<valuemap type="QVariantMap" key="ProjectExplorer.BuildConfiguration.BuildStepList.1"> | |||
<valuemap type="QVariantMap" key="ProjectExplorer.BuildStepList.Step.0"> | |||
<value type="bool" key="ProjectExplorer.BuildStep.Enabled">true</value> | |||
<value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">Qt4ProjectManager.MakeStep</value> | |||
<valuelist type="QVariantList" key="Qt4ProjectManager.MakeStep.BuildTargets"/> | |||
<value type="bool" key="Qt4ProjectManager.MakeStep.Clean">true</value> | |||
<value type="QString" key="Qt4ProjectManager.MakeStep.MakeArguments">clean</value> | |||
<value type="QString" key="Qt4ProjectManager.MakeStep.MakeCommand"></value> | |||
<value type="bool" key="Qt4ProjectManager.MakeStep.OverrideMakeflags">false</value> | |||
</valuemap> | |||
<value type="int" key="ProjectExplorer.BuildStepList.StepsCount">1</value> | |||
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">Clean</value> | |||
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName">Clean</value> | |||
<value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">ProjectExplorer.BuildSteps.Clean</value> | |||
</valuemap> | |||
<value type="int" key="ProjectExplorer.BuildConfiguration.BuildStepListCount">2</value> | |||
<value type="bool" key="ProjectExplorer.BuildConfiguration.ClearSystemEnvironment">false</value> | |||
<valuelist type="QVariantList" key="ProjectExplorer.BuildConfiguration.CustomParsers"/> | |||
<valuelist type="QVariantList" key="ProjectExplorer.BuildConfiguration.UserEnvironmentChanges"/> | |||
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName">Release</value> | |||
<value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">Qt4ProjectManager.Qt4BuildConfiguration</value> | |||
<value type="int" key="Qt4ProjectManager.Qt4BuildConfiguration.BuildConfiguration">0</value> | |||
<value type="int" key="QtQuickCompiler">0</value> | |||
<value type="int" key="SeparateDebugInfo">2</value> | |||
</valuemap> | |||
<valuemap type="QVariantMap" key="ProjectExplorer.Target.BuildConfiguration.2"> | |||
<value type="bool">true</value> | |||
<value type="int" key="EnableQmlDebugging">0</value> | |||
<value type="QString" key="ProjectExplorer.BuildConfiguration.BuildDirectory">/home/michael/baConditionMonitoring/build-asio_inet_client_server-Desktop_Qt_5_15_1_GCC_64bit-Profile</value> | |||
<value type="QString" key="ProjectExplorer.BuildConfiguration.BuildDirectory.shadowDir">/home/michael/baConditionMonitoring/build-asio_inet_client_server-Desktop_Qt_5_15_1_GCC_64bit-Profile</value> | |||
<valuemap type="QVariantMap" key="ProjectExplorer.BuildConfiguration.BuildStepList.0"> | |||
<valuemap type="QVariantMap" key="ProjectExplorer.BuildStepList.Step.0"> | |||
<value type="bool" key="ProjectExplorer.BuildStep.Enabled">true</value> | |||
<value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">QtProjectManager.QMakeBuildStep</value> | |||
<value type="QString" key="QtProjectManager.QMakeBuildStep.QMakeArguments"></value> | |||
<value type="bool" key="QtProjectManager.QMakeBuildStep.QMakeForced">false</value> | |||
<valuelist type="QVariantList" key="QtProjectManager.QMakeBuildStep.SelectedAbis"/> | |||
</valuemap> | |||
<valuemap type="QVariantMap" key="ProjectExplorer.BuildStepList.Step.1"> | |||
<value type="bool" key="ProjectExplorer.BuildStep.Enabled">true</value> | |||
<value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">Qt4ProjectManager.MakeStep</value> | |||
<valuelist type="QVariantList" key="Qt4ProjectManager.MakeStep.BuildTargets"/> | |||
<value type="bool" key="Qt4ProjectManager.MakeStep.Clean">false</value> | |||
<value type="QString" key="Qt4ProjectManager.MakeStep.MakeArguments"></value> | |||
<value type="QString" key="Qt4ProjectManager.MakeStep.MakeCommand"></value> | |||
<value type="bool" key="Qt4ProjectManager.MakeStep.OverrideMakeflags">false</value> | |||
</valuemap> | |||
<value type="int" key="ProjectExplorer.BuildStepList.StepsCount">2</value> | |||
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">Build</value> | |||
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName">Build</value> | |||
<value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">ProjectExplorer.BuildSteps.Build</value> | |||
</valuemap> | |||
<valuemap type="QVariantMap" key="ProjectExplorer.BuildConfiguration.BuildStepList.1"> | |||
<valuemap type="QVariantMap" key="ProjectExplorer.BuildStepList.Step.0"> | |||
<value type="bool" key="ProjectExplorer.BuildStep.Enabled">true</value> | |||
<value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">Qt4ProjectManager.MakeStep</value> | |||
<valuelist type="QVariantList" key="Qt4ProjectManager.MakeStep.BuildTargets"/> | |||
<value type="bool" key="Qt4ProjectManager.MakeStep.Clean">true</value> | |||
<value type="QString" key="Qt4ProjectManager.MakeStep.MakeArguments">clean</value> | |||
<value type="QString" key="Qt4ProjectManager.MakeStep.MakeCommand"></value> | |||
<value type="bool" key="Qt4ProjectManager.MakeStep.OverrideMakeflags">false</value> | |||
</valuemap> | |||
<value type="int" key="ProjectExplorer.BuildStepList.StepsCount">1</value> | |||
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">Clean</value> | |||
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName">Clean</value> | |||
<value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">ProjectExplorer.BuildSteps.Clean</value> | |||
</valuemap> | |||
<value type="int" key="ProjectExplorer.BuildConfiguration.BuildStepListCount">2</value> | |||
<value type="bool" key="ProjectExplorer.BuildConfiguration.ClearSystemEnvironment">false</value> | |||
<valuelist type="QVariantList" key="ProjectExplorer.BuildConfiguration.CustomParsers"/> | |||
<valuelist type="QVariantList" key="ProjectExplorer.BuildConfiguration.UserEnvironmentChanges"/> | |||
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName">Profile</value> | |||
<value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">Qt4ProjectManager.Qt4BuildConfiguration</value> | |||
<value type="int" key="Qt4ProjectManager.Qt4BuildConfiguration.BuildConfiguration">0</value> | |||
<value type="int" key="QtQuickCompiler">0</value> | |||
<value type="int" key="SeparateDebugInfo">0</value> | |||
</valuemap> | |||
<value type="int" key="ProjectExplorer.Target.BuildConfigurationCount">3</value> | |||
<valuemap type="QVariantMap" key="ProjectExplorer.Target.DeployConfiguration.0"> | |||
<valuemap type="QVariantMap" key="ProjectExplorer.BuildConfiguration.BuildStepList.0"> | |||
<value type="int" key="ProjectExplorer.BuildStepList.StepsCount">0</value> | |||
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">Deploy</value> | |||
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName">Deploy</value> | |||
<value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">ProjectExplorer.BuildSteps.Deploy</value> | |||
</valuemap> | |||
<value type="int" key="ProjectExplorer.BuildConfiguration.BuildStepListCount">1</value> | |||
<valuemap type="QVariantMap" key="ProjectExplorer.DeployConfiguration.CustomData"/> | |||
<value type="bool" key="ProjectExplorer.DeployConfiguration.CustomDataEnabled">false</value> | |||
<value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">ProjectExplorer.DefaultDeployConfiguration</value> | |||
</valuemap> | |||
<value type="int" key="ProjectExplorer.Target.DeployConfigurationCount">1</value> | |||
<valuemap type="QVariantMap" key="ProjectExplorer.Target.PluginSettings"/> | |||
<valuemap type="QVariantMap" key="ProjectExplorer.Target.RunConfiguration.0"> | |||
<value type="QString" key="Analyzer.Perf.CallgraphMode">dwarf</value> | |||
<valuelist type="QVariantList" key="Analyzer.Perf.Events"> | |||
<value type="QString">cpu-cycles</value> | |||
</valuelist> | |||
<valuelist type="QVariantList" key="Analyzer.Perf.ExtraArguments"/> | |||
<value type="int" key="Analyzer.Perf.Frequency">250</value> | |||
<valuelist type="QVariantList" key="Analyzer.Perf.RecordArguments"> | |||
<value type="QString">-e</value> | |||
<value type="QString">cpu-cycles</value> | |||
<value type="QString">--call-graph</value> | |||
<value type="QString">dwarf,4096</value> | |||
<value type="QString">-F</value> | |||
<value type="QString">250</value> | |||
</valuelist> | |||
<value type="QString" key="Analyzer.Perf.SampleMode">-F</value> | |||
<value type="bool" key="Analyzer.Perf.Settings.UseGlobalSettings">true</value> | |||
<value type="int" key="Analyzer.Perf.StackSize">4096</value> | |||
<value type="bool" key="Analyzer.QmlProfiler.AggregateTraces">false</value> | |||
<value type="bool" key="Analyzer.QmlProfiler.FlushEnabled">false</value> | |||
<value type="uint" key="Analyzer.QmlProfiler.FlushInterval">1000</value> | |||
<value type="QString" key="Analyzer.QmlProfiler.LastTraceFile"></value> | |||
<value type="bool" key="Analyzer.QmlProfiler.Settings.UseGlobalSettings">true</value> | |||
<valuelist type="QVariantList" key="Analyzer.Valgrind.AddedSuppressionFiles"/> | |||
<value type="bool" key="Analyzer.Valgrind.Callgrind.CollectBusEvents">false</value> | |||
<value type="bool" key="Analyzer.Valgrind.Callgrind.CollectSystime">false</value> | |||
<value type="bool" key="Analyzer.Valgrind.Callgrind.EnableBranchSim">false</value> | |||
<value type="bool" key="Analyzer.Valgrind.Callgrind.EnableCacheSim">false</value> | |||
<value type="bool" key="Analyzer.Valgrind.Callgrind.EnableEventToolTips">true</value> | |||
<value type="double" key="Analyzer.Valgrind.Callgrind.MinimumCostRatio">0.01</value> | |||
<value type="double" key="Analyzer.Valgrind.Callgrind.VisualisationMinimumCostRatio">10</value> | |||
<value type="bool" key="Analyzer.Valgrind.FilterExternalIssues">true</value> | |||
<value type="QString" key="Analyzer.Valgrind.KCachegrindExecutable">kcachegrind</value> | |||
<value type="int" key="Analyzer.Valgrind.LeakCheckOnFinish">1</value> | |||
<value type="int" key="Analyzer.Valgrind.NumCallers">25</value> | |||
<valuelist type="QVariantList" key="Analyzer.Valgrind.RemovedSuppressionFiles"/> | |||
<value type="int" key="Analyzer.Valgrind.SelfModifyingCodeDetection">1</value> | |||
<value type="bool" key="Analyzer.Valgrind.Settings.UseGlobalSettings">true</value> | |||
<value type="bool" key="Analyzer.Valgrind.ShowReachable">false</value> | |||
<value type="bool" key="Analyzer.Valgrind.TrackOrigins">true</value> | |||
<value type="QString" key="Analyzer.Valgrind.ValgrindExecutable">valgrind</value> | |||
<valuelist type="QVariantList" key="Analyzer.Valgrind.VisibleErrorKinds"> | |||
<value type="int">0</value> | |||
<value type="int">1</value> | |||
<value type="int">2</value> | |||
<value type="int">3</value> | |||
<value type="int">4</value> | |||
<value type="int">5</value> | |||
<value type="int">6</value> | |||
<value type="int">7</value> | |||
<value type="int">8</value> | |||
<value type="int">9</value> | |||
<value type="int">10</value> | |||
<value type="int">11</value> | |||
<value type="int">12</value> | |||
<value type="int">13</value> | |||
<value type="int">14</value> | |||
</valuelist> | |||
<valuelist type="QVariantList" key="CustomOutputParsers"/> | |||
<value type="int" key="PE.EnvironmentAspect.Base">2</value> | |||
<valuelist type="QVariantList" key="PE.EnvironmentAspect.Changes"/> | |||
<value type="QString" key="ProjectExplorer.CustomExecutableRunConfiguration.Executable"></value> | |||
<value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">ProjectExplorer.CustomExecutableRunConfiguration</value> | |||
<value type="QString" key="ProjectExplorer.RunConfiguration.BuildKey"></value> | |||
<value type="QString" key="RunConfiguration.Arguments"></value> | |||
<value type="bool" key="RunConfiguration.Arguments.multi">false</value> | |||
<value type="QString" key="RunConfiguration.OverrideDebuggerStartup"></value> | |||
<value type="bool" key="RunConfiguration.UseCppDebugger">false</value> | |||
<value type="bool" key="RunConfiguration.UseCppDebuggerAuto">true</value> | |||
<value type="bool" key="RunConfiguration.UseMultiProcess">false</value> | |||
<value type="bool" key="RunConfiguration.UseQmlDebugger">false</value> | |||
<value type="bool" key="RunConfiguration.UseQmlDebuggerAuto">true</value> | |||
<value type="QString" key="RunConfiguration.WorkingDirectory"></value> | |||
<value type="QString" key="RunConfiguration.WorkingDirectory.default"></value> | |||
</valuemap> | |||
<value type="int" key="ProjectExplorer.Target.RunConfigurationCount">1</value> | |||
</valuemap> | |||
</data> | |||
<data> | |||
<variable>ProjectExplorer.Project.TargetCount</variable> | |||
<value type="int">1</value> | |||
</data> | |||
<data> | |||
<variable>ProjectExplorer.Project.Updater.FileVersion</variable> | |||
<value type="int">22</value> | |||
</data> | |||
<data> | |||
<variable>Version</variable> | |||
<value type="int">22</value> | |||
</data> | |||
</qtcreator> |
@@ -0,0 +1,317 @@ | |||
<?xml version="1.0" encoding="UTF-8"?> | |||
<!DOCTYPE QtCreatorProject> | |||
<!-- Written by QtCreator 4.15.1, 2021-07-23T08:11:18. --> | |||
<qtcreator> | |||
<data> | |||
<variable>EnvironmentId</variable> | |||
<value type="QByteArray">{eac5e3ee-8a8a-4d3e-ba79-20701eff322a}</value> | |||
</data> | |||
<data> | |||
<variable>ProjectExplorer.Project.ActiveTarget</variable> | |||
<value type="int">0</value> | |||
</data> | |||
<data> | |||
<variable>ProjectExplorer.Project.EditorSettings</variable> | |||
<valuemap type="QVariantMap"> | |||
<value type="bool" key="EditorConfiguration.AutoIndent">true</value> | |||
<value type="bool" key="EditorConfiguration.AutoSpacesForTabs">false</value> | |||
<value type="bool" key="EditorConfiguration.CamelCaseNavigation">true</value> | |||
<valuemap type="QVariantMap" key="EditorConfiguration.CodeStyle.0"> | |||
<value type="QString" key="language">Cpp</value> | |||
<valuemap type="QVariantMap" key="value"> | |||
<value type="QByteArray" key="CurrentPreferences">CppGlobal</value> | |||
</valuemap> | |||
</valuemap> | |||
<valuemap type="QVariantMap" key="EditorConfiguration.CodeStyle.1"> | |||
<value type="QString" key="language">QmlJS</value> | |||
<valuemap type="QVariantMap" key="value"> | |||
<value type="QByteArray" key="CurrentPreferences">QmlJSGlobal</value> | |||
</valuemap> | |||
</valuemap> | |||
<value type="int" key="EditorConfiguration.CodeStyle.Count">2</value> | |||
<value type="QByteArray" key="EditorConfiguration.Codec">UTF-8</value> | |||
<value type="bool" key="EditorConfiguration.ConstrainTooltips">false</value> | |||
<value type="int" key="EditorConfiguration.IndentSize">4</value> | |||
<value type="bool" key="EditorConfiguration.KeyboardTooltips">false</value> | |||
<value type="int" key="EditorConfiguration.MarginColumn">80</value> | |||
<value type="bool" key="EditorConfiguration.MouseHiding">true</value> | |||
<value type="bool" key="EditorConfiguration.MouseNavigation">true</value> | |||
<value type="int" key="EditorConfiguration.PaddingMode">1</value> | |||
<value type="bool" key="EditorConfiguration.PreferSingleLineComments">false</value> | |||
<value type="bool" key="EditorConfiguration.ScrollWheelZooming">true</value> | |||
<value type="bool" key="EditorConfiguration.ShowMargin">false</value> | |||
<value type="int" key="EditorConfiguration.SmartBackspaceBehavior">0</value> | |||
<value type="bool" key="EditorConfiguration.SmartSelectionChanging">true</value> | |||
<value type="bool" key="EditorConfiguration.SpacesForTabs">true</value> | |||
<value type="int" key="EditorConfiguration.TabKeyBehavior">0</value> | |||
<value type="int" key="EditorConfiguration.TabSize">8</value> | |||
<value type="bool" key="EditorConfiguration.UseGlobal">true</value> | |||
<value type="bool" key="EditorConfiguration.UseIndenter">false</value> | |||
<value type="int" key="EditorConfiguration.Utf8BomBehavior">1</value> | |||
<value type="bool" key="EditorConfiguration.addFinalNewLine">true</value> | |||
<value type="bool" key="EditorConfiguration.cleanIndentation">true</value> | |||
<value type="bool" key="EditorConfiguration.cleanWhitespace">true</value> | |||
<value type="QString" key="EditorConfiguration.ignoreFileTypes">*.md, *.MD, Makefile</value> | |||
<value type="bool" key="EditorConfiguration.inEntireDocument">false</value> | |||
<value type="bool" key="EditorConfiguration.skipTrailingWhitespace">true</value> | |||
</valuemap> | |||
</data> | |||
<data> | |||
<variable>ProjectExplorer.Project.PluginSettings</variable> | |||
<valuemap type="QVariantMap"> | |||
<valuemap type="QVariantMap" key="AutoTest.ActiveFrameworks"> | |||
<value type="bool" key="AutoTest.Framework.Boost">true</value> | |||
<value type="bool" key="AutoTest.Framework.CTest">false</value> | |||
<value type="bool" key="AutoTest.Framework.Catch">true</value> | |||
<value type="bool" key="AutoTest.Framework.GTest">true</value> | |||
<value type="bool" key="AutoTest.Framework.QtQuickTest">true</value> | |||
<value type="bool" key="AutoTest.Framework.QtTest">true</value> | |||
</valuemap> | |||
<valuemap type="QVariantMap" key="AutoTest.CheckStates"/> | |||
<value type="int" key="AutoTest.RunAfterBuild">0</value> | |||
<value type="bool" key="AutoTest.UseGlobal">true</value> | |||
<valuelist type="QVariantList" key="ClangCodeModel.CustomCommandLineKey"/> | |||
<value type="bool" key="ClangCodeModel.UseGlobalConfig">true</value> | |||
<value type="QString" key="ClangCodeModel.WarningConfigId">Builtin.BuildSystem</value> | |||
<valuemap type="QVariantMap" key="ClangTools"> | |||
<value type="bool" key="ClangTools.AnalyzeOpenFiles">true</value> | |||
<value type="bool" key="ClangTools.BuildBeforeAnalysis">true</value> | |||
<value type="QString" key="ClangTools.DiagnosticConfig">Builtin.DefaultTidyAndClazy</value> | |||
<value type="int" key="ClangTools.ParallelJobs">1</value> | |||
<valuelist type="QVariantList" key="ClangTools.SelectedDirs"/> | |||
<valuelist type="QVariantList" key="ClangTools.SelectedFiles"/> | |||
<valuelist type="QVariantList" key="ClangTools.SuppressedDiagnostics"/> | |||
<value type="bool" key="ClangTools.UseGlobalSettings">true</value> | |||
</valuemap> | |||
</valuemap> | |||
</data> | |||
<data> | |||
<variable>ProjectExplorer.Project.Target.0</variable> | |||
<valuemap type="QVariantMap"> | |||
<value type="QString" key="DeviceType">Desktop</value> | |||
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">Desktop Qt 6.1.1 GCC 64bit</value> | |||
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName">Desktop Qt 6.1.1 GCC 64bit</value> | |||
<value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">qt.qt6.611.gcc_64_kit</value> | |||
<value type="int" key="ProjectExplorer.Target.ActiveBuildConfiguration">1</value> | |||
<value type="int" key="ProjectExplorer.Target.ActiveDeployConfiguration">0</value> | |||
<value type="int" key="ProjectExplorer.Target.ActiveRunConfiguration">0</value> | |||
<valuemap type="QVariantMap" key="ProjectExplorer.Target.BuildConfiguration.0"> | |||
<value type="int" key="EnableQmlDebugging">0</value> | |||
<value type="QString" key="ProjectExplorer.BuildConfiguration.BuildDirectory">/home/michael/baConditionMonitoring/AsioNetClientServer/build-asio_inet_client_server-Desktop_Qt_6_1_1_GCC_64bit-Debug</value> | |||
<value type="QString" key="ProjectExplorer.BuildConfiguration.BuildDirectory.shadowDir">/home/michael/baConditionMonitoring/AsioNetClientServer/build-asio_inet_client_server-Desktop_Qt_6_1_1_GCC_64bit-Debug</value> | |||
<valuemap type="QVariantMap" key="ProjectExplorer.BuildConfiguration.BuildStepList.0"> | |||
<valuemap type="QVariantMap" key="ProjectExplorer.BuildStepList.Step.0"> | |||
<value type="bool" key="ProjectExplorer.BuildStep.Enabled">true</value> | |||
<value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">QtProjectManager.QMakeBuildStep</value> | |||
<value type="bool" key="QtProjectManager.QMakeBuildStep.QMakeForced">false</value> | |||
<valuelist type="QVariantList" key="QtProjectManager.QMakeBuildStep.SelectedAbis"/> | |||
</valuemap> | |||
<valuemap type="QVariantMap" key="ProjectExplorer.BuildStepList.Step.1"> | |||
<value type="bool" key="ProjectExplorer.BuildStep.Enabled">true</value> | |||
<value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">Qt4ProjectManager.MakeStep</value> | |||
</valuemap> | |||
<value type="int" key="ProjectExplorer.BuildStepList.StepsCount">2</value> | |||
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">Build</value> | |||
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName">Build</value> | |||
<value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">ProjectExplorer.BuildSteps.Build</value> | |||
</valuemap> | |||
<valuemap type="QVariantMap" key="ProjectExplorer.BuildConfiguration.BuildStepList.1"> | |||
<valuemap type="QVariantMap" key="ProjectExplorer.BuildStepList.Step.0"> | |||
<value type="bool" key="ProjectExplorer.BuildStep.Enabled">true</value> | |||
<value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">Qt4ProjectManager.MakeStep</value> | |||
<value type="QString" key="Qt4ProjectManager.MakeStep.MakeArguments">clean</value> | |||
</valuemap> | |||
<value type="int" key="ProjectExplorer.BuildStepList.StepsCount">1</value> | |||
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">Clean</value> | |||
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName">Clean</value> | |||
<value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">ProjectExplorer.BuildSteps.Clean</value> | |||
</valuemap> | |||
<value type="int" key="ProjectExplorer.BuildConfiguration.BuildStepListCount">2</value> | |||
<value type="bool" key="ProjectExplorer.BuildConfiguration.ClearSystemEnvironment">false</value> | |||
<valuelist type="QVariantList" key="ProjectExplorer.BuildConfiguration.CustomParsers"/> | |||
<valuelist type="QVariantList" key="ProjectExplorer.BuildConfiguration.UserEnvironmentChanges"/> | |||
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName">Debug</value> | |||
<value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">Qt4ProjectManager.Qt4BuildConfiguration</value> | |||
<value type="int" key="Qt4ProjectManager.Qt4BuildConfiguration.BuildConfiguration">2</value> | |||
</valuemap> | |||
<valuemap type="QVariantMap" key="ProjectExplorer.Target.BuildConfiguration.1"> | |||
<value type="QString" key="ProjectExplorer.BuildConfiguration.BuildDirectory">debug</value> | |||
<value type="QString" key="ProjectExplorer.BuildConfiguration.BuildDirectory.shadowDir">debug</value> | |||
<valuemap type="QVariantMap" key="ProjectExplorer.BuildConfiguration.BuildStepList.0"> | |||
<valuemap type="QVariantMap" key="ProjectExplorer.BuildStepList.Step.0"> | |||
<value type="bool" key="ProjectExplorer.BuildStep.Enabled">true</value> | |||
<value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">QtProjectManager.QMakeBuildStep</value> | |||
<value type="bool" key="QtProjectManager.QMakeBuildStep.QMakeForced">false</value> | |||
<valuelist type="QVariantList" key="QtProjectManager.QMakeBuildStep.SelectedAbis"/> | |||
</valuemap> | |||
<valuemap type="QVariantMap" key="ProjectExplorer.BuildStepList.Step.1"> | |||
<value type="bool" key="ProjectExplorer.BuildStep.Enabled">true</value> | |||
<value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">Qt4ProjectManager.MakeStep</value> | |||
</valuemap> | |||
<value type="int" key="ProjectExplorer.BuildStepList.StepsCount">2</value> | |||
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">Build</value> | |||
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName">Build</value> | |||
<value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">ProjectExplorer.BuildSteps.Build</value> | |||
</valuemap> | |||
<valuemap type="QVariantMap" key="ProjectExplorer.BuildConfiguration.BuildStepList.1"> | |||
<valuemap type="QVariantMap" key="ProjectExplorer.BuildStepList.Step.0"> | |||
<value type="bool" key="ProjectExplorer.BuildStep.Enabled">true</value> | |||
<value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">Qt4ProjectManager.MakeStep</value> | |||
<value type="QString" key="Qt4ProjectManager.MakeStep.MakeArguments">clean</value> | |||
</valuemap> | |||
<value type="int" key="ProjectExplorer.BuildStepList.StepsCount">1</value> | |||
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">Clean</value> | |||
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName">Clean</value> | |||
<value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">ProjectExplorer.BuildSteps.Clean</value> | |||
</valuemap> | |||
<value type="int" key="ProjectExplorer.BuildConfiguration.BuildStepListCount">2</value> | |||
<value type="bool" key="ProjectExplorer.BuildConfiguration.ClearSystemEnvironment">false</value> | |||
<valuelist type="QVariantList" key="ProjectExplorer.BuildConfiguration.CustomParsers"/> | |||
<valuelist type="QVariantList" key="ProjectExplorer.BuildConfiguration.UserEnvironmentChanges"/> | |||
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName">Release</value> | |||
<value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">Qt4ProjectManager.Qt4BuildConfiguration</value> | |||
<value type="int" key="Qt4ProjectManager.Qt4BuildConfiguration.BuildConfiguration">0</value> | |||
<value type="int" key="QtQuickCompiler">0</value> | |||
</valuemap> | |||
<valuemap type="QVariantMap" key="ProjectExplorer.Target.BuildConfiguration.2"> | |||
<value type="int" key="EnableQmlDebugging">0</value> | |||
<value type="QString" key="ProjectExplorer.BuildConfiguration.BuildDirectory">/home/michael/baConditionMonitoring/AsioNetClientServer/build-asio_inet_client_server-Desktop_Qt_6_1_1_GCC_64bit-Profile</value> | |||
<value type="QString" key="ProjectExplorer.BuildConfiguration.BuildDirectory.shadowDir">/home/michael/baConditionMonitoring/AsioNetClientServer/build-asio_inet_client_server-Desktop_Qt_6_1_1_GCC_64bit-Profile</value> | |||
<valuemap type="QVariantMap" key="ProjectExplorer.BuildConfiguration.BuildStepList.0"> | |||
<valuemap type="QVariantMap" key="ProjectExplorer.BuildStepList.Step.0"> | |||
<value type="bool" key="ProjectExplorer.BuildStep.Enabled">true</value> | |||
<value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">QtProjectManager.QMakeBuildStep</value> | |||
<value type="bool" key="QtProjectManager.QMakeBuildStep.QMakeForced">false</value> | |||
<valuelist type="QVariantList" key="QtProjectManager.QMakeBuildStep.SelectedAbis"/> | |||
</valuemap> | |||
<valuemap type="QVariantMap" key="ProjectExplorer.BuildStepList.Step.1"> | |||
<value type="bool" key="ProjectExplorer.BuildStep.Enabled">true</value> | |||
<value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">Qt4ProjectManager.MakeStep</value> | |||
</valuemap> | |||
<value type="int" key="ProjectExplorer.BuildStepList.StepsCount">2</value> | |||
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">Build</value> | |||
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName">Build</value> | |||
<value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">ProjectExplorer.BuildSteps.Build</value> | |||
</valuemap> | |||
<valuemap type="QVariantMap" key="ProjectExplorer.BuildConfiguration.BuildStepList.1"> | |||
<valuemap type="QVariantMap" key="ProjectExplorer.BuildStepList.Step.0"> | |||
<value type="bool" key="ProjectExplorer.BuildStep.Enabled">true</value> | |||
<value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">Qt4ProjectManager.MakeStep</value> | |||
<value type="QString" key="Qt4ProjectManager.MakeStep.MakeArguments">clean</value> | |||
</valuemap> | |||
<value type="int" key="ProjectExplorer.BuildStepList.StepsCount">1</value> | |||
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">Clean</value> | |||
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName">Clean</value> | |||
<value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">ProjectExplorer.BuildSteps.Clean</value> | |||
</valuemap> | |||
<value type="int" key="ProjectExplorer.BuildConfiguration.BuildStepListCount">2</value> | |||
<value type="bool" key="ProjectExplorer.BuildConfiguration.ClearSystemEnvironment">false</value> | |||
<valuelist type="QVariantList" key="ProjectExplorer.BuildConfiguration.CustomParsers"/> | |||
<valuelist type="QVariantList" key="ProjectExplorer.BuildConfiguration.UserEnvironmentChanges"/> | |||
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName">Profile</value> | |||
<value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">Qt4ProjectManager.Qt4BuildConfiguration</value> | |||
<value type="int" key="Qt4ProjectManager.Qt4BuildConfiguration.BuildConfiguration">0</value> | |||
<value type="int" key="QtQuickCompiler">0</value> | |||
<value type="int" key="SeparateDebugInfo">0</value> | |||
</valuemap> | |||
<value type="int" key="ProjectExplorer.Target.BuildConfigurationCount">3</value> | |||
<valuemap type="QVariantMap" key="ProjectExplorer.Target.DeployConfiguration.0"> | |||
<valuemap type="QVariantMap" key="ProjectExplorer.BuildConfiguration.BuildStepList.0"> | |||
<value type="int" key="ProjectExplorer.BuildStepList.StepsCount">0</value> | |||
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">Deploy</value> | |||
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName">Deploy</value> | |||
<value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">ProjectExplorer.BuildSteps.Deploy</value> | |||
</valuemap> | |||
<value type="int" key="ProjectExplorer.BuildConfiguration.BuildStepListCount">1</value> | |||
<valuemap type="QVariantMap" key="ProjectExplorer.DeployConfiguration.CustomData"/> | |||
<value type="bool" key="ProjectExplorer.DeployConfiguration.CustomDataEnabled">false</value> | |||
<value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">ProjectExplorer.DefaultDeployConfiguration</value> | |||
</valuemap> | |||
<value type="int" key="ProjectExplorer.Target.DeployConfigurationCount">1</value> | |||
<valuemap type="QVariantMap" key="ProjectExplorer.Target.RunConfiguration.0"> | |||
<value type="QString" key="Analyzer.Perf.CallgraphMode">dwarf</value> | |||
<valuelist type="QVariantList" key="Analyzer.Perf.Events"> | |||
<value type="QString">cpu-cycles</value> | |||
</valuelist> | |||
<valuelist type="QVariantList" key="Analyzer.Perf.ExtraArguments"/> | |||
<value type="int" key="Analyzer.Perf.Frequency">250</value> | |||
<valuelist type="QVariantList" key="Analyzer.Perf.RecordArguments"> | |||
<value type="QString">-e</value> | |||
<value type="QString">cpu-cycles</value> | |||
<value type="QString">--call-graph</value> | |||
<value type="QString">dwarf,4096</value> | |||
<value type="QString">-F</value> | |||
<value type="QString">250</value> | |||
</valuelist> | |||
<value type="QString" key="Analyzer.Perf.SampleMode">-F</value> | |||
<value type="bool" key="Analyzer.Perf.Settings.UseGlobalSettings">true</value> | |||
<value type="int" key="Analyzer.Perf.StackSize">4096</value> | |||
<value type="bool" key="Analyzer.QmlProfiler.AggregateTraces">false</value> | |||
<value type="bool" key="Analyzer.QmlProfiler.FlushEnabled">false</value> | |||
<value type="uint" key="Analyzer.QmlProfiler.FlushInterval">1000</value> | |||
<value type="QString" key="Analyzer.QmlProfiler.LastTraceFile"></value> | |||
<value type="bool" key="Analyzer.QmlProfiler.Settings.UseGlobalSettings">true</value> | |||
<valuelist type="QVariantList" key="Analyzer.Valgrind.AddedSuppressionFiles"/> | |||
<value type="QString" key="Analyzer.Valgrind.Callgrind.Arguments"></value> | |||
<value type="bool" key="Analyzer.Valgrind.Callgrind.CollectBusEvents">false</value> | |||
<value type="bool" key="Analyzer.Valgrind.Callgrind.CollectSystime">false</value> | |||
<value type="bool" key="Analyzer.Valgrind.Callgrind.EnableBranchSim">false</value> | |||
<value type="bool" key="Analyzer.Valgrind.Callgrind.EnableCacheSim">false</value> | |||
<value type="bool" key="Analyzer.Valgrind.Callgrind.EnableEventToolTips">true</value> | |||
<value type="double" key="Analyzer.Valgrind.Callgrind.MinimumCostRatio">0.01</value> | |||
<value type="double" key="Analyzer.Valgrind.Callgrind.VisualisationMinimumCostRatio">10</value> | |||
<value type="bool" key="Analyzer.Valgrind.FilterExternalIssues">true</value> | |||
<value type="QString" key="Analyzer.Valgrind.KCachegrindExecutable">kcachegrind</value> | |||
<value type="int" key="Analyzer.Valgrind.LeakCheckOnFinish">1</value> | |||
<value type="QString" key="Analyzer.Valgrind.Memcheck.Arguments"></value> | |||
<value type="int" key="Analyzer.Valgrind.NumCallers">25</value> | |||
<valuelist type="QVariantList" key="Analyzer.Valgrind.RemovedSuppressionFiles"/> | |||
<value type="int" key="Analyzer.Valgrind.SelfModifyingCodeDetection">1</value> | |||
<value type="bool" key="Analyzer.Valgrind.Settings.UseGlobalSettings">true</value> | |||
<value type="bool" key="Analyzer.Valgrind.ShowReachable">false</value> | |||
<value type="bool" key="Analyzer.Valgrind.TrackOrigins">true</value> | |||
<value type="QString" key="Analyzer.Valgrind.ValgrindArguments"></value> | |||
<value type="QString" key="Analyzer.Valgrind.ValgrindExecutable">valgrind</value> | |||
<valuelist type="QVariantList" key="Analyzer.Valgrind.VisibleErrorKinds"> | |||
<value type="int">0</value> | |||
<value type="int">1</value> | |||
<value type="int">2</value> | |||
<value type="int">3</value> | |||
<value type="int">4</value> | |||
<value type="int">5</value> | |||
<value type="int">6</value> | |||
<value type="int">7</value> | |||
<value type="int">8</value> | |||
<value type="int">9</value> | |||
<value type="int">10</value> | |||
<value type="int">11</value> | |||
<value type="int">12</value> | |||
<value type="int">13</value> | |||
<value type="int">14</value> | |||
</valuelist> | |||
<valuelist type="QVariantList" key="CustomOutputParsers"/> | |||
<value type="int" key="PE.EnvironmentAspect.Base">2</value> | |||
<valuelist type="QVariantList" key="PE.EnvironmentAspect.Changes"/> | |||
<value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">ProjectExplorer.CustomExecutableRunConfiguration</value> | |||
<value type="QString" key="ProjectExplorer.RunConfiguration.BuildKey"></value> | |||
<value type="bool" key="RunConfiguration.UseCppDebugger">false</value> | |||
<value type="bool" key="RunConfiguration.UseCppDebuggerAuto">true</value> | |||
<value type="bool" key="RunConfiguration.UseQmlDebugger">false</value> | |||
<value type="bool" key="RunConfiguration.UseQmlDebuggerAuto">true</value> | |||
</valuemap> | |||
<value type="int" key="ProjectExplorer.Target.RunConfigurationCount">1</value> | |||
</valuemap> | |||
</data> | |||
<data> | |||
<variable>ProjectExplorer.Project.TargetCount</variable> | |||
<value type="int">1</value> | |||
</data> | |||
<data> | |||
<variable>ProjectExplorer.Project.Updater.FileVersion</variable> | |||
<value type="int">22</value> | |||
</data> | |||
<data> | |||
<variable>Version</variable> | |||
<value type="int">22</value> | |||
</data> | |||
</qtcreator> |
@@ -0,0 +1,78 @@ | |||
/* | |||
MMO Client/Server Framework using ASIO | |||
"Happy Birthday Mrs Javidx9!" - javidx9 | |||
Videos: | |||
Part #1: https://youtu.be/2hNdkYInj4g | |||
Part #2: https://youtu.be/UbjxGvrDrbw | |||
License (OLC-3) | |||
~~~~~~~~~~~~~~~ | |||
Copyright 2018 - 2020 OneLoneCoder.com | |||
Redistribution and use in source and binary forms, with or without | |||
modification, are permitted provided that the following conditions | |||
are met: | |||
1. Redistributions or derivations of source code must retain the above | |||
copyright notice, this list of conditions and the following disclaimer. | |||
2. Redistributions or derivative works in binary form must reproduce | |||
the above copyright notice. This list of conditions and the following | |||
disclaimer must be reproduced in the documentation and/or other | |||
materials provided with the distribution. | |||
3. Neither the name of the copyright holder nor the names of its | |||
contributors may be used to endorse or promote products derived | |||
from this software without specific prior written permission. | |||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS | |||
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT | |||
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR | |||
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT | |||
HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, | |||
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT | |||
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, | |||
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY | |||
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT | |||
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE | |||
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | |||
Links | |||
~~~~~ | |||
YouTube: https://www.youtube.com/javidx9 | |||
Discord: https://discord.gg/WhwHUMV | |||
Twitter: https://www.twitter.com/javidx9 | |||
Twitch: https://www.twitch.tv/javidx9 | |||
GitHub: https://www.github.com/onelonecoder | |||
Homepage: https://www.onelonecoder.com | |||
Author | |||
~~~~~~ | |||
David Barr, aka javidx9, ©OneLoneCoder 2019, 2020 | |||
*/ | |||
#pragma once | |||
namespace net { | |||
enum class MessageTypes | |||
{ | |||
ServerAccept, | |||
ServerDeny, | |||
ServerData, | |||
ServerLog, | |||
ServerCondition, | |||
ServerAlert, | |||
ServerCloseConnection, | |||
}; | |||
} | |||
#include "src/net_common.h" | |||
#include "src/net_dequeue_ts.h" | |||
#include "src/net_message.h" | |||
#include "src/net_client.h" | |||
#include "src/net_server.h" | |||
#include "src/net_connection.h" |
@@ -0,0 +1,157 @@ | |||
/* | |||
MMO Client/Server Framework using ASIO | |||
"Happy Birthday Mrs Javidx9!" - javidx9 | |||
Videos: | |||
Part #1: https://youtu.be/2hNdkYInj4g | |||
Part #2: https://youtu.be/UbjxGvrDrbw | |||
License (OLC-3) | |||
~~~~~~~~~~~~~~~ | |||
Copyright 2018 - 2020 OneLoneCoder.com | |||
Redistribution and use in source and binary forms, with or without | |||
modification, are permitted provided that the following conditions | |||
are met: | |||
1. Redistributions or derivations of source code must retain the above | |||
copyright notice, this list of conditions and the following disclaimer. | |||
2. Redistributions or derivative works in binary form must reproduce | |||
the above copyright notice. This list of conditions and the following | |||
disclaimer must be reproduced in the documentation and/or other | |||
materials provided with the distribution. | |||
3. Neither the name of the copyright holder nor the names of its | |||
contributors may be used to endorse or promote products derived | |||
from this software without specific prior written permission. | |||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS | |||
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT | |||
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR | |||
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT | |||
HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, | |||
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT | |||
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, | |||
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY | |||
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT | |||
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE | |||
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | |||
Links | |||
~~~~~ | |||
YouTube: https://www.youtube.com/javidx9 | |||
Discord: https://discord.gg/WhwHUMV | |||
Twitter: https://www.twitter.com/javidx9 | |||
Twitch: https://www.twitch.tv/javidx9 | |||
GitHub: https://www.github.com/onelonecoder | |||
Homepage: https://www.onelonecoder.com | |||
Author | |||
~~~~~~ | |||
David Barr, aka javidx9, ©OneLoneCoder 2019, 2020 | |||
*/ | |||
#pragma once | |||
#include "net_common.h" | |||
#include "net_connection.h" | |||
namespace net | |||
{ | |||
template <typename T> | |||
class ClientInterface | |||
{ | |||
public: | |||
ClientInterface() | |||
{} | |||
virtual ~ClientInterface() | |||
{ | |||
// If the client is destroyed, always try and disconnect from server | |||
Disconnect(); | |||
} | |||
public: | |||
// Connect to server with hostname/ip-address and port | |||
bool Connect(const std::string& host, const uint16_t port) | |||
{ | |||
try | |||
{ | |||
// Resolve hostname/ip-address into tangiable physical address | |||
asio::ip::tcp::resolver resolver(m_context); | |||
asio::ip::tcp::resolver::results_type endpoints = resolver.resolve(host, std::to_string(port)); | |||
// Create connection | |||
m_connection = std::make_unique<Connection<T>>(Connection<T>::Owner::CLIENT, m_context, asio::ip::tcp::socket(m_context), m_qMessagesIn); | |||
// Tell the connection object to connect to server | |||
m_connection->ConnectToServer(endpoints); | |||
// Start Context Thread | |||
thrContext = std::thread([this]() { m_context.run(); }); | |||
} | |||
catch (std::exception& e) | |||
{ | |||
std::cerr << "Client Exception: " << e.what() << "\n"; | |||
return false; | |||
} | |||
return true; | |||
} | |||
// Disconnect from server | |||
void Disconnect() | |||
{ | |||
// If connection exists, and it's connected then... | |||
if(IsConnected()) | |||
{ | |||
// ...disconnect from server gracefully | |||
m_connection->Disconnect(); | |||
} | |||
// Either way, we're also done with the asio context... | |||
m_context.stop(); | |||
// ...and its thread | |||
if (thrContext.joinable()) | |||
thrContext.join(); | |||
// Destroy the connection object | |||
m_connection.release(); | |||
} | |||
// Check if client is actually connected to a server | |||
bool IsConnected() | |||
{ | |||
if (m_connection) | |||
return m_connection->IsConnected(); | |||
else | |||
return false; | |||
} | |||
public: | |||
// Send message to server | |||
void Send(const Message<T>& msg) | |||
{ | |||
if (IsConnected()) | |||
m_connection->Send(msg); | |||
} | |||
// Retrieve queue of messages from server | |||
net::ts_dequeue<OwnedMessage<T>>& Incoming() | |||
{ | |||
return m_qMessagesIn; | |||
} | |||
protected: | |||
// asio context handles the data transfer... | |||
asio::io_context m_context; | |||
// ...but needs a thread of its own to execute its work commands | |||
std::thread thrContext; | |||
// The client has a single instance of a "connection" object, which handles data transfer | |||
std::unique_ptr<Connection<T>> m_connection; | |||
private: | |||
// This is the thread safe queue of incoming messages from server | |||
net::ts_dequeue<OwnedMessage<T>> m_qMessagesIn; | |||
}; | |||
} |
@@ -0,0 +1,76 @@ | |||
/* | |||
MMO Client/Server Framework using ASIO | |||
"Happy Birthday Mrs Javidx9!" - javidx9 | |||
Videos: | |||
Part #1: https://youtu.be/2hNdkYInj4g | |||
Part #2: https://youtu.be/UbjxGvrDrbw | |||
License (OLC-3) | |||
~~~~~~~~~~~~~~~ | |||
Copyright 2018 - 2020 OneLoneCoder.com | |||
Redistribution and use in source and binary forms, with or without | |||
modification, are permitted provided that the following conditions | |||
are met: | |||
1. Redistributions or derivations of source code must retain the above | |||
copyright notice, this list of conditions and the following disclaimer. | |||
2. Redistributions or derivative works in binary form must reproduce | |||
the above copyright notice. This list of conditions and the following | |||
disclaimer must be reproduced in the documentation and/or other | |||
materials provided with the distribution. | |||
3. Neither the name of the copyright holder nor the names of its | |||
contributors may be used to endorse or promote products derived | |||
from this software without specific prior written permission. | |||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS | |||
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT | |||
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR | |||
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT | |||
HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, | |||
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT | |||
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, | |||
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY | |||
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT | |||
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE | |||
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | |||
Links | |||
~~~~~ | |||
YouTube: https://www.youtube.com/javidx9 | |||
Discord: https://discord.gg/WhwHUMV | |||
Twitter: https://www.twitter.com/javidx9 | |||
Twitch: https://www.twitch.tv/javidx9 | |||
GitHub: https://www.github.com/onelonecoder | |||
Homepage: https://www.onelonecoder.com | |||
Author | |||
~~~~~~ | |||
David Barr, aka javidx9, ©OneLoneCoder 2019, 2020 | |||
*/ | |||
#pragma once | |||
#include <memory> | |||
#include <thread> | |||
#include <mutex> | |||
#include <deque> | |||
#include <optional> | |||
#include <vector> | |||
#include <iostream> | |||
#include <algorithm> | |||
#include <chrono> | |||
#include <cstdint> | |||
#ifdef _WIN32 | |||
#define _WIN32_WINNT 0x0A00 | |||
#endif | |||
#define ASIO_STANDALONE | |||
#include <asio.hpp> | |||
#include <asio/ts/buffer.hpp> | |||
#include <asio/ts/internet.hpp> |
@@ -0,0 +1,343 @@ | |||
/* | |||
MMO Client/Server Framework using ASIO | |||
"Happy Birthday Mrs Javidx9!" - javidx9 | |||
Videos: | |||
Part #1: https://youtu.be/2hNdkYInj4g | |||
Part #2: https://youtu.be/UbjxGvrDrbw | |||
License (OLC-3) | |||
~~~~~~~~~~~~~~~ | |||
Copyright 2018 - 2020 OneLoneCoder.com | |||
Redistribution and use in source and binary forms, with or without | |||
modification, are permitted provided that the following conditions | |||
are met: | |||
1. Redistributions or derivations of source code must retain the above | |||
copyright notice, this list of conditions and the following disclaimer. | |||
2. Redistributions or derivative works in binary form must reproduce | |||
the above copyright notice. This list of conditions and the following | |||
disclaimer must be reproduced in the documentation and/or other | |||
materials provided with the distribution. | |||
3. Neither the name of the copyright holder nor the names of its | |||
contributors may be used to endorse or promote products derived | |||
from this software without specific prior written permission. | |||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS | |||
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT | |||
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR | |||
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT | |||
HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, | |||
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT | |||
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, | |||
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY | |||
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT | |||
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE | |||
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | |||
Links | |||
~~~~~ | |||
YouTube: https://www.youtube.com/javidx9 | |||
Discord: https://discord.gg/WhwHUMV | |||
Twitter: https://www.twitter.com/javidx9 | |||
Twitch: https://www.twitch.tv/javidx9 | |||
GitHub: https://www.github.com/onelonecoder | |||
Homepage: https://www.onelonecoder.com | |||
Author | |||
~~~~~~ | |||
David Barr, aka javidx9, ©OneLoneCoder 2019, 2020 | |||
*/ | |||
#pragma once | |||
#include "net_common.h" | |||
#include "net_dequeue_ts.h" | |||
#include "net_message.h" | |||
namespace net | |||
{ | |||
template<typename T> | |||
class Connection : public std::enable_shared_from_this<Connection<T>> | |||
{ | |||
public: | |||
// A connection is "owned" by either a server or a client, and its | |||
// behaviour is slightly different bewteen the two. | |||
enum class Owner | |||
{ | |||
SERVER, | |||
CLIENT | |||
}; | |||
public: | |||
// Constructor: Specify Owner, connect to context, transfer the socket | |||
// Provide reference to incoming message queue | |||
Connection(Owner parent, asio::io_context& asioContext, asio::ip::tcp::socket socket, ts_dequeue<OwnedMessage<T>>& qIn) | |||
: m_socket(std::move(socket)), m_asioContext(asioContext), m_qMessagesIn(qIn) | |||
{ | |||
m_nOwnerType = parent; | |||
} | |||
virtual ~Connection() | |||
{} | |||
// This ID is used system wide - its how clients will understand other clients | |||
// exist across the whole system. | |||
uint32_t GetID() const | |||
{ | |||
return id; | |||
} | |||
public: | |||
void ConnectToClient(uint32_t uid = 0) | |||
{ | |||
if (m_nOwnerType == Owner::SERVER) | |||
{ | |||
if (m_socket.is_open()) | |||
{ | |||
id = uid; | |||
ReadHeader(); | |||
} | |||
} | |||
} | |||
void ConnectToServer(const asio::ip::tcp::resolver::results_type& endpoints) | |||
{ | |||
// Only clients can connect to servers | |||
if (m_nOwnerType == Owner::CLIENT) | |||
{ | |||
// Request asio attempts to connect to an endpoint | |||
asio::async_connect(m_socket, endpoints, | |||
[this](std::error_code ec, asio::ip::tcp::endpoint endpoint) | |||
{ | |||
if (!ec) | |||
{ | |||
ReadHeader(); | |||
} | |||
}); | |||
} | |||
} | |||
void Disconnect() | |||
{ | |||
if (IsConnected()) | |||
asio::post(m_asioContext, [this]() { m_socket.close(); }); | |||
} | |||
bool IsConnected() const | |||
{ | |||
return m_socket.is_open(); | |||
} | |||
// Prime the connection to wait for incoming messages | |||
void StartListening() | |||
{ | |||
} | |||
public: | |||
// ASYNC - Send a message, connections are one-to-one so no need to specifiy | |||
// the target, for a client, the target is the server and vice versa | |||
void Send(const Message<T>& msg) | |||
{ | |||
asio::post(m_asioContext, | |||
[this, msg]() | |||
{ | |||
// If the queue has a message in it, then we must | |||
// assume that it is in the process of asynchronously being written. | |||
// Either way add the message to the queue to be output. If no messages | |||
// were available to be written, then start the process of writing the | |||
// message at the front of the queue. | |||
bool bWritingMessage = !m_qMessagesOut.empty(); | |||
m_qMessagesOut.push_back(msg); | |||
if (!bWritingMessage) | |||
{ | |||
WriteHeader(); | |||
} | |||
}); | |||
} | |||
private: | |||
// ASYNC - Prime context to write a message header | |||
void WriteHeader() | |||
{ | |||
// If this function is called, we know the outgoing message queue must have | |||
// at least one message to send. So allocate a transmission buffer to hold | |||
// the message, and issue the work - asio, send these bytes | |||
asio::async_write(m_socket, asio::buffer(&m_qMessagesOut.front().header, sizeof(MessageHeader<T>)), | |||
[this](std::error_code ec, std::size_t length) | |||
{ | |||
// asio has now sent the bytes - if there was a problem | |||
// an error would be available... | |||
if (!ec) | |||
{ | |||
// ... no error, so check if the message header just sent also | |||
// has a message body... | |||
if (m_qMessagesOut.front().body.size() > 0) | |||
{ | |||
// ...it does, so issue the task to write the body bytes | |||
WriteBody(); | |||
} | |||
else | |||
{ | |||
// ...it didnt, so we are done with this message. Remove it from | |||
// the outgoing message queue | |||
m_qMessagesOut.pop_front(); | |||
// If the queue is not empty, there are more messages to send, so | |||
// make this happen by issuing the task to send the next header. | |||
if (!m_qMessagesOut.empty()) | |||
{ | |||
WriteHeader(); | |||
} | |||
} | |||
} | |||
else | |||
{ | |||
// ...asio failed to write the message, we could analyse why but | |||
// for now simply assume the connection has died by closing the | |||
// socket. When a future attempt to write to this client fails due | |||
// to the closed socket, it will be tidied up. | |||
std::cout << "[" << id << "] Write Header Fail.\n"; | |||
m_socket.close(); | |||
} | |||
}); | |||
} | |||
// ASYNC - Prime context to write a message body | |||
void WriteBody() | |||
{ | |||
// If this function is called, a header has just been sent, and that header | |||
// indicated a body existed for this message. Fill a transmission buffer | |||
// with the body data, and send it! | |||
asio::async_write(m_socket, asio::buffer(m_qMessagesOut.front().body.data(), m_qMessagesOut.front().body.size()), | |||
[this](std::error_code ec, std::size_t length) | |||
{ | |||
if (!ec) | |||
{ | |||
// Sending was successful, so we are done with the message | |||
// and remove it from the queue | |||
m_qMessagesOut.pop_front(); | |||
// If the queue still has messages in it, then issue the task to | |||
// send the next messages' header. | |||
if (!m_qMessagesOut.empty()) | |||
{ | |||
WriteHeader(); | |||
} | |||
} | |||
else | |||
{ | |||
// Sending failed, see WriteHeader() equivalent for description :P | |||
std::cout << "[" << id << "] Write Body Fail.\n"; | |||
m_socket.close(); | |||
} | |||
}); | |||
} | |||
// ASYNC - Prime context ready to read a message header | |||
void ReadHeader() | |||
{ | |||
// asio to waits until it receives | |||
// enough bytes to form a header of a message. We know the headers are a fixed | |||
// size, so allocate a transmission buffer large enough to store it. | |||
//Call this function to set up an asynchronous listener for a certain Connection | |||
asio::async_read(m_socket, asio::buffer(&m_msgTemporaryIn.header, sizeof(MessageHeader<T>)), | |||
[this](std::error_code ec, std::size_t length) | |||
{ | |||
if (!ec) | |||
{ | |||
//Full header readed | |||
//Check for message body | |||
if (m_msgTemporaryIn.header.size > 0) | |||
{ | |||
//Allocate storage | |||
m_msgTemporaryIn.body.resize(m_msgTemporaryIn.header.size); | |||
//Read if available | |||
ReadBody(); | |||
} | |||
else | |||
{ | |||
//Bodyless message, add to queue | |||
AddToIncomingMessageQueue(); | |||
} | |||
} | |||
else | |||
{ | |||
//Failure, probably a disconnection | |||
std::cout << "[" << id << "] Error: " << ec.message() << std::endl; | |||
m_socket.close(); | |||
} | |||
}); | |||
} | |||
// ASYNC - Prime context to read a message body | |||
void ReadBody() | |||
{ | |||
//Called after header has been read successfully | |||
//Read the body in the pre allocated storage | |||
asio::async_read(m_socket, asio::buffer(m_msgTemporaryIn.body.data(), m_msgTemporaryIn.body.size()), | |||
[this](std::error_code ec, std::size_t length) | |||
{ | |||
if (!ec) | |||
{ | |||
// Complete message, add to queue | |||
AddToIncomingMessageQueue(); | |||
} | |||
else | |||
{ | |||
//Failure, probably a disconnection | |||
std::cout << "[" << id << "] Error reading body: " << ec.message() << std::endl; | |||
m_socket.close(); | |||
} | |||
}); | |||
} | |||
// Add a complete message to the incoming queue, with or without body | |||
void AddToIncomingMessageQueue() | |||
{ | |||
//Put it in the queue, put a owner to the object to let the server know who send the message (which connection) | |||
if(m_nOwnerType == Owner::SERVER) | |||
m_qMessagesIn.push_back({ this->shared_from_this(), m_msgTemporaryIn }); | |||
else | |||
m_qMessagesIn.push_back({ nullptr, m_msgTemporaryIn }); | |||
//Done queueing the message, now initialize a new async read to wait for next message | |||
ReadHeader(); | |||
} | |||
protected: | |||
// unique socket to a remote | |||
asio::ip::tcp::socket m_socket; | |||
// This context is shared with the whole asio instance | |||
asio::io_context& m_asioContext; | |||
// This queue holds all messages to be sent to the remote side | |||
// of this connection | |||
ts_dequeue<Message<T>> m_qMessagesOut; | |||
// This references the incoming queue of the parent object | |||
ts_dequeue<OwnedMessage<T>>& m_qMessagesIn; | |||
// Incoming messages are constructed asynchronously, so we will | |||
// store the part assembled message here, until it is ready | |||
Message<T> m_msgTemporaryIn; | |||
// The "owner" decides how some of the connection behaves | |||
Owner m_nOwnerType = Owner::SERVER; | |||
uint32_t id = 0; | |||
}; | |||
} |
@@ -0,0 +1,161 @@ | |||
/* | |||
MMO Client/Server Framework using ASIO | |||
"Happy Birthday Mrs Javidx9!" - javidx9 | |||
Videos: | |||
Part #1: https://youtu.be/2hNdkYInj4g | |||
Part #2: https://youtu.be/UbjxGvrDrbw | |||
License (OLC-3) | |||
~~~~~~~~~~~~~~~ | |||
Copyright 2018 - 2020 OneLoneCoder.com | |||
Redistribution and use in source and binary forms, with or without | |||
modification, are permitted provided that the following conditions | |||
are met: | |||
1. Redistributions or derivations of source code must retain the above | |||
copyright notice, this list of conditions and the following disclaimer. | |||
2. Redistributions or derivative works in binary form must reproduce | |||
the above copyright notice. This list of conditions and the following | |||
disclaimer must be reproduced in the documentation and/or other | |||
materials provided with the distribution. | |||
3. Neither the name of the copyright holder nor the names of its | |||
contributors may be used to endorse or promote products derived | |||
from this software without specific prior written permission. | |||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS | |||
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT | |||
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR | |||
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT | |||
HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, | |||
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT | |||
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, | |||
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY | |||
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT | |||
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE | |||
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | |||
Links | |||
~~~~~ | |||
YouTube: https://www.youtube.com/javidx9 | |||
Discord: https://discord.gg/WhwHUMV | |||
Twitter: https://www.twitter.com/javidx9 | |||
Twitch: https://www.twitch.tv/javidx9 | |||
GitHub: https://www.github.com/onelonecoder | |||
Homepage: https://www.onelonecoder.com | |||
Author | |||
~~~~~~ | |||
David Barr, aka javidx9, ©OneLoneCoder 2019, 2020 | |||
*/ | |||
#pragma once | |||
#include "net_common.h" | |||
namespace net | |||
{ | |||
template<typename T> | |||
class ts_dequeue | |||
{ | |||
public: | |||
ts_dequeue() = default; | |||
ts_dequeue(const ts_dequeue<T>&) = delete; | |||
virtual ~ts_dequeue() { clear(); } | |||
public: | |||
// Returns and maintains item at front of Queue | |||
const T& front() | |||
{ | |||
std::scoped_lock lock(muxQueue); | |||
return deqQueue.front(); | |||
} | |||
// Returns and maintains item at back of Queue | |||
const T& back() | |||
{ | |||
std::scoped_lock lock(muxQueue); | |||
return deqQueue.back(); | |||
} | |||
// Removes and returns item from front of Queue | |||
T pop_front() | |||
{ | |||
std::scoped_lock lock(muxQueue); | |||
auto t = std::move(deqQueue.front()); | |||
deqQueue.pop_front(); | |||
return t; | |||
} | |||
// Removes and returns item from back of Queue | |||
T pop_back() | |||
{ | |||
std::scoped_lock lock(muxQueue); | |||
auto t = std::move(deqQueue.back()); | |||
deqQueue.pop_back(); | |||
return t; | |||
} | |||
// Adds an item to back of Queue | |||
void push_back(const T& item) | |||
{ | |||
std::scoped_lock lock(muxQueue); | |||
deqQueue.emplace_back(std::move(item)); | |||
std::unique_lock<std::mutex> ul(muxBlocking); | |||
cvBlocking.notify_one(); | |||
} | |||
// Adds an item to front of Queue | |||
void push_front(const T& item) | |||
{ | |||
std::scoped_lock lock(muxQueue); | |||
deqQueue.emplace_front(std::move(item)); | |||
std::unique_lock<std::mutex> ul(muxBlocking); | |||
cvBlocking.notify_one(); | |||
} | |||
// Returns true if Queue has no items | |||
bool empty() | |||
{ | |||
std::scoped_lock lock(muxQueue); | |||
return deqQueue.empty(); | |||
} | |||
// Returns number of items in Queue | |||
size_t count() | |||
{ | |||
std::scoped_lock lock(muxQueue); | |||
return deqQueue.size(); | |||
} | |||
// Clears Queue | |||
void clear() | |||
{ | |||
std::scoped_lock lock(muxQueue); | |||
deqQueue.clear(); | |||
} | |||
void wait() | |||
{ | |||
while (empty()) | |||
{ | |||
std::unique_lock<std::mutex> ul(muxBlocking); | |||
cvBlocking.wait(ul); | |||
} | |||
} | |||
protected: | |||
std::mutex muxQueue; | |||
std::deque<T> deqQueue; | |||
std::condition_variable cvBlocking; | |||
std::mutex muxBlocking; | |||
}; | |||
} |
@@ -0,0 +1,214 @@ | |||
/* | |||
MMO Client/Server Framework using ASIO | |||
"Happy Birthday Mrs Javidx9!" - javidx9 | |||
Videos: | |||
Part #1: https://youtu.be/2hNdkYInj4g | |||
Part #2: https://youtu.be/UbjxGvrDrbw | |||
License (OLC-3) | |||
~~~~~~~~~~~~~~~ | |||
Copyright 2018 - 2020 OneLoneCoder.com | |||
Redistribution and use in source and binary forms, with or without | |||
modification, are permitted provided that the following conditions | |||
are met: | |||
1. Redistributions or derivations of source code must retain the above | |||
copyright notice, this list of conditions and the following disclaimer. | |||
2. Redistributions or derivative works in binary form must reproduce | |||
the above copyright notice. This list of conditions and the following | |||
disclaimer must be reproduced in the documentation and/or other | |||
materials provided with the distribution. | |||
3. Neither the name of the copyright holder nor the names of its | |||
contributors may be used to endorse or promote products derived | |||
from this software without specific prior written permission. | |||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS | |||
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT | |||
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR | |||
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT | |||
HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, | |||
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT | |||
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, | |||
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY | |||
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT | |||
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE | |||
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | |||
Links | |||
~~~~~ | |||
YouTube: https://www.youtube.com/javidx9 | |||
Discord: https://discord.gg/WhwHUMV | |||
Twitter: https://www.twitter.com/javidx9 | |||
Twitch: https://www.twitch.tv/javidx9 | |||
GitHub: https://www.github.com/onelonecoder | |||
Homepage: https://www.onelonecoder.com | |||
Author | |||
~~~~~~ | |||
David Barr, aka javidx9, �OneLoneCoder 2019, 2020 | |||
*/ | |||
#pragma once | |||
#include "net_common.h" | |||
#include <string> | |||
namespace net | |||
{ | |||
///[OLC_HEADERIFYIER] START "MESSAGE" | |||
// Message Header is sent at start of all messages. The template allows us | |||
// to use "enum class" to ensure that the messages are valid at compile time | |||
template <typename T> | |||
struct MessageHeader | |||
{ | |||
T id{}; | |||
uint32_t size = 0; | |||
}; | |||
// Message Body contains a header and a std::vector, containing raw bytes | |||
// of infomation. This way the message can be variable length, but the size | |||
// in the header must be updated. | |||
template <typename T> | |||
struct Message | |||
{ | |||
// Header & Body vector | |||
MessageHeader<T> header{}; | |||
std::vector<uint8_t> body; | |||
// returns size of entire message packet in bytes | |||
size_t size() const | |||
{ | |||
return body.size(); | |||
} | |||
// Override for std::cout compatibility - produces friendly description of message | |||
friend std::ostream& operator << (std::ostream& os, const Message<T>& msg) | |||
{ | |||
os << "ID:" << int(msg.header.id) << " Size:" << msg.header.size; | |||
return os; | |||
} | |||
// Convenience Operator overloads - These allow us to add and remove stuff from | |||
// the body vector as if it were a stack, so First in, Last Out. These are a | |||
// template in itself, because we dont know what data type the user is pushing or | |||
// popping, so lets allow them all. NOTE: It assumes the data type is fundamentally | |||
// Plain Old Data (POD). TLDR: Serialise & Deserialise into/from a vector | |||
// Pushes any POD-like data into the message buffer | |||
template<typename DataType> | |||
friend Message<T>& operator << (Message<T>& msg, const DataType& data) | |||
{ | |||
// Check that the type of the data being pushed is trivially copyable | |||
static_assert(std::is_standard_layout<DataType>::value, "Data is too complex to be pushed into vector"); | |||
// Cache current size of vector, as this will be the point we insert the data | |||
size_t i = msg.body.size(); | |||
// Resize the vector by the size of the data being pushed | |||
msg.body.resize(i + sizeof(DataType)); | |||
// Physically copy the data into the newly allocated vector space | |||
std::memcpy(msg.body.data() + i, &data, sizeof(DataType)); | |||
// Recalculate the message size | |||
msg.header.size = msg.size(); | |||
// Return the target message so it can be "chained" | |||
return msg; | |||
} | |||
//Specified template to write string | |||
friend Message<T>& operator << (Message<T>& msg, const std::string& data) | |||
{ | |||
// Cache current size of vector, as this will be the point we insert the data | |||
size_t i = msg.body.size(); | |||
// Resize the vector by the size of the data being pushed | |||
//msg.body.resize(i + sizeof(data)); | |||
// Physically copy the data of the string character by character | |||
msg.body.resize(i + data.size()); | |||
for (size_t index = 0; index < data.size(); index++) { | |||
msg.body[i+index] = data.at(index); | |||
//std::memcpy(msg.body.data() + i, &c, sizeof(uint8_t)); | |||
} | |||
// Recalculate the message size | |||
msg.header.size = (uint32_t)msg.size(); | |||
// Return the target message so it can be "chained" | |||
return msg; | |||
} | |||
// Pulls any POD-like data form the message buffer | |||
template<typename DataType> | |||
friend Message<T>& operator >> (Message<T>& msg, DataType& data) | |||
{ | |||
// Check that the type of the data being pushed is trivially copyable | |||
static_assert(std::is_standard_layout<DataType>::value, "Data is too complex to be pulled from vector"); | |||
// Cache the location towards the end of the vector where the pulled data starts | |||
size_t i = msg.body.size() - sizeof(DataType); | |||
// Physically copy the data from the vector into the user variable | |||
std::memcpy(&data, msg.body.data() + i, sizeof(DataType)); | |||
// Shrink the vector to remove read bytes, and reset end position | |||
msg.body.resize(i); | |||
// Recalculate the message size | |||
msg.header.size = msg.size(); | |||
// Return the target message so it can be "chained" | |||
return msg; | |||
} | |||
//Specified template to read string | |||
friend Message<T>& operator >> (Message<T>& msg, std::string& data) | |||
{ | |||
// Cache the location towards the end of the vector where the pulled data starts | |||
size_t i = 0; | |||
// Physically copy the data from the vector into the user variable | |||
std::memcpy(&data, msg.body.data(), msg.body.size()); | |||
// Shrink the vector to remove read bytes, and reset end position | |||
msg.body.resize(i); | |||
// Return the target message so it can be "chained" | |||
return msg; | |||
} | |||
}; | |||
// An "owned" message is identical to a regular message, but it is associated with | |||
// a connection. On a server, the owner would be the client that sent the message, | |||
// on a client the owner would be the server. | |||
// Forward declare the connection | |||
template <typename T> | |||
class Connection; | |||
template <typename T> | |||
struct OwnedMessage | |||
{ | |||
std::shared_ptr<Connection<T>> remote = nullptr; | |||
Message<T> msg; | |||
// Again, a friendly string maker | |||
friend std::ostream& operator<<(std::ostream& os, const OwnedMessage<T>& msg) | |||
{ | |||
os << msg.msg; | |||
return os; | |||
} | |||
}; | |||
} |
@@ -0,0 +1,279 @@ | |||
/* | |||
MMO Client/Server Framework using ASIO | |||
"Happy Birthday Mrs Javidx9!" - javidx9 | |||
Videos: | |||
Part #1: https://youtu.be/2hNdkYInj4g | |||
Part #2: https://youtu.be/UbjxGvrDrbw | |||
License (OLC-3) | |||
~~~~~~~~~~~~~~~ | |||
Copyright 2018 - 2020 OneLoneCoder.com | |||
Redistribution and use in source and binary forms, with or without | |||
modification, are permitted provided that the following conditions | |||
are met: | |||
1. Redistributions or derivations of source code must retain the above | |||
copyright notice, this list of conditions and the following disclaimer. | |||
2. Redistributions or derivative works in binary form must reproduce | |||
the above copyright notice. This list of conditions and the following | |||
disclaimer must be reproduced in the documentation and/or other | |||
materials provided with the distribution. | |||
3. Neither the name of the copyright holder nor the names of its | |||
contributors may be used to endorse or promote products derived | |||
from this software without specific prior written permission. | |||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS | |||
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT | |||
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR | |||
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT | |||
HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, | |||
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT | |||
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, | |||
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY | |||
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT | |||
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE | |||
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | |||
Links | |||
~~~~~ | |||
YouTube: https://www.youtube.com/javidx9 | |||
Discord: https://discord.gg/WhwHUMV | |||
Twitter: https://www.twitter.com/javidx9 | |||
Twitch: https://www.twitch.tv/javidx9 | |||
GitHub: https://www.github.com/onelonecoder | |||
Homepage: https://www.onelonecoder.com | |||
Author | |||
~~~~~~ | |||
David Barr, aka javidx9, ?OneLoneCoder 2019, 2020 | |||
*/ | |||
#pragma once | |||
#include "net_dequeue_ts.h" | |||
#include "net_common.h" | |||
#include "net_message.h" | |||
#include "net_connection.h" | |||
#include "easylogging++.h" | |||
namespace net | |||
{ | |||
template<typename T> | |||
class ServerInterface | |||
{ | |||
public: // Create a server, ready to listen on specified port | |||
ServerInterface(uint16_t port) | |||
: m_asioAcceptor(m_asioContext, asio::ip::tcp::endpoint(asio::ip::tcp::v4(), port)) { } | |||
virtual ~ServerInterface() { Stop(); } | |||
// Starts the server | |||
virtual bool Start() | |||
{ | |||
try | |||
{ | |||
// Issue a task to the asio context - This is important | |||
// as it will prime the context with "work", and stop it | |||
// from exiting immediately. Since this is a server, we | |||
// want it primed ready to handle clients trying to | |||
// connect. | |||
WaitForClientConnection(); | |||
// Launch the asio context in its own thread | |||
m_threadContext = std::thread([this]() { m_asioContext.run(); }); | |||
} | |||
catch (std::exception& e) | |||
{ | |||
// Something prohibited the server from listening | |||
std::cerr << "[SERVER] Exception: " << e.what() << "\n"; | |||
return false; | |||
} | |||
LOG(INFO) << "[SERVER] Started\n"; | |||
return true; | |||
} | |||
bool isStopped()const { | |||
return m_asioContext.stopped(); | |||
} | |||
// Stops the server! | |||
virtual void Stop() | |||
{ | |||
// Request the context to close | |||
m_asioContext.stop(); | |||
// Tidy up the context thread | |||
if (m_threadContext.joinable()) m_threadContext.join(); | |||
// Inform someone, anybody, if they care... | |||
LOG(INFO) << "[SERVER] Stopped!\n"; | |||
} | |||
// ASYNC - Instruct asio to wait for connection | |||
void WaitForClientConnection() | |||
{ | |||
// Prime context with an instruction to wait until a socket connects. This | |||
// is the purpose of an "acceptor" object. It will provide a unique socket | |||
// for each incoming connection attempt | |||
m_asioAcceptor.async_accept( | |||
[this](std::error_code ec, asio::ip::tcp::socket socket) | |||
{ | |||
// Triggered by incoming connection request | |||
if (!ec) | |||
{ | |||
LOG(INFO) << "[SERVER] New Connection: " << socket.remote_endpoint(); | |||
// Create a new connection to handle this client | |||
std::shared_ptr<Connection<T>> newconn = | |||
std::make_shared<Connection<T>>(Connection<T>::Owner::SERVER, | |||
m_asioContext, std::move(socket), m_qMessagesIn); | |||
// Give the user server a chance to deny connection | |||
if (OnClientConnect(newconn)) | |||
{ | |||
// Connection allowed, so add to container of new connections | |||
m_deqConnections.push_back(std::move(newconn)); | |||
// Issue a task to the connection's | |||
// asio context to sit and wait for bytes to arrive! | |||
m_deqConnections.back()->ConnectToClient(nIDCounter++); | |||
LOG(INFO) << "[" << m_deqConnections.back()->GetID() << "] Connection Approved\n"; | |||
} | |||
else | |||
{ | |||
LOG(INFO) << "[SERVER] Connection Denied"; | |||
// Connection will go out of scope with no pending tasks, so will | |||
// get destroyed automatically (smart pointer) | |||
} | |||
} | |||
else | |||
{ | |||
// Error has occurred during acceptance | |||
LOG(INFO) << "[SERVER] New Connection Error: " << ec.message(); | |||
} | |||
// Prime the asio context with more work - again simply wait for | |||
// another connection... | |||
WaitForClientConnection(); | |||
}); | |||
} | |||
// Send a message to a specific client | |||
void MessageClient(std::shared_ptr<Connection<T>> client, const Message<T>& msg) | |||
{ | |||
// Check client is legitimate... | |||
if (client && client->IsConnected()) | |||
{ | |||
// ...and post the message via the connection | |||
client->Send(msg); | |||
} | |||
else | |||
{ | |||
// If we cant communicate with client then we may as | |||
// well remove the client - let the server know, it may | |||
// be tracking it somehow | |||
OnClientDisconnect(client); | |||
// Off you go now, bye bye! | |||
client.reset(); | |||
// Then physically remove it from the container | |||
m_deqConnections.erase( | |||
std::remove(m_deqConnections.begin(), m_deqConnections.end(), client), m_deqConnections.end()); | |||
} | |||
} | |||
// Send message to all clients | |||
void MessageAllClients(const Message<T>& msg, std::shared_ptr<Connection<T>> pIgnoreClient = nullptr) | |||
{ | |||
bool bInvalidClientExists = false; | |||
// Iterate through all clients in container | |||
for (auto& client : m_deqConnections) | |||
{ | |||
// Check client is connected... | |||
if (client && client->IsConnected()) | |||
{ | |||
// ..it is! | |||
if(client != pIgnoreClient) | |||
client->Send(msg); | |||
} | |||
else | |||
{ | |||
// The client couldnt be contacted, so assume it has | |||
// disconnected. | |||
OnClientDisconnect(client); | |||
client.reset(); | |||
// Set this flag to then remove dead clients from container | |||
bInvalidClientExists = true; | |||
} | |||
} | |||
// Remove dead clients, all in one go - this way, we dont invalidate the | |||
// container as we iterated through it. | |||
if (bInvalidClientExists) | |||
m_deqConnections.erase( | |||
std::remove(m_deqConnections.begin(), m_deqConnections.end(), nullptr), m_deqConnections.end()); | |||
} | |||
// Force server to respond to incoming messages | |||
// size_t nmaxMessages: Assign -1 to unsigned to unspecify max message count | |||
// bool bWait: if queue is empty, wait synchronously until message arrives | |||
void Update(size_t nMaxMessages = -1, bool bWait = false) | |||
{ | |||
if (bWait) m_qMessagesIn.wait(); | |||
// Process as many messages as you can up to the value | |||
// specified | |||
size_t nMessageCount = 0; | |||
while (nMessageCount < nMaxMessages && !m_qMessagesIn.empty()) | |||
{ | |||
// Grab the front message | |||
auto msg = m_qMessagesIn.pop_front(); | |||
// Pass to message handler | |||
OnMessage(msg.remote, msg.msg); | |||
nMessageCount++; | |||
} | |||
} | |||
protected: | |||
//Overwritable functions to customize server behaviour | |||
// Called when a client connects, you can veto the connection by returning false | |||
virtual bool OnClientConnect(std::shared_ptr<Connection<T>> client) = 0; | |||
// Called when a client appears to have disconnected | |||
virtual void OnClientDisconnect(std::shared_ptr<Connection<T>> client) = 0; | |||
// Called when a message arrives | |||
virtual void OnMessage(std::shared_ptr<Connection<T>> client, Message<T>& msg) = 0; | |||
protected: | |||
// Thread Safe Queue for incoming message packets | |||
ts_dequeue<OwnedMessage<T>> m_qMessagesIn; | |||
// Container of active validated connections | |||
std::deque<std::shared_ptr<Connection<T>>> m_deqConnections; | |||
// Order of declaration is important - it is also the order of initialisation | |||
asio::io_context m_asioContext; | |||
std::thread m_threadContext; | |||
// These things need an asio context | |||
asio::ip::tcp::acceptor m_asioAcceptor; // Handles new incoming connection attempts... | |||
// Clients will be identified in the "wider system" via an ID | |||
uint32_t nIDCounter = 100; | |||
}; | |||
} |
@@ -0,0 +1,197 @@ | |||
//Simulation of an external IP-TCP client using ASIO lib | |||
#include <iostream> | |||
#include "asio.hpp" | |||
#include <iostream> | |||
#include <array> | |||
#include <sstream> | |||
#include <string> | |||
#include <fstream> | |||
#include "PublisherData.h" | |||
#include "DataModel.h" | |||
#include "IpTcpClient.h" | |||
#include "NetClient.h" | |||
#include <fstream> | |||
#include <filesystem> | |||
#include <thread> | |||
#include <memory> | |||
#include <atomic> | |||
#include <regex> | |||
#include "easylogging++.h" | |||
INITIALIZE_EASYLOGGINGPP | |||
constexpr unsigned int BUFFER_SIZE = 256; | |||
//Format of Date in the log files | |||
constexpr char logDateFormat[] = "%Y-%m-%d %H:%M:%S"; | |||
constexpr unsigned short DATE_HEADER_SIZE = 19; | |||
const auto session_id = std::chrono::duration_cast<std::chrono::seconds>(std::chrono::system_clock::now().time_since_epoch()).count(); | |||
using asio::ip::tcp; | |||
std::atomic_char keyboardInput = '0'; | |||
void readInput() { | |||
while (1){ | |||
keyboardInput = std::cin.get(); | |||
std::cin.get(); | |||
} | |||
} | |||
//Takes a message with log file body and extracts the last written log date | |||
//This values is taken for the next log file downloading, to minimize download data size | |||
//and prevent the aplication from downloading data twice | |||
long long parseDate(net::Message<net::MessageTypes>& msg) { | |||
if (msg.header.size < DATE_HEADER_SIZE) | |||
return 0; | |||
std::stringstream ss; | |||
//Find last occurence of '\n' with reverse iteration | |||
auto res = std::find_if(msg.body.rbegin(), msg.body.rend(), | |||
[](const uint8_t i) { return i == '\n'; }); | |||
if (res == msg.body.rend()) { | |||
//No occurence of '\n', log file is empty | |||
return 0; | |||
} | |||
//Find last but one occurence of '\n' using reverse iteration | |||
res = std::find_if(res+1, msg.body.rend(), | |||
[](const uint8_t i) { return i == '\n'; }); | |||
if (res == msg.body.rend()) { | |||
//No second occurence of '\n' | |||
//-> only one line of log, set iterator to first position | |||
res = msg.body.rend(); | |||
} | |||
//Extreact the header and parse it to proper date format | |||
for (size_t i = 0; i < DATE_HEADER_SIZE; i++) { | |||
ss << *(--res); | |||
} | |||
std::tm tm = {}; | |||
ss >> std::get_time(&tm, logDateFormat); | |||
long long tp = std::chrono::system_clock::from_time_t(std::mktime(&tm)).time_since_epoch().count(); | |||
return tp; | |||
} | |||
void writeToFile(net::Message<net::MessageTypes>& msg) { | |||
std::ofstream file; | |||
std::stringstream fileName; | |||
switch(msg.header.id){ | |||
case net::MessageTypes::ServerData: | |||
fileName << "backup_data_" << session_id << ".log"; | |||
break; | |||
case net::MessageTypes::ServerLog: | |||
fileName << "backup_log_" << session_id << ".log"; | |||
break; | |||
default: break; | |||
} | |||
file.open(fileName.str(), std::ios_base::app); | |||
for (auto c : msg.body) | |||
file << c; | |||
file.close(); | |||
} | |||
int main() | |||
{ | |||
NetClient c; | |||
long long lastLog = 0; | |||
LOG(INFO) << "press key to connect"; | |||
std::cin.get(); | |||
c.Connect("127.0.0.1", 7777); | |||
std::thread keyboardInputThread(readInput); | |||
bool connectionCancelled = false; | |||
while (!connectionCancelled) | |||
{ | |||
if (c.IsConnected()) | |||
{ | |||
if (!c.Incoming().empty()) | |||
{ | |||
auto msg = c.Incoming().pop_front().msg; | |||
net::Message<net::MessageTypes> messageSend; | |||
std::string buf = ""; | |||
switch (msg.header.id) | |||
{ | |||
case net::MessageTypes::ServerAlert: | |||
// Server has responded to a ping request | |||
LOG(INFO) << "Server Alert notification"; | |||
for (size_t index = 0; index < msg.header.size; index++) { | |||
buf += msg.body.at(index); | |||
} | |||
LOG(INFO) << buf; | |||
break; | |||
case net::MessageTypes::ServerAccept: | |||
// Server has responded to a ping request | |||
LOG(INFO) << "Server Accepted Connection"; | |||
break; | |||
case net::MessageTypes::ServerDeny: | |||
// Server has responded to a ping request | |||
LOG(INFO) << "Server Denied Connection"; | |||
connectionCancelled = true; | |||
break; | |||
case net::MessageTypes::ServerLog: | |||
// Server has send log data | |||
LOG(INFO) << "Received Server Log File"; | |||
LOG(INFO) << "Received " << msg.header.size << " Bytes"; | |||
writeToFile(msg); | |||
lastLog = parseDate(msg); | |||
break; | |||
case net::MessageTypes::ServerData: | |||
LOG(INFO) << "Received Server Data"; | |||
LOG(INFO) << "Received " << msg.header.size << " Bytes"; | |||
writeToFile(msg); | |||
break; | |||
default: break; | |||
} | |||
} | |||
if (keyboardInput != '0') { | |||
net::Message<net::MessageTypes> messageSend; | |||
switch (keyboardInput) | |||
{ | |||
//Log | |||
case 'l': | |||
LOG(INFO) << "Request server log files"; | |||
messageSend.header.id = net::MessageTypes::ServerLog; | |||
messageSend << lastLog; | |||
c.Send(messageSend); | |||
break; | |||
case 'd': | |||
LOG(INFO) << "Request permanent server data"; | |||
messageSend.header.id = net::MessageTypes::ServerData; | |||
c.Send(messageSend); | |||
break; | |||
case 't': | |||
LOG(INFO) << "Request temporary server data"; | |||
messageSend.header.id = net::MessageTypes::ServerData; | |||
c.Send(messageSend); | |||
break; | |||
case 'c': | |||
LOG(INFO) << "Request closing connection"; | |||
messageSend.header.id = net::MessageTypes::ServerCloseConnection; | |||
c.Send(messageSend); | |||
break; | |||
default: | |||
break; | |||
} | |||
keyboardInput = '0'; | |||
} | |||
} | |||
else | |||
{ | |||
LOG(INFO) << "Server Down"; | |||
break; | |||
} | |||
} | |||
LOG(INFO) << "End excution"; | |||
return 0; | |||
} |
@@ -0,0 +1,34 @@ | |||
TEMPLATE = app | |||
CONFIG += console c++17 | |||
CONFIG -= app_bundle | |||
CONFIG -= qt | |||
QMAKE_CXXFLAGS += -std=c++0x -pthread | |||
LIBS += -pthread | |||
INCLUDEPATH += /home/michael/baConditionMonitoring/ClientSimulation/ClientSimulation/AsioNetClientServer/ | |||
INCLUDEPATH += /home/michael/baConditionMonitoring/ClientSimulation/ClientSimulation/AsioNetClientServer/src | |||
SOURCES += \ | |||
ClientSimulation.cpp \ | |||
DataModel.cpp \ | |||
IpTcpClient.cpp \ | |||
NetClient.cpp \ | |||
PublisherData.cpp \ | |||
easylogging++.cc | |||
HEADERS += \ | |||
AsioNetClientServer/net_server_client.h \ | |||
AsioNetClientServer/src/net_client.h \ | |||
AsioNetClientServer/src/net_common.h \ | |||
AsioNetClientServer/src/net_connection.h \ | |||
AsioNetClientServer/src/net_dequeue_ts.h \ | |||
AsioNetClientServer/src/net_message.h \ | |||
AsioNetClientServer/src/net_server.h \ | |||
DataModel.h \ | |||
IpTcpClient.h \ | |||
NetClient.h \ | |||
PublisherData.h \ | |||
PublisherType.h \ | |||
easylogging++.h \ | |||
instreamOperator.h |
@@ -0,0 +1,355 @@ | |||
<?xml version="1.0" encoding="UTF-8"?> | |||
<!DOCTYPE QtCreatorProject> | |||
<!-- Written by QtCreator 4.13.3, 2021-08-09T12:31:54. --> | |||
<qtcreator> | |||
<data> | |||
<variable>EnvironmentId</variable> | |||
<value type="QByteArray">{5a632e4a-e744-412b-acc7-3b951573dab3}</value> | |||
</data> | |||
<data> | |||
<variable>ProjectExplorer.Project.ActiveTarget</variable> | |||
<value type="int">0</value> | |||
</data> | |||
<data> | |||
<variable>ProjectExplorer.Project.EditorSettings</variable> | |||
<valuemap type="QVariantMap"> | |||
<value type="bool" key="EditorConfiguration.AutoIndent">true</value> | |||
<value type="bool" key="EditorConfiguration.AutoSpacesForTabs">false</value> | |||
<value type="bool" key="EditorConfiguration.CamelCaseNavigation">true</value> | |||
<valuemap type="QVariantMap" key="EditorConfiguration.CodeStyle.0"> | |||
<value type="QString" key="language">Cpp</value> | |||
<valuemap type="QVariantMap" key="value"> | |||
<value type="QByteArray" key="CurrentPreferences">CppGlobal</value> | |||
</valuemap> | |||
</valuemap> | |||
<valuemap type="QVariantMap" key="EditorConfiguration.CodeStyle.1"> | |||
<value type="QString" key="language">QmlJS</value> | |||
<valuemap type="QVariantMap" key="value"> | |||
<value type="QByteArray" key="CurrentPreferences">QmlJSGlobal</value> | |||
</valuemap> | |||
</valuemap> | |||
<value type="int" key="EditorConfiguration.CodeStyle.Count">2</value> | |||
<value type="QByteArray" key="EditorConfiguration.Codec">UTF-8</value> | |||
<value type="bool" key="EditorConfiguration.ConstrainTooltips">false</value> | |||
<value type="int" key="EditorConfiguration.IndentSize">4</value> | |||
<value type="bool" key="EditorConfiguration.KeyboardTooltips">false</value> | |||
<value type="int" key="EditorConfiguration.MarginColumn">80</value> | |||
<value type="bool" key="EditorConfiguration.MouseHiding">true</value> | |||
<value type="bool" key="EditorConfiguration.MouseNavigation">true</value> | |||
<value type="int" key="EditorConfiguration.PaddingMode">1</value> | |||
<value type="bool" key="EditorConfiguration.ScrollWheelZooming">true</value> | |||
<value type="bool" key="EditorConfiguration.ShowMargin">false</value> | |||
<value type="int" key="EditorConfiguration.SmartBackspaceBehavior">0</value> | |||
<value type="bool" key="EditorConfiguration.SmartSelectionChanging">true</value> | |||
<value type="bool" key="EditorConfiguration.SpacesForTabs">true</value> | |||
<value type="int" key="EditorConfiguration.TabKeyBehavior">0</value> | |||
<value type="int" key="EditorConfiguration.TabSize">8</value> | |||
<value type="bool" key="EditorConfiguration.UseGlobal">true</value> | |||
<value type="int" key="EditorConfiguration.Utf8BomBehavior">1</value> | |||
<value type="bool" key="EditorConfiguration.addFinalNewLine">true</value> | |||
<value type="bool" key="EditorConfiguration.cleanIndentation">true</value> | |||
<value type="bool" key="EditorConfiguration.cleanWhitespace">true</value> | |||
<value type="QString" key="EditorConfiguration.ignoreFileTypes">*.md, *.MD, Makefile</value> | |||
<value type="bool" key="EditorConfiguration.inEntireDocument">false</value> | |||
<value type="bool" key="EditorConfiguration.skipTrailingWhitespace">true</value> | |||
</valuemap> | |||
</data> | |||
<data> | |||
<variable>ProjectExplorer.Project.PluginSettings</variable> | |||
<valuemap type="QVariantMap"> | |||
<valuemap type="QVariantMap" key="AutoTest.ActiveFrameworks"> | |||
<value type="bool" key="AutoTest.Framework.Boost">true</value> | |||
<value type="bool" key="AutoTest.Framework.Catch">true</value> | |||
<value type="bool" key="AutoTest.Framework.GTest">true</value> | |||
<value type="bool" key="AutoTest.Framework.QtQuickTest">true</value> | |||
<value type="bool" key="AutoTest.Framework.QtTest">true</value> | |||
</valuemap> | |||
<valuemap type="QVariantMap" key="AutoTest.CheckStates"/> | |||
<value type="int" key="AutoTest.RunAfterBuild">0</value> | |||
<value type="bool" key="AutoTest.UseGlobal">true</value> | |||
<valuelist type="QVariantList" key="ClangCodeModel.CustomCommandLineKey"/> | |||
<value type="bool" key="ClangCodeModel.UseGlobalConfig">true</value> | |||
<value type="QString" key="ClangCodeModel.WarningConfigId">Builtin.Questionable</value> | |||
<valuemap type="QVariantMap" key="ClangTools"> | |||
<value type="bool" key="ClangTools.BuildBeforeAnalysis">true</value> | |||
<value type="QString" key="ClangTools.DiagnosticConfig">Builtin.DefaultTidyAndClazy</value> | |||
<value type="int" key="ClangTools.ParallelJobs">1</value> | |||
<valuelist type="QVariantList" key="ClangTools.SelectedDirs"/> | |||
<valuelist type="QVariantList" key="ClangTools.SelectedFiles"/> | |||
<valuelist type="QVariantList" key="ClangTools.SuppressedDiagnostics"/> | |||
<value type="bool" key="ClangTools.UseGlobalSettings">true</value> | |||
</valuemap> | |||
</valuemap> | |||
</data> | |||
<data> | |||
<variable>ProjectExplorer.Project.Target.0</variable> | |||
<valuemap type="QVariantMap"> | |||
<value type="QString" key="DeviceType">Desktop</value> | |||
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">Desktop Qt 5.15.1 GCC 64bit</value> | |||
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName">Desktop Qt 5.15.1 GCC 64bit</value> | |||
<value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">qt.qt5.5151.gcc_64_kit</value> | |||
<value type="int" key="ProjectExplorer.Target.ActiveBuildConfiguration">0</value> | |||
<value type="int" key="ProjectExplorer.Target.ActiveDeployConfiguration">0</value> | |||
<value type="int" key="ProjectExplorer.Target.ActiveRunConfiguration">0</value> | |||
<valuemap type="QVariantMap" key="ProjectExplorer.Target.BuildConfiguration.0"> | |||
<value type="bool">true</value> | |||
<value type="int" key="EnableQmlDebugging">0</value> | |||
<value type="QString" key="ProjectExplorer.BuildConfiguration.BuildDirectory">/home/michael/baConditionMonitoring/ClientSimulation/build-ClientSimulation-Desktop_Qt_5_15_1_GCC_64bit-Debug</value> | |||
<value type="QString" key="ProjectExplorer.BuildConfiguration.BuildDirectory.shadowDir">/home/michael/baConditionMonitoring/ClientSimulation/build-ClientSimulation-Desktop_Qt_5_15_1_GCC_64bit-Debug</value> | |||
<valuemap type="QVariantMap" key="ProjectExplorer.BuildConfiguration.BuildStepList.0"> | |||
<valuemap type="QVariantMap" key="ProjectExplorer.BuildStepList.Step.0"> | |||
<value type="bool" key="ProjectExplorer.BuildStep.Enabled">true</value> | |||
<value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">QtProjectManager.QMakeBuildStep</value> | |||
<value type="QString" key="QtProjectManager.QMakeBuildStep.QMakeArguments"></value> | |||
<value type="bool" key="QtProjectManager.QMakeBuildStep.QMakeForced">false</value> | |||
<valuelist type="QVariantList" key="QtProjectManager.QMakeBuildStep.SelectedAbis"/> | |||
</valuemap> | |||
<valuemap type="QVariantMap" key="ProjectExplorer.BuildStepList.Step.1"> | |||
<value type="bool" key="ProjectExplorer.BuildStep.Enabled">true</value> | |||
<value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">Qt4ProjectManager.MakeStep</value> | |||
<valuelist type="QVariantList" key="Qt4ProjectManager.MakeStep.BuildTargets"/> | |||
<value type="bool" key="Qt4ProjectManager.MakeStep.Clean">false</value> | |||
<value type="QString" key="Qt4ProjectManager.MakeStep.MakeArguments"></value> | |||
<value type="QString" key="Qt4ProjectManager.MakeStep.MakeCommand"></value> | |||
<value type="bool" key="Qt4ProjectManager.MakeStep.OverrideMakeflags">false</value> | |||
</valuemap> | |||
<value type="int" key="ProjectExplorer.BuildStepList.StepsCount">2</value> | |||
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">Build</value> | |||
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName">Build</value> | |||
<value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">ProjectExplorer.BuildSteps.Build</value> | |||
</valuemap> | |||
<valuemap type="QVariantMap" key="ProjectExplorer.BuildConfiguration.BuildStepList.1"> | |||
<valuemap type="QVariantMap" key="ProjectExplorer.BuildStepList.Step.0"> | |||
<value type="bool" key="ProjectExplorer.BuildStep.Enabled">true</value> | |||
<value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">Qt4ProjectManager.MakeStep</value> | |||
<valuelist type="QVariantList" key="Qt4ProjectManager.MakeStep.BuildTargets"/> | |||
<value type="bool" key="Qt4ProjectManager.MakeStep.Clean">true</value> | |||
<value type="QString" key="Qt4ProjectManager.MakeStep.MakeArguments">clean</value> | |||
<value type="QString" key="Qt4ProjectManager.MakeStep.MakeCommand"></value> | |||
<value type="bool" key="Qt4ProjectManager.MakeStep.OverrideMakeflags">false</value> | |||
</valuemap> | |||
<value type="int" key="ProjectExplorer.BuildStepList.StepsCount">1</value> | |||
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">Clean</value> | |||
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName">Clean</value> | |||
<value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">ProjectExplorer.BuildSteps.Clean</value> | |||
</valuemap> | |||
<value type="int" key="ProjectExplorer.BuildConfiguration.BuildStepListCount">2</value> | |||
<value type="bool" key="ProjectExplorer.BuildConfiguration.ClearSystemEnvironment">false</value> | |||
<valuelist type="QVariantList" key="ProjectExplorer.BuildConfiguration.CustomParsers"/> | |||
<valuelist type="QVariantList" key="ProjectExplorer.BuildConfiguration.UserEnvironmentChanges"/> | |||
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName">Debug</value> | |||
<value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">Qt4ProjectManager.Qt4BuildConfiguration</value> | |||
<value type="int" key="Qt4ProjectManager.Qt4BuildConfiguration.BuildConfiguration">2</value> | |||
<value type="int" key="QtQuickCompiler">2</value> | |||
<value type="int" key="SeparateDebugInfo">2</value> | |||
</valuemap> | |||
<valuemap type="QVariantMap" key="ProjectExplorer.Target.BuildConfiguration.1"> | |||
<value type="bool">true</value> | |||
<value type="int" key="EnableQmlDebugging">2</value> | |||
<value type="QString" key="ProjectExplorer.BuildConfiguration.BuildDirectory">/home/michael/baConditionMonitoring/ClientSimulation/build-ClientSimulation-Desktop_Qt_5_15_1_GCC_64bit-Release</value> | |||
<value type="QString" key="ProjectExplorer.BuildConfiguration.BuildDirectory.shadowDir">/home/michael/baConditionMonitoring/ClientSimulation/build-ClientSimulation-Desktop_Qt_5_15_1_GCC_64bit-Release</value> | |||
<valuemap type="QVariantMap" key="ProjectExplorer.BuildConfiguration.BuildStepList.0"> | |||
<valuemap type="QVariantMap" key="ProjectExplorer.BuildStepList.Step.0"> | |||
<value type="bool" key="ProjectExplorer.BuildStep.Enabled">true</value> | |||
<value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">QtProjectManager.QMakeBuildStep</value> | |||
<value type="QString" key="QtProjectManager.QMakeBuildStep.QMakeArguments"></value> | |||
<value type="bool" key="QtProjectManager.QMakeBuildStep.QMakeForced">false</value> | |||
<valuelist type="QVariantList" key="QtProjectManager.QMakeBuildStep.SelectedAbis"/> | |||
</valuemap> | |||
<valuemap type="QVariantMap" key="ProjectExplorer.BuildStepList.Step.1"> | |||
<value type="bool" key="ProjectExplorer.BuildStep.Enabled">true</value> | |||
<value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">Qt4ProjectManager.MakeStep</value> | |||
<valuelist type="QVariantList" key="Qt4ProjectManager.MakeStep.BuildTargets"/> | |||
<value type="bool" key="Qt4ProjectManager.MakeStep.Clean">false</value> | |||
<value type="QString" key="Qt4ProjectManager.MakeStep.MakeArguments"></value> | |||
<value type="QString" key="Qt4ProjectManager.MakeStep.MakeCommand"></value> | |||
<value type="bool" key="Qt4ProjectManager.MakeStep.OverrideMakeflags">false</value> | |||
</valuemap> | |||
<value type="int" key="ProjectExplorer.BuildStepList.StepsCount">2</value> | |||
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">Build</value> | |||
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName">Build</value> | |||
<value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">ProjectExplorer.BuildSteps.Build</value> | |||
</valuemap> | |||
<valuemap type="QVariantMap" key="ProjectExplorer.BuildConfiguration.BuildStepList.1"> | |||
<valuemap type="QVariantMap" key="ProjectExplorer.BuildStepList.Step.0"> | |||
<value type="bool" key="ProjectExplorer.BuildStep.Enabled">true</value> | |||
<value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">Qt4ProjectManager.MakeStep</value> | |||
<valuelist type="QVariantList" key="Qt4ProjectManager.MakeStep.BuildTargets"/> | |||
<value type="bool" key="Qt4ProjectManager.MakeStep.Clean">true</value> | |||
<value type="QString" key="Qt4ProjectManager.MakeStep.MakeArguments">clean</value> | |||
<value type="QString" key="Qt4ProjectManager.MakeStep.MakeCommand"></value> | |||
<value type="bool" key="Qt4ProjectManager.MakeStep.OverrideMakeflags">false</value> | |||
</valuemap> | |||
<value type="int" key="ProjectExplorer.BuildStepList.StepsCount">1</value> | |||
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">Clean</value> | |||
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName">Clean</value> | |||
<value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">ProjectExplorer.BuildSteps.Clean</value> | |||
</valuemap> | |||
<value type="int" key="ProjectExplorer.BuildConfiguration.BuildStepListCount">2</value> | |||
<value type="bool" key="ProjectExplorer.BuildConfiguration.ClearSystemEnvironment">false</value> | |||
<valuelist type="QVariantList" key="ProjectExplorer.BuildConfiguration.CustomParsers"/> | |||
<valuelist type="QVariantList" key="ProjectExplorer.BuildConfiguration.UserEnvironmentChanges"/> | |||
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName">Release</value> | |||
<value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">Qt4ProjectManager.Qt4BuildConfiguration</value> | |||
<value type="int" key="Qt4ProjectManager.Qt4BuildConfiguration.BuildConfiguration">0</value> | |||
<value type="int" key="QtQuickCompiler">0</value> | |||
<value type="int" key="SeparateDebugInfo">2</value> | |||
</valuemap> | |||
<valuemap type="QVariantMap" key="ProjectExplorer.Target.BuildConfiguration.2"> | |||
<value type="bool">true</value> | |||
<value type="int" key="EnableQmlDebugging">0</value> | |||
<value type="QString" key="ProjectExplorer.BuildConfiguration.BuildDirectory">/home/michael/baConditionMonitoring/ClientSimulation/build-ClientSimulation-Desktop_Qt_5_15_1_GCC_64bit-Profile</value> | |||
<value type="QString" key="ProjectExplorer.BuildConfiguration.BuildDirectory.shadowDir">/home/michael/baConditionMonitoring/ClientSimulation/build-ClientSimulation-Desktop_Qt_5_15_1_GCC_64bit-Profile</value> | |||
<valuemap type="QVariantMap" key="ProjectExplorer.BuildConfiguration.BuildStepList.0"> | |||
<valuemap type="QVariantMap" key="ProjectExplorer.BuildStepList.Step.0"> | |||
<value type="bool" key="ProjectExplorer.BuildStep.Enabled">true</value> | |||
<value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">QtProjectManager.QMakeBuildStep</value> | |||
<value type="QString" key="QtProjectManager.QMakeBuildStep.QMakeArguments"></value> | |||
<value type="bool" key="QtProjectManager.QMakeBuildStep.QMakeForced">false</value> | |||
<valuelist type="QVariantList" key="QtProjectManager.QMakeBuildStep.SelectedAbis"/> | |||
</valuemap> | |||
<valuemap type="QVariantMap" key="ProjectExplorer.BuildStepList.Step.1"> | |||
<value type="bool" key="ProjectExplorer.BuildStep.Enabled">true</value> | |||
<value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">Qt4ProjectManager.MakeStep</value> | |||
<valuelist type="QVariantList" key="Qt4ProjectManager.MakeStep.BuildTargets"/> | |||
<value type="bool" key="Qt4ProjectManager.MakeStep.Clean">false</value> | |||
<value type="QString" key="Qt4ProjectManager.MakeStep.MakeArguments"></value> | |||
<value type="QString" key="Qt4ProjectManager.MakeStep.MakeCommand"></value> | |||
<value type="bool" key="Qt4ProjectManager.MakeStep.OverrideMakeflags">false</value> | |||
</valuemap> | |||
<value type="int" key="ProjectExplorer.BuildStepList.StepsCount">2</value> | |||
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">Build</value> | |||
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName">Build</value> | |||
<value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">ProjectExplorer.BuildSteps.Build</value> | |||
</valuemap> | |||
<valuemap type="QVariantMap" key="ProjectExplorer.BuildConfiguration.BuildStepList.1"> | |||
<valuemap type="QVariantMap" key="ProjectExplorer.BuildStepList.Step.0"> | |||
<value type="bool" key="ProjectExplorer.BuildStep.Enabled">true</value> | |||
<value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">Qt4ProjectManager.MakeStep</value> | |||
<valuelist type="QVariantList" key="Qt4ProjectManager.MakeStep.BuildTargets"/> | |||
<value type="bool" key="Qt4ProjectManager.MakeStep.Clean">true</value> | |||
<value type="QString" key="Qt4ProjectManager.MakeStep.MakeArguments">clean</value> | |||
<value type="QString" key="Qt4ProjectManager.MakeStep.MakeCommand"></value> | |||
<value type="bool" key="Qt4ProjectManager.MakeStep.OverrideMakeflags">false</value> | |||
</valuemap> | |||
<value type="int" key="ProjectExplorer.BuildStepList.StepsCount">1</value> | |||
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">Clean</value> | |||
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName">Clean</value> | |||
<value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">ProjectExplorer.BuildSteps.Clean</value> | |||
</valuemap> | |||
<value type="int" key="ProjectExplorer.BuildConfiguration.BuildStepListCount">2</value> | |||
<value type="bool" key="ProjectExplorer.BuildConfiguration.ClearSystemEnvironment">false</value> | |||
<valuelist type="QVariantList" key="ProjectExplorer.BuildConfiguration.CustomParsers"/> | |||
<valuelist type="QVariantList" key="ProjectExplorer.BuildConfiguration.UserEnvironmentChanges"/> | |||
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName">Profile</value> | |||
<value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">Qt4ProjectManager.Qt4BuildConfiguration</value> | |||
<value type="int" key="Qt4ProjectManager.Qt4BuildConfiguration.BuildConfiguration">0</value> | |||
<value type="int" key="QtQuickCompiler">0</value> | |||
<value type="int" key="SeparateDebugInfo">0</value> | |||
</valuemap> | |||
<value type="int" key="ProjectExplorer.Target.BuildConfigurationCount">3</value> | |||
<valuemap type="QVariantMap" key="ProjectExplorer.Target.DeployConfiguration.0"> | |||
<valuemap type="QVariantMap" key="ProjectExplorer.BuildConfiguration.BuildStepList.0"> | |||
<value type="int" key="ProjectExplorer.BuildStepList.StepsCount">0</value> | |||
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">Deploy</value> | |||
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName">Deploy</value> | |||
<value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">ProjectExplorer.BuildSteps.Deploy</value> | |||
</valuemap> | |||
<value type="int" key="ProjectExplorer.BuildConfiguration.BuildStepListCount">1</value> | |||
<valuemap type="QVariantMap" key="ProjectExplorer.DeployConfiguration.CustomData"/> | |||
<value type="bool" key="ProjectExplorer.DeployConfiguration.CustomDataEnabled">false</value> | |||
<value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">ProjectExplorer.DefaultDeployConfiguration</value> | |||
</valuemap> | |||
<value type="int" key="ProjectExplorer.Target.DeployConfigurationCount">1</value> | |||
<valuemap type="QVariantMap" key="ProjectExplorer.Target.PluginSettings"/> | |||
<valuemap type="QVariantMap" key="ProjectExplorer.Target.RunConfiguration.0"> | |||
<value type="QString" key="Analyzer.Perf.CallgraphMode">dwarf</value> | |||
<valuelist type="QVariantList" key="Analyzer.Perf.Events"> | |||
<value type="QString">cpu-cycles</value> | |||
</valuelist> | |||
<valuelist type="QVariantList" key="Analyzer.Perf.ExtraArguments"/> | |||
<value type="int" key="Analyzer.Perf.Frequency">250</value> | |||
<valuelist type="QVariantList" key="Analyzer.Perf.RecordArguments"> | |||
<value type="QString">-e</value> | |||
<value type="QString">cpu-cycles</value> | |||
<value type="QString">--call-graph</value> | |||
<value type="QString">dwarf,4096</value> | |||
<value type="QString">-F</value> | |||
<value type="QString">250</value> | |||
</valuelist> | |||
<value type="QString" key="Analyzer.Perf.SampleMode">-F</value> | |||
<value type="bool" key="Analyzer.Perf.Settings.UseGlobalSettings">true</value> | |||
<value type="int" key="Analyzer.Perf.StackSize">4096</value> | |||
<value type="bool" key="Analyzer.QmlProfiler.AggregateTraces">false</value> | |||
<value type="bool" key="Analyzer.QmlProfiler.FlushEnabled">false</value> | |||
<value type="uint" key="Analyzer.QmlProfiler.FlushInterval">1000</value> | |||
<value type="QString" key="Analyzer.QmlProfiler.LastTraceFile"></value> | |||
<value type="bool" key="Analyzer.QmlProfiler.Settings.UseGlobalSettings">true</value> | |||
<valuelist type="QVariantList" key="Analyzer.Valgrind.AddedSuppressionFiles"/> | |||
<value type="bool" key="Analyzer.Valgrind.Callgrind.CollectBusEvents">false</value> | |||
<value type="bool" key="Analyzer.Valgrind.Callgrind.CollectSystime">false</value> | |||
<value type="bool" key="Analyzer.Valgrind.Callgrind.EnableBranchSim">false</value> | |||
<value type="bool" key="Analyzer.Valgrind.Callgrind.EnableCacheSim">false</value> | |||
<value type="bool" key="Analyzer.Valgrind.Callgrind.EnableEventToolTips">true</value> | |||
<value type="double" key="Analyzer.Valgrind.Callgrind.MinimumCostRatio">0.01</value> | |||
<value type="double" key="Analyzer.Valgrind.Callgrind.VisualisationMinimumCostRatio">10</value> | |||
<value type="bool" key="Analyzer.Valgrind.FilterExternalIssues">true</value> | |||
<value type="QString" key="Analyzer.Valgrind.KCachegrindExecutable">kcachegrind</value> | |||
<value type="int" key="Analyzer.Valgrind.LeakCheckOnFinish">1</value> | |||
<value type="int" key="Analyzer.Valgrind.NumCallers">25</value> | |||
<valuelist type="QVariantList" key="Analyzer.Valgrind.RemovedSuppressionFiles"/> | |||
<value type="int" key="Analyzer.Valgrind.SelfModifyingCodeDetection">1</value> | |||
<value type="bool" key="Analyzer.Valgrind.Settings.UseGlobalSettings">true</value> | |||
<value type="bool" key="Analyzer.Valgrind.ShowReachable">false</value> | |||
<value type="bool" key="Analyzer.Valgrind.TrackOrigins">true</value> | |||
<value type="QString" key="Analyzer.Valgrind.ValgrindExecutable">valgrind</value> | |||
<valuelist type="QVariantList" key="Analyzer.Valgrind.VisibleErrorKinds"> | |||
<value type="int">0</value> | |||
<value type="int">1</value> | |||
<value type="int">2</value> | |||
<value type="int">3</value> | |||
<value type="int">4</value> | |||
<value type="int">5</value> | |||
<value type="int">6</value> | |||
<value type="int">7</value> | |||
<value type="int">8</value> | |||
<value type="int">9</value> | |||
<value type="int">10</value> | |||
<value type="int">11</value> | |||
<value type="int">12</value> | |||
<value type="int">13</value> | |||
<value type="int">14</value> | |||
</valuelist> | |||
<valuelist type="QVariantList" key="CustomOutputParsers"/> | |||
<value type="int" key="PE.EnvironmentAspect.Base">2</value> | |||
<valuelist type="QVariantList" key="PE.EnvironmentAspect.Changes"/> | |||
<value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">Qt4ProjectManager.Qt4RunConfiguration:/home/michael/baConditionMonitoring/ClientSimulation/ClientSimulation/ClientSimulation.pro</value> | |||
<value type="QString" key="ProjectExplorer.RunConfiguration.BuildKey">/home/michael/baConditionMonitoring/ClientSimulation/ClientSimulation/ClientSimulation.pro</value> | |||
<value type="QString" key="RunConfiguration.Arguments"></value> | |||
<value type="bool" key="RunConfiguration.Arguments.multi">false</value> | |||
<value type="QString" key="RunConfiguration.OverrideDebuggerStartup"></value> | |||
<value type="bool" key="RunConfiguration.UseCppDebugger">false</value> | |||
<value type="bool" key="RunConfiguration.UseCppDebuggerAuto">true</value> | |||
<value type="bool" key="RunConfiguration.UseLibrarySearchPath">true</value> | |||
<value type="bool" key="RunConfiguration.UseMultiProcess">false</value> | |||
<value type="bool" key="RunConfiguration.UseQmlDebugger">false</value> | |||
<value type="bool" key="RunConfiguration.UseQmlDebuggerAuto">true</value> | |||
<value type="QString" key="RunConfiguration.WorkingDirectory"></value> | |||
<value type="QString" key="RunConfiguration.WorkingDirectory.default">/home/michael/baConditionMonitoring/ClientSimulation/build-ClientSimulation-Desktop_Qt_5_15_1_GCC_64bit-Debug</value> | |||
</valuemap> | |||
<value type="int" key="ProjectExplorer.Target.RunConfigurationCount">1</value> | |||
</valuemap> | |||
</data> | |||
<data> | |||
<variable>ProjectExplorer.Project.TargetCount</variable> | |||
<value type="int">1</value> | |||
</data> | |||
<data> | |||
<variable>ProjectExplorer.Project.Updater.FileVersion</variable> | |||
<value type="int">22</value> | |||
</data> | |||
<data> | |||
<variable>Version</variable> | |||
<value type="int">22</value> | |||
</data> | |||
</qtcreator> |
@@ -0,0 +1,103 @@ | |||
#include "DataModel.h" | |||
#include "instreamOperator.h" | |||
#include <fstream> | |||
#include <filesystem> | |||
#include <charconv> | |||
#include <ranges> | |||
#include <mutex> | |||
//Initialization of static member | |||
std::unique_ptr<DataModel> DataModel::instance = nullptr; | |||
//Read file locker | |||
std::timed_mutex accessFilesMTX; | |||
inline void DataModel::Create() { | |||
instance = std::make_unique<DataModel>(); | |||
} | |||
std::unique_ptr<DataModel>& DataModel::Instance() { | |||
if (!instance) | |||
Create(); | |||
return instance; | |||
} | |||
inline void DataModel::Destroy() { | |||
if (instance) | |||
instance.reset(); | |||
} | |||
std::ostream& operator<<(std::ostream& os, const PublisherType type) { | |||
switch (type) { | |||
case PublisherType::RCMS_BENDER: | |||
os << "Bender RCMS"; | |||
break; | |||
case PublisherType::POWERCENTER: | |||
os << "Siemens Powercenter"; | |||
break; | |||
default: | |||
os << "<Unknown Publisher Type>"; | |||
break; | |||
} | |||
return os; | |||
} | |||
void DataModel::savePublishedData(PublisherData data) | |||
{ | |||
auto iter = savedPublishedData.find(data.getID()); | |||
if (iter != savedPublishedData.end()) { | |||
iter->second.push_back(data); | |||
} | |||
else { | |||
std::vector<PublisherData> test{ data }; | |||
savedPublishedData.emplace(data.getID(), test); | |||
} | |||
} | |||
std::istream& operator>>(std::istream& is, char const* pat); | |||
//Deserialize dataModel object | |||
std::istream& operator>>(std::istream& is, DataModel& dataModel) { | |||
char a; | |||
//Prase header | |||
unsigned long long startTime; | |||
unsigned int interval; | |||
is >> startTime >> "," >> interval; | |||
//remove return | |||
is.get(); | |||
//Parse Body | |||
while (( a = is.peek()) != EOF) { | |||
unsigned int id; | |||
is >> id >> ":"; | |||
try { | |||
std::vector<PublisherData> values; | |||
while (is.peek() != '\n') { | |||
PublisherData data; | |||
is >> data; | |||
data.setID(id); | |||
values.push_back(data); | |||
} | |||
is.get(); | |||
auto iter = dataModel.savedPublishedData.find(id); | |||
if (iter == dataModel.savedPublishedData.end()) { | |||
dataModel.savedPublishedData.emplace(id, values); | |||
} | |||
else { | |||
for (auto& v : values) | |||
{ | |||
iter->second.push_back(v); | |||
} | |||
} | |||
} | |||
catch (std::exception& e) { std::cout << e.what(); } | |||
} | |||
return is; | |||
} |
@@ -0,0 +1,43 @@ | |||
#pragma once | |||
#include <memory> | |||
#include <vector> | |||
#include <map> | |||
#include <chrono> | |||
#include <optional> | |||
#include <regex> | |||
#include <atomic> | |||
#include "PublisherData.h" | |||
constexpr auto READ_BUFFER_SIZE = 4096; | |||
typedef std::map<unsigned int, std::vector<PublisherData>> data_key_map; | |||
using namespace std::chrono; | |||
class DataModel | |||
{ | |||
public: | |||
//Sigleton Methods | |||
static std::unique_ptr<DataModel>& Instance(); | |||
static void Destroy(); | |||
static void Create(); | |||
void savePublishedData(PublisherData data); | |||
data_key_map& getSavedPublishedData() { return savedPublishedData; }; | |||
//saves collected data after a certain amount of time points | |||
void checkIfToFlush(bool keepDataLocally = false); | |||
private: | |||
//static instance which can be accessed by calling DataModel::Instance() | |||
static std::unique_ptr<DataModel> instance; | |||
//Data from publishers, one elemt in outer vector for one id | |||
//Each id consists of a vector of PublisherData (use map to make the id become a unique key) | |||
data_key_map savedPublishedData; | |||
//ostream operators (read and write dataModel data from streams) | |||
friend std::ostream& operator<<(std::ostream& os, DataModel& dataModel); | |||
friend std::istream& operator>>(std::istream& is, DataModel& dataModel); | |||
}; |
@@ -0,0 +1,126 @@ | |||
#include "IpTcpClient.h" | |||
#include <iostream> | |||
#include "DataModel.h" | |||
constexpr unsigned int bufferSize = 256; | |||
IpTcpClient::IpTcpClient(const std::string targetIP, const unsigned int targetPort) : | |||
ip(targetIP), port(targetPort), lastRequest(TCP_REQUESTS::NA) | |||
{ | |||
} | |||
IpTcpClient::IpTcpClient(std::string targetIP, unsigned int targetPort, TCP_REQUESTS requestCode) : | |||
IpTcpClient(targetIP, targetPort) | |||
{ | |||
requestCode = requestCode; | |||
} | |||
void IpTcpClient::connect() | |||
{ | |||
asio::error_code error; | |||
tcp::resolver resolver(context); | |||
endpoints = resolver.resolve(ip, std::to_string(port)); | |||
socket = std::make_unique<tcp::socket>(context); | |||
asio::connect(*socket, endpoints, error); | |||
if (error) { | |||
throw asio::system_error(error); | |||
} | |||
} | |||
void IpTcpClient::sendRequest(const TCP_REQUESTS& code) | |||
{ | |||
this->lastRequest = code; | |||
inputStream.clear(); | |||
asio::error_code error; | |||
std::string codeString = "cmd:" + std::to_string(toUnderlyingType(code)) + '\n'; | |||
//Send the request code to server, which encodes the clients connection purpose | |||
size_t retVal = socket->write_some(asio::buffer(codeString), error); | |||
if (retVal == 0) { | |||
if (error == asio::error::eof) { | |||
//No error occured, sending finished | |||
std::cout << "Finnished sending request code" << std::endl; | |||
return; | |||
} | |||
throw asio::system_error(error); | |||
} | |||
} | |||
void IpTcpClient::processServerResponse() { | |||
if (TCP_REQUESTS::DOWNLOAD_DATA == lastRequest) { | |||
DataModel dataModel; | |||
inputStream >> dataModel; | |||
auto& savedData = dataModel.getSavedPublishedData(); | |||
std::cout << "Summary: " << std::endl; | |||
for (auto& id : savedData) { | |||
std::cout << "\tID " << id.first << ": " << id.second.size() << " datapoints" << std::endl; | |||
} | |||
} | |||
else if (TCP_REQUESTS::GET_STATUS == lastRequest) { | |||
std::cout << inputStream.str(); | |||
} | |||
} | |||
size_t IpTcpClient::waitRead() | |||
{ | |||
size_t total_bytes_readed = 0, lastLen = 0; | |||
asio::error_code error; | |||
//std::array<char, bufferSize> buf; | |||
//Loop for the input pipe, init with 3 ('Invalid') | |||
std::array<int, 1> codeBuffer; | |||
codeBuffer[0] = 3; | |||
while(1){ | |||
/*Get the serevrs intent | |||
CODE: | |||
0: Invoke connection | |||
1: Continuing | |||
2: Finished | |||
3: Invalid | |||
*/ | |||
std::array<char, 15> buf; | |||
socket->read_some(asio::buffer(buf)); | |||
if (codeBuffer[0] != 1) //Steram does not continue | |||
break; | |||
//When stream continues | |||
while (codeBuffer[0] == 1) { | |||
size_t len = socket->read_some(asio::buffer(buf), error); | |||
total_bytes_readed += len; | |||
//Buffer as long as data readed | |||
if (len != 0) { | |||
std::cout << "Readed " << len << " bytes to buffer" << std::endl; | |||
if (len != bufferSize) | |||
lastLen = len; | |||
} | |||
// Connection closed cleanly by peer. | |||
if (error == asio::error::eof) { | |||
std::cout << "Transmition ended normally" << std::endl; | |||
break; | |||
} | |||
// Some other error. | |||
else if (error) { | |||
//Reply to server: 1 means failure | |||
std::array<char, 1>ans { 1 }; | |||
socket->write_some(asio::buffer(ans)); | |||
throw asio::system_error(error); | |||
} | |||
std::string data = std::move(std::string(buf.begin(), lastLen == 0 ? buf.end() : buf.begin() + lastLen)); | |||
inputStream << data; | |||
} | |||
processServerResponse(); | |||
//Reply to server: 0 means okay | |||
codeBuffer[0] = 0; | |||
socket->write_some(asio::buffer(codeBuffer)); | |||
} | |||
return total_bytes_readed; | |||
} |
@@ -0,0 +1,84 @@ | |||
#pragma once | |||
#include "asio.hpp" | |||
#include <memory> | |||
using tcp = asio::ip::tcp; | |||
enum class TCP_REQUESTS { | |||
NA = 0, | |||
DOWNLOAD_DATA = 1, | |||
GET_STATUS = 2, | |||
GET_LOG_FILES | |||
}; | |||
namespace REQUEST { | |||
enum class INTENT { | |||
NA = 0, | |||
DOWNLOAD_DATA = 1, | |||
GET_STATUS = 2, | |||
INVALID | |||
}; | |||
INTENT assignInt(const unsigned int value); | |||
enum class CODE_RCV { | |||
SUCCESS = 0, | |||
FAILED, | |||
INVALID | |||
}; | |||
inline CODE_RCV intToRcv(const unsigned int); | |||
enum class CODE_SND { | |||
CONTINUING, | |||
FINISHED, | |||
INVALID | |||
}; | |||
template<typename E> | |||
constexpr auto toUnderlyingType(E e) | |||
{ | |||
return static_cast<typename std::underlying_type<E>::type>(e); | |||
} | |||
} | |||
template<typename E> | |||
constexpr auto toUnderlyingType(E e) | |||
{ | |||
return static_cast<typename std::underlying_type<E>::type>(e); | |||
} | |||
class IpTcpClient | |||
{ | |||
private: | |||
std::string ip; | |||
unsigned int port; | |||
std::unique_ptr<tcp::socket> socket; | |||
asio::io_context context; | |||
tcp::resolver::results_type endpoints; | |||
std::stringstream inputStream; | |||
TCP_REQUESTS lastRequest; | |||
public: | |||
IpTcpClient(std::string targetIP, unsigned int targetPort); | |||
IpTcpClient(std::string targetIP, unsigned int targetPort, TCP_REQUESTS requestCode); | |||
//getter and setter | |||
std::stringstream& getInputStream() { return inputStream; } | |||
TCP_REQUESTS getLastRequestCode() const { return lastRequest; } | |||
//Client Routine | |||
void connect(); | |||
//send request code to server | |||
void sendRequest(const TCP_REQUESTS& code); | |||
//Wait until server responds | |||
size_t waitRead(); | |||
//Process the received data according to the requested data | |||
void processServerResponse(); | |||
}; | |||
@@ -0,0 +1 @@ | |||
#include "NetClient.h" |
@@ -0,0 +1,16 @@ | |||
#pragma once | |||
#include "net_server_client.h" | |||
class NetClient : public net::ClientInterface<net::MessageTypes> | |||
{ | |||
public: | |||
void RequestLogFile() | |||
{ | |||
net::Message<net::MessageTypes> msg; | |||
msg.header.id = net::MessageTypes::ServerLog; | |||
Send(msg); | |||
} | |||
}; | |||
@@ -0,0 +1,85 @@ | |||
#include "PublisherData.h" | |||
#include "instreamOperator.h" | |||
#include <sstream> | |||
PublisherData::PublisherData(const int _publisherID, PublisherType pubType, float _value) : | |||
publisherID(_publisherID), publisherType(pubType),time_generated(system_clock::now()), values(std::vector<float>()) | |||
{ | |||
values.push_back(_value); | |||
} | |||
PublisherData::PublisherData(const int _publisherID, PublisherType pubType, std::vector<float> _values) : | |||
publisherID(_publisherID), publisherType(pubType), time_generated(system_clock::now()), values(_values) | |||
{ | |||
} | |||
PublisherData::PublisherData() : | |||
publisherID(0), publisherType(PublisherType::NA), time_generated(system_clock::now()), values({ 0.0 }) | |||
{ | |||
} | |||
std::string PublisherData::toString() const{ | |||
//auto timeNow = system_clock::to_time_t(time_generated); | |||
//char timestring[26]; | |||
//ctime_s(timestring, sizeof timestring, &timeNow); | |||
//std::stringstream ss; | |||
//ss << "PublisherData from ID: " << publisherID << " at " << timestring; | |||
//unsigned int i = 0; | |||
//for (auto v : values) { | |||
// ss << " Value " << ++i << " <type: " << typeid(v).name() << "> " << ": " << v << std::endl; | |||
//} | |||
//return ss.str(); | |||
} | |||
std::istream& operator>>(std::istream& is, char const* pat) { | |||
char ch; | |||
while (isspace(static_cast<unsigned char>(is.peek()))) | |||
is.get(ch); | |||
while (*pat && is && *pat == is.peek() && is.get(ch)) { | |||
++pat; | |||
} | |||
// if we didn't reach the end of the pattern, matching failed (mismatch, premature EOF, etc.) | |||
if (*pat) { | |||
is.setstate(std::ios::failbit); | |||
} | |||
return is; | |||
} | |||
std::ostream& operator<<(std::ostream& os, const PublisherData& data){ | |||
//auto timeNow = system_clock::to_time_t(data.time_generated); | |||
//char timestring[26]; | |||
//ctime_s(timestring, sizeof timestring, &timeNow); | |||
os << duration_cast<seconds>(data.time_generated.time_since_epoch()).count() << "_"; | |||
for (unsigned int i = 0; i < data.values.size()-1; i++) { | |||
os << data.values[i] << ","; | |||
} | |||
os << data.values[data.values.size()-1] << ";"; | |||
return os; | |||
} | |||
std::istream& operator>>(std::istream& is, PublisherData& data) { | |||
//size_t time; | |||
float value; | |||
is >> value; | |||
data.values.clear(); | |||
data.values.push_back(value); | |||
//data.time_generated = std::chrono::system_clock::from_time_t(time); | |||
while (is.peek() == ',') { | |||
is >> "," >> value; | |||
data.values.push_back(value); | |||
} | |||
if (is.peek() == ';') { | |||
is.get(); | |||
return is; | |||
} | |||
else | |||
throw std::invalid_argument("Stream object has invalid pattern (should be %d:%f,...,%f;)"); | |||
} |
@@ -0,0 +1,44 @@ | |||
#pragma once | |||
#include <chrono> | |||
#include <vector> | |||
#include <iostream> | |||
#include "PublisherType.h" | |||
using namespace std::chrono; | |||
class PublisherData | |||
{ | |||
private: | |||
unsigned int publisherID; | |||
const PublisherType publisherType; | |||
system_clock::time_point time_generated; | |||
std::vector<float> values; | |||
public: | |||
//constructors | |||
PublisherData(const int _publisherID, PublisherType pubType, float value); | |||
PublisherData(const int _publisherID, PublisherType pubType, std::vector<float> _values); | |||
PublisherData(); | |||
//void updateTime() { this->time_generated = system_clock::now(); } | |||
inline void addData(const float data) { values.push_back(data); } | |||
std::string toString()const; | |||
unsigned int getID() { return publisherID; } | |||
void setID(unsigned int id) { this->publisherID = id; }; | |||
std::vector<float>& getValues() { return values; }; | |||
//getter/setter | |||
PublisherType getType()const { return publisherType; } | |||
system_clock::time_point getTimeGenerated()const { return time_generated; } | |||
bool hasData()const { return values.size() == 0 ? false : true; } | |||
//operator | |||
friend std::ostream& operator<<(std::ostream&, const PublisherData&); | |||
friend std::istream& operator>>(std::istream&, PublisherData&); | |||
}; | |||
@@ -0,0 +1,7 @@ | |||
#pragma once | |||
enum class PublisherType { | |||
NA = 0, | |||
RCMS_BENDER, | |||
POWERCENTER | |||
}; |
@@ -0,0 +1,2 @@ | |||
#pragma once | |||
#include <iostream> |
@@ -0,0 +1,14 @@ | |||
* GLOBAL: | |||
FORMAT = "%datetime{%Y-%M-%d %H:%m:%s} [%level]: %msg" | |||
FILENAME = "log/data_analysis.log" | |||
ENABLED = true | |||
TO_FILE = true | |||
TO_STANDARD_OUTPUT = true | |||
SUBSECOND_PRECISION = 6 | |||
PERFORMANCE_TRACKING = true | |||
MAX_LOG_FILE_SIZE = 20971520 ## 20MB | |||
LOG_FLUSH_THRESHOLD = 10 ## Flush after every 10 logs | |||
* ERROR: | |||
FORMAT = "%datetime{%Y-%M-%d %H:%m:%s} [%level]: %msg: occured at %loc" | |||
* FATAL: | |||
FORMAT = "%datetime{%Y-%M-%d %H:%m:%s} [%level]: %msg: occured at %loc" |
@@ -0,0 +1,16 @@ | |||
SystemConfig: | |||
read_data_interval_s = 50 #continous reading interval in seconds | |||
tcp_server_port = 7777 #TCP Port to access stored data | |||
modbus_poc_ip = 127.0.0.1 #ip address for modbus tcp poc | |||
modbus_poc_port = 502 #port for modbus tcp powercenter | |||
modbus_rtu_device = /dev/pts/6 #serial modbus rtu interface | |||
modbus_rtu_baud = 9600 #serial modbus baud rate | |||
modbus_rtu_stop_bits = 2 #serial modbus stop bits | |||
modbus_rtu_pairity = N #serial modbus pairiy | |||
modbus_rtu_slave_address = 1 #serial modbus slave address | |||
modbus_tcp_slave_address = 1 #tcp/ip modbus slave address | |||
permanent_param_history = 5000 #seconds of permanent storage | |||
crit_residual_current = 30.0 #critical residual current [mA] | |||
crit_residual_timerange = 120 #notify if crit tendency is within n weeks | |||
update_model_rate = 10 #Update ML model after n data points | |||
narrow_block = 50 #Flushing n data points at once |
@@ -0,0 +1,877 @@ | |||
0.460810617 | |||
0.667493396 | |||
-0.443195565 | |||
0.451420754 | |||
0.462200256 | |||
0.78015967 | |||
0.649423425 | |||
0.472740394 | |||
0.486673552 | |||
0.838948148 | |||
0.300340483 | |||
0.957082627 | |||
0.633772488 | |||
-0.05326406 | |||
-0.340396804 | |||
0.652534454 | |||
1.137682544 | |||
0.606227512 | |||
0.468579246 | |||
-0.363173937 | |||
0.382317456 | |||
1.820396804 | |||
0.249622483 | |||
0.25746422 | |||
0.678327297 | |||
1.192740394 | |||
0.492506604 | |||
1.082365069 | |||
1.723195565 | |||
1.352740394 | |||
0.53746422 | |||
1.601672703 | |||
1.26978314 | |||
1.153768435 | |||
1.6338494 | |||
1.702200256 | |||
1.568187082 | |||
0.81746422 | |||
1.822200256 | |||
2.540396804 | |||
1.805926673 | |||
1.116804435 | |||
1.885926673 | |||
1.76 | |||
1.212506604 | |||
2.662426813 | |||
1.817169327 | |||
2.273151281 | |||
2.281672703 | |||
2.262200256 | |||
0.876826063 | |||
2.13021686 | |||
2.3538494 | |||
1.662771058 | |||
1.846848719 | |||
1.853903393 | |||
2.33021686 | |||
2.5538494 | |||
2.63669236 | |||
3.040775783 | |||
2.71669236 | |||
2.817244875 | |||
2.940810617 | |||
3.26253578 | |||
3.30253578 | |||
2.253903393 | |||
3.706874455 | |||
3.123210624 | |||
3.30015967 | |||
2.888187082 | |||
3.662426813 | |||
2.955484608 | |||
3.62253578 | |||
3.112740394 | |||
3.54015967 | |||
2.733593504 | |||
3.577228942 | |||
3.942426813 | |||
2.756789376 | |||
2.722917373 | |||
2.462613203 | |||
2.253125545 | |||
2.61746422 | |||
3.038327297 | |||
3.67669236 | |||
3.465076792 | |||
3.593772488 | |||
2.579603196 | |||
3.66094674 | |||
3.765926673 | |||
3.819229397 | |||
4.198216695 | |||
2.693125545 | |||
3.81021686 | |||
3.724515392 | |||
3.453903393 | |||
4.142200256 | |||
4.241672703 | |||
3.90978314 | |||
4.386096607 | |||
3.733593504 | |||
4.08 | |||
3.342613203 | |||
4.86253578 | |||
5.140396804 | |||
3.886848719 | |||
3.942755125 | |||
4.5538494 | |||
5.182426813 | |||
4.606231565 | |||
4.605926673 | |||
4.314073327 | |||
3.356826063 | |||
5.037082627 | |||
4.486227512 | |||
5.280775783 | |||
4.540340483 | |||
4.757634931 | |||
4.468579246 | |||
5.537895514 | |||
5.177244875 | |||
4.316804435 | |||
4.86978314 | |||
5.297244875 | |||
4.987465546 | |||
5.153772488 | |||
5.219659517 | |||
4.766848719 | |||
5.43669236 | |||
5.30094674 | |||
4.933593504 | |||
5.432740394 | |||
5.26978314 | |||
5.713151281 | |||
5.552740394 | |||
5.233768435 | |||
5.53021686 | |||
5.41905326 | |||
4.533125545 | |||
5.179189383 | |||
5.162917373 | |||
5.705076792 | |||
5.657169327 | |||
6.051420754 | |||
5.939659517 | |||
4.813125545 | |||
5.892534454 | |||
5.713768435 | |||
6.457228942 | |||
6.54015967 | |||
6.002365069 | |||
6.817895514 | |||
5.782755125 | |||
6.273772488 | |||
6.419956583 | |||
5.721783305 | |||
5.876789376 | |||
5.156826063 | |||
6.878216695 | |||
6.234073327 | |||
6.118327297 | |||
6.110576575 | |||
6.826406496 | |||
6.471812918 | |||
5.959224217 | |||
6.819229397 | |||
7.066096607 | |||
6.682365069 | |||
6.835484608 | |||
6.25984033 | |||
6.276804435 | |||
6.905076792 | |||
7.417228942 | |||
6.934923208 | |||
6.94978314 | |||
6.748579246 | |||
6.832074826 | |||
6.601783305 | |||
7.05905326 | |||
6.908579246 | |||
6.992074826 | |||
7.114073327 | |||
7.472740394 | |||
7.271812918 | |||
7.247259606 | |||
6.89984033 | |||
6.982771058 | |||
8.038216695 | |||
8.586874455 | |||
7.953151281 | |||
8.280775783 | |||
7.845926673 | |||
7.242917373 | |||
8.257228942 | |||
7.837634931 | |||
8.087925174 | |||
8.266096607 | |||
8.358948148 | |||
7.668579246 | |||
7.481783305 | |||
7.42673594 | |||
8.417244875 | |||
8.441672703 | |||
8.185076792 | |||
7.681783305 | |||
7.213125545 | |||
8.617244875 | |||
9.142426813 | |||
8.112074826 | |||
8.387465546 | |||
8.465076792 | |||
8.42978314 | |||
8.923210624 | |||
9.26253578 | |||
8.819956583 | |||
8.766673552 | |||
8.310576575 | |||
8.382755125 | |||
9.347493396 | |||
8.74978314 | |||
8.78978314 | |||
8.573593504 | |||
9.742426813 | |||
8.871812918 | |||
9.587493396 | |||
9.409423425 | |||
9.219659517 | |||
8.297573187 | |||
9.147465546 | |||
8.681783305 | |||
9.827493396 | |||
9.0461506 | |||
9.057799744 | |||
9.97326406 | |||
9.013903393 | |||
9.001051852 | |||
8.86673594 | |||
9.380340483 | |||
8.919224217 | |||
9.102771058 | |||
9.627465546 | |||
9.95669236 | |||
9.872740394 | |||
9.734923208 | |||
9.737169327 | |||
9.633768435 | |||
9.892534454 | |||
10.5074934 | |||
10.5474934 | |||
10.08818708 | |||
10.23266023 | |||
10.81789551 | |||
10.10746555 | |||
10.80077578 | |||
9.422613203 | |||
10.04733977 | |||
10.15332645 | |||
11.34687446 | |||
9.65746422 | |||
11.1773868 | |||
10.22004342 | |||
11.64317394 | |||
10.49492321 | |||
9.396826063 | |||
10.87669236 | |||
10.43376844 | |||
10.25918938 | |||
10.73253445 | |||
11.25722894 | |||
10.88818708 | |||
10.54857925 | |||
10.6461506 | |||
11.0992294 | |||
10.7807706 | |||
10.94978314 | |||
10.83376844 | |||
10.25757319 | |||
10.24465696 | |||
10.61984033 | |||
11.87037752 | |||
10.96330764 | |||
11.00330764 | |||
11.0135935 | |||
11.52592667 | |||
12.10253578 | |||
11.51548461 | |||
12.12077578 | |||
11.88942342 | |||
11.56 | |||
11.44725961 | |||
12.02609661 | |||
11.84592667 | |||
12.05724488 | |||
12.16321062 | |||
11.09746422 | |||
12.24321062 | |||
12.21724488 | |||
11.79332645 | |||
12.38081062 | |||
11.12465696 | |||
11.33746422 | |||
11.88733977 | |||
12.66015967 | |||
11.75678938 | |||
12.28818708 | |||
11.56962248 | |||
12.31763493 | |||
11.15682606 | |||
12.57995658 | |||
11.37312554 | |||
13.00319556 | |||
12.00291737 | |||
13.06015967 | |||
13.43534304 | |||
12.7792294 | |||
12.0525066 | |||
12.54034048 | |||
12.55407333 | |||
12.83548461 | |||
12.0226132 | |||
12.41918938 | |||
13.24942342 | |||
12.56684872 | |||
13.22220026 | |||
12.78004342 | |||
12.0996032 | |||
13.43315128 | |||
12.96725961 | |||
13.3938494 | |||
12.95207483 | |||
12.88684872 | |||
13.19181292 | |||
12.96684872 | |||
13.79894815 | |||
13.56592667 | |||
12.98231746 | |||
13.14275512 | |||
13.25779974 | |||
12.73757319 | |||
14.16319556 | |||
13.70283067 | |||
13.79377249 | |||
13.64451539 | |||
13.9392294 | |||
13.12962248 | |||
13.86507679 | |||
14.52077578 | |||
13.89492321 | |||
13.74004342 | |||
12.83682606 | |||
13.93905326 | |||
14.4016727 | |||
13.91376844 | |||
14.86253578 | |||
14.28818708 | |||
14.10034048 | |||
14.82015967 | |||
14.77768254 | |||
13.74673594 | |||
15.04077578 | |||
14.70220026 | |||
14.31407333 | |||
14.40622751 | |||
14.39407333 | |||
15.24077578 | |||
14.42004342 | |||
15.29326406 | |||
14.93995658 | |||
15.46253578 | |||
13.63682606 | |||
15.4274934 | |||
14.00465696 | |||
15.27315128 | |||
15.36321062 | |||
14.91181292 | |||
14.2626132 | |||
15.78253578 | |||
15.61722894 | |||
15.40792517 | |||
14.49746422 | |||
15.03376844 | |||
14.9735935 | |||
15.65724488 | |||
15.22034048 | |||
15.18004342 | |||
15.54094674 | |||
14.98277106 | |||
15.92321062 | |||
16.72317394 | |||
15.39376844 | |||
15.30275512 | |||
16.70687446 | |||
16.10609661 | |||
15.87377249 | |||
15.68622751 | |||
15.40105185 | |||
15.68733977 | |||
15.18210449 | |||
16.45722894 | |||
16.08818708 | |||
15.7335935 | |||
16.28623156 | |||
16.7074934 | |||
15.82275512 | |||
16.47669236 | |||
17.1803968 | |||
16.84319556 | |||
16.44667355 | |||
15.86277106 | |||
16.9874934 | |||
16.80942342 | |||
16.34034048 | |||
16.2861506 | |||
16.2535935 | |||
16.49905326 | |||
16.51332645 | |||
16.65492321 | |||
16.69492321 | |||
17.25722894 | |||
16.58004342 | |||
17.26081062 | |||
17.39821669 | |||
16.49918938 | |||
17.01021686 | |||
16.57918938 | |||
16.4525066 | |||
17.4016727 | |||
16.91376844 | |||
16.5725066 | |||
17.4338494 | |||
17.22746555 | |||
17.1007706 | |||
17.11376844 | |||
17.14004342 | |||
18.3403968 | |||
18.26242681 | |||
16.7026132 | |||
17.46978314 | |||
18.3373868 | |||
16.72465696 | |||
18.5803968 | |||
17.97142075 | |||
17.83377249 | |||
17.05746422 | |||
17.95274039 | |||
17.71332645 | |||
17.79181292 | |||
17.40178331 | |||
17.99763493 | |||
17.88622751 | |||
18.8173868 | |||
17.05312554 | |||
17.95407333 | |||
17.95376844 | |||
18.60321062 | |||
19.26687446 | |||
18.5864065 | |||
18.38283067 | |||
17.92105185 | |||
18.89722894 | |||
17.98231746 | |||
18.04105185 | |||
18.71266023 | |||
18.63548461 | |||
18.63763493 | |||
18.16291737 | |||
18.92792517 | |||
18.79548461 | |||
18.72236507 | |||
18.93965952 | |||
17.81312554 | |||
18.77905326 | |||
19.18220026 | |||
19.34609661 | |||
18.8207706 | |||
19.3464065 | |||
19.01716933 | |||
19.19548461 | |||
18.8383273 | |||
19.32667355 | |||
18.74277106 | |||
19.89326406 | |||
19.05779974 | |||
19.55266023 | |||
19.61995658 | |||
19.23376844 | |||
20.12077578 | |||
20.22253578 | |||
19.82220026 | |||
19.63763493 | |||
19.37779974 | |||
19.4461506 | |||
19.38275512 | |||
19.91274039 | |||
18.63682606 | |||
19.77716933 | |||
19.33984033 | |||
19.97021686 | |||
19.96 | |||
20.01253445 | |||
20.09021686 | |||
20.75037752 | |||
20.99534304 | |||
20.3392294 | |||
20.49142075 | |||
19.96330764 | |||
20.71894815 | |||
19.7325066 | |||
20.29716933 | |||
21.1773868 | |||
20.00105185 | |||
20.21779974 | |||
20.95894815 | |||
20.98081062 | |||
21.47534304 | |||
20.16291737 | |||
21.84317394 | |||
19.89757319 | |||
20.5261506 | |||
21.0338494 | |||
21.31708263 | |||
21.55037752 | |||
20.48105185 | |||
20.62275512 | |||
20.7661506 | |||
22.20317394 | |||
21.4016727 | |||
21.99534304 | |||
21.89789551 | |||
22.22687446 | |||
20.85390339 | |||
20.40465696 | |||
21.4992294 | |||
21.44818708 | |||
20.8125066 | |||
21.27407333 | |||
21.23207483 | |||
21.11678938 | |||
20.88962248 | |||
20.89746422 | |||
22.34253578 | |||
21.54034048 | |||
21.82094674 | |||
22.12942342 | |||
22.53789551 | |||
21.50275512 | |||
21.85492321 | |||
21.3325066 | |||
21.69779974 | |||
22.10094674 | |||
23.20317394 | |||
21.43922422 | |||
22.04451539 | |||
22.54609661 | |||
21.55922422 | |||
21.6525066 | |||
23.10242681 | |||
22.70609661 | |||
21.90231746 | |||
22.20733977 | |||
21.41312554 | |||
23.2573868 | |||
22.18275512 | |||
22.48451539 | |||
23.02081062 | |||
22.99315128 | |||
22.60451539 | |||
23.19708263 | |||
23.12942342 | |||
22.39678938 | |||
23.66242681 | |||
22.6461506 | |||
22.53390339 | |||
23.1938494 | |||
22.75207483 | |||
22.82004342 | |||
23.06746555 | |||
22.84330764 | |||
23.29965952 | |||
22.03682606 | |||
23.13905326 | |||
23.6016727 | |||
23.74081062 | |||
23.00684872 | |||
23.0935935 | |||
22.98231746 | |||
23.21779974 | |||
23.16684872 | |||
24.01768254 | |||
23.80623156 | |||
22.96962248 | |||
23.16178331 | |||
23.31678938 | |||
23.95266023 | |||
23.18673594 | |||
24.48077578 | |||
24.09995658 | |||
24.48319556 | |||
23.96 | |||
25.02687446 | |||
23.98978314 | |||
24.48321062 | |||
23.38210449 | |||
24.61768254 | |||
24.93789551 | |||
23.85390339 | |||
23.94275512 | |||
24.67315128 | |||
23.81984033 | |||
24.60623156 | |||
24.73142075 | |||
24.31407333 | |||
24.22857925 | |||
24.12105185 | |||
24.6 | |||
25.2274934 | |||
24.13984033 | |||
25.17768254 | |||
24.11922422 | |||
25.23894815 | |||
24.48684872 | |||
24.40291737 | |||
23.9796032 | |||
25.63037752 | |||
24.38673594 | |||
25.2192294 | |||
24.60291737 | |||
24.66231746 | |||
25.13492321 | |||
24.86275512 | |||
25.39274039 | |||
25.38094674 | |||
25.23181292 | |||
24.92105185 | |||
25.7216727 | |||
25.32622751 | |||
24.91680444 | |||
25.88942342 | |||
25.28330764 | |||
26.42242681 | |||
25.4061506 | |||
25.92792517 | |||
26.0416727 | |||
25.9392294 | |||
26.25768254 | |||
26.26081062 | |||
26.35708263 | |||
25.56684872 | |||
26.11274039 | |||
26.15274039 | |||
26.42609661 | |||
26.41724488 | |||
26.7074934 | |||
26.18507679 | |||
26.63894815 | |||
26.12622751 | |||
27.10242681 | |||
26.34507679 | |||
25.68962248 | |||
26.24725961 | |||
25.96291737 | |||
25.93984033 | |||
26.2861506 | |||
26.8664065 | |||
26.75274039 | |||
26.8738494 | |||
26.03922422 | |||
26.8992294 | |||
26.89965952 | |||
26.32291737 | |||
25.96465696 | |||
27.17142075 | |||
27.04667355 | |||
27.2816727 | |||
27 | |||
27.74253578 | |||
27.08 | |||
27.23377249 | |||
27.7474934 | |||
27.90253578 | |||
26.72178331 | |||
27.35548461 | |||
27.65724488 | |||
26.65746422 | |||
27.47548461 | |||
27.60592667 | |||
27.35332645 | |||
27.67274039 | |||
27.2535935 | |||
27.40733977 | |||
27.76667355 | |||
28.2674934 | |||
27.28105185 | |||
28.58242681 | |||
28.34015967 | |||
28.27894815 | |||
27.54275512 | |||
27.42277106 | |||
27.75376844 | |||
27.32962248 | |||
27.30210449 | |||
27.95332645 | |||
27.66231746 | |||
27.96733977 | |||
27.72291737 | |||
28.03376844 | |||
28.07376844 | |||
27.61746422 | |||
28.43548461 | |||
28.75315128 | |||
27.56465696 | |||
27.91680444 | |||
27.49312554 | |||
28.29779974 | |||
27.98673594 | |||
29.5803968 | |||
28.87266023 | |||
29.15894815 | |||
28.30231746 | |||
29.29722894 | |||
29.57789551 | |||
28.58857925 | |||
28.30673594 | |||
29.03548461 | |||
28.4125066 | |||
29.14094674 | |||
28.4925066 | |||
29.4264065 | |||
29.00725961 | |||
28.6125066 | |||
29.20236507 | |||
28.85918938 | |||
29.19332645 | |||
28.88291737 | |||
29.4 | |||
29.89768254 | |||
29.64592667 | |||
29.90609661 | |||
29.45905326 | |||
29.46034048 | |||
29.3335935 | |||
29.61716933 | |||
30.17768254 | |||
29.1725066 | |||
29.69905326 | |||
30.51037752 | |||
29.85492321 | |||
29.94507679 | |||
30.07377249 | |||
29.72330764 | |||
28.87682606 | |||
30.6674934 | |||
30.2992294 | |||
30.65722894 | |||
30.5064065 | |||
29.56962248 | |||
30.11407333 | |||
30.47274039 | |||
30.16733977 | |||
29.96105185 | |||
30.91708263 | |||
30.21779974 | |||
30.67274039 | |||
31.03708263 | |||
30.51181292 | |||
30.48725961 | |||
31.06609661 | |||
30.87274039 | |||
30.95266023 | |||
30.64725961 | |||
31.03266023 | |||
30.84236507 | |||
31.28942342 | |||
30.46277106 | |||
30.35922422 | |||
30.60105185 | |||
30.96622751 | |||
31.48942342 | |||
31.04622751 | |||
30.49746422 | |||
30.85390339 | |||
31.33021686 | |||
30.67922422 | |||
32.23534304 | |||
31.0783273 | |||
31.42746555 | |||
31.7864065 | |||
31.25779974 | |||
31.85142075 | |||
31.23057658 | |||
32.31037752 | |||
32.01724488 | |||
31.10673594 | |||
31.30231746 | |||
32.53789551 | |||
32.86687446 | |||
31.05757319 | |||
31.09757319 | |||
31.90978314 | |||
32.40321062 | |||
32.3464065 | |||
31.92725961 | |||
31.76684872 | |||
31.61984033 | |||
32.5216727 | |||
31.21312554 | |||
32.31763493 | |||
31.89918938 | |||
32.57995658 | |||
32.82081062 | |||
32.08684872 | |||
32.49253445 | |||
32.76792517 | |||
32.45905326 | |||
32.19678938 | |||
32.36330764 | |||
33.15708263 | |||
31.9426132 | |||
32.83548461 | |||
33.20321062 | |||
32.56330764 | |||
33.26609661 | |||
33.39708263 | |||
32.7261506 | |||
33.15274039 | |||
33.3464065 | |||
34.24317394 | |||
33.03181292 | |||
32.9807706 | |||
33.22507679 | |||
32.2996032 | |||
33.0461506 | |||
33.96077578 | |||
33.63669236 | |||
33.94015967 | |||
33.31332645 | |||
33.02231746 | |||
33.41905326 | |||
34.07821669 | |||
34.1874934 | |||
32.93746422 | |||
33.40330764 | |||
33.69492321 | |||
34.3474934 | |||
34.50253578 | |||
34.10220026 | |||
34.49326406 | |||
33.90746555 | |||
34.20792517 | |||
33.88622751 | |||
34.44321062 | |||
34.4016727 | |||
34.4416727 | |||
33.28465696 | |||
34.00733977 | |||
34.64321062 | |||
34.30507679 | |||
33.70673594 | |||
33.99057658 | |||
33.66210449 | |||
34.77724488 | |||
33.8925066 | |||
34.99708263 | |||
33.88962248 | |||
34.96942342 | |||
34.50034048 | |||
34.75548461 | |||
34.38275512 | |||
34.49779974 | |||
33.8596032 | |||
34.48684872 | |||
34.75332645 | |||
35.32321062 | |||
34.0196032 | |||
34.7661506 | |||
35.20592667 | |||
36.24317394 |
@@ -0,0 +1,41 @@ | |||
#include <iostream> | |||
#include <fstream> | |||
#include <unistd.h> | |||
#include <iomanip> | |||
#include <vector> | |||
#include <cstring> | |||
using namespace std; | |||
//0x4090793e | |||
int main() | |||
{ | |||
std::vector<uint16_t> rawData; | |||
//Push some eample data | |||
double value = 7.5; | |||
//rawData.push_back(0x); | |||
//rawData.push_back(0x); | |||
//rawData.push_back(0x); | |||
//rawData.push_back(0x); | |||
std::memcpy(&value, rawData.data(), 4); | |||
std::cout << "Copied value = " << value; | |||
/* | |||
string line; | |||
const string cmd = "/home/michael/baConditionMonitoring/modpoll/x86_64-linux-gnu/modpoll -b 9600 -p none -m rtu -r 100 -1 -t 4:float /dev/pts/6 "; | |||
ifstream file ("data.txt"); | |||
if (file.is_open()) | |||
{ | |||
while ( getline (file,line) ) | |||
{ | |||
sleep(1); | |||
string cmdValue = cmd + line; | |||
system(cmdValue.c_str()); | |||
std::cout << "Written value " << line << endl; | |||
} | |||
file.close(); | |||
} | |||
else | |||
cout << "opening failed..." << endl; | |||
*/ | |||
return 0; | |||
} |
@@ -0,0 +1,10 @@ | |||
TEMPLATE = app | |||
CONFIG += console c++11 | |||
CONFIG -= app_bundle | |||
CONFIG -= qt | |||
SOURCES += \ | |||
main.cpp | |||
DISTFILES += \ | |||
data.txt |
@@ -0,0 +1,355 @@ | |||
<?xml version="1.0" encoding="UTF-8"?> | |||
<!DOCTYPE QtCreatorProject> | |||
<!-- Written by QtCreator 4.13.3, 2021-08-08T20:19:55. --> | |||
<qtcreator> | |||
<data> | |||
<variable>EnvironmentId</variable> | |||
<value type="QByteArray">{5a632e4a-e744-412b-acc7-3b951573dab3}</value> | |||
</data> | |||
<data> | |||
<variable>ProjectExplorer.Project.ActiveTarget</variable> | |||
<value type="int">0</value> | |||
</data> | |||
<data> | |||
<variable>ProjectExplorer.Project.EditorSettings</variable> | |||
<valuemap type="QVariantMap"> | |||
<value type="bool" key="EditorConfiguration.AutoIndent">true</value> | |||
<value type="bool" key="EditorConfiguration.AutoSpacesForTabs">false</value> | |||
<value type="bool" key="EditorConfiguration.CamelCaseNavigation">true</value> | |||
<valuemap type="QVariantMap" key="EditorConfiguration.CodeStyle.0"> | |||
<value type="QString" key="language">Cpp</value> | |||
<valuemap type="QVariantMap" key="value"> | |||
<value type="QByteArray" key="CurrentPreferences">CppGlobal</value> | |||
</valuemap> | |||
</valuemap> | |||
<valuemap type="QVariantMap" key="EditorConfiguration.CodeStyle.1"> | |||
<value type="QString" key="language">QmlJS</value> | |||
<valuemap type="QVariantMap" key="value"> | |||
<value type="QByteArray" key="CurrentPreferences">QmlJSGlobal</value> | |||
</valuemap> | |||
</valuemap> | |||
<value type="int" key="EditorConfiguration.CodeStyle.Count">2</value> | |||
<value type="QByteArray" key="EditorConfiguration.Codec">UTF-8</value> | |||
<value type="bool" key="EditorConfiguration.ConstrainTooltips">false</value> | |||
<value type="int" key="EditorConfiguration.IndentSize">4</value> | |||
<value type="bool" key="EditorConfiguration.KeyboardTooltips">false</value> | |||
<value type="int" key="EditorConfiguration.MarginColumn">80</value> | |||
<value type="bool" key="EditorConfiguration.MouseHiding">true</value> | |||
<value type="bool" key="EditorConfiguration.MouseNavigation">true</value> | |||
<value type="int" key="EditorConfiguration.PaddingMode">1</value> | |||
<value type="bool" key="EditorConfiguration.ScrollWheelZooming">true</value> | |||
<value type="bool" key="EditorConfiguration.ShowMargin">false</value> | |||
<value type="int" key="EditorConfiguration.SmartBackspaceBehavior">0</value> | |||
<value type="bool" key="EditorConfiguration.SmartSelectionChanging">true</value> | |||
<value type="bool" key="EditorConfiguration.SpacesForTabs">true</value> | |||
<value type="int" key="EditorConfiguration.TabKeyBehavior">0</value> | |||
<value type="int" key="EditorConfiguration.TabSize">8</value> | |||
<value type="bool" key="EditorConfiguration.UseGlobal">true</value> | |||
<value type="int" key="EditorConfiguration.Utf8BomBehavior">1</value> | |||
<value type="bool" key="EditorConfiguration.addFinalNewLine">true</value> | |||
<value type="bool" key="EditorConfiguration.cleanIndentation">true</value> | |||
<value type="bool" key="EditorConfiguration.cleanWhitespace">true</value> | |||
<value type="QString" key="EditorConfiguration.ignoreFileTypes">*.md, *.MD, Makefile</value> | |||
<value type="bool" key="EditorConfiguration.inEntireDocument">false</value> | |||
<value type="bool" key="EditorConfiguration.skipTrailingWhitespace">true</value> | |||
</valuemap> | |||
</data> | |||
<data> | |||
<variable>ProjectExplorer.Project.PluginSettings</variable> | |||
<valuemap type="QVariantMap"> | |||
<valuemap type="QVariantMap" key="AutoTest.ActiveFrameworks"> | |||
<value type="bool" key="AutoTest.Framework.Boost">true</value> | |||
<value type="bool" key="AutoTest.Framework.Catch">true</value> | |||
<value type="bool" key="AutoTest.Framework.GTest">true</value> | |||
<value type="bool" key="AutoTest.Framework.QtQuickTest">true</value> | |||
<value type="bool" key="AutoTest.Framework.QtTest">true</value> | |||
</valuemap> | |||
<valuemap type="QVariantMap" key="AutoTest.CheckStates"/> | |||
<value type="int" key="AutoTest.RunAfterBuild">0</value> | |||
<value type="bool" key="AutoTest.UseGlobal">true</value> | |||
<valuelist type="QVariantList" key="ClangCodeModel.CustomCommandLineKey"/> | |||
<value type="bool" key="ClangCodeModel.UseGlobalConfig">true</value> | |||
<value type="QString" key="ClangCodeModel.WarningConfigId">Builtin.Questionable</value> | |||
<valuemap type="QVariantMap" key="ClangTools"> | |||
<value type="bool" key="ClangTools.BuildBeforeAnalysis">true</value> | |||
<value type="QString" key="ClangTools.DiagnosticConfig">Builtin.DefaultTidyAndClazy</value> | |||
<value type="int" key="ClangTools.ParallelJobs">1</value> | |||
<valuelist type="QVariantList" key="ClangTools.SelectedDirs"/> | |||
<valuelist type="QVariantList" key="ClangTools.SelectedFiles"/> | |||
<valuelist type="QVariantList" key="ClangTools.SuppressedDiagnostics"/> | |||
<value type="bool" key="ClangTools.UseGlobalSettings">true</value> | |||
</valuemap> | |||
</valuemap> | |||
</data> | |||
<data> | |||
<variable>ProjectExplorer.Project.Target.0</variable> | |||
<valuemap type="QVariantMap"> | |||
<value type="QString" key="DeviceType">Desktop</value> | |||
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">Desktop Qt 5.15.1 GCC 64bit</value> | |||
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName">Desktop Qt 5.15.1 GCC 64bit</value> | |||
<value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">qt.qt5.5151.gcc_64_kit</value> | |||
<value type="int" key="ProjectExplorer.Target.ActiveBuildConfiguration">0</value> | |||
<value type="int" key="ProjectExplorer.Target.ActiveDeployConfiguration">0</value> | |||
<value type="int" key="ProjectExplorer.Target.ActiveRunConfiguration">0</value> | |||
<valuemap type="QVariantMap" key="ProjectExplorer.Target.BuildConfiguration.0"> | |||
<value type="bool">false</value> | |||
<value type="int" key="EnableQmlDebugging">0</value> | |||
<value type="QString" key="ProjectExplorer.BuildConfiguration.BuildDirectory">/home/michael/modpollData</value> | |||
<value type="QString" key="ProjectExplorer.BuildConfiguration.BuildDirectory.shadowDir">/home/michael/modpollData</value> | |||
<valuemap type="QVariantMap" key="ProjectExplorer.BuildConfiguration.BuildStepList.0"> | |||
<valuemap type="QVariantMap" key="ProjectExplorer.BuildStepList.Step.0"> | |||
<value type="bool" key="ProjectExplorer.BuildStep.Enabled">true</value> | |||
<value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">QtProjectManager.QMakeBuildStep</value> | |||
<value type="QString" key="QtProjectManager.QMakeBuildStep.QMakeArguments"></value> | |||
<value type="bool" key="QtProjectManager.QMakeBuildStep.QMakeForced">false</value> | |||
<valuelist type="QVariantList" key="QtProjectManager.QMakeBuildStep.SelectedAbis"/> | |||
</valuemap> | |||
<valuemap type="QVariantMap" key="ProjectExplorer.BuildStepList.Step.1"> | |||
<value type="bool" key="ProjectExplorer.BuildStep.Enabled">true</value> | |||
<value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">Qt4ProjectManager.MakeStep</value> | |||
<valuelist type="QVariantList" key="Qt4ProjectManager.MakeStep.BuildTargets"/> | |||
<value type="bool" key="Qt4ProjectManager.MakeStep.Clean">false</value> | |||
<value type="QString" key="Qt4ProjectManager.MakeStep.MakeArguments"></value> | |||
<value type="QString" key="Qt4ProjectManager.MakeStep.MakeCommand"></value> | |||
<value type="bool" key="Qt4ProjectManager.MakeStep.OverrideMakeflags">false</value> | |||
</valuemap> | |||
<value type="int" key="ProjectExplorer.BuildStepList.StepsCount">2</value> | |||
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">Build</value> | |||
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName">Build</value> | |||
<value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">ProjectExplorer.BuildSteps.Build</value> | |||
</valuemap> | |||
<valuemap type="QVariantMap" key="ProjectExplorer.BuildConfiguration.BuildStepList.1"> | |||
<valuemap type="QVariantMap" key="ProjectExplorer.BuildStepList.Step.0"> | |||
<value type="bool" key="ProjectExplorer.BuildStep.Enabled">true</value> | |||
<value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">Qt4ProjectManager.MakeStep</value> | |||
<valuelist type="QVariantList" key="Qt4ProjectManager.MakeStep.BuildTargets"/> | |||
<value type="bool" key="Qt4ProjectManager.MakeStep.Clean">true</value> | |||
<value type="QString" key="Qt4ProjectManager.MakeStep.MakeArguments">clean</value> | |||
<value type="QString" key="Qt4ProjectManager.MakeStep.MakeCommand"></value> | |||
<value type="bool" key="Qt4ProjectManager.MakeStep.OverrideMakeflags">false</value> | |||
</valuemap> | |||
<value type="int" key="ProjectExplorer.BuildStepList.StepsCount">1</value> | |||
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">Clean</value> | |||
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName">Clean</value> | |||
<value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">ProjectExplorer.BuildSteps.Clean</value> | |||
</valuemap> | |||
<value type="int" key="ProjectExplorer.BuildConfiguration.BuildStepListCount">2</value> | |||
<value type="bool" key="ProjectExplorer.BuildConfiguration.ClearSystemEnvironment">false</value> | |||
<valuelist type="QVariantList" key="ProjectExplorer.BuildConfiguration.CustomParsers"/> | |||
<valuelist type="QVariantList" key="ProjectExplorer.BuildConfiguration.UserEnvironmentChanges"/> | |||
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName">Debug</value> | |||
<value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">Qt4ProjectManager.Qt4BuildConfiguration</value> | |||
<value type="int" key="Qt4ProjectManager.Qt4BuildConfiguration.BuildConfiguration">2</value> | |||
<value type="int" key="QtQuickCompiler">2</value> | |||
<value type="int" key="SeparateDebugInfo">2</value> | |||
</valuemap> | |||
<valuemap type="QVariantMap" key="ProjectExplorer.Target.BuildConfiguration.1"> | |||
<value type="bool">true</value> | |||
<value type="int" key="EnableQmlDebugging">2</value> | |||
<value type="QString" key="ProjectExplorer.BuildConfiguration.BuildDirectory">/home/michael/build-modpollData-Desktop_Qt_5_15_1_GCC_64bit-Release</value> | |||
<value type="QString" key="ProjectExplorer.BuildConfiguration.BuildDirectory.shadowDir">/home/michael/build-modpollData-Desktop_Qt_5_15_1_GCC_64bit-Release</value> | |||
<valuemap type="QVariantMap" key="ProjectExplorer.BuildConfiguration.BuildStepList.0"> | |||
<valuemap type="QVariantMap" key="ProjectExplorer.BuildStepList.Step.0"> | |||
<value type="bool" key="ProjectExplorer.BuildStep.Enabled">true</value> | |||
<value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">QtProjectManager.QMakeBuildStep</value> | |||
<value type="QString" key="QtProjectManager.QMakeBuildStep.QMakeArguments"></value> | |||
<value type="bool" key="QtProjectManager.QMakeBuildStep.QMakeForced">false</value> | |||
<valuelist type="QVariantList" key="QtProjectManager.QMakeBuildStep.SelectedAbis"/> | |||
</valuemap> | |||
<valuemap type="QVariantMap" key="ProjectExplorer.BuildStepList.Step.1"> | |||
<value type="bool" key="ProjectExplorer.BuildStep.Enabled">true</value> | |||
<value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">Qt4ProjectManager.MakeStep</value> | |||
<valuelist type="QVariantList" key="Qt4ProjectManager.MakeStep.BuildTargets"/> | |||
<value type="bool" key="Qt4ProjectManager.MakeStep.Clean">false</value> | |||
<value type="QString" key="Qt4ProjectManager.MakeStep.MakeArguments"></value> | |||
<value type="QString" key="Qt4ProjectManager.MakeStep.MakeCommand"></value> | |||
<value type="bool" key="Qt4ProjectManager.MakeStep.OverrideMakeflags">false</value> | |||
</valuemap> | |||
<value type="int" key="ProjectExplorer.BuildStepList.StepsCount">2</value> | |||
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">Build</value> | |||
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName">Build</value> | |||
<value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">ProjectExplorer.BuildSteps.Build</value> | |||
</valuemap> | |||
<valuemap type="QVariantMap" key="ProjectExplorer.BuildConfiguration.BuildStepList.1"> | |||
<valuemap type="QVariantMap" key="ProjectExplorer.BuildStepList.Step.0"> | |||
<value type="bool" key="ProjectExplorer.BuildStep.Enabled">true</value> | |||
<value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">Qt4ProjectManager.MakeStep</value> | |||
<valuelist type="QVariantList" key="Qt4ProjectManager.MakeStep.BuildTargets"/> | |||
<value type="bool" key="Qt4ProjectManager.MakeStep.Clean">true</value> | |||
<value type="QString" key="Qt4ProjectManager.MakeStep.MakeArguments">clean</value> | |||
<value type="QString" key="Qt4ProjectManager.MakeStep.MakeCommand"></value> | |||
<value type="bool" key="Qt4ProjectManager.MakeStep.OverrideMakeflags">false</value> | |||
</valuemap> | |||
<value type="int" key="ProjectExplorer.BuildStepList.StepsCount">1</value> | |||
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">Clean</value> | |||
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName">Clean</value> | |||
<value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">ProjectExplorer.BuildSteps.Clean</value> | |||
</valuemap> | |||
<value type="int" key="ProjectExplorer.BuildConfiguration.BuildStepListCount">2</value> | |||
<value type="bool" key="ProjectExplorer.BuildConfiguration.ClearSystemEnvironment">false</value> | |||
<valuelist type="QVariantList" key="ProjectExplorer.BuildConfiguration.CustomParsers"/> | |||
<valuelist type="QVariantList" key="ProjectExplorer.BuildConfiguration.UserEnvironmentChanges"/> | |||
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName">Release</value> | |||
<value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">Qt4ProjectManager.Qt4BuildConfiguration</value> | |||
<value type="int" key="Qt4ProjectManager.Qt4BuildConfiguration.BuildConfiguration">0</value> | |||
<value type="int" key="QtQuickCompiler">0</value> | |||
<value type="int" key="SeparateDebugInfo">2</value> | |||
</valuemap> | |||
<valuemap type="QVariantMap" key="ProjectExplorer.Target.BuildConfiguration.2"> | |||
<value type="bool">true</value> | |||
<value type="int" key="EnableQmlDebugging">0</value> | |||
<value type="QString" key="ProjectExplorer.BuildConfiguration.BuildDirectory">/home/michael/build-modpollData-Desktop_Qt_5_15_1_GCC_64bit-Profile</value> | |||
<value type="QString" key="ProjectExplorer.BuildConfiguration.BuildDirectory.shadowDir">/home/michael/build-modpollData-Desktop_Qt_5_15_1_GCC_64bit-Profile</value> | |||
<valuemap type="QVariantMap" key="ProjectExplorer.BuildConfiguration.BuildStepList.0"> | |||
<valuemap type="QVariantMap" key="ProjectExplorer.BuildStepList.Step.0"> | |||
<value type="bool" key="ProjectExplorer.BuildStep.Enabled">true</value> | |||
<value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">QtProjectManager.QMakeBuildStep</value> | |||
<value type="QString" key="QtProjectManager.QMakeBuildStep.QMakeArguments"></value> | |||
<value type="bool" key="QtProjectManager.QMakeBuildStep.QMakeForced">false</value> | |||
<valuelist type="QVariantList" key="QtProjectManager.QMakeBuildStep.SelectedAbis"/> | |||
</valuemap> | |||
<valuemap type="QVariantMap" key="ProjectExplorer.BuildStepList.Step.1"> | |||
<value type="bool" key="ProjectExplorer.BuildStep.Enabled">true</value> | |||
<value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">Qt4ProjectManager.MakeStep</value> | |||
<valuelist type="QVariantList" key="Qt4ProjectManager.MakeStep.BuildTargets"/> | |||
<value type="bool" key="Qt4ProjectManager.MakeStep.Clean">false</value> | |||
<value type="QString" key="Qt4ProjectManager.MakeStep.MakeArguments"></value> | |||
<value type="QString" key="Qt4ProjectManager.MakeStep.MakeCommand"></value> | |||
<value type="bool" key="Qt4ProjectManager.MakeStep.OverrideMakeflags">false</value> | |||
</valuemap> | |||
<value type="int" key="ProjectExplorer.BuildStepList.StepsCount">2</value> | |||
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">Build</value> | |||
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName">Build</value> | |||
<value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">ProjectExplorer.BuildSteps.Build</value> | |||
</valuemap> | |||
<valuemap type="QVariantMap" key="ProjectExplorer.BuildConfiguration.BuildStepList.1"> | |||
<valuemap type="QVariantMap" key="ProjectExplorer.BuildStepList.Step.0"> | |||
<value type="bool" key="ProjectExplorer.BuildStep.Enabled">true</value> | |||
<value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">Qt4ProjectManager.MakeStep</value> | |||
<valuelist type="QVariantList" key="Qt4ProjectManager.MakeStep.BuildTargets"/> | |||
<value type="bool" key="Qt4ProjectManager.MakeStep.Clean">true</value> | |||
<value type="QString" key="Qt4ProjectManager.MakeStep.MakeArguments">clean</value> | |||
<value type="QString" key="Qt4ProjectManager.MakeStep.MakeCommand"></value> | |||
<value type="bool" key="Qt4ProjectManager.MakeStep.OverrideMakeflags">false</value> | |||
</valuemap> | |||
<value type="int" key="ProjectExplorer.BuildStepList.StepsCount">1</value> | |||
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">Clean</value> | |||
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName">Clean</value> | |||
<value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">ProjectExplorer.BuildSteps.Clean</value> | |||
</valuemap> | |||
<value type="int" key="ProjectExplorer.BuildConfiguration.BuildStepListCount">2</value> | |||
<value type="bool" key="ProjectExplorer.BuildConfiguration.ClearSystemEnvironment">false</value> | |||
<valuelist type="QVariantList" key="ProjectExplorer.BuildConfiguration.CustomParsers"/> | |||
<valuelist type="QVariantList" key="ProjectExplorer.BuildConfiguration.UserEnvironmentChanges"/> | |||
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName">Profile</value> | |||
<value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">Qt4ProjectManager.Qt4BuildConfiguration</value> | |||
<value type="int" key="Qt4ProjectManager.Qt4BuildConfiguration.BuildConfiguration">0</value> | |||
<value type="int" key="QtQuickCompiler">0</value> | |||
<value type="int" key="SeparateDebugInfo">0</value> | |||
</valuemap> | |||
<value type="int" key="ProjectExplorer.Target.BuildConfigurationCount">3</value> | |||
<valuemap type="QVariantMap" key="ProjectExplorer.Target.DeployConfiguration.0"> | |||
<valuemap type="QVariantMap" key="ProjectExplorer.BuildConfiguration.BuildStepList.0"> | |||
<value type="int" key="ProjectExplorer.BuildStepList.StepsCount">0</value> | |||
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">Deploy</value> | |||
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName">Deploy</value> | |||
<value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">ProjectExplorer.BuildSteps.Deploy</value> | |||
</valuemap> | |||
<value type="int" key="ProjectExplorer.BuildConfiguration.BuildStepListCount">1</value> | |||
<valuemap type="QVariantMap" key="ProjectExplorer.DeployConfiguration.CustomData"/> | |||
<value type="bool" key="ProjectExplorer.DeployConfiguration.CustomDataEnabled">false</value> | |||
<value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">ProjectExplorer.DefaultDeployConfiguration</value> | |||
</valuemap> | |||
<value type="int" key="ProjectExplorer.Target.DeployConfigurationCount">1</value> | |||
<valuemap type="QVariantMap" key="ProjectExplorer.Target.PluginSettings"/> | |||
<valuemap type="QVariantMap" key="ProjectExplorer.Target.RunConfiguration.0"> | |||
<value type="QString" key="Analyzer.Perf.CallgraphMode">dwarf</value> | |||
<valuelist type="QVariantList" key="Analyzer.Perf.Events"> | |||
<value type="QString">cpu-cycles</value> | |||
</valuelist> | |||
<valuelist type="QVariantList" key="Analyzer.Perf.ExtraArguments"/> | |||
<value type="int" key="Analyzer.Perf.Frequency">250</value> | |||
<valuelist type="QVariantList" key="Analyzer.Perf.RecordArguments"> | |||
<value type="QString">-e</value> | |||
<value type="QString">cpu-cycles</value> | |||
<value type="QString">--call-graph</value> | |||
<value type="QString">dwarf,4096</value> | |||
<value type="QString">-F</value> | |||
<value type="QString">250</value> | |||
</valuelist> | |||
<value type="QString" key="Analyzer.Perf.SampleMode">-F</value> | |||
<value type="bool" key="Analyzer.Perf.Settings.UseGlobalSettings">true</value> | |||
<value type="int" key="Analyzer.Perf.StackSize">4096</value> | |||
<value type="bool" key="Analyzer.QmlProfiler.AggregateTraces">false</value> | |||
<value type="bool" key="Analyzer.QmlProfiler.FlushEnabled">false</value> | |||
<value type="uint" key="Analyzer.QmlProfiler.FlushInterval">1000</value> | |||
<value type="QString" key="Analyzer.QmlProfiler.LastTraceFile"></value> | |||
<value type="bool" key="Analyzer.QmlProfiler.Settings.UseGlobalSettings">true</value> | |||
<valuelist type="QVariantList" key="Analyzer.Valgrind.AddedSuppressionFiles"/> | |||
<value type="bool" key="Analyzer.Valgrind.Callgrind.CollectBusEvents">false</value> | |||
<value type="bool" key="Analyzer.Valgrind.Callgrind.CollectSystime">false</value> | |||
<value type="bool" key="Analyzer.Valgrind.Callgrind.EnableBranchSim">false</value> | |||
<value type="bool" key="Analyzer.Valgrind.Callgrind.EnableCacheSim">false</value> | |||
<value type="bool" key="Analyzer.Valgrind.Callgrind.EnableEventToolTips">true</value> | |||
<value type="double" key="Analyzer.Valgrind.Callgrind.MinimumCostRatio">0.01</value> | |||
<value type="double" key="Analyzer.Valgrind.Callgrind.VisualisationMinimumCostRatio">10</value> | |||
<value type="bool" key="Analyzer.Valgrind.FilterExternalIssues">true</value> | |||
<value type="QString" key="Analyzer.Valgrind.KCachegrindExecutable">kcachegrind</value> | |||
<value type="int" key="Analyzer.Valgrind.LeakCheckOnFinish">1</value> | |||
<value type="int" key="Analyzer.Valgrind.NumCallers">25</value> | |||
<valuelist type="QVariantList" key="Analyzer.Valgrind.RemovedSuppressionFiles"/> | |||
<value type="int" key="Analyzer.Valgrind.SelfModifyingCodeDetection">1</value> | |||
<value type="bool" key="Analyzer.Valgrind.Settings.UseGlobalSettings">true</value> | |||
<value type="bool" key="Analyzer.Valgrind.ShowReachable">false</value> | |||
<value type="bool" key="Analyzer.Valgrind.TrackOrigins">true</value> | |||
<value type="QString" key="Analyzer.Valgrind.ValgrindExecutable">valgrind</value> | |||
<valuelist type="QVariantList" key="Analyzer.Valgrind.VisibleErrorKinds"> | |||
<value type="int">0</value> | |||
<value type="int">1</value> | |||
<value type="int">2</value> | |||
<value type="int">3</value> | |||
<value type="int">4</value> | |||
<value type="int">5</value> | |||
<value type="int">6</value> | |||
<value type="int">7</value> | |||
<value type="int">8</value> | |||
<value type="int">9</value> | |||
<value type="int">10</value> | |||
<value type="int">11</value> | |||
<value type="int">12</value> | |||
<value type="int">13</value> | |||
<value type="int">14</value> | |||
</valuelist> | |||
<valuelist type="QVariantList" key="CustomOutputParsers"/> | |||
<value type="int" key="PE.EnvironmentAspect.Base">2</value> | |||
<valuelist type="QVariantList" key="PE.EnvironmentAspect.Changes"/> | |||
<value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">Qt4ProjectManager.Qt4RunConfiguration:/home/michael/modpollData/modpollData.pro</value> | |||
<value type="QString" key="ProjectExplorer.RunConfiguration.BuildKey">/home/michael/modpollData/modpollData.pro</value> | |||
<value type="QString" key="RunConfiguration.Arguments"></value> | |||
<value type="bool" key="RunConfiguration.Arguments.multi">false</value> | |||
<value type="QString" key="RunConfiguration.OverrideDebuggerStartup"></value> | |||
<value type="bool" key="RunConfiguration.UseCppDebugger">false</value> | |||
<value type="bool" key="RunConfiguration.UseCppDebuggerAuto">true</value> | |||
<value type="bool" key="RunConfiguration.UseLibrarySearchPath">true</value> | |||
<value type="bool" key="RunConfiguration.UseMultiProcess">false</value> | |||
<value type="bool" key="RunConfiguration.UseQmlDebugger">false</value> | |||
<value type="bool" key="RunConfiguration.UseQmlDebuggerAuto">true</value> | |||
<value type="QString" key="RunConfiguration.WorkingDirectory"></value> | |||
<value type="QString" key="RunConfiguration.WorkingDirectory.default">/home/michael/modpollData</value> | |||
</valuemap> | |||
<value type="int" key="ProjectExplorer.Target.RunConfigurationCount">1</value> | |||
</valuemap> | |||
</data> | |||
<data> | |||
<variable>ProjectExplorer.Project.TargetCount</variable> | |||
<value type="int">1</value> | |||
</data> | |||
<data> | |||
<variable>ProjectExplorer.Project.Updater.FileVersion</variable> | |||
<value type="int">22</value> | |||
</data> | |||
<data> | |||
<variable>Version</variable> | |||
<value type="int">22</value> | |||
</data> | |||
</qtcreator> |