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 |
<?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> |
<?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> |
/* | |||||
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" |
/* | |||||
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; | |||||
}; | |||||
} |
/* | |||||
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> |
/* | |||||
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; | |||||
}; | |||||
} |
/* | |||||
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; | |||||
}; | |||||
} |
/* | |||||
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; | |||||
} | |||||
}; | |||||
} |
/* | |||||
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; | |||||
}; | |||||
} |
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 |
<?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> |
<?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> |
/* | |||||
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" |
/* | |||||
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; | |||||
}; | |||||
} |
/* | |||||
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> |
/* | |||||
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; | |||||
}; | |||||
} |
/* | |||||
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; | |||||
}; | |||||
} |
/* | |||||
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; | |||||
} | |||||
}; | |||||
} |
/* | |||||
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; | |||||
}; | |||||
} |
//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; | |||||
} |
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 |
<?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> |
#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; | |||||
} |
#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); | |||||
}; |
#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; | |||||
} |
#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(); | |||||
}; | |||||
#include "NetClient.h" |
#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); | |||||
} | |||||
}; | |||||
#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;)"); | |||||
} |
#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&); | |||||
}; | |||||
#pragma once | |||||
enum class PublisherType { | |||||
NA = 0, | |||||
RCMS_BENDER, | |||||
POWERCENTER | |||||
}; |
#pragma once | |||||
#include <iostream> |
* 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" |
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.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 |
#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; | |||||
} |
TEMPLATE = app | |||||
CONFIG += console c++11 | |||||
CONFIG -= app_bundle | |||||
CONFIG -= qt | |||||
SOURCES += \ | |||||
main.cpp | |||||
DISTFILES += \ | |||||
data.txt |
<?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> |