diff --git a/.gitignore b/.gitignore index 4e1f38f5..0fa14b13 100644 --- a/.gitignore +++ b/.gitignore @@ -249,4 +249,5 @@ pip-log.txt # CMake cmake-build-*/ -unittest-cpp \ No newline at end of file +unittest-cpp +*.opendb diff --git a/examples/QueuedFSM/QueuedFSM.cpp b/examples/QueuedFSM/QueuedFSM.cpp new file mode 100644 index 00000000..f15da447 --- /dev/null +++ b/examples/QueuedFSM/QueuedFSM.cpp @@ -0,0 +1,297 @@ +/****************************************************************************** +The MIT License(MIT) + +Embedded Template Library. +https://github.com/ETLCPP/etl +https://www.etlcpp.com + +Copyright(c) 2020 jwellbelove + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files(the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and / or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions : + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. +******************************************************************************/ + +//***************************************************************************** +// This example demonstrates the basic method to queue messages to an etl::fsm +// derived class. +//***************************************************************************** + +#include "etl/queue.h" +#include "etl/fsm.h" +#include "etl/message_packet.h" + +#include +#include + +//***************************************************************************** +// The messages. +//***************************************************************************** +struct Message1 : public etl::message<1> +{ + Message1(int i_) + : i(i_) + { + } + + int i; +}; + +struct Message2 : public etl::message<2> +{ + Message2(double d_) + : d(d_) + { + } + + double d; +}; + +struct Message3 : public etl::message<3> +{ + Message3(const std::string& s_) + : s(s_) + { + } + + std::string s; +}; + +struct Message4 : public etl::message<4> +{ +}; + +enum +{ + STATE1, + STATE2 +}; + +//***************************************************************************** +// The Finite State Machine. +//***************************************************************************** +class Fsm : public etl::fsm +{ +public: + + //*************************************************************************** + // Constructor. + //*************************************************************************** + Fsm() + : fsm(1) + { + } + + //*************************************************************************** + // The overridden virtual receive function. + //*************************************************************************** + void receive(etl::imessage_router& sender_, const etl::imessage& msg_) + { + if (accepts(msg_)) + { + // Place in queue. + queue.emplace(&sender_, msg_); + + std::cout << "Queueing message " << int(msg_.message_id) << std::endl; + } + else + { + std::cout << "Ignoring message " << int(msg_.message_id) << std::endl; + } + } + + //*************************************************************************** + // The method to call to handle any queued messages. + //*************************************************************************** + void process_queue() + { + while (!queue.empty()) + { + Item& item = queue.front(); + etl::imessage& msg = item.packet.get(); + etl::imessage_router& sender = *item.sender; + std::cout << "Processing message " << int(msg.message_id) << std::endl; + + // Call the base class's receive function. + // This will route it to the correct 'on_event' handler. + etl::fsm::receive(sender, msg); + + queue.pop(); + } + } + +private: + + //*************************************************************************** + // The item to queue. + //*************************************************************************** + struct Item + { + Item(etl::imessage_router* sender_, const etl::imessage& msg_) + : sender(sender_), + packet(msg_) + { + } + + etl::imessage_router* sender; + etl::message_packet< Message1, Message2, Message3> packet; // Defines a packet suitable for all handled messages. + }; + + etl::queue queue; +}; + +//***************************************************************************** +// State 1. +//***************************************************************************** +class State1 : public etl::fsm_state +{ +public: + + //*************************************************************************** + etl::fsm_state_id_t on_enter_state() + { + std::cout << " S1 : Enter" << std::endl; + return STATE1; + } + + //*************************************************************************** + void on_exit_state() + { + std::cout << " S1 : Exit" << std::endl; + } + + //*************************************************************************** + etl::fsm_state_id_t on_event(etl::imessage_router& sender, const Message1& msg) + { + std::cout << " S1 : Received message " << int(msg.message_id) << " : '" << msg.i << "'" << std::endl; + std::cout.flush(); + return STATE1; + } + + //*************************************************************************** + etl::fsm_state_id_t on_event(etl::imessage_router& sender, const Message2& msg) + { + std::cout << " S1 : Received message " << int(msg.message_id) << " : '" << msg.d << "'" << std::endl; + std::cout.flush(); + return STATE1; + } + + //*************************************************************************** + etl::fsm_state_id_t on_event(etl::imessage_router& sender, const Message3& msg) + { + std::cout << " S1 : Received message " << int(msg.message_id) << " : '" << msg.s << "'" << std::endl; + std::cout.flush(); + return STATE1; + } + + //*************************************************************************** + etl::fsm_state_id_t on_event_unknown(etl::imessage_router& sender, const etl::imessage& msg) + { + std::cout << " S1 : Received unknown message " << int(msg.message_id) << std::endl; + std::cout.flush(); + return STATE2; + } +}; + +//***************************************************************************** +// State 2. +//***************************************************************************** +class State2 : public etl::fsm_state +{ +public: + + //*************************************************************************** + etl::fsm_state_id_t on_enter_state() + { + std::cout << " S2 : Enter" << std::endl; + return STATE2; + } + + //*************************************************************************** + void on_exit_state() + { + std::cout << " S2 : Exit" << std::endl; + } + + //*************************************************************************** + etl::fsm_state_id_t on_event(etl::imessage_router& sender, const Message1& msg) + { + std::cout << " S2 : Received message " << int(msg.message_id) << " : '" << msg.i << "'" << std::endl; + return STATE2; + } + + //*************************************************************************** + etl::fsm_state_id_t on_event(etl::imessage_router& sender, const Message2& msg) + { + std::cout << " S2 : Received message " << int(msg.message_id) << " : '" << msg.d << "'" << std::endl; + return STATE2; + } + + //*************************************************************************** + etl::fsm_state_id_t on_event(etl::imessage_router& sender, const Message3& msg) + { + std::cout << " S2 : Received message " << int(msg.message_id) << " : '" << msg.s << "'" << std::endl; + return STATE2; + } + + //*************************************************************************** + etl::fsm_state_id_t on_event_unknown(etl::imessage_router& sender, const etl::imessage& msg) + { + std::cout << " S2 : Received unknown message " << int(msg.message_id) << std::endl; + return STATE1; + } +}; + +//***************************************************************************** +// The test application. +//***************************************************************************** +int main() +{ + Fsm fsm; + + State1 state1; + State2 state2; + + // The list of states. + etl::ifsm_state* state_list[] = { &state1, &state2 }; + + // Define some messages. + Message1 m1(1); + Message2 m2(1.2); + Message3 m3("Hello"); + + // Set up the FSM + fsm.set_states(state_list, 2); + fsm.start(); + + // Queue all of the messages. + etl::send_message(fsm, m1); + etl::send_message(fsm, Message1(2)); + etl::send_message(fsm, m2); + etl::send_message(fsm, Message2(3.4)); + etl::send_message(fsm, m3); + etl::send_message(fsm, Message3("World")); + etl::send_message(fsm, Message4()); + + std::cout << std::endl; + + // De-queue them + fsm.process_queue(); + + return 0; +} + diff --git a/examples/QueuedFSM/vs2017/QueuedFSM.sln b/examples/QueuedFSM/vs2017/QueuedFSM.sln new file mode 100644 index 00000000..ad890d44 --- /dev/null +++ b/examples/QueuedFSM/vs2017/QueuedFSM.sln @@ -0,0 +1,30 @@ + +Microsoft Visual Studio Solution File, Format Version 12.00 +# Visual Studio 15 +VisualStudioVersion = 15.0.26730.10 +MinimumVisualStudioVersion = 10.0.40219.1 +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "QueuedFSM", "QueuedFSM.vcxproj", "{2BB47D48-5EFC-4C38-B2BE-002172F00E3B}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|x64 = Debug|x64 + Debug|x86 = Debug|x86 + Release|x64 = Release|x64 + Release|x86 = Release|x86 + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {2BB47D48-5EFC-4C38-B2BE-002172F00E3B}.Debug|x64.ActiveCfg = Debug|x64 + {2BB47D48-5EFC-4C38-B2BE-002172F00E3B}.Debug|x86.ActiveCfg = Debug|Win32 + {2BB47D48-5EFC-4C38-B2BE-002172F00E3B}.Debug|x86.Build.0 = Debug|Win32 + {2BB47D48-5EFC-4C38-B2BE-002172F00E3B}.Release|x64.ActiveCfg = Release|x64 + {2BB47D48-5EFC-4C38-B2BE-002172F00E3B}.Release|x64.Build.0 = Release|x64 + {2BB47D48-5EFC-4C38-B2BE-002172F00E3B}.Release|x86.ActiveCfg = Release|Win32 + {2BB47D48-5EFC-4C38-B2BE-002172F00E3B}.Release|x86.Build.0 = Release|Win32 + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection + GlobalSection(ExtensibilityGlobals) = postSolution + SolutionGuid = {98B87835-6672-45D4-95BF-CC5C22C87D2C} + EndGlobalSection +EndGlobal diff --git a/examples/QueuedFSM/vs2017/QueuedFSM.vcxproj b/examples/QueuedFSM/vs2017/QueuedFSM.vcxproj new file mode 100644 index 00000000..e103e7a8 --- /dev/null +++ b/examples/QueuedFSM/vs2017/QueuedFSM.vcxproj @@ -0,0 +1,160 @@ + + + + + Debug + Win32 + + + Release + Win32 + + + Debug + x64 + + + Release + x64 + + + + 15.0 + {2BB47D48-5EFC-4C38-B2BE-002172F00E3B} + Win32Proj + QueuedFSM + 10.0.18362.0 + + + + Application + true + v141 + Unicode + + + Application + false + v141 + true + Unicode + + + Application + true + v141 + Unicode + + + Application + false + v141 + true + Unicode + + + + + + + + + + + + + + + + + + + + + true + + + true + + + false + + + false + + + + NotUsing + Level3 + Disabled + WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions) + true + ../../../include;../vs2017 + stdcpp17 + + + Console + true + + + + + NotUsing + Level3 + Disabled + _DEBUG;_CONSOLE;%(PreprocessorDefinitions) + true + ../../../include;../vs2017 + + stdcpp17 + + + Console + true + + + + + Use + Level3 + MaxSpeed + true + true + WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions) + true + + + Console + true + true + true + + + + + Use + Level3 + MaxSpeed + true + true + NDEBUG;_CONSOLE;%(PreprocessorDefinitions) + true + %(AdditionalIncludeDirectories) + + + Console + true + true + true + + + + + + + + + + + + \ No newline at end of file diff --git a/examples/QueuedFSM/vs2017/QueuedFSM.vcxproj.filters b/examples/QueuedFSM/vs2017/QueuedFSM.vcxproj.filters new file mode 100644 index 00000000..7b45b51d --- /dev/null +++ b/examples/QueuedFSM/vs2017/QueuedFSM.vcxproj.filters @@ -0,0 +1,27 @@ + + + + + {4FC737F1-C7A5-4376-A066-2A32D752A2FF} + cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx + + + {93995380-89BD-4b04-88EB-625FBE52EBFB} + h;hh;hpp;hxx;hm;inl;inc;xsd + + + {67DA6AB6-F800-4c08-8B7A-83BB121AAD01} + rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms + + + + + Source Files + + + + + Header Files + + + \ No newline at end of file diff --git a/examples/QueuedFSM/vs2017/etl_profile.h b/examples/QueuedFSM/vs2017/etl_profile.h new file mode 100644 index 00000000..c96719fd --- /dev/null +++ b/examples/QueuedFSM/vs2017/etl_profile.h @@ -0,0 +1,47 @@ +///\file + +/****************************************************************************** +The MIT License(MIT) + +Embedded Template Library. +https://github.com/ETLCPP/etl +https://www.etlcpp.com + +Copyright(c) 2017 jwellbelove + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files(the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and / or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions : + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. +******************************************************************************/ + +#ifndef __ETL_PROFILE_H__ +#define __ETL_PROFILE_H__ + +#define ETL_THROW_EXCEPTIONS +#define ETL_VERBOSE_ERRORS +#define ETL_CHECK_PUSH_POP +#define ETL_ISTRING_REPAIR_ENABLE +#define ETL_IVECTOR_REPAIR_ENABLE +#define ETL_IDEQUE_REPAIR_ENABLE + +#ifdef _MSC_VER + #include "etl/profiles/msvc_x86.h" +#else + #include "etl/profiles/gcc_windows_x86.h" +#endif + +#endif