From 4a97988227046642f5ed5e166cee2fe9cf177a05 Mon Sep 17 00:00:00 2001 From: Gustice Date: Sat, 15 Nov 2025 20:57:22 +0100 Subject: [PATCH] refactor: Tidy up SPIT --- components/spit/include/spit_client.hpp | 155 +- components/spit/include/spit_message.hpp | 3 + components/spit/include/spit_player.hpp | 22 +- components/spit/include/spit_processor.hpp | 285 +-- components/spit/src/spit_client.cpp | 692 +------- components/spit/src/spit_processor.cpp | 1568 +++++++---------- components/spit/uTest/spitProcessorTest.cpp | 8 +- .../spit/uTest/spitProcessor_complexTest.cpp | 8 +- core | 2 +- main/watchMain.cpp | 8 +- 10 files changed, 828 insertions(+), 1923 deletions(-) diff --git a/components/spit/include/spit_client.hpp b/components/spit/include/spit_client.hpp index 3c4a22c..90cbf2c 100644 --- a/components/spit/include/spit_client.hpp +++ b/components/spit/include/spit_client.hpp @@ -1,17 +1,16 @@ #pragma once #include "sad_DetectedServer.hpp" +#include "spit_message.hpp" #include "spit_object.hpp" #include "spit_player.hpp" #include "spit_processor.hpp" +#include "spit_repo.hpp" #include "spit_socket.hpp" #include "spit_type.hpp" -#include "spit_message.hpp" -#include "spit_repo.hpp" +#include #include #include -#include -#include "syslog.hpp" using namespace std; @@ -19,53 +18,28 @@ namespace spit { class SClient : ISadClient { public: - /** Maximal length of a SPITMessage*/ - static const int MAXSPITMESSAGEBYTECOUNT = 512; - using Callbacks = SProcessor::Callbacks; using ProjUpdate = SProcessor::ProjUpdate; using ServerEvent = SProcessor::ServerEvent; using ObjectEvent = SProcessor::ObjectEvent; using Connection = SProcessor::Connection; - //------ PlayerType ------ - public: - /** continous main player, time value can be used like a timecode.
The time value is the position in server's project.
A server should use only one main player.*/ - static constexpr char PLAYERTYPE_MAIN = 0x02; - /** continous player. This player plays SPIT objects sometime during the project.*/ - static constexpr char PLAYERTYPE_CONTINOUS = 0x01; - /** diescrete player. This player is used to transmit single discrete values.*/ - static constexpr char PLAYERTYPE_DISCRETE = 0x00; + using PlayerType = SPlayer::PTypes; + using ValueFlags = SPlayer::VFlags; - //------ Value Flag ------ - //------ used by sendRemoteObject - public: - /**Set the given value directly*/ - static constexpr char VALUEFLAG_DIRECT = 0x00; - /**Increase the existing value by the given value.
This is usefull e.g. when instead of a fader a endless wheel is used*/ - static constexpr char VALUEFLAG_INCREASE = 0x01; - /**Decrease the existing value by the given value.
This is usefull e.g. when instead of a fader a endless wheel is used*/ - static constexpr char VALUEFLAG_DECREASE = 0x02; - static constexpr int MAX_OVERTAKING_SPIT_MESSAGES = 10; - - //----- SClient ----- - public: SClient(string name, string projName, ISocket &socket, Callbacks calls); virtual ~SClient(); + private: Callbacks mCallbacks; - fos::TaskT *mThreadReceive{}; fos::TaskT *mThreadProcess{}; bool mStopReceiveMessages{}; Connection mConnectionStatus{Connection::None}; bool mDisconnectedByServer{}; // flag true = when server disconnects - string mID; - string mName; - string mProjName; - string mComputerName; + SProcessor mProcessor; string mClientProjectName; @@ -80,19 +54,13 @@ class SClient : ISadClient { string mServerComputerName{}; int mServerStepTime{-1}; - //--- Server Project --- - string mServerProjectID; - string mServerProjectName; - int mServerFramesPerSecond; - public: /** The ID of the client.
Every client instance should set an unique id*/ - string getID() { return mID; } + string getID() { return mProcessor.getID(); } /** The name of the client, should be set by the user app*/ - string getName() { return mName; } - //----- Computer Params ----- + string getName() { return mProcessor.getName(); } /** The name of the client's host computer*/ - string getComputerName() { return mComputerName; } + string getComputerName() { return mProcessor.getComputerName(); } void setClientProjectName(string clientProjectName) { mClientProjectName = clientProjectName; } string getClientProjectName() { return mClientProjectName; } @@ -117,8 +85,12 @@ class SClient : ISadClient { */ void clientProjectLoaded(); - void setActionSPITType(string spitypeID, bool actionAssigned); - void setActionSPITObject(string objectID, bool actionAssigned); + void setActionType(string spitypeID, bool actionAssigned) { + mProcessor.setActionType(spitypeID, actionAssigned); + } + void setActionObject(string objectID, bool actionAssigned) { + mProcessor.setActionObject(objectID, actionAssigned); + } //--------------- SPITMessage --------------- private: @@ -129,7 +101,7 @@ class SClient : ISadClient { // Reconnect to the server when connection is lost see eventConnectionStatus and eventServerDetected bool _doReconnect{}; // true = on eventServerDetected connect to the server identified by mServerID public: - int sendSPITMessage(Message::OPPart & spitMessageOPPart); + int sendMessage(Message::OPPart &spitMessageOPPart); //--------------- ServerAutoDetection SAD --------------- public: @@ -179,22 +151,13 @@ class SClient : ISadClient { /** Used internally. When the connection to the SPITServer is lost an eventConnectionStatus will occur*/ void eventWatchdogLost(); //--------------- SPIT Project --------------- - private: - void parseReportProject(Message::ReportProject &message); - void parseCloseProject(Message::CloseProject &message); - public: /** Returns the SPITServer's project ID - may be the same as the project's name*/ - string getServerProjectID(); + string getServerProjectID() { return mProcessor.getServerProjectID(); } /** Returns the SPITServer's project name*/ - string getServerProjectName(); + string getServerProjectName() { return mProcessor.getServerProjectName(); } /** Returns frame rate per second. This is the time resolution in which the server transmits time data. The unit of time data is always frames.*/ - int getServerFramesPerSecond(); - - private: - void parseRequestProjectTransfer(Message::RequestProjectTransfer &message); - void parseStartProjectTransfer(Message::StartProjectTransfer &message); - void parseEndProjectTransfer(Message::EndProjectTransfer &message); + int getServerFramesPerSecond() { return mProcessor.getServerFramesPerSecond(); } public: static void sendProject(SClient *p_PtrSClient); @@ -214,76 +177,17 @@ class SClient : ISadClient { */ SType *createTypeFixed(string iD, string groupName, string name, uint64_t defaultDelay, uint64_t defaultDuration); - /** - * Creates a SPITType for application actions.
- * These SPITTypes will be automatically added to the SPITType-List and sended to the server. - * @param p_ID an unique of the SPITType, these are always the same per client approach. Different client approaches should use different ids. - * @param p_GroupName a name which groups the actions/SPITTypes - * @param p_Name the name of the Action/SPITType - * @param p_DefaultDelay maybe there is an default delay until the action starts, this is only used for graphical representations, 0 is allowd - * @param p_DefaultDuration maybe the action has a default duration, this is only used for graphical representations, 0 is allowd - * @param p_Fixed true = the server is not allowed to change this SPITType, false = the server may change or delete this SPITType - * @param p_ProjectIndepended true = the SPITType belongs to a specific project, false = the SpitType always exists for every project - * @return the pointer to the new SPITType. - */ - SType *createType(string iD, string groupName, string name, uint64_t defaultDelay, uint64_t defaultDuration, bool fixed, bool projectIndepended); - - private: - // receive SPIT-Types - void parseReportType(Message::ReportType &message); - void parseRemoveSPITType(Message::RemoveType &message); - int sendSPITTypeInternal(SType &spitType); + public: + bool changeType(SType *spitType) { return mProcessor.changeType(spitType); } + int removeType(string spitypeID) { return mProcessor.removeType(spitypeID); } public: - /** - * If a client wants to change a SPITType, he should send it to the server.
- * If the SPITTye is a fixed one and not created by the client himself, then an eventSPITType can be sent from the server, which cancels the change.
- * @param spitypeID the id of the SPITType to remove. - * @return 0 = is sended, -1 = is not sended - */ - bool changeSPITType(SType *spitType); - /** - * If a client wants to remove a SPITType, he should send it to the server.
- * If the SPITTye is a fixed one and not created by the client himself, then an eventSPITType can be sent from the server, which cancels the deletion.
- * @param spitypeID the id of the SPITType to remove. - * @return 0 = is sended, -1 = is not sended - */ - int removeSPITType(string spitypeID); public: - //--------------- SPIT Objects --------------- - private: - void parseReportSPITObject(Message::ReportObject &message); - void parseRemoveSPITObject(Message::RemoveObject &message); - int sendSPITObjectInternal(SObject *ptrObject); - - public: - /** - * When the client changes a SPITObject (normally the client should not do this), then it should send the changes to the SPITServer.
- * The SPITServer may discard the changes and an eventSPITObject occurs.
- * @param spitObject the pointer to the changed SPITObject. - * @return 0 = sended, -1 = not sended - */ - bool changeSPITObject(SObject *spitObject); - /** - * When the client removes a SPITObject (normally the client should not do this), then he should send it to the SPITServer.
- * The SPITServer may discard the deletion and an eventSPITObject occurs.
- * @param objectID the id of the SPITObject to remove. - * @return 0 = sended, -1 = not sended - */ - int removeSPITObject(string objectID); - - public: - //--------------- Play SPIT Objects --------------- - private: - void parsePlaySPITStart(Message::PlayStart &message); - void parsePlaySPITObject(Message::PlayObject &message); - void parsePlaySPITEnd(Message::PlayEnd &message); - void parseReportPlayStatus(Message::ReportPlayStatus &message); - - public: - //--------- Remote ---------- - void sendRemoteObject(string objectID, int valuePpm = 0, char valueFlag = 0x00); + bool changeObject(SObject *sObject) { return mProcessor.changeObject(sObject); } + void sendRemoteObject(string objectID, int valuePpm = 0, char valueFlag = 0x00) { + mProcessor.sendRemoteObject(objectID, valuePpm, valueFlag); + } private: static void processSocketTask(SClient &instance); @@ -295,9 +199,6 @@ class SClient : ISadClient { void answerWatchdog() { sAnswered = true; } - - SpitRepo mSpitObjects; - SpitRepo mRemoteSpitObjects; }; -} \ No newline at end of file +} // namespace spit \ No newline at end of file diff --git a/components/spit/include/spit_message.hpp b/components/spit/include/spit_message.hpp index b50b44a..7d28095 100644 --- a/components/spit/include/spit_message.hpp +++ b/components/spit/include/spit_message.hpp @@ -14,6 +14,9 @@ namespace spit { class Message { //----------- Header ----------- public: + /** Maximal length of a SPITMessage*/ + static const int MAX_MESSAGE_SIZE = 512; + class Header { public: static constexpr int BYTESLENGTH = 99; diff --git a/components/spit/include/spit_player.hpp b/components/spit/include/spit_player.hpp index eff2ef2..1fb59de 100644 --- a/components/spit/include/spit_player.hpp +++ b/components/spit/include/spit_player.hpp @@ -9,6 +9,24 @@ class SPlayer { //----- PlayObject used in PlaySequences: PlaySPITStart, PlaySPITObject,..., PlaySPITEnd ------ public: + enum PTypes { + // diescrete player: This player is used to transmit single discrete values. + PTYPE_DISCRETE = 0x00, + // continous player: This player plays SPIT objects sometime during the project. + PTYPE_CONTINOUS = 0x01, + // continous main player: time value can be used like a timecode.
The time value is the position in server's project.
A server should use only one main player. + PTYPE_MAIN = 0x02, + }; + + enum VFlags { + // Set the given value directly + VFLAG_DIRECT = 0x00, + // Increase the existing value by the given value.
This is usefull e.g. when instead of a fader a endless wheel is used*/ + VFLAG_INCREASE = 0x01, + // Decrease the existing value by the given value.
This is usefull e.g. when instead of a fader a endless wheel is used*/ + VFLAG_DECREASE = 0x02, + }; + class PlayType { public: PlayType(SPlayer *spitPlayer, string spitObjectID); @@ -43,7 +61,7 @@ class SPlayer { public: // list the SPITPlayers static unordered_map> sSpitPlayers; // all actual played objects - static SPlayer &getSPITPlayer(string pPlayerID); // if a player does not exist creates a new one + static SPlayer &getSPITPlayer(string pPlayerID); // if a player does not exist creates a new one static void clearPlayers() { sSpitPlayers.clear(); } SPlayer(string pPlayerID); @@ -77,4 +95,4 @@ class SPlayer { uint64_t mTimeFrames; }; -} \ No newline at end of file +} // namespace spit \ No newline at end of file diff --git a/components/spit/include/spit_processor.hpp b/components/spit/include/spit_processor.hpp index b168e7c..a0c0c42 100644 --- a/components/spit/include/spit_processor.hpp +++ b/components/spit/include/spit_processor.hpp @@ -16,9 +16,6 @@ namespace spit { class SProcessor { public: - // /** Maximal length of a SPITMessage*/ - // static const int MAXSPITMESSAGEBYTECOUNT = 512; - enum class ProjUpdate { ServerLoaded, StartTransfer, @@ -57,188 +54,71 @@ class SProcessor { }; struct InternalCallbacks { - function sendSpitTypeInternal; + function delay; + function sendMessage; }; - // //------ PlayerType ------ - // public: - // /** continous main player, time value can be used like a timecode.
The time value is the position in server's project.
A server should use only one main player.*/ - // static constexpr char PLAYERTYPE_MAIN = 0x02; - // /** continous player. This player plays SPIT objects sometime during the project.*/ - // static constexpr char PLAYERTYPE_CONTINOUS = 0x01; - // /** diescrete player. This player is used to transmit single discrete values.*/ - // static constexpr char PLAYERTYPE_DISCRETE = 0x00; - - // //------ Value Flag ------ - // //------ used by sendRemoteObject - // public: - // /**Set the given value directly*/ - // static constexpr char VALUEFLAG_DIRECT = 0x00; - // /**Increase the existing value by the given value.
This is usefull e.g. when instead of a fader a endless wheel is used*/ - // static constexpr char VALUEFLAG_INCREASE = 0x01; - // /**Decrease the existing value by the given value.
This is usefull e.g. when instead of a fader a endless wheel is used*/ - // static constexpr char VALUEFLAG_DECREASE = 0x02; - // static constexpr int MAX_OVERTAKING_SPIT_MESSAGES = 10; + static constexpr int MAX_OVERTAKING_SPIT_MESSAGES = 10; //----- SProcessor ----- public: - SProcessor(string name, string projName, string hostName, string guid, - Callbacks calls, InternalCallbacks intern); + SProcessor(string name, string projName, string hostName, string guid, + Callbacks calls, InternalCallbacks intern); virtual ~SProcessor(); private: Callbacks mCallbacks; InternalCallbacks mInternCallbacks; - // Connection mConnectionStatus{Connection::None}; - // bool mDisconnectedByServer{}; // flag true = when server disconnects - string mGuid; string mName; + string mGuid; string mProjName; string mComputerName; // string mClientProjectName; - // uint8_t mMessageNumberSend{1}; - // int mMessageNumberReceived{-1}; // set to -1 because the first received message will set the number (1..255) - // vector> mOvertakingMessages; + uint8_t mMessageNumberSend{1}; + int mMessageNumberReceived{-1}; // set to -1 because the first received message will set the number (1..255) + vector> mOvertakingMessages; // // Server's info filled by parseConnectAnswer - // string mServerID{}; + string mServerID{}; // string mServerName{}; // string mServerComputerName{}; // int mServerStepTime{-1}; // //--- Server Project --- - // string mServerProjectID; - // string mServerProjectName; - // int mServerFramesPerSecond; + string mServerProjectID; + string mServerProjectName; + int mServerFramesPerSecond; - // public: - // /** The ID of the client.
Every client instance should set an unique id*/ - // string getID() { return mGuid; } - // /** The name of the client, should be set by the user app*/ - // string getName() { return mName; } - // //----- Computer Params ----- - // /** The name of the client's host computer*/ - // string getComputerName() { return mComputerName; } - // void setClientProjectName(string clientProjectName) { mClientProjectName = clientProjectName; } - // string getClientProjectName() { return mClientProjectName; } + public: + string getID() { return mGuid; } + string getName() { return mName; } + string getProjName() { return mProjName; } + string getComputerName() { return mComputerName; } + void setActionType(string spitypeID, bool actionAssigned); + void setActionObject(string objectID, bool actionAssigned); + void checkParseMessageData(vector data); + + unique_ptr createConnectMessage(string serverIP, string serverPort, string loginName, string loginPassword); + + std::vector createMessage(Message::OPPart &spitMessageOPPart); + void parseMessage(Message &message); + void addOvertakingMessage(unique_ptr message); + void parseReportProject(Message::ReportProject &message); + void parseCloseProject(Message::CloseProject &message); + + string getServerProjectID() { return mServerProjectID; } + string getServerProjectName() { return mServerProjectName; } + int getServerFramesPerSecond() { return mServerFramesPerSecond; } - // // connected Server Infos - // /** The ID of the connected SPITServer*/ - // string getServerID() { return mServerID; } - // /** The host computername of the connected SPITServer*/ - // string getServerComputerName() { return mServerComputerName; } - // /** The name of the connected SPITServer*/ - // string getServerName() { return mServerName; } - - // /** Expected Refreah Rate of the connectd SPITServer.
- // * When the server plays objects, it will do so at discrete time steps.
- // * Play events will take place in these time steps.. - // */ - // int getServerStepTime() { return mServerStepTime; } - - // /** Should be called when the client wants to close his project*/ - // void clientProjectClose(); - // /** - // * Should be called whenever the client has a project loaded - // */ - // void clientProjectLoaded(); - - // void setActionSPITType(string spitypeID, bool actionAssigned); - // void setActionSPITObject(string objectID, bool actionAssigned); - - // //--------------- SPITMessage --------------- - // private: - // // Reconnect to the server when connection is lost see eventConnectionStatus and eventServerDetected - // bool _doReconnect{}; // true = on eventServerDetected connect to the server identified by mServerID - // public: - // std::vector createMessage(Message::OPPart & spitMessageOPPart); - // void checkParseMessageData(vector data); - - // //--------------- ServerAutoDetection SAD --------------- - // public: - // /** Starts the autodetection of SPITServers in the local network. If a connection is tried, the autodetection should be stopped before.*/ - // void startServerAutoDetect(); - // /** Stops the autodetection of SPITServers in the local network*/ - // void stopServerAutoDetect(); - // /** Called every time a new SPITServer is detetced in the local network */ - // void eventServerDetected(SadDetectedServer &server); - // /** Called every time a prior detected SPITServer is is no longer found.*/ - // void eventServerLost(SadDetectedServer &server); - // void eventServerChanged(SadDetectedServer &server); - - // //--------------- Connection --------------- - // public: - // /** - // * Tries a connection to the SPITServer - // * @param p_ServerIP ip address of the SPITServer - // * @param p_ServerPort port of the SPITServer - // * @param p_ClientIP IP of the client - // * @param p_ClientPort if "0" any free port will be used - // * @param p_LoginName maybe some SPITServer need a login - liveSHOWsoftware will not. - // * @param p_LoginPassword maybe some SPITServer need a login - liveSHOWsoftware will not - // * @return true = the connection try is ok, SPITServer will answer with COnnectAnswer and an eventConnectionStatus will occur.
- // * false = something is going wrong. (client could not bind) - // */ - // bool connect(string serverIP, string serverPort, string clientIP, string clientPort, string loginName = "", string loginPassword = ""); - // /** - // * Terminates the connection to the SPITServer. - // */ - // void disconnect(); - - // private: - // void disconnectInternal(Connection cause); - // void resetMessageNumberReceived(); - // void parseMessage(Message& message); - // void addOvertakingMessage(unique_ptr message); - // void parseConnectAnswer(Message::ConnectAnswer &message); - // void parseDisconnect(Message::Disconnect &message); - // void parseWatchdog(Message::Watchdog &message); - // void parseWatchdogAnswer(Message::WatchdogAnswer &message); - - // public: - // /** Used internally*/ - // void sendWatchdog(); - // /** Used internally. When the connection to the SPITServer is lost an eventConnectionStatus will occur*/ - // void eventWatchdogLost(); - // //--------------- SPIT Project --------------- - // private: - // void parseReportProject(Message::ReportProject &message); - // void parseCloseProject(Message::CloseProject &message); - - // public: - // /** Returns the SPITServer's project ID - may be the same as the project's name*/ - // string getServerProjectID(); - // /** Returns the SPITServer's project name*/ - // string getServerProjectName(); - // /** Returns frame rate per second. This is the time resolution in which the server transmits time data. The unit of time data is always frames.*/ - // int getServerFramesPerSecond(); - - // private: - // void parseRequestProjectTransfer(Message::RequestProjectTransfer &message); - // void parseStartProjectTransfer(Message::StartProjectTransfer &message); - // void parseEndProjectTransfer(Message::EndProjectTransfer &message); - - // public: - // // static void sendProject(SClient *p_PtrSProcessor); + void parseRequestProjectTransfer(Message::RequestProjectTransfer &message); + void parseStartProjectTransfer(Message::StartProjectTransfer &message); + void parseEndProjectTransfer(Message::EndProjectTransfer &message); // // --------------- SPIT Types --------------- // public: - // /** - // * Creates a fixed SPITType for application actions that are always present and project independent.
- // * Fixed SPIT types cannot be changed or deleted by the server.
- // * These SPITTypes will be automatically added to the SPITType-List and sended to the server. - // * @param p_ID an unique of the SPITType, these are always the same per client approach. Different client approaches should use different ids. - // * @param p_GroupName a name which groups the actions/SPITTypes - // * @param p_Name the name of the Action/SPITType - // * @param p_DefaultDelay maybe there is an default delay until the action starts, this is only used for graphical representations, 0 is allowd - // * @param p_DefaultDuration maybe the action has a default duration, this is only used for graphical representations, 0 is allowd - // * @return the pointer to the new SPITType. - // */ - // SType *createTypeFixed(string iD, string groupName, string name, uint64_t defaultDelay, uint64_t defaultDuration); - // /** // * Creates a SPITType for application actions.
// * These SPITTypes will be automatically added to the SPITType-List and sended to the server. @@ -251,75 +131,64 @@ class SProcessor { // * @param p_ProjectIndepended true = the SPITType belongs to a specific project, false = the SpitType always exists for every project // * @return the pointer to the new SPITType. // */ - // SType *createType(string iD, string groupName, string name, uint64_t defaultDelay, uint64_t defaultDuration, bool fixed, bool projectIndepended); - private: -public: // @todo delete - void parseReportType(Message::ReportType &message); - // void parseRemoveSPITType(Message::RemoveType &message); - // int sendSPITTypeInternal(SType &sType); + SType *createType(string iD, string groupName, string name, uint64_t defaultDelay, uint64_t defaultDuration, bool fixed, bool projectIndepended); + int sendTypeInternal(SType &sType); - // public: - // /** - // * If a client wants to change a SPITType, he should send it to the server.
- // * If the SPITTye is a fixed one and not created by the client himself, then an eventSPITType can be sent from the server, which cancels the change.
- // * @param spitypeID the id of the SPITType to remove. - // * @return 0 = is sended, -1 = is not sended - // */ - // bool changeSPITType(SType *spitType); - // /** - // * If a client wants to remove a SPITType, he should send it to the server.
- // * If the SPITTye is a fixed one and not created by the client himself, then an eventSPITType can be sent from the server, which cancels the deletion.
- // * @param spitypeID the id of the SPITType to remove. - // * @return 0 = is sended, -1 = is not sended - // */ - // int removeSPITType(string spitypeID); + private: + public: // @todo delete + void parseReportType(Message::ReportType &message); + void parseRemoveType(Message::RemoveType &message); + + public: + /** + * If a client wants to change a SPITType, he should send it to the server.
+ * If the SPITTye is a fixed one and not created by the client himself, then an eventSPITType can be sent from the server, which cancels the change.
+ * @param spitypeID the id of the SPITType to remove. + * @return 0 = is sended, -1 = is not sended + */ + bool changeType(SType *spitType); + /** + * If a client wants to remove a SPITType, he should send it to the server.
+ * If the SPITTye is a fixed one and not created by the client himself, then an eventSPITType can be sent from the server, which cancels the deletion.
+ * @param spitypeID the id of the SPITType to remove. + * @return 0 = is sended, -1 = is not sended + */ + int removeType(string spitypeID); // public: // //--------------- SPIT Objects --------------- // private: - // void parseReportSPITObject(Message::ReportObject &message); - // void parseRemoveSPITObject(Message::RemoveObject &message); - // int sendSPITObjectInternal(SObject *ptrObject); + public: + void parseReportObject(Message::ReportObject &message); + void parseRemoveObject(Message::RemoveObject &message); + int sendObjectInternal(SObject *sObject); // public: - // /** - // * When the client changes a SPITObject (normally the client should not do this), then it should send the changes to the SPITServer.
- // * The SPITServer may discard the changes and an eventSPITObject occurs.
- // * @param spitObject the pointer to the changed SPITObject. - // * @return 0 = sended, -1 = not sended - // */ - // bool changeSPITObject(SObject *spitObject); - // /** - // * When the client removes a SPITObject (normally the client should not do this), then he should send it to the SPITServer.
- // * The SPITServer may discard the deletion and an eventSPITObject occurs.
- // * @param objectID the id of the SPITObject to remove. - // * @return 0 = sended, -1 = not sended - // */ - // int removeSPITObject(string objectID); + int removeObject(string objectID); + bool changeObject(SObject *sObject); // public: // //--------------- Play SPIT Objects --------------- // private: - // void parsePlaySPITStart(Message::PlayStart &message); - // void parsePlaySPITObject(Message::PlayObject &message); - // void parsePlaySPITEnd(Message::PlayEnd &message); - // void parseReportPlayStatus(Message::ReportPlayStatus &message); + public: + void parsePlayStart(Message::PlayStart &message); + void parsePlayObject(Message::PlayObject &message); + void parsePlayEnd(Message::PlayEnd &message); + void parseReportPlayStatus(Message::ReportPlayStatus &message); // public: // //--------- Remote ---------- - // void sendRemoteObject(string objectID, int valuePpm = 0, char valueFlag = 0x00); + void sendRemoteObject(string objectID, int valuePpm = 0, char valueFlag = 0x00); - // private: - // bool mAbortSearch{}; - // bool sAnswered{}; - // void answerWatchdog() { - // sAnswered = true; - // } + void resetConfirmedFlags() { + SType::setConfirmedFalse(mSpitTypes); + SObject::setConfirmedFalse(mSpitObjects); + } - // SpitRepo mSpitObjects; - // SpitRepo mRemoteSpitObjects; - public: // @todo remove + private: + SpitRepo mSpitObjects; SpitRepo mSpitTypes; + SpitRepo mRemoteSpitObjects; SpitRepo mRemoteSpitTypes; }; diff --git a/components/spit/src/spit_client.cpp b/components/spit/src/spit_client.cpp index f0963ca..5e09db1 100644 --- a/components/spit/src/spit_client.cpp +++ b/components/spit/src/spit_client.cpp @@ -16,16 +16,13 @@ static fos::Queue> incommingSpit(128); SClient::SClient(string name, string projName, ISocket &socket, Callbacks calls) : ISadClient(), mCallbacks(calls), - mName(name), - mProjName(projName), mProcessor(name, projName, getClientHostName(), createGUID(), calls, { - .sendSpitTypeInternal = [&](SType &sType) { return sendSPITTypeInternal(sType);} + .delay = [&](int ms){ return fos::Task::delayMs(ms); }, + .sendMessage = [&](Message::OPPart &msg){ return sendMessage(msg); }, } ), - mSocket(socket) { - mID = createGUID(); - mComputerName = getClientHostName(); + mSocket(socket) { } SClient::~SClient() { @@ -36,8 +33,8 @@ SClient::~SClient() { void SClient::clientProjectClose() { if (mConnectionStatus == Connection::Ok) { ESP_LOGI(TAG, " ... tidy up ressources"); - Message::CloseProject closeSPITProject(mProjName); - if (sendSPITMessage(closeSPITProject) < 0) { + Message::CloseProject closeSPITProject(mProcessor.getProjName()); + if (sendMessage(closeSPITProject) < 0) { ESP_LOGD(TAG, "Client could not send Client's ReportProject"); } } @@ -45,58 +42,23 @@ void SClient::clientProjectClose() { void SClient::clientProjectLoaded() { // set confirmed = false for all SPITTypes and SPITObjects - SType::setConfirmedFalse(mProcessor.mSpitTypes); - SObject::setConfirmedFalse(mSpitObjects); - + mProcessor.resetConfirmedFlags(); if (mConnectionStatus == Connection::Ok) { // send ReportProject to the server - Message::ReportProject reportSPITProject(mProjName, mProjName); + Message::ReportProject reportSPITProject(mProcessor.getProjName(), mProcessor.getProjName()); reportSPITProject.setFramesPerSecond(0); - if (sendSPITMessage(reportSPITProject) < 0) { + if (sendMessage(reportSPITProject) < 0) { ESP_LOGD(TAG, "SPIT_CLient::clientProjectLoaded could not send Client's ReportProject"); } // send RequestProjectTransfer Message::RequestProjectTransfer sMRequestProjectTransfer; - if (sendSPITMessage(sMRequestProjectTransfer) < 0) { + if (sendMessage(sMRequestProjectTransfer) < 0) { ESP_LOGD(TAG, "SPIT_CLient::clientProjectLoaded could not send RequestProjectTransfer"); } } } -/** - * Virtual construct - means actionAssigned for SPITTypes is is not implemented in SPITProtocol. - * This can used to setActionAssigned to all SPITObjects with this SPITType. - * This may be used in the case when the same action should be done for every SPITObject with this SPITType associated. - * This tells the server not what action is done, but it tells the server that there is an action. - * @param typeId the id of the SPITType - * @param actionAssigned - */ -void SClient::setActionSPITType(string typeId, bool actionAssigned) { - SType *spitType = mProcessor.mSpitTypes.getEntry(typeId); - if (spitType == nullptr) - return; - if (spitType->ActionAssigned.set(actionAssigned)) { - sendSPITTypeInternal(*spitType); - for (auto& [key, value] : mSpitObjects.getRepo()) { - if (value->SPITTypeID.get() == spitType->getID()) { - if (value->setActionAssignedType(actionAssigned) == true) { - sendSPITObjectInternal(value.get()); - } - } - } - } -} - -/** This should be called if the user wants to associate/remove an action with a SPITObject. */ -void SClient::setActionSPITObject(string spitObjId, bool actionAssigned) { - SObject *spitObject = mSpitObjects.getEntry(spitObjId); - if (spitObject == nullptr) - return; - if (spitObject->setActionAssigned(actionAssigned) == true) { - sendSPITObjectInternal(spitObject); - } -} //---------- ServerAutoDetection SAD ----------- /** Starts the autodetection of SPITServers in the local network. If a connection is tried, the autodetection should be stopped before. @@ -205,13 +167,13 @@ void SClient::eventServerChanged(SadDetectedServer &server) { // // } //Excample // } -int SClient::sendSPITMessage(Message::OPPart &opPart) { +int SClient::sendMessage(Message::OPPart &opPart) { if (mMessageNumberSend == 255) mMessageNumberSend = 1; else mMessageNumberSend++; opPart.setMessageNumber(mMessageNumberSend); - opPart.setServerInfoInHeader(mID, mServerID); + opPart.setServerInfoInHeader(mProcessor.getID(), mServerID); int opFlag = opPart.getHeader()->getType(); try { @@ -244,10 +206,10 @@ void SClient::stopReceiveSPITMessages() { } void SClient::receiveSpitMessage(SClient &rM) { - char buffer[MAXSPITMESSAGEBYTECOUNT + 1]; + char buffer[Message::MAX_MESSAGE_SIZE]; int rdLen; while (rM.mStopReceiveMessages == false) { - rdLen = rM.mSocket.receiveMessage(buffer, MAXSPITMESSAGEBYTECOUNT, nullptr); + rdLen = rM.mSocket.receiveMessage(buffer, Message::MAX_MESSAGE_SIZE, nullptr); if (rdLen < 0) { if (rM.mStopReceiveMessages) { return; @@ -281,14 +243,14 @@ void SClient::checkParseMessage(unique_ptr p_SPITMessage) { return; } - int intActualMessageNumber = (int)(p_SPITMessage->getHeader()->getMessageNumber() & 0xFF); + int msgNum = (int)(p_SPITMessage->getHeader()->getMessageNumber() & 0xFF); - if (intActualMessageNumber == 0) { + if (msgNum == 0) { parseMessage(std::move(p_SPITMessage)); return; } if (mMessageNumberReceived < 0) { - mMessageNumberReceived = intActualMessageNumber; + mMessageNumberReceived = msgNum; parseMessage(std::move(p_SPITMessage)); return; } @@ -297,8 +259,8 @@ void SClient::checkParseMessage(unique_ptr p_SPITMessage) { if (intNextMessageNumber > 255 || intNextMessageNumber < 1) intNextMessageNumber = 1; - if (intActualMessageNumber == intNextMessageNumber) { - mMessageNumberReceived = intActualMessageNumber; + if (msgNum == intNextMessageNumber) { + mMessageNumberReceived = msgNum; parseMessage(std::move(p_SPITMessage)); // check overtaking messages @@ -310,10 +272,10 @@ void SClient::checkParseMessage(unique_ptr p_SPITMessage) { intNextMessageNumber = 1; auto &ptrOvertakingSPIT_Message = *it; - intActualMessageNumber = (int)(ptrOvertakingSPIT_Message->getHeader()->getMessageNumber() & 0xFF); + msgNum = (int)(ptrOvertakingSPIT_Message->getHeader()->getMessageNumber() & 0xFF); - if (intActualMessageNumber == intNextMessageNumber) { - mMessageNumberReceived = intActualMessageNumber; + if (msgNum == intNextMessageNumber) { + mMessageNumberReceived = msgNum; parseMessage(move(ptrOvertakingSPIT_Message)); mOvertakingMessages.erase(it); @@ -333,7 +295,7 @@ void SClient::addOvertakingMessage(unique_ptr message) { if (!message) { return; } - if (mOvertakingMessages.size() > MAX_OVERTAKING_SPIT_MESSAGES) { + if (mOvertakingMessages.size() > mProcessor.MAX_OVERTAKING_SPIT_MESSAGES) { ESP_LOGD(TAG, "Client receiveing: perhaps message lost !!!!!"); } @@ -365,7 +327,7 @@ void SClient::parseMessage(unique_ptr message) { parseDisconnect(message->getAs()); break; case Message::ReportProject::OPFLAG: - parseReportProject(message->getAs()); + mProcessor.parseReportProject(message->getAs()); break; case Message::Watchdog::OPFLAG: parseWatchdog(message->getAs()); @@ -375,43 +337,43 @@ void SClient::parseMessage(unique_ptr message) { break; //----- SPIT Project ----- case Message::StartProjectTransfer::OPFLAG: - parseStartProjectTransfer(message->getAs()); + mProcessor.parseStartProjectTransfer(message->getAs()); break; case Message::CloseProject::OPFLAG: - parseCloseProject(message->getAs()); + mProcessor.parseCloseProject(message->getAs()); break; case Message::RequestProjectTransfer::OPFLAG: - parseRequestProjectTransfer(message->getAs()); + mProcessor.parseRequestProjectTransfer(message->getAs()); break; case Message::EndProjectTransfer::OPFLAG: - parseEndProjectTransfer(message->getAs()); + mProcessor.parseEndProjectTransfer(message->getAs()); break; //----- SPIT Types ------ case Message::ReportType::OPFLAG: mProcessor.parseReportType(message->getAs()); break; case Message::RemoveType::OPFLAG: - parseRemoveSPITType(message->getAs()); + mProcessor. parseRemoveType(message->getAs()); //----- SPIT Objects ------ break; case Message::ReportObject::OPFLAG: - parseReportSPITObject(message->getAs()); + mProcessor.parseReportObject(message->getAs()); break; case Message::RemoveObject::OPFLAG: - parseRemoveSPITObject(message->getAs()); + mProcessor.parseRemoveObject(message->getAs()); break; //----- Play SPIT Objects ------ case Message::PlayStart::OPFLAG: - parsePlaySPITStart(message->getAs()); + mProcessor.parsePlayStart(message->getAs()); break; case Message::PlayObject::OPFLAG: - parsePlaySPITObject(message->getAs()); + mProcessor.parsePlayObject(message->getAs()); break; case Message::PlayEnd::OPFLAG: - parsePlaySPITEnd(message->getAs()); + mProcessor.parsePlayEnd(message->getAs()); break; case Message::ReportPlayStatus::OPFLAG: - parseReportPlayStatus(message->getAs()); + mProcessor.parseReportPlayStatus(message->getAs()); break; default: ESP_LOGD(TAG, "Client::parseMessage: Unknown Message"); @@ -436,15 +398,8 @@ bool SClient::connect(string serverIP, string serverPort, string clientIP, strin mStopReceiveMessages = true; return false; } - Message::Connect sMConnect(mComputerName, mName); - sMConnect.setLoginName(loginName); - sMConnect.setLoginPassword(loginPassword); - sMConnect.setServerIP(serverIP); - if (serverPort.length() <= 0) { - serverPort = "0"; - } - int intServerPort = stoi(serverPort); - sMConnect.setServerPort(intServerPort); + + auto connMsg = mProcessor.createConnectMessage(serverIP, serverPort, loginName, loginPassword); if (startReceiveSPITMessages() == false) { mStopReceiveMessages = true; @@ -459,7 +414,7 @@ bool SClient::connect(string serverIP, string serverPort, string clientIP, strin // sleep a little to make sure that the reception of the messages is started fos::Task::delayMs(500); - if (sendSPITMessage(sMConnect) < 0) { + if (sendMessage(*connMsg) < 0) { mConnectionStatus = Connection::None; mStopReceiveMessages = true; return false; @@ -483,7 +438,7 @@ void SClient::disconnectInternal(Connection cause) { break; case Connection::None: { Message::Disconnect sMDisconnect; - sendSPITMessage(sMDisconnect); + sendMessage(sMDisconnect); } break; case Connection::NoneServer: break; @@ -505,7 +460,7 @@ void SClient::disconnectInternal(Connection cause) { ESP_LOGD(TAG, "connection terminated by server"); // call eventProjectClosed because this may not be sended by the server, // when the connection is closed - mCallbacks.onProjectUpdate(ProjUpdate::ServerClosed, mServerProjectID); + mCallbacks.onProjectUpdate(ProjUpdate::ServerClosed, mProcessor.getServerProjectID()); // Server has terminated the connection -> start a new game // _doReconnect = false; @@ -525,7 +480,7 @@ void SClient::disconnectInternal(Connection cause) { } void SClient::parseConnectAnswer(Message::ConnectAnswer &message) { - if (message.getClientID() != mID) + if (message.getClientID() != mProcessor.getID()) return; mServerID = message.getServerID(); @@ -574,7 +529,7 @@ void SClient::parseDisconnect(Message::Disconnect &message) { void SClient::parseWatchdog(Message::Watchdog &message) { // ESP_LOGD(TAG, "parse Watchdog "); Message::WatchdogAnswer o_WatchdogAnswer; - sendSPITMessage(o_WatchdogAnswer); + sendMessage(o_WatchdogAnswer); } /** * The SPIT server sends a watchdog message at regular intervals. The client responds immediately with WatchdogAnswer @@ -588,7 +543,7 @@ void SClient::parseWatchdogAnswer(Message::WatchdogAnswer &message) { void SClient::sendWatchdog() { int intResult; Message::Watchdog message; - intResult = sendSPITMessage(message); + intResult = sendMessage(message); if (intResult < 0) { ESP_LOGW("WDT", "Failed to send Watchdog msg"); } @@ -601,130 +556,6 @@ void SClient::eventWatchdogLost() { } } -//----- SPIT Project ------ -void SClient::parseReportProject(Message::ReportProject &message) { - ESP_LOGD(TAG, "parse ReportProject"); - mServerProjectID = message.getProjectID(); - mServerProjectName = message.getProjectName(); - mServerFramesPerSecond = message.getFramesPerSecond(); - mCallbacks.onProjectUpdate(ProjUpdate::ServerLoaded, mServerProjectID); - - // Set all SPITTypes and SPITObjects confirmed = false - SType::setConfirmedFalse(mProcessor.mSpitTypes); - SObject::setConfirmedFalse(mSpitObjects); - - // Send RequestProjectTransfer - Message::RequestProjectTransfer sMRequestProjectTransfer; - if (sendSPITMessage(sMRequestProjectTransfer) < 0) { - ESP_LOGD(TAG, "Client::parseReportProject could not send RequestProjectTransfer"); - } - - // todo Don't send the ReportProject here it should be sended after parseEndProjectTransfer - // Send client's ReportProject - Message::ReportProject reportProject(mProjName, mProjName); - reportProject.setFramesPerSecond(0); - if (sendSPITMessage(reportProject) < 0) { - ESP_LOGD(TAG, "Client::parseReportProject could not send Client's ReportProject"); - } -} -void SClient::parseCloseProject(Message::CloseProject &p_CloseSPITProject) { - ESP_LOGD(TAG, "parse CloseProject"); - string stringProjectID; - mCallbacks.onProjectUpdate(ProjUpdate::ServerClosed, p_CloseSPITProject.getProjectID()); - SPlayer::clearPlayers(); -} - -string SClient::getServerProjectID() { return mServerProjectID; } -string SClient::getServerProjectName() { return mServerProjectName; } -int SClient::getServerFramesPerSecond() { return mServerFramesPerSecond; } - -void SClient::parseRequestProjectTransfer(Message::RequestProjectTransfer &message) { - ESP_LOGD(TAG, "parse RequestProjectTransfer"); - // StartProjectTransfer - Message::StartProjectTransfer sMStartProjectTransfer; - if (sendSPITMessage(sMStartProjectTransfer) < 0) { - return; - } - - // send all listes SPITTypes - for (const auto& [key, value] : mProcessor.mSpitTypes.getRepo()) { - sendSPITTypeInternal(*value); - fos::Task::delayMs(10); - } - for (auto& [key, value] : mSpitObjects.getRepo()) { - sendSPITObjectInternal(value.get()); - fos::Task::delayMs(10); - } - - // EndProjectTransfer - Message::EndProjectTransfer sMEndProjectTransfer; - sendSPITMessage(sMEndProjectTransfer); -} - -/* NEW IMPLEMENTATION - -void SClient::parseRequestProjectTransfer(Message::RequestProjectTransfer* message) { -// ESP_LOGD(TAG, "parse RequestProjectTransfer"); - thread* o_ThreadSend; - o_ThreadSend = new thread(&this->sendProject, this); - // int intResult; - // Message::StartProjectTransfer* ptrSMStartProjectTransfer; - // Message::EndProjectTransfer* ptrSMEndProjectTransfer; - // int intCount; - // SPITType* ptrSPITType; - // SObject* ptrSPITObject; - - - // //StartProjectTransfer - // NotifyStartProjectTransfer_Client* o_RunnableStart = new NotifyStartProjectTransfer_Client(mSPITClientInterface); - // SPIT_Handler::addRunnable(o_RunnableStart); - - // ptrSMStartProjectTransfer = new Message::StartProjectTransfer(); - // intResult = sendSPITMessage(ptrSMStartProjectTransfer); - // if (intResult < 0) { - // return; - // } - // mWatchdog->answerWatchdog(); - // { - // //send all listes SPITTypes - // unique_lock o_LockType(*SPITType::getMutex()); - // intCount = SPITType::getSPITTypeCount(); - // for (int i = 0; i < intCount; i++) { - // ptrSPITType = mSpitTypes.getEntry(i); - // if (ptrSPITType == nullptr) continue; - // intResult = sendSPITTypeInternal(ptrSPITType); - // if (intResult < 0) return; - // mWatchdog->answerWatchdog(); - // this_thread::sleep_for(chrono::milliseconds(7)); - // } - // } - - // { - // unique_lock o_LockObject(*SObject::getMutex()); - // intCount = mSpitObjects.getEntryCount(); - // for (int i = 0; i < intCount; i++) { - // ptrSPITObject = mSpitObjects.getEntry(i); - // if (ptrSPITObject == nullptr) continue; - // intResult = sendSPITObjectInternal(ptrSPITObject); - // if (intResult < 0) return; - // mWatchdog->answerWatchdog(); - // this_thread::sleep_for(chrono::milliseconds(7)); - // } - // } - - // //EndProjectTransfer - // ptrSMEndProjectTransfer = new Message::EndProjectTransfer(); - // intResult = sendSPITMessage(ptrSMEndProjectTransfer); - // if (intResult < 0) { - // return; - // } - // mWatchdog->answerWatchdog(); - // NotifyEndProjectTransfer_Client* o_RunnableEnd = new NotifyEndProjectTransfer_Client(mSPITClientInterface); - // SPIT_Handler::addRunnable(o_RunnableEnd); - - // //Send act -} -*/ void SClient::sendProject(SClient *p_PtrSPIT_Client) { // int intResult; @@ -739,7 +570,7 @@ void SClient::sendProject(SClient *p_PtrSPIT_Client) { // SPIT_Handler::addRunnable(o_RunnableStart); // ptrSMStartProjectTransfer = new Message::StartProjectTransfer(); - // intResult = p_PtrSPIT_Client->sendSPITMessage(ptrSMStartProjectTransfer); + // intResult = p_PtrSPIT_Client->sendMessage(ptrSMStartProjectTransfer); // if (intResult < 0) { // return; // } @@ -753,7 +584,7 @@ void SClient::sendProject(SClient *p_PtrSPIT_Client) { // ptrSPITType = mSpitTypes.getEntry(i); // if (ptrSPITType == nullptr) continue; // if (ptrSPITType->getCreatedByClient() == false) continue; - // intResult = p_PtrSPIT_Client->sendSPITTypeInternal(ptrSPITType); + // intResult = p_PtrSPIT_Client->sendTypeInternal(ptrSPITType); // if (intResult < 0) return; // // mWatchdog->answerWatchdog(); // this_thread::sleep_for(chrono::milliseconds(7)); @@ -767,7 +598,7 @@ void SClient::sendProject(SClient *p_PtrSPIT_Client) { // ptrSPITObject = mSpitObjects.getEntry(i); // if (ptrSPITObject == nullptr) continue; // if (ptrSPITObject->getCreatedByClient() == false) continue; - // intResult = p_PtrSPIT_Client->sendSPITObjectInternal(ptrSPITObject); + // intResult = p_PtrSPIT_Client->sendObjectInternal(ptrSPITObject); // if (intResult < 0) return; // // mWatchdog->answerWatchdog(); // this_thread::sleep_for(chrono::milliseconds(7)); @@ -776,7 +607,7 @@ void SClient::sendProject(SClient *p_PtrSPIT_Client) { // //EndProjectTransfer // ptrSMEndProjectTransfer = new Message::EndProjectTransfer(); - // intResult = p_PtrSPIT_Client->sendSPITMessage(ptrSMEndProjectTransfer); + // intResult = p_PtrSPIT_Client->sendMessage(ptrSMEndProjectTransfer); // if (intResult < 0) { // return; // } @@ -787,433 +618,8 @@ void SClient::sendProject(SClient *p_PtrSPIT_Client) { // //Send act } -void SClient::parseStartProjectTransfer(Message::StartProjectTransfer &message) { - mCallbacks.onProjectUpdate(ProjUpdate::StartTransfer, mServerProjectID); -} -void SClient::parseEndProjectTransfer(Message::EndProjectTransfer &message) { - SObject::clearUnconfirmedObjects(mSpitObjects); - mCallbacks.onProjectUpdate(ProjUpdate::EndTransfer, mServerProjectID); - - // Send Message::ReportProject after the mSPITClientInterface is notfied of EndProjectTransfer - Message::ReportProject reportSPITProject(mProjName, mProjName); - reportSPITProject.setFramesPerSecond(0); - if (sendSPITMessage(reportSPITProject) < 0) { - ESP_LOGD(TAG, "Client::parseReportProject could not send Client's ReportProject"); - } -} - -void SClient::parseRemoveSPITType(Message::RemoveType &message) { - ESP_LOGD(TAG, "parse RemoveType %s", message.getID().c_str()); - bool boolRemote = false; - string stringSPITTypeID = message.getID(); - - SType *ptrSPITType = mProcessor.mRemoteSpitTypes.getEntry(stringSPITTypeID); - if (!ptrSPITType) { - boolRemote = true; - } else { - ptrSPITType = mProcessor.mSpitTypes.getEntry(stringSPITTypeID); - if (!ptrSPITType) { - boolRemote = false; - } else { - // No SPITType with stringSPITTypeID is listet - return; - } - } - - if (ptrSPITType->getCreatedByClient() && ptrSPITType->Fixed.get()) { - // the SPITyte is created by client himself and it is fixed -> don't remove the SPITType!! - // Send the SPITTyp back to the server - sendSPITTypeInternal(*ptrSPITType); - return; - } - - mCallbacks.onSpitType(ObjectEvent::Deleted, boolRemote, *ptrSPITType); - if (boolRemote == false) { - mProcessor.mSpitTypes.removeEntry(*ptrSPITType); - } else { - mProcessor.mRemoteSpitTypes.removeEntry(*ptrSPITType); - } -} - -/** - * If a client has changed a SPITType, it should send it to the server to transmit the changes. - * If the SPITType is a fixed one and not created by the client himself, then an eventSPITType can be sent from the server, which cancels the changes. - * @param p_SPITType the pointer to the changed SPITType - * @return 0 = is sended, -1 = is not sended - */ -int SClient::sendSPITTypeInternal(SType &p_SPITType) { - Message::ReportType sMReportSPITType; - p_SPITType.fillMessageOP(sMReportSPITType); - return sendSPITMessage(sMReportSPITType); -} - -/** - * Change an existing SPIT_Type. - * @param p_SPITType the SPITType vont - * @return true = changed, false = not changed maybe p_SPITType is NULL or the SPITType doesn't exists - */ -bool SClient::changeSPITType(SType *p_SPITType) { - if (p_SPITType == nullptr) - return false; - SType *ptrSPITType = mProcessor.mSpitTypes.getEntry(p_SPITType->getID()); - if (ptrSPITType == nullptr) - return false; - - ptrSPITType->DefaultDelay.set(p_SPITType->DefaultDelay.get()); - ptrSPITType->DefaultDuration.set(p_SPITType->DefaultDuration.get()); - ptrSPITType->Fixed.set(p_SPITType->Fixed.get()); - ptrSPITType->GroupName.set(p_SPITType->GroupName.get()); - ptrSPITType->Name.set(p_SPITType->Name.get()); - ptrSPITType->ProjectIndepended.set(p_SPITType->ProjectIndepended.get()); - - mCallbacks.onSpitType(ObjectEvent::Changed, false, *ptrSPITType); - sendSPITTypeInternal(*ptrSPITType); - - return true; -} - -/** - * If a client has removed a SPITType where id == p_SPITTypeID, it should send it to the server. - * The corresponding SPITType if listet in SPITType will be deleted. - * An eventRemoveSPITType will occur. - * If a connection to a SPITServer is established, the SPITServer may dicard the deletion an an eventSPITType will occur - * -> the SPITType will be listet again. - * @param p_SPITType the id of the SPITType ro remove - * @return 0 = is sended, -1 = is not sended - */ -int SClient::removeSPITType(string p_SPITTypeID) { - if (p_SPITTypeID.length() <= 0) - return -1; - SType *ptrSPITType; - { - ptrSPITType = mProcessor.mSpitTypes.getEntry(p_SPITTypeID); - if (ptrSPITType == nullptr) - return -1; - Message::RemoveType sMRemoveSPITType; - ptrSPITType->fillMessageOP(sMRemoveSPITType); - mCallbacks.onSpitType(ObjectEvent::Deleted, false, *ptrSPITType); - mProcessor.mSpitTypes.removeEntry(*ptrSPITType); - return sendSPITMessage(sMRemoveSPITType); - } - return -1; -} - -SType *SClient::createTypeFixed(string iD, string p_GroupName, string p_Name, uint64_t p_DefaultDelay, uint64_t p_DefaultDuration) { - return createType(iD, p_GroupName, p_Name, p_DefaultDelay, p_DefaultDuration, true, true); -} - -SType *SClient::createType(string p_ID, string p_GroupName, string p_Name, uint64_t p_DefaultDelay, uint64_t p_DefaultDuration, bool p_FIxed, bool p_ProjectIndepended) { - bool boolNew; - SType *ptrSPITType = mProcessor.mSpitTypes.getEntry(p_ID); - if (ptrSPITType == nullptr) { - auto spitType = make_unique(p_ID, p_GroupName, p_Name, p_FIxed, p_ProjectIndepended, p_DefaultDelay, p_DefaultDuration); - ptrSPITType = spitType.get(); - mProcessor.mSpitTypes.addEntry(move(spitType)); - ptrSPITType->setCreatedByClient(true); - boolNew = true; - } else { - ptrSPITType->GroupName.set(p_GroupName); - ptrSPITType->Name.set(p_Name); - ptrSPITType->Fixed.set(p_FIxed); - ptrSPITType->ProjectIndepended.set(p_ProjectIndepended); - ptrSPITType->DefaultDelay.set(p_DefaultDelay); - ptrSPITType->DefaultDuration.set(p_DefaultDuration); - boolNew = false; - } - - auto eventType = boolNew ? ObjectEvent::Created : ObjectEvent::Changed; - mCallbacks.onSpitType(eventType, false, *ptrSPITType); - sendSPITTypeInternal(*ptrSPITType); - return ptrSPITType; -} - -//----- SPIT Objects ------ -void SClient::parseReportSPITObject(Message::ReportObject &message) { - ESP_LOGD(TAG, "parse ReportObject %s", message.getID().c_str()); - SObject *ptrSPITObject; - SType *ptrSPITType; - bool boolNew = false; - bool boolRemote = false; - bool boolChanged = false; - { - ESP_LOGD(TAG, "parse ReportObject %s / %s", message.getID().c_str(), message.getName().c_str()); - if (message.getServerRemote() == false) { - boolRemote = false; - ptrSPITObject = mSpitObjects.getEntry(message.getID()); - ptrSPITType = mProcessor.mSpitTypes.getEntry(message.getSPITTypeID()); - - if (ptrSPITType == nullptr) { - // No associated SPITType found - if (ptrSPITObject != nullptr) { - // SpitObject exists but has no corresponding SPITType -> remove the SPITObject without sending a message - // Maybe the SPITObject has changed the SPITTypeID to a SPITTypeID of another board - mSpitObjects.removeEntry(*ptrSPITObject); - } - return; - } - bool isKnownType = ptrSPITType != nullptr; - if (ptrSPITObject == nullptr) { - // The user's app my veto the SPITType - if (mCallbacks.onCheckSpitObjectVeto(isKnownType) == false) { - ESP_LOGW(TAG, "ObjectVeto %s / %s", message.getID().c_str(), message.getName().c_str()); - return; - } - auto spitObj = make_unique(message.getID()); - ptrSPITObject = spitObj.get(); - mSpitObjects.addEntry(move(spitObj)); - boolNew = true; - } else { - // The user's app my veto the SPITType - if (mCallbacks.onCheckSpitObjectVeto(isKnownType) == false) { - // SpitObject exists and User APp denied the SPITObject -> remove the SPITObject without sending a message - mSpitObjects.removeEntry(*ptrSPITObject); - ESP_LOGW(TAG, "TypeVeto %s / %s", message.getID().c_str(), message.getName().c_str()); - return; - } - } - } else { - boolRemote = true; - ptrSPITObject = mRemoteSpitObjects.getEntry(message.getID()); - ptrSPITType = mProcessor.mRemoteSpitTypes.getEntry(message.getSPITTypeID()); - if (ptrSPITType == nullptr) { - // No associated SPITType found - return; - } - if (ptrSPITObject == nullptr) { - auto spitObj = make_unique(message.getID()); - ptrSPITObject = spitObj.get(); - mRemoteSpitObjects.addEntry(move(spitObj)); - boolNew = true; - } - } - - if (!ptrSPITObject->setMessageOP(&message)) { - ESP_LOGE(TAG, "Change not allowed"); - // setMessageOP error - the SPITObject can't be changed, it may be fixed and crated by this client - sendSPITObjectInternal(ptrSPITObject); - return; - } - - if (boolRemote == false) { - // set the virtual action assignment - ptrSPITObject->setActionAssignedType(ptrSPITType->ActionAssigned.get()); - } - - auto eventType = boolNew ? ObjectEvent::Created : ObjectEvent::Changed; - mCallbacks.onSpitObject(eventType, boolRemote, *ptrSPITType, *ptrSPITObject); - - if (ptrSPITObject->setConfirmed(true) == true || boolChanged == true) { - // Confirmation has changed - sendSPITObjectInternal(ptrSPITObject); - } - } -} -void SClient::parseRemoveSPITObject(Message::RemoveObject &message) { - ESP_LOGD(TAG, "parse RemoveObject %s", message.getID().c_str()); - SObject *ptrSPITObject = mRemoteSpitObjects.getEntry(message.getID()); - if (ptrSPITObject != nullptr) { - SType *ptrSPITType = mProcessor.mRemoteSpitTypes.getEntry(ptrSPITObject->SPITTypeID.get()); - if (ptrSPITType != nullptr) { - mCallbacks.onSpitObject(ObjectEvent::Deleted, true, *ptrSPITType, *ptrSPITObject); - } - mRemoteSpitObjects.removeEntry(*ptrSPITObject); - } else { - // call removeSPITObject, this will notify the server that the object is removed - removeSPITObject(message.getID()); - } -} - -int SClient::sendSPITObjectInternal(SObject *ptrSPITObject) { - if (ptrSPITObject == nullptr) - return -1; - Message::ReportObject sMReportSPITObject; - ptrSPITObject->fillMessageOP(sMReportSPITObject); - - return sendSPITMessage(sMReportSPITObject); -} -/** - * When the client changes an existing SPITObject (normally the client should not do this), then he should send the changes to the SPITServer. - * An eventSPITObject occurs. - * The SPITServer may discard the changes and a second eventSPITObject occurs to correct the changes. - * @param obj the pointer to the changed SPITObject. - * CAUTION: The SPITObject must already exist. - * @return true = SPITObject is changed, false = not changed, maybe obj is NULL or the SPITObject doesn't exists - */ -bool SClient::changeSPITObject(SObject *obj) { - if (obj == nullptr) - return false; - SObject *ptrSPITObject; - SType *ptrSPITType; - { - ptrSPITObject = mSpitObjects.getEntry(obj->getID()); - if (ptrSPITObject == nullptr) - return false; - ptrSPITType = mProcessor.mSpitTypes.getEntry(obj->getID()); - if (ptrSPITObject == nullptr) - return false; - - ptrSPITObject->setActionAssigned(obj->getActionAssigned()); - ; - ptrSPITObject->Delay.set(obj->Delay.get()); - ptrSPITObject->Duration.set(obj->Delay.get()); - ptrSPITObject->Fixed.set(obj->Fixed.get()); - ptrSPITObject->FrameFadeInLength.set(obj->FrameFadeInLength.get()); - ptrSPITObject->FrameFadeOutLength.set(obj->FrameFadeOutLength.get()); - ptrSPITObject->FrameLength.set(obj->FrameLength.get()); - ptrSPITObject->FrameStart.set(obj->FrameStart.get()); - ptrSPITObject->Name.set(obj->Name.get()); - ptrSPITObject->Remark.set(obj->Remark.get()); - ptrSPITObject->SPITTypeID.set(obj->SPITTypeID.get()); - ptrSPITObject->ServerParams.set(obj->ServerParams.get()); - ptrSPITObject->Track.set(obj->Track.get()); - ptrSPITObject->ValueFactor.set(obj->ValueFactor.get()); - ptrSPITObject->ValueUse.set(obj->ValueUse.get()); - - mCallbacks.onSpitObject(ObjectEvent::Changed, false, *ptrSPITType, *ptrSPITObject); - sendSPITObjectInternal(ptrSPITObject); - } - return true; -} - -/** - * When the client wants to remove a SPITObject with id == p_SPITObjectID (normally the client should not do this), then he should send it to the SPITServer. - * The corresponding SPITObject if listet in SPITObject will be deleted. - * An eventRemoveSPITType will occur. - * If an connection to a SPITServer is established, the SPITServer may discard the deletion and an eventSPITObject occurs - * -> the SPITObject is listet again. - * @param objId the id of the SPITObject to remove. - * @return 0 = sended to the SPITServer, -1 = not sended to the SPITServer or nos SPITObject with id == objId exists. - */ -int SClient::removeSPITObject(string objId) { - if (objId.length() <= 0) - return -1; - SType *ptrSPITType; - SObject *ptrSPITObject; - { - Message::RemoveObject sMRemoveSPITObject; - - ptrSPITObject = mSpitObjects.getEntry(objId); - if (ptrSPITObject == nullptr) - return -1; - ptrSPITType = mProcessor.mSpitTypes.getEntry(ptrSPITObject->SPITTypeID.get()); - if (ptrSPITType == nullptr) - return -1; - ptrSPITObject->fillMessageOP(sMRemoveSPITObject); - mCallbacks.onSpitObject(ObjectEvent::Deleted, false, *ptrSPITType, *ptrSPITObject); - mSpitObjects.removeEntry(*ptrSPITObject); - return sendSPITMessage(sMRemoveSPITObject); - } - return -1; -} - -//----- Play SPIT Objects ------ - -void SClient::parsePlaySPITStart(Message::PlayStart &message) { - ESP_LOGD(TAG, "parse PlayStart ID: %s Name: %s Running: %d", message.getPlayerID().c_str(), message.getPlayerName().c_str(), (int)message.getPlayerIsRunning()); - SPlayer &spitPlayer = SPlayer::getSPITPlayer(message.getPlayerID()); - spitPlayer.setIsRunning(message.getPlayerIsRunning()); - spitPlayer.setName(message.getPlayerName()); - spitPlayer.setType(message.getPlayerType()); - spitPlayer.setTime(message.getTime()); - spitPlayer.startPlaySequence(); - - mCallbacks.onPlay(spitPlayer.getID(), spitPlayer.getName(), spitPlayer.getType(), spitPlayer.getIsRunning(), spitPlayer.getTime()); -} -void SClient::parsePlaySPITObject(Message::PlayObject &message) { - - SPlayer &ptrSPITPlayer = SPlayer::getSPITPlayer(message.getPlayerID()); - SObject *ptrSPITObject = mSpitObjects.getEntry(message.getSPITObjectID()); - - if (ptrSPITObject == nullptr) { - return; - } - SPlayer::PlayType *ptrPlaySPITType = ptrSPITPlayer.addTypePlaying(ptrSPITObject->SPITTypeID.get()); - if (ptrPlaySPITType == nullptr) { - return; - } - ptrPlaySPITType->setPlayerIsRunning(ptrSPITPlayer.getIsRunning()); - ptrPlaySPITType->addValue(((double)message.getValue() / 1000000), ((double)ptrSPITObject->ValueFactor.get() / 1000000)); -} - -void SClient::parsePlaySPITEnd(Message::PlayEnd &message) { - SPlayer &ptrSPITPlayer = SPlayer::getSPITPlayer(message.getPlayerID()); - - auto &ptrPlaySPITTypes = ptrSPITPlayer.getPlaySPITTypes(); - for (auto i = ptrPlaySPITTypes.begin(); i != ptrPlaySPITTypes.end(); i++) { - SPlayer::PlayType *ptrPlaySPITType = i->second.get(); - bool boolStarted = ptrPlaySPITType->getIsNew(); - bool boolStopped = (ptrPlaySPITType->getIsPlayed() == false); - SType *ptrSPITType = mProcessor.mSpitTypes.getEntry(ptrPlaySPITType->getSPITTypeID()); - if (ptrSPITType == nullptr) { - // set isplayed to false, the ptrPlayObject will be removed by ptrSPITPlayer.endPlaySequence() - ptrPlaySPITType->setIsPlayed(false); - continue; - } - mCallbacks.onPlaySpitType(ptrPlaySPITType->getPlayerID(), ptrPlaySPITType->getSPITTypeID(), ptrPlaySPITType->getPlayerIsRunning(), boolStarted, boolStopped, ptrPlaySPITType->getValue()); - } - ptrSPITPlayer.endPlaySequence(); -} - -void SClient::parseReportPlayStatus(Message::ReportPlayStatus &message) { - SType *ptrSPITType = NULL; - - SObject *ptrSPITObject = mRemoteSpitObjects.getEntry(message.getID()); - if (ptrSPITObject == nullptr) { - ptrSPITObject = mSpitObjects.getEntry(message.getID()); - if (ptrSPITObject == nullptr) { - return; - } - } - if (ptrSPITObject->ServerRemote.get() == false) { - ptrSPITType = mProcessor.mSpitTypes.getEntry(ptrSPITObject->SPITTypeID.get()); - } else { - ptrSPITType = mProcessor.mRemoteSpitTypes.getEntry(ptrSPITObject->SPITTypeID.get()); - } - - if (ptrSPITType == nullptr) { - return; - } - mCallbacks.onPlayRemoteObjectStatus(*ptrSPITType, *ptrSPITObject, message.getFrameInsideObject(), message.getValue()); -} - -//--------- Remote ---------- - -/** - * Send a remote control command to the SPITServer. - * There may be different command types: - * a) Some don't use value e.g. go to next scene, olay a jingle - * b) Some use values e.g. the main sound fader - * @param p_SPITObjectID the id of the remote SPITObject (this represents the remote control command) - * @param valuePpm the value in ppm - * in case a) the value is ignored - * in case b) the value is used - * @param valueFlag indicates how the server should use valuePpm: - * VALUEFLAG_DIRECT (0x00) The server overwrites its existing value with p_Value - * VALUEFLAG_INCREASE (0x01) The server increases his existing value by valuePpm - * VALUEFLAG_DECREASE (0x01) The server decreases his existing value by valuePpm - */ -void SClient::sendRemoteObject(string p_SPITObjectID, int valuePpm, char valueFlag) { - SObject *ptrRemoteSPITObject = mRemoteSpitObjects.getEntry(p_SPITObjectID); - if (ptrRemoteSPITObject == nullptr) { - ESP_LOGD(TAG, "Unknown ID %s", p_SPITObjectID.c_str()); - return; - } - - Message::PlayStart playSPITStart(mID, mProjName, PLAYERTYPE_DISCRETE); - playSPITStart.setPlayerIsRunning(false); - playSPITStart.setTime(0); - sendSPITMessage(playSPITStart); - - Message::PlayObject playSPITObject; - playSPITObject.setID(ptrRemoteSPITObject->getID()); - playSPITObject.setPlayPrePosition(false); - playSPITObject.setPlayerID(mID); - playSPITObject.setValue(valuePpm); - playSPITObject.setValueFlag(valueFlag); - sendSPITMessage(playSPITObject); - - Message::PlayEnd playSPITEnd(mID); - sendSPITMessage(playSPITEnd); +SType *SClient::createTypeFixed(string iD, string group, string name, uint64_t delay, uint64_t duration) { + return mProcessor.createType(iD, group, name, delay, duration, true, true); } fos::Semaphore SClient::sStartSad; @@ -1304,7 +710,7 @@ void SClient::processSocketTask(SClient &instance) { ESP_LOGW(TAG, "Finished searching"); ESP_LOGW(TAG, "Start working"); auto nextWdTrigger = fos::Timing::getMilliSec() + WATCHDOGTIME; - auto nextWdCheck = nextWdTrigger + WATCHDOGTIME; + // auto nextWdCheck = nextWdTrigger + WATCHDOGTIME; while (true) { // auto time = fos::Timing::getMilliSec(); // if (time > nextWdTrigger) { diff --git a/components/spit/src/spit_processor.cpp b/components/spit/src/spit_processor.cpp index 080d234..3906c2b 100644 --- a/components/spit/src/spit_processor.cpp +++ b/components/spit/src/spit_processor.cpp @@ -12,206 +12,79 @@ static const char *TAG = "SPIT"; SProcessor::SProcessor(string name, string projName, string hostName, string guid, Callbacks calls, InternalCallbacks intern) : mCallbacks(calls), mInternCallbacks(intern), + mName(name), mGuid(guid), - mName(name), mProjName(projName), mComputerName(hostName) { } SProcessor::~SProcessor() { - // stopServerAutoDetect(); - // disconnectInternal(Connection::None); } -// void SProcessor::clientProjectClose() { -// if (mConnectionStatus == Connection::Ok) { -// ESP_LOGI(TAG, " ... tidy up ressources"); -// Message::CloseProject closeSPITProject(mProjName); -// // if (sendSPITMessage(closeSPITProject) < 0) { -// // ESP_LOGD(TAG, "Client could not send Client's ReportProject"); -// // } -// } -// } +unique_ptr SProcessor::createConnectMessage(string serverIP, string serverPort, string loginName, string loginPassword) { + auto msg = make_unique(getComputerName(), mName); + msg->setLoginName(loginName); + msg->setLoginPassword(loginPassword); + msg->setServerIP(serverIP); + if (serverPort.length() <= 0) { + serverPort = "0"; + } + int intServerPort = stoi(serverPort); + msg->setServerPort(intServerPort); + return msg; +} -// void SProcessor::clientProjectLoaded() { -// // set confirmed = false for all SPITTypes and SPITObjects -// SType::setConfirmedFalse(mSpitTypes); -// SObject::setConfirmedFalse(mSpitObjects); +/** + * Virtual construct - means actionAssigned for SPITTypes is is not implemented in SPITProtocol. + * This can used to setActionAssigned to all SPITObjects with this SPITType. + * This may be used in the case when the same action should be done for every SPITObject with this SPITType associated. + * This tells the server not what action is done, but it tells the server that there is an action. + * @param typeId the id of the SPITType + * @param actionAssigned + */ +void SProcessor::setActionType(string typeId, bool actionAssigned) { + SType *spitType = mSpitTypes.getEntry(typeId); + if (spitType == nullptr) + return; + if (spitType->ActionAssigned.set(actionAssigned)) { + sendTypeInternal(*spitType); + for (auto &[key, value] : mSpitObjects.getRepo()) { + if (value->SPITTypeID.get() == spitType->getID()) { + if (value->setActionAssignedType(actionAssigned) == true) { + sendObjectInternal(value.get()); + } + } + } + } +} -// if (mConnectionStatus == Connection::Ok) { -// // send ReportProject to the server -// Message::ReportProject reportSPITProject(mProjName, mProjName); -// reportSPITProject.setFramesPerSecond(0); -// // if (sendSPITMessage(reportSPITProject) < 0) { -// // ESP_LOGD(TAG, "SPIT_CLient::clientProjectLoaded could not send Client's ReportProject"); -// // } +/** This should be called if the user wants to associate/remove an action with a SPITObject. */ +void SProcessor::setActionObject(string spitObjId, bool actionAssigned) { + SObject *spitObject = mSpitObjects.getEntry(spitObjId); + if (spitObject == nullptr) + return; + if (spitObject->setActionAssigned(actionAssigned) == true) { + sendObjectInternal(spitObject); + } +} -// // send RequestProjectTransfer -// Message::RequestProjectTransfer sMRequestProjectTransfer; -// // if (sendSPITMessage(sMRequestProjectTransfer) < 0) { -// // ESP_LOGD(TAG, "SPIT_CLient::clientProjectLoaded could not send RequestProjectTransfer"); -// // } -// } -// } +std::vector SProcessor::createMessage(Message::OPPart &opPart) { + if (mMessageNumberSend == 255) + mMessageNumberSend = 1; + else + mMessageNumberSend++; + opPart.setMessageNumber(mMessageNumberSend); + opPart.setServerInfoInHeader(mGuid, mServerID); -// /** -// * Virtual construct - means actionAssigned for SPITTypes is is not implemented in SPITProtocol. -// * This can used to setActionAssigned to all SPITObjects with this SPITType. -// * This may be used in the case when the same action should be done for every SPITObject with this SPITType associated. -// * This tells the server not what action is done, but it tells the server that there is an action. -// * @param typeId the id of the SPITType -// * @param actionAssigned -// */ -// void SProcessor::setActionSPITType(string typeId, bool actionAssigned) { -// SType *spitType = mSpitTypes.getEntry(typeId); -// if (spitType == nullptr) -// return; -// if (spitType->ActionAssigned.set(actionAssigned)) { -// sendSPITTypeInternal(*spitType); -// for (auto& [key, value] : mSpitObjects.getRepo()) { -// if (value->SPITTypeID.get() == spitType->getID()) { -// if (value->setActionAssignedType(actionAssigned) == true) { -// sendSPITObjectInternal(value.get()); -// } -// } -// } -// } -// } - -// /** This should be called if the user wants to associate/remove an action with a SPITObject. */ -// void SProcessor::setActionSPITObject(string spitObjId, bool actionAssigned) { -// SObject *spitObject = mSpitObjects.getEntry(spitObjId); -// if (spitObject == nullptr) -// return; -// if (spitObject->setActionAssigned(actionAssigned) == true) { -// sendSPITObjectInternal(spitObject); -// } -// } -// //---------- ServerAutoDetection SAD ----------- - -// /** Starts the autodetection of SPITServers in the local network. If a connection is tried, the autodetection should be stopped before. -// * If a SPITServer is detected in the locale network an eventServerDetected occurs. -// */ -// void SProcessor::startServerAutoDetect() { -// // if (mDisconnectedByServer == true) { -// // // Server has previously disconnected -> do not start ServerAutodetect directly -// // fos::Task::delayMs(1000); // sleep a little to give the SPITServer time to clean up its stuff -// // } -// // SadDetectedServer::clearDetectedServers(); -// // if (!sThread) { -// // sThread = new fos::TaskT(SProcessor::processSocketTask, *this, "spitSock", fos::Task::DefaultStackSize * 2); -// // } -// // mAbortSearch = false; -// // sStartSad.give(); -// } - -// /** Stops the auto detection of SPIT servers. */ -// void SProcessor::stopServerAutoDetect() { -// mAbortSearch = true; -// } -// /** -// * If a new server was found by the ServerAutoDetect mechanism, this function is called. -// * To do so the SAD_Client ServerAutoDetect has to be startet - see SAD_Client::startServerAutoDetect. -// * If a server can be reached via several IP addresses, the IP address is selected according to the following preference: -// */ -// void SProcessor::eventServerDetected(SadDetectedServer &server) { -// mCallbacks.onServerEvent(ServerEvent::Detect, server); -// // If a connection has been established and the connection is lost -> reconnect -// if (_doReconnect) { -// if (mServerID == server.getID()) { -// stopServerAutoDetect(); -// ESP_LOGI(TAG, "reconnect to %s / %s", server.getIP().data(), server.getPort().data()); -// if (connect(server.getIP(), server.getPort(), server.getClientIP(), "0")) { -// return; -// } -// } -// } -// // Stop auto detection because a suitable server was found -// stopServerAutoDetect(); -// ESP_LOGI(TAG, "connect to %s / %s", server.getIP().data(), server.getPort().data()); -// if (!connect(server.getIP(), server.getPort(), server.getClientIP(), "0" /*= any port*/)) { -// // connection message could not be sent -> better to restart AutoDetection -// startServerAutoDetect(); -// } -// } - -// /** -// * If a SPITServer is not more found, this function is called. -// * To do so the SAD_Client ServerAutoDetect has to be startet - see SAD_Client::startServerAutoDetect. -// */ -// void SProcessor::eventServerLost(SadDetectedServer &server) { -// mCallbacks.onServerEvent(ServerEvent::Lost, server); -// } - -// void SProcessor::eventServerChanged(SadDetectedServer &server) { -// mCallbacks.onServerEvent(ServerEvent::Changed, server); -// // tryConnection(detectedServer); -// } - -// // void MyApp::tryConnection(const SadDetectedServer &detected) { -// // // fetch the infoemations from the detected -// // bool boolSuccess = false; -// // bool boolPossibleConnect = checkPossibleConnection(detected); - -// // if (boolPossibleConnect == false) -// // return; - -// // // -------------------------------------- -// // // You have three Options to use the detected server -// // // OPTION 1 Use the first server found -// // // OPTION 2 Use the first server found that fulfills specific conditions -// // // OPTION 3 take a copy of the detected and do connection later -// // // SadDetectedServer o_DetectedServer = detected; //this will call the copy constructor -// // // --------------------------------------- - -// // // Excample use the first detected LOOPBACK server, means the server runs on the same computer as this client -// // // if (detected.getIpIsLoopback() == true) { //omit the if condition if you want to use the first server found - -// // boolSuccess = false; -// // // Stop auto detection because a suitable server was found -// // stopServerAutoDetect(); -// // if (mSPIT_Client != nullptr) { -// // mServerProjectName = detected.getProjectName(); -// // mServerIP = detected.getIP(); - -// // #if defined(DEBUGOUTPUT) -// // ESP_LOGD(TAG, "MySPITApp: connect to %s ", detected.getIP().data()); -// // #endif -// // // Use the mBoardNumber as login name -// // string stringLoginName = ""; -// // string stringLoginPassword = ""; -// // boolSuccess = mSPIT_Client->connect(detected.getIP(), detected.getPort(), detected.getClientIP(), stringLoginName, stringLoginPassword); // ClientPort = "0" meeans use any port -// // } -// // if (boolSuccess == false) { -// // // connection message could not be sent -// // // perhaps restart AutoDetection -// // startServerAutoDetect(); -// // } else { -// // // WAITING FOR CONNECTION ANSWER -// // // If the Server is closed in the meantime no answer will return -// // //-> connect(..) has started the watchdog -// // } - -// // // } //Excample -// // } - -// std::vector SProcessor::createMessage(Message::OPPart &opPart) { -// if (mMessageNumberSend == 255) -// mMessageNumberSend = 1; -// else -// mMessageNumberSend++; -// opPart.setMessageNumber(mMessageNumberSend); -// opPart.setServerInfoInHeader(mGuid, mServerID); - -// int opFlag = opPart.getHeader()->getType(); -// try { -// return Message::createMessage(opPart); -// } catch (...) { -// ESP_LOGD(TAG, "Exception client OPFlag: %d", opFlag); -// } -// return {}; -// } -// // todo Delete SProcessor::sendSPITMessage(Message::OPPart &opPart + int opFlag = opPart.getHeader()->getType(); + try { + return Message::createMessage(opPart); + } catch (...) { + ESP_LOGD(TAG, "Exception client OPFlag: %d", opFlag); + } + return {}; +} +// todo Delete SProcessor::mInternCallbacks.sendMessage(Message::OPPart &opPart // // void SProcessor::receiveSPITMessage(SClient &rM) { // // char buffer[MAXSPITMESSAGEBYTECOUNT + 1]; @@ -235,256 +108,150 @@ SProcessor::~SProcessor() { // mOvertakingMessages.clear(); // } -// void SProcessor::checkParseMessageData(vector data) { -// auto message = make_unique(data); -// answerWatchdog(); -// if (!message->getHeader() || !message->getOPPart()) { -// ESP_LOGD(TAG, "Client::parseMessage incomplete message"); -// return; -// } +void SProcessor::checkParseMessageData(vector data) { + auto message = make_unique(data); + // answerWatchdog(); + if (!message->getHeader() || !message->getOPPart()) { + ESP_LOGD(TAG, "Client::parseMessage incomplete message"); + return; + } -// int msgNum = (int)(message->getHeader()->getMessageNumber() & 0xFF); + int msgNum = (int)(message->getHeader()->getMessageNumber() & 0xFF); -// if (msgNum == 0) { -// parseMessage(*message); -// return; -// } -// if (mMessageNumberReceived < 0) { -// mMessageNumberReceived = msgNum; -// parseMessage(*message); -// return; -// } + if (msgNum == 0) { + parseMessage(*message); + return; + } + if (mMessageNumberReceived < 0) { + mMessageNumberReceived = msgNum; + parseMessage(*message); + return; + } -// int msgNumNext = mMessageNumberReceived + 1; -// if (msgNumNext > 255 || msgNumNext < 1) -// msgNumNext = 1; + int msgNumNext = mMessageNumberReceived + 1; + if (msgNumNext > 255 || msgNumNext < 1) + msgNumNext = 1; -// if (msgNum == msgNumNext) { -// mMessageNumberReceived = msgNum; -// parseMessage(*message); + if (msgNum == msgNumNext) { + mMessageNumberReceived = msgNum; + parseMessage(*message); -// // check overtaking messages -// auto it = mOvertakingMessages.begin(); -// while (mOvertakingMessages.size() > 0) { + // check overtaking messages + auto it = mOvertakingMessages.begin(); + while (mOvertakingMessages.size() > 0) { -// msgNumNext = mMessageNumberReceived + 1; -// if (msgNumNext > 255 || msgNumNext < 1) -// msgNumNext = 1; + msgNumNext = mMessageNumberReceived + 1; + if (msgNumNext > 255 || msgNumNext < 1) + msgNumNext = 1; -// auto &overtakingMessage = *it; -// msgNum = (int)(overtakingMessage->getHeader()->getMessageNumber() & 0xFF); + auto &overtakingMessage = *it; + msgNum = (int)(overtakingMessage->getHeader()->getMessageNumber() & 0xFF); -// if (msgNum == msgNumNext) { -// mMessageNumberReceived = msgNum; -// parseMessage(*overtakingMessage); -// mOvertakingMessages.erase(it); + if (msgNum == msgNumNext) { + mMessageNumberReceived = msgNum; + parseMessage(*overtakingMessage); + mOvertakingMessages.erase(it); -// it = mOvertakingMessages.begin(); -// } else { -// break; -// } -// } + it = mOvertakingMessages.begin(); + } else { + break; + } + } -// } else { -// // p_SPITMessage has overtaken another message -// addOvertakingMessage(move(message)); -// } -// } + } else { + // message has overtaken another message + addOvertakingMessage(move(message)); + } +} -// void SProcessor::addOvertakingMessage(unique_ptr message) { -// if (!message) { -// return; -// } -// if (mOvertakingMessages.size() > MAX_OVERTAKING_SPIT_MESSAGES) { -// ESP_LOGD(TAG, "Client receiveing: perhaps message lost !!!!!"); -// } +void SProcessor::addOvertakingMessage(unique_ptr message) { + if (!message) { + return; + } + if (mOvertakingMessages.size() > MAX_OVERTAKING_SPIT_MESSAGES) { + ESP_LOGD(TAG, "Client receiveing: perhaps message lost !!!!!"); + } -// int intMessageNumber = (int)(message->getHeader()->getMessageNumber() & 0xFF); -// for (auto it = mOvertakingMessages.begin(); it != mOvertakingMessages.end(); ++it) { -// const auto &overtaking = *it; -// int intOvertakingMessageNumber = (int)(overtaking->getHeader()->getMessageNumber() & 0xFF); -// if (intMessageNumber < intOvertakingMessageNumber) { -// mOvertakingMessages.insert(it, move(message)); -// return; -// } -// } -// mOvertakingMessages.push_back(move(message)); -// } + int intMessageNumber = (int)(message->getHeader()->getMessageNumber() & 0xFF); + for (auto it = mOvertakingMessages.begin(); it != mOvertakingMessages.end(); ++it) { + const auto &overtaking = *it; + int intOvertakingMessageNumber = (int)(overtaking->getHeader()->getMessageNumber() & 0xFF); + if (intMessageNumber < intOvertakingMessageNumber) { + mOvertakingMessages.insert(it, move(message)); + return; + } + } + mOvertakingMessages.push_back(move(message)); +} -// void SProcessor::parseMessage(Message& message) { -// answerWatchdog(); -// if (!message.getHeader() || !message.getOPPart()) { -// ESP_LOGD(TAG, "Client::parseMessage incomplete message"); -// return; -// } +void SProcessor::parseMessage(Message &message) { + // answerWatchdog(); + if (!message.getHeader() || !message.getOPPart()) { + ESP_LOGD(TAG, "Client::parseMessage incomplete message"); + return; + } -// switch (message.getType()) { -// //----- Connection ----- -// case Message::ConnectAnswer::OPFLAG: -// parseConnectAnswer(message.getAs()); -// break; -// case Message::Disconnect::OPFLAG: -// parseDisconnect(message.getAs()); -// break; -// case Message::ReportProject::OPFLAG: -// parseReportProject(message.getAs()); -// break; -// case Message::Watchdog::OPFLAG: -// parseWatchdog(message.getAs()); -// break; -// case Message::WatchdogAnswer::OPFLAG: -// parseWatchdogAnswer(message.getAs()); -// break; -// //----- SPIT Project ----- -// case Message::StartProjectTransfer::OPFLAG: -// parseStartProjectTransfer(message.getAs()); -// break; -// case Message::CloseProject::OPFLAG: -// parseCloseProject(message.getAs()); -// break; -// case Message::RequestProjectTransfer::OPFLAG: -// parseRequestProjectTransfer(message.getAs()); -// break; -// case Message::EndProjectTransfer::OPFLAG: -// parseEndProjectTransfer(message.getAs()); -// break; -// //----- SPIT Types ------ -// case Message::ReportType::OPFLAG: -// parseReportType(message.getAs()); -// break; -// case Message::RemoveType::OPFLAG: -// parseRemoveSPITType(message.getAs()); -// //----- SPIT Objects ------ -// break; -// case Message::ReportObject::OPFLAG: -// parseReportSPITObject(message.getAs()); -// break; -// case Message::RemoveObject::OPFLAG: -// parseRemoveSPITObject(message.getAs()); -// break; -// //----- Play SPIT Objects ------ -// case Message::PlayStart::OPFLAG: -// parsePlaySPITStart(message.getAs()); -// break; -// case Message::PlayObject::OPFLAG: -// parsePlaySPITObject(message.getAs()); -// break; -// case Message::PlayEnd::OPFLAG: -// parsePlaySPITEnd(message.getAs()); -// break; -// case Message::ReportPlayStatus::OPFLAG: -// parseReportPlayStatus(message.getAs()); -// break; -// default: -// ESP_LOGD(TAG, "Client::parseMessage: Unknown Message"); -// } -// } - -// //----- Connection ------ -// /** -// * Tries to connect to a SPITServer. -// * @param serverIP the ip address of the SPIT server -// * @param serverPort the port number of the SPIT server -// * @param clientIP the local IP address of the client -// * @param clientPort the port number of the Client, if "0" the OS uses any possible port number -// * @param loginName login user name (liveSHOW does not use this -> mayby "" -// * @param loginPassword login user password (liveSHOW does not use this -> mayby "" -// * @return false = an error has occured, true = the connect was sent to the server -// */ -// bool SProcessor::connect(string serverIP, string serverPort, string clientIP, string clientPort, string loginName, string loginPassword) { -// disconnect(); -// // mSocket.setConnectionParams(serverIP, serverPort, clientIP, clientPort); -// // if (mSocket.bindSocket(clientIP, clientPort) < 0) { -// // mStopReceiveMessages = true; -// // return false; -// // } -// Message::Connect sMConnect(mComputerName, mName); -// sMConnect.setLoginName(loginName); -// sMConnect.setLoginPassword(loginPassword); -// sMConnect.setServerIP(serverIP); -// if (serverPort.length() <= 0) { -// serverPort = "0"; -// } -// int intServerPort = stoi(serverPort); -// sMConnect.setServerPort(intServerPort); - -// // if (startReceiveSPITMessages() == false) { -// // mStopReceiveMessages = true; -// // return false; -// // } -// resetMessageNumberReceived(); -// Connection intOldConnectionStatus = mConnectionStatus; - -// mConnectionStatus = Connection::TryConnection; -// mCallbacks.onConnectionStatus(mServerID, mServerComputerName, mServerName, mServerStepTime, -// mConnectionStatus, intOldConnectionStatus); - -// // sleep a little to make sure that the reception of the messages is started -// // fos::Task::delayMs(500); -// // if (sendSPITMessage(sMConnect) < 0) { -// // mConnectionStatus = Connection::None; -// // mStopReceiveMessages = true; -// // return false; -// // } -// return true; -// } - -// /** -// * Terminates the connection to the SPITServer. -// */ -// void SProcessor::disconnect() { -// disconnectInternal(Connection::None); -// } - -// void SProcessor::disconnectInternal(Connection cause) { -// Connection intOldConnectionStatus = mConnectionStatus; - -// mConnectionStatus = cause; -// switch (mConnectionStatus) { -// case Connection::Lost: -// break; -// case Connection::None: { -// Message::Disconnect sMDisconnect; -// // sendSPITMessage(sMDisconnect); -// } break; -// case Connection::NoneServer: -// break; -// default: -// break; -// } - -// // stopReceiveSPITMessages(); -// mCallbacks.onConnectionStatus(mServerID, mServerComputerName, mServerName, mServerStepTime, -// mConnectionStatus, intOldConnectionStatus); - -// if (intOldConnectionStatus != Connection::None && intOldConnectionStatus != Connection::NoneServer) { -// ESP_LOGI(TAG, "eventConnectionStatus %d ", (int)mConnectionStatus); -// switch (mConnectionStatus) { -// case SProcessor::Connection::None: -// ESP_LOGD(TAG, "not connected"); -// break; -// case SProcessor::Connection::NoneServer: -// ESP_LOGD(TAG, "connection terminated by server"); -// // call eventProjectClosed because this may not be sended by the server, -// // when the connection is closed -// mCallbacks.onProjectUpdate(ProjUpdate::ServerClosed, mServerProjectID); - -// // Server has terminated the connection -> start a new game -// // _doReconnect = false; -// startServerAutoDetect(); -// break; -// case SProcessor::Connection::Lost: -// ESP_LOGD(TAG, "connection lost"); -// // Maybe you want to reconnect, see eventServerDetected(...) -// // We have lost the connection -> set the flag to true and start the autodetection to reconnect at eventServerDetected(...) -// // _doReconnect = true; -// startServerAutoDetect(); -// break; -// default: -// break; -// } -// } -// } + switch (message.getType()) { + //----- Connection ----- + case Message::ConnectAnswer::OPFLAG: + // parseConnectAnswer(message.getAs()); + break; + case Message::Disconnect::OPFLAG: + // parseDisconnect(message.getAs()); + break; + case Message::ReportProject::OPFLAG: + parseReportProject(message.getAs()); + break; + case Message::Watchdog::OPFLAG: + // parseWatchdog(message.getAs()); + break; + case Message::WatchdogAnswer::OPFLAG: + // parseWatchdogAnswer(message.getAs()); + break; + //----- SPIT Project ----- + case Message::StartProjectTransfer::OPFLAG: + parseStartProjectTransfer(message.getAs()); + break; + case Message::CloseProject::OPFLAG: + parseCloseProject(message.getAs()); + break; + case Message::RequestProjectTransfer::OPFLAG: + parseRequestProjectTransfer(message.getAs()); + break; + case Message::EndProjectTransfer::OPFLAG: + parseEndProjectTransfer(message.getAs()); + break; + //----- SPIT Types ------ + case Message::ReportType::OPFLAG: + parseReportType(message.getAs()); + break; + case Message::RemoveType::OPFLAG: + parseRemoveType(message.getAs()); + //----- SPIT Objects ------ + break; + case Message::ReportObject::OPFLAG: + parseReportObject(message.getAs()); + break; + case Message::RemoveObject::OPFLAG: + parseRemoveObject(message.getAs()); + break; + //----- Play SPIT Objects ------ + case Message::PlayStart::OPFLAG: + parsePlayStart(message.getAs()); + break; + case Message::PlayObject::OPFLAG: + parsePlayObject(message.getAs()); + break; + case Message::PlayEnd::OPFLAG: + parsePlayEnd(message.getAs()); + break; + case Message::ReportPlayStatus::OPFLAG: + parseReportPlayStatus(message.getAs()); + break; + default: + ESP_LOGD(TAG, "Client::parseMessage: Unknown Message"); + } +} // void SProcessor::parseConnectAnswer(Message::ConnectAnswer &message) { // if (message.getClientID() != mGuid) @@ -536,7 +303,7 @@ SProcessor::~SProcessor() { // void SProcessor::parseWatchdog(Message::Watchdog &message) { // // ESP_LOGD(TAG, "parse Watchdog "); // Message::WatchdogAnswer o_WatchdogAnswer; -// // sendSPITMessage(o_WatchdogAnswer); +// // mInternCallbacks.sendMessage(o_WatchdogAnswer); // } // /** // * The SPIT server sends a watchdog message at regular intervals. The client responds immediately with WatchdogAnswer @@ -550,7 +317,7 @@ SProcessor::~SProcessor() { // void SProcessor::sendWatchdog() { // int intResult{}; // Message::Watchdog message; -// // intResult = sendSPITMessage(message); +// // intResult = mInternCallbacks.sendMessage(message); // if (intResult < 0) { // ESP_LOGW("WDT", "Failed to send Watchdog msg"); // } @@ -563,65 +330,62 @@ SProcessor::~SProcessor() { // } // } -// //----- SPIT Project ------ -// void SProcessor::parseReportProject(Message::ReportProject &message) { -// ESP_LOGD(TAG, "parse ReportProject"); -// mServerProjectID = message.getProjectID(); -// mServerProjectName = message.getProjectName(); -// mServerFramesPerSecond = message.getFramesPerSecond(); -// mCallbacks.onProjectUpdate(ProjUpdate::ServerLoaded, mServerProjectID); +//----- SPIT Project ------ +void SProcessor::parseReportProject(Message::ReportProject &message) { + ESP_LOGD(TAG, "parse ReportProject"); + mServerProjectID = message.getProjectID(); + mServerProjectName = message.getProjectName(); + mServerFramesPerSecond = message.getFramesPerSecond(); + mCallbacks.onProjectUpdate(ProjUpdate::ServerLoaded, mServerProjectID); -// // Set all SPITTypes and SPITObjects confirmed = false -// SType::setConfirmedFalse(mSpitTypes); -// SObject::setConfirmedFalse(mSpitObjects); + // Set all SPITTypes and SPITObjects confirmed = false + SType::setConfirmedFalse(mSpitTypes); + SObject::setConfirmedFalse(mSpitObjects); -// // Send RequestProjectTransfer -// Message::RequestProjectTransfer sMRequestProjectTransfer; -// // if (sendSPITMessage(sMRequestProjectTransfer) < 0) { -// // ESP_LOGD(TAG, "Client::parseReportProject could not send RequestProjectTransfer"); -// // } + // Send RequestProjectTransfer + Message::RequestProjectTransfer sMRequestProjectTransfer; + if (mInternCallbacks.sendMessage(sMRequestProjectTransfer) < 0) { + ESP_LOGD(TAG, "Client::parseReportProject could not send RequestProjectTransfer"); + } -// // todo Don't send the ReportProject here it should be sended after parseEndProjectTransfer -// // Send client's ReportProject -// Message::ReportProject reportProject(mProjName, mProjName); -// reportProject.setFramesPerSecond(0); -// // if (sendSPITMessage(reportProject) < 0) { -// // ESP_LOGD(TAG, "Client::parseReportProject could not send Client's ReportProject"); -// // } -// } -// void SProcessor::parseCloseProject(Message::CloseProject &p_CloseSPITProject) { -// ESP_LOGD(TAG, "parse CloseProject"); -// string stringProjectID; -// mCallbacks.onProjectUpdate(ProjUpdate::ServerClosed, p_CloseSPITProject.getProjectID()); -// SPlayer::clearPlayers(); -// } + // todo Don't send the ReportProject here it should be sended after parseEndProjectTransfer + // Send client's ReportProject + Message::ReportProject reportProject(mProjName, mProjName); + reportProject.setFramesPerSecond(0); + if (mInternCallbacks.sendMessage(reportProject) < 0) { + ESP_LOGD(TAG, "Client::parseReportProject could not send Client's ReportProject"); + } +} -// string SProcessor::getServerProjectID() { return mServerProjectID; } -// string SProcessor::getServerProjectName() { return mServerProjectName; } -// int SProcessor::getServerFramesPerSecond() { return mServerFramesPerSecond; } +void SProcessor::parseCloseProject(Message::CloseProject &p_CloseSPITProject) { + ESP_LOGD(TAG, "parse CloseProject"); + string stringProjectID; + mCallbacks.onProjectUpdate(ProjUpdate::ServerClosed, p_CloseSPITProject.getProjectID()); + SPlayer::clearPlayers(); +} -// void SProcessor::parseRequestProjectTransfer(Message::RequestProjectTransfer &message) { -// ESP_LOGD(TAG, "parse RequestProjectTransfer"); -// // StartProjectTransfer -// Message::StartProjectTransfer sMStartProjectTransfer; -// // if (sendSPITMessage(sMStartProjectTransfer) < 0) { -// // return; -// // } +void SProcessor::parseRequestProjectTransfer(Message::RequestProjectTransfer &message) { + ESP_LOGD(TAG, "parse RequestProjectTransfer"); + // StartProjectTransfer + Message::StartProjectTransfer sMStartProjectTransfer; + if (mInternCallbacks.sendMessage(sMStartProjectTransfer) < 0) { + return; + } -// // send all listes SPITTypes -// for (const auto& [key, value] : mSpitTypes.getRepo()) { -// sendSPITTypeInternal(*value); -// // fos::Task::delayMs(10); -// } -// for (auto& [key, value] : mSpitObjects.getRepo()) { -// sendSPITObjectInternal(value.get()); -// // fos::Task::delayMs(10); -// } + // send all listes SPITTypes + for (const auto &[key, value] : mSpitTypes.getRepo()) { + sendTypeInternal(*value); + mInternCallbacks.delay(10); + } + for (auto &[key, value] : mSpitObjects.getRepo()) { + sendObjectInternal(value.get()); + mInternCallbacks.delay(10); + } -// // EndProjectTransfer -// Message::EndProjectTransfer sMEndProjectTransfer; -// // sendSPITMessage(sMEndProjectTransfer); -// } + // EndProjectTransfer + Message::EndProjectTransfer sMEndProjectTransfer; + mInternCallbacks.sendMessage(sMEndProjectTransfer); +} // /* NEW IMPLEMENTATION @@ -641,7 +405,7 @@ SProcessor::~SProcessor() { // // SPIT_Handler::addRunnable(o_RunnableStart); // // ptrSMStartProjectTransfer = new Message::StartProjectTransfer(); -// // intResult = sendSPITMessage(ptrSMStartProjectTransfer); +// // intResult = mInternCallbacks.sendMessage(ptrSMStartProjectTransfer); // // if (intResult < 0) { // // return; // // } @@ -653,7 +417,7 @@ SProcessor::~SProcessor() { // // for (int i = 0; i < intCount; i++) { // // ptrSPITType = mSpitTypes.getEntry(i); // // if (ptrSPITType == nullptr) continue; -// // intResult = sendSPITTypeInternal(ptrSPITType); +// // intResult = sendTypeInternal(ptrSPITType); // // if (intResult < 0) return; // // mWatchdog->answerWatchdog(); // // this_thread::sleep_for(chrono::milliseconds(7)); @@ -675,7 +439,7 @@ SProcessor::~SProcessor() { // // //EndProjectTransfer // // ptrSMEndProjectTransfer = new Message::EndProjectTransfer(); -// // intResult = sendSPITMessage(ptrSMEndProjectTransfer); +// // intResult = mInternCallbacks.sendMessage(ptrSMEndProjectTransfer); // // if (intResult < 0) { // // return; // // } @@ -687,87 +451,27 @@ SProcessor::~SProcessor() { // } // */ -// // void SProcessor::sendProject(SClient *p_PtrSPIT_Client) { -// // int intResult; -// // Message::StartProjectTransfer* ptrSMStartProjectTransfer; -// // Message::EndProjectTransfer* ptrSMEndProjectTransfer; -// // int intCount; -// // SPITType* ptrSPITType; -// // SObject* ptrSPITObject; +void SProcessor::parseStartProjectTransfer(Message::StartProjectTransfer &message) { + mCallbacks.onProjectUpdate(ProjUpdate::StartTransfer, mServerProjectID); +} -// // //StartProjectTransfer -// // NotifyStartProjectTransfer_Client* o_RunnableStart = new NotifyStartProjectTransfer_Client(p_PtrSPIT_Client->getSPITClientInterface()); -// // SPIT_Handler::addRunnable(o_RunnableStart); +void SProcessor::parseEndProjectTransfer(Message::EndProjectTransfer &message) { + SObject::clearUnconfirmedObjects(mSpitObjects); + mCallbacks.onProjectUpdate(ProjUpdate::EndTransfer, mServerProjectID); -// // ptrSMStartProjectTransfer = new Message::StartProjectTransfer(); -// // intResult = p_PtrSPIT_Client->sendSPITMessage(ptrSMStartProjectTransfer); -// // if (intResult < 0) { -// // return; -// // } - -// // // mWatchdog->answerWatchdog(); -// // // { -// // //send all listes SPITTypes -// // // unique_lock o_LockType(*SPITType::getMutex()); -// // intCount = SPITType::getSPITTypeCount(); -// // for (int i = 0; i < intCount; i++) { -// // ptrSPITType = mSpitTypes.getEntry(i); -// // if (ptrSPITType == nullptr) continue; -// // if (ptrSPITType->getCreatedByClient() == false) continue; -// // intResult = p_PtrSPIT_Client->sendSPITTypeInternal(ptrSPITType); -// // if (intResult < 0) return; -// // // mWatchdog->answerWatchdog(); -// // this_thread::sleep_for(chrono::milliseconds(7)); -// // } -// // // } - -// // // { -// // // unique_lock o_LockObject(*SObject::getMutex()); -// // intCount = mSpitObjects.getEntryCount(); -// // for (int i = 0; i < intCount; i++) { -// // ptrSPITObject = mSpitObjects.getEntry(i); -// // if (ptrSPITObject == nullptr) continue; -// // if (ptrSPITObject->getCreatedByClient() == false) continue; -// // intResult = p_PtrSPIT_Client->sendSPITObjectInternal(ptrSPITObject); -// // if (intResult < 0) return; -// // // mWatchdog->answerWatchdog(); -// // this_thread::sleep_for(chrono::milliseconds(7)); -// // } -// // // } - -// // //EndProjectTransfer -// // ptrSMEndProjectTransfer = new Message::EndProjectTransfer(); -// // intResult = p_PtrSPIT_Client->sendSPITMessage(ptrSMEndProjectTransfer); -// // if (intResult < 0) { -// // return; -// // } -// // // mWatchdog->answerWatchdog(); -// // NotifyEndProjectTransfer_Client* o_RunnableEnd = new NotifyEndProjectTransfer_Client(p_PtrSPIT_Client->getSPITClientInterface()); -// // SPIT_Handler::addRunnable(o_RunnableEnd); - -// // //Send act -// // } - -// void SProcessor::parseStartProjectTransfer(Message::StartProjectTransfer &message) { -// mCallbacks.onProjectUpdate(ProjUpdate::StartTransfer, mServerProjectID); -// } -// void SProcessor::parseEndProjectTransfer(Message::EndProjectTransfer &message) { -// SObject::clearUnconfirmedObjects(mSpitObjects); -// mCallbacks.onProjectUpdate(ProjUpdate::EndTransfer, mServerProjectID); - -// // Send Message::ReportProject after the mSPITClientInterface is notfied of EndProjectTransfer -// Message::ReportProject reportSPITProject(mProjName, mProjName); -// reportSPITProject.setFramesPerSecond(0); -// // if (sendSPITMessage(reportSPITProject) < 0) { -// // ESP_LOGD(TAG, "Client::parseReportProject could not send Client's ReportProject"); -// // } -// } + // Send Message::ReportProject after the mSPITClientInterface is notfied of EndProjectTransfer + Message::ReportProject reportSPITProject(mProjName, mProjName); + reportSPITProject.setFramesPerSecond(0); + if (mInternCallbacks.sendMessage(reportSPITProject) < 0) { + ESP_LOGD(TAG, "Client::parseReportProject could not send Client's ReportProject"); + } +} void SProcessor::parseReportType(Message::ReportType &message) { ESP_LOGD(TAG, "parse ReportType ID %s Name %s", message.getID().c_str(), message.getName().c_str()); SType *sType; - bool boolNew = false; - bool boolChanged = false; + bool isNew = false; + bool isChanged = false; { if (message.getServerRemote() == false) { sType = mSpitTypes.getEntry(message.getID()); @@ -785,7 +489,7 @@ void SProcessor::parseReportType(Message::ReportType &message) { auto spitType = make_unique(message.getID()); sType = spitType.get(); mSpitTypes.addEntry(move(spitType)); - boolNew = true; + isNew = true; } } else { sType = mRemoteSpitTypes.getEntry(message.getID()); @@ -793,440 +497,432 @@ void SProcessor::parseReportType(Message::ReportType &message) { auto spitType = make_unique(message.getID()); sType = spitType.get(); mRemoteSpitTypes.addEntry(move(spitType)); - boolNew = true; + isNew = true; } } if (!sType->setMessageOP(message)) { // SPITType is not changable -> send back to the server - mInternCallbacks.sendSpitTypeInternal(*sType); + sendTypeInternal(*sType); return; } - auto eventType = boolNew ? ObjectEvent::Created : ObjectEvent::Changed; + auto eventType = isNew ? ObjectEvent::Created : ObjectEvent::Changed; // add or change SPITType mCallbacks.onSpitType(eventType, sType->ServerRemote.get(), *sType); if (sType != nullptr) { - if (sType->setConfirmed(true) == true || boolChanged == true) { - mInternCallbacks.sendSpitTypeInternal(*sType); + if (sType->setConfirmed(true) == true || isChanged == true) { + sendTypeInternal(*sType); } } } } -// void SProcessor::parseRemoveSPITType(Message::RemoveType &message) { -// ESP_LOGD(TAG, "parse RemoveType %s", message.getID().c_str()); -// bool boolRemote = false; -// string stringSPITTypeID = message.getID(); +void SProcessor::parseRemoveType(Message::RemoveType &message) { + ESP_LOGD(TAG, "parse RemoveType %s", message.getID().c_str()); + bool isRemote = false; + string sTypeID = message.getID(); -// SType *ptrSPITType = mRemoteSpitTypes.getEntry(stringSPITTypeID); -// if (!ptrSPITType) { -// boolRemote = true; -// } else { -// ptrSPITType = mSpitTypes.getEntry(stringSPITTypeID); -// if (!ptrSPITType) { -// boolRemote = false; -// } else { -// // No SPITType with stringSPITTypeID is listet -// return; -// } -// } + SType *sType = mRemoteSpitTypes.getEntry(sTypeID); + if (!sType) { + isRemote = true; + } else { + sType = mSpitTypes.getEntry(sTypeID); + if (!sType) { + isRemote = false; + } else { + // No SType with sTypeID is listet + return; + } + } -// if (ptrSPITType->getCreatedByClient() && ptrSPITType->Fixed.get()) { -// // the SPITyte is created by client himself and it is fixed -> don't remove the SPITType!! -// // Send the SPITTyp back to the server -// sendSPITTypeInternal(*ptrSPITType); -// return; -// } + if (sType->getCreatedByClient() && sType->Fixed.get()) { + // the SPITyte is created by client himself and it is fixed -> don't remove the SType!! + // Send the SPITTyp back to the server + sendTypeInternal(*sType); + return; + } -// mCallbacks.onSpitType(ObjectEvent::Deleted, boolRemote, *ptrSPITType); -// if (boolRemote == false) { -// mSpitTypes.removeEntry(*ptrSPITType); -// } else { -// mRemoteSpitTypes.removeEntry(*ptrSPITType); -// } -// } + mCallbacks.onSpitType(ObjectEvent::Deleted, isRemote, *sType); + if (isRemote == false) { + mSpitTypes.removeEntry(*sType); + } else { + mRemoteSpitTypes.removeEntry(*sType); + } +} -// /** -// * If a client has changed a SPITType, it should send it to the server to transmit the changes. -// * If the SPITType is a fixed one and not created by the client himself, then an eventSPITType can be sent from the server, which cancels the changes. -// * @param p_SPITType the pointer to the changed SPITType -// * @return 0 = is sended, -1 = is not sended -// */ -// int SProcessor::sendSPITTypeInternal(SType &p_SPITType) { -// Message::ReportType sMReportSPITType; -// p_SPITType.fillMessageOP(sMReportSPITType); -// // return sendSPITMessage(sMReportSPITType); -// return 1; -// } +/** + * Change an existing SPIT_Type. + * @param p_SPITType the SPITType vont + * @return true = changed, false = not changed maybe p_SPITType is NULL or the SPITType doesn't exists + */ +bool SProcessor::changeType(SType *p_SPITType) { + if (p_SPITType == nullptr) + return false; + SType *ptrSPITType = mSpitTypes.getEntry(p_SPITType->getID()); + if (ptrSPITType == nullptr) + return false; -// /** -// * Change an existing SPIT_Type. -// * @param p_SPITType the SPITType vont -// * @return true = changed, false = not changed maybe p_SPITType is NULL or the SPITType doesn't exists -// */ -// bool SProcessor::changeSPITType(SType *p_SPITType) { -// if (p_SPITType == nullptr) -// return false; -// SType *ptrSPITType = mSpitTypes.getEntry(p_SPITType->getID()); -// if (ptrSPITType == nullptr) -// return false; + ptrSPITType->DefaultDelay.set(p_SPITType->DefaultDelay.get()); + ptrSPITType->DefaultDuration.set(p_SPITType->DefaultDuration.get()); + ptrSPITType->Fixed.set(p_SPITType->Fixed.get()); + ptrSPITType->GroupName.set(p_SPITType->GroupName.get()); + ptrSPITType->Name.set(p_SPITType->Name.get()); + ptrSPITType->ProjectIndepended.set(p_SPITType->ProjectIndepended.get()); -// ptrSPITType->DefaultDelay.set(p_SPITType->DefaultDelay.get()); -// ptrSPITType->DefaultDuration.set(p_SPITType->DefaultDuration.get()); -// ptrSPITType->Fixed.set(p_SPITType->Fixed.get()); -// ptrSPITType->GroupName.set(p_SPITType->GroupName.get()); -// ptrSPITType->Name.set(p_SPITType->Name.get()); -// ptrSPITType->ProjectIndepended.set(p_SPITType->ProjectIndepended.get()); + mCallbacks.onSpitType(ObjectEvent::Changed, false, *ptrSPITType); + sendTypeInternal(*ptrSPITType); -// mCallbacks.onSpitType(ObjectEvent::Changed, false, *ptrSPITType); -// sendSPITTypeInternal(*ptrSPITType); + return true; +} -// return true; -// } +/** + * If a client has removed a SPITType where id == p_SPITTypeID, it should send it to the server. + * The corresponding SPITType if listet in SPITType will be deleted. + * An eventRemoveSPITType will occur. + * If a connection to a SPITServer is established, the SPITServer may dicard the deletion an an eventSPITType will occur + * -> the SPITType will be listet again. + * @param p_SPITType the id of the SPITType ro remove + * @return 0 = is sended, -1 = is not sended + */ +int SProcessor::removeType(string p_SPITTypeID) { + if (p_SPITTypeID.length() <= 0) + return -1; + SType *ptrSPITType; + { + ptrSPITType = mSpitTypes.getEntry(p_SPITTypeID); + if (ptrSPITType == nullptr) + return -1; + Message::RemoveType sMRemoveSPITType; + ptrSPITType->fillMessageOP(sMRemoveSPITType); + mCallbacks.onSpitType(ObjectEvent::Deleted, false, *ptrSPITType); + mSpitTypes.removeEntry(*ptrSPITType); + return mInternCallbacks.sendMessage(sMRemoveSPITType); + } + return -1; +} -// /** -// * If a client has removed a SPITType where id == p_SPITTypeID, it should send it to the server. -// * The corresponding SPITType if listet in SPITType will be deleted. -// * An eventRemoveSPITType will occur. -// * If a connection to a SPITServer is established, the SPITServer may dicard the deletion an an eventSPITType will occur -// * -> the SPITType will be listet again. -// * @param p_SPITType the id of the SPITType ro remove -// * @return 0 = is sended, -1 = is not sended -// */ -// int SProcessor::removeSPITType(string p_SPITTypeID) { -// if (p_SPITTypeID.length() <= 0) -// return -1; -// SType *ptrSPITType; -// { -// ptrSPITType = mSpitTypes.getEntry(p_SPITTypeID); -// if (ptrSPITType == nullptr) -// return -1; -// Message::RemoveType sMRemoveSPITType; -// ptrSPITType->fillMessageOP(sMRemoveSPITType); -// mCallbacks.onSpitType(ObjectEvent::Deleted, false, *ptrSPITType); -// mSpitTypes.removeEntry(*ptrSPITType); -// // return sendSPITMessage(sMRemoveSPITType); -// return 1; -// } -// return -1; -// } +SType *SProcessor::createType(string id, string groupName, string name, uint64_t delay, uint64_t duration, bool fixed, bool projIndipendent) { + bool boolNew; + SType *sType = mSpitTypes.getEntry(id); + if (sType == nullptr) { + auto spitType = make_unique(id, groupName, name, fixed, projIndipendent, delay, duration); + sType = spitType.get(); + mSpitTypes.addEntry(move(spitType)); + sType->setCreatedByClient(true); + boolNew = true; + } else { + sType->GroupName.set(groupName); + sType->Name.set(name); + sType->Fixed.set(fixed); + sType->ProjectIndepended.set(projIndipendent); + sType->DefaultDelay.set(delay); + sType->DefaultDuration.set(duration); + boolNew = false; + } -// SType *SProcessor::createTypeFixed(string iD, string p_GroupName, string p_Name, uint64_t p_DefaultDelay, uint64_t p_DefaultDuration) { -// return createType(iD, p_GroupName, p_Name, p_DefaultDelay, p_DefaultDuration, true, true); -// } + auto eventType = boolNew ? ObjectEvent::Created : ObjectEvent::Changed; + mCallbacks.onSpitType(eventType, false, *sType); + sendTypeInternal(*sType); + return sType; +} -// SType *SProcessor::createType(string p_ID, string p_GroupName, string p_Name, uint64_t p_DefaultDelay, uint64_t p_DefaultDuration, bool p_FIxed, bool p_ProjectIndepended) { -// bool boolNew; -// SType *ptrSPITType = mSpitTypes.getEntry(p_ID); -// if (ptrSPITType == nullptr) { -// auto spitType = make_unique(p_ID, p_GroupName, p_Name, p_FIxed, p_ProjectIndepended, p_DefaultDelay, p_DefaultDuration); -// ptrSPITType = spitType.get(); -// mSpitTypes.addEntry(move(spitType)); -// ptrSPITType->setCreatedByClient(true); -// boolNew = true; -// } else { -// ptrSPITType->GroupName.set(p_GroupName); -// ptrSPITType->Name.set(p_Name); -// ptrSPITType->Fixed.set(p_FIxed); -// ptrSPITType->ProjectIndepended.set(p_ProjectIndepended); -// ptrSPITType->DefaultDelay.set(p_DefaultDelay); -// ptrSPITType->DefaultDuration.set(p_DefaultDuration); -// boolNew = false; -// } +/** + * If a client has changed a SPITType, it should send it to the server to transmit the changes. + * If the SPITType is a fixed one and not created by the client himself, then an eventSPITType can be sent from the server, which cancels the changes. + * @param sType the pointer to the changed SPITType + * @return 0 = is sended, -1 = is not sended + */ +int SProcessor::sendTypeInternal(SType &sType) { + Message::ReportType reportType; + sType.fillMessageOP(reportType); + return mInternCallbacks.sendMessage(reportType); +} -// auto eventType = boolNew ? ObjectEvent::Created : ObjectEvent::Changed; -// mCallbacks.onSpitType(eventType, false, *ptrSPITType); -// sendSPITTypeInternal(*ptrSPITType); -// return ptrSPITType; -// } +//----- SPIT Objects ------ +void SProcessor::parseReportObject(Message::ReportObject &message) { + ESP_LOGD(TAG, "parse ReportObject %s", message.getID().c_str()); + SObject *sObject; + SType *sType; + bool isNew = false; + bool isRemote = false; + bool isChanged = false; + { + ESP_LOGD(TAG, "parse ReportObject %s / %s", message.getID().c_str(), message.getName().c_str()); + if (message.getServerRemote() == false) { + isRemote = false; + sObject = mSpitObjects.getEntry(message.getID()); + sType = mSpitTypes.getEntry(message.getSPITTypeID()); -// //----- SPIT Objects ------ -// void SProcessor::parseReportSPITObject(Message::ReportObject &message) { -// ESP_LOGD(TAG, "parse ReportObject %s", message.getID().c_str()); -// SObject *ptrSPITObject; -// SType *ptrSPITType; -// bool boolNew = false; -// bool boolRemote = false; -// bool boolChanged = false; -// { -// ESP_LOGD(TAG, "parse ReportObject %s / %s", message.getID().c_str(), message.getName().c_str()); -// if (message.getServerRemote() == false) { -// boolRemote = false; -// ptrSPITObject = mSpitObjects.getEntry(message.getID()); -// ptrSPITType = mSpitTypes.getEntry(message.getSPITTypeID()); + if (sType == nullptr) { + // No associated SPITType found + if (sObject != nullptr) { + // SpitObject exists but has no corresponding SPITType -> remove the SPITObject without sending a message + // Maybe the SPITObject has changed the SPITTypeID to a SPITTypeID of another board + mSpitObjects.removeEntry(*sObject); + } + return; + } + bool isKnownType = sType != nullptr; + if (sObject == nullptr) { + // The user's app my veto the SPITType + if (mCallbacks.onCheckSpitObjectVeto(isKnownType) == false) { + ESP_LOGW(TAG, "ObjectVeto %s / %s", message.getID().c_str(), message.getName().c_str()); + return; + } + auto spitObj = make_unique(message.getID()); + sObject = spitObj.get(); + mSpitObjects.addEntry(move(spitObj)); + isNew = true; + } else { + // The user's app my veto the SPITType + if (mCallbacks.onCheckSpitObjectVeto(isKnownType) == false) { + // SpitObject exists and User APp denied the SPITObject -> remove the SPITObject without sending a message + mSpitObjects.removeEntry(*sObject); + ESP_LOGW(TAG, "TypeVeto %s / %s", message.getID().c_str(), message.getName().c_str()); + return; + } + } + } else { + isRemote = true; + sObject = mRemoteSpitObjects.getEntry(message.getID()); + sType = mRemoteSpitTypes.getEntry(message.getSPITTypeID()); + if (sType == nullptr) { + // No associated SPITType found + return; + } + if (sObject == nullptr) { + auto spitObj = make_unique(message.getID()); + sObject = spitObj.get(); + mRemoteSpitObjects.addEntry(move(spitObj)); + isNew = true; + } + } -// if (ptrSPITType == nullptr) { -// // No associated SPITType found -// if (ptrSPITObject != nullptr) { -// // SpitObject exists but has no corresponding SPITType -> remove the SPITObject without sending a message -// // Maybe the SPITObject has changed the SPITTypeID to a SPITTypeID of another board -// mSpitObjects.removeEntry(*ptrSPITObject); -// } -// return; -// } -// bool isKnownType = ptrSPITType != nullptr; -// if (ptrSPITObject == nullptr) { -// // The user's app my veto the SPITType -// if (mCallbacks.onCheckSpitObjectVeto(isKnownType) == false) { -// ESP_LOGW(TAG, "ObjectVeto %s / %s", message.getID().c_str(), message.getName().c_str()); -// return; -// } -// auto spitObj = make_unique(message.getID()); -// ptrSPITObject = spitObj.get(); -// mSpitObjects.addEntry(move(spitObj)); -// boolNew = true; -// } else { -// // The user's app my veto the SPITType -// if (mCallbacks.onCheckSpitObjectVeto(isKnownType) == false) { -// // SpitObject exists and User APp denied the SPITObject -> remove the SPITObject without sending a message -// mSpitObjects.removeEntry(*ptrSPITObject); -// ESP_LOGW(TAG, "TypeVeto %s / %s", message.getID().c_str(), message.getName().c_str()); -// return; -// } -// } -// } else { -// boolRemote = true; -// ptrSPITObject = mRemoteSpitObjects.getEntry(message.getID()); -// ptrSPITType = mRemoteSpitTypes.getEntry(message.getSPITTypeID()); -// if (ptrSPITType == nullptr) { -// // No associated SPITType found -// return; -// } -// if (ptrSPITObject == nullptr) { -// auto spitObj = make_unique(message.getID()); -// ptrSPITObject = spitObj.get(); -// mRemoteSpitObjects.addEntry(move(spitObj)); -// boolNew = true; -// } -// } + if (!sObject->setMessageOP(&message)) { + ESP_LOGE(TAG, "Change not allowed %s", sObject->getID().c_str()); + // setMessageOP error - the SPITObject can't be changed, it may be fixed and crated by this client + sendObjectInternal(sObject); + return; + } -// if (!ptrSPITObject->setMessageOP(&message)) { -// ESP_LOGE(TAG, "Change not allowed"); -// // setMessageOP error - the SPITObject can't be changed, it may be fixed and crated by this client -// sendSPITObjectInternal(ptrSPITObject); -// return; -// } + if (isRemote == false) { + // set the virtual action assignment + sObject->setActionAssignedType(sType->ActionAssigned.get()); + } -// if (boolRemote == false) { -// // set the virtual action assignment -// ptrSPITObject->setActionAssignedType(ptrSPITType->ActionAssigned.get()); -// } + auto eventType = isNew ? ObjectEvent::Created : ObjectEvent::Changed; + mCallbacks.onSpitObject(eventType, isRemote, *sType, *sObject); -// auto eventType = boolNew ? ObjectEvent::Created : ObjectEvent::Changed; -// mCallbacks.onSpitObject(eventType, boolRemote, *ptrSPITType, *ptrSPITObject); + if (sObject->setConfirmed(true) == true || isChanged == true) { + // Confirmation has changed + sendObjectInternal(sObject); + } + } +} -// if (ptrSPITObject->setConfirmed(true) == true || boolChanged == true) { -// // Confirmation has changed -// sendSPITObjectInternal(ptrSPITObject); -// } -// } -// } -// void SProcessor::parseRemoveSPITObject(Message::RemoveObject &message) { -// ESP_LOGD(TAG, "parse RemoveObject %s", message.getID().c_str()); -// SObject *ptrSPITObject = mRemoteSpitObjects.getEntry(message.getID()); -// if (ptrSPITObject != nullptr) { -// SType *ptrSPITType = mRemoteSpitTypes.getEntry(ptrSPITObject->SPITTypeID.get()); -// if (ptrSPITType != nullptr) { -// mCallbacks.onSpitObject(ObjectEvent::Deleted, true, *ptrSPITType, *ptrSPITObject); -// } -// mRemoteSpitObjects.removeEntry(*ptrSPITObject); -// } else { -// // call removeSPITObject, this will notify the server that the object is removed -// removeSPITObject(message.getID()); -// } -// } +void SProcessor::parseRemoveObject(Message::RemoveObject &message) { + ESP_LOGD(TAG, "parse RemoveObject %s", message.getID().c_str()); + SObject *sObject = mRemoteSpitObjects.getEntry(message.getID()); + if (sObject != nullptr) { + SType *sType = mRemoteSpitTypes.getEntry(sObject->SPITTypeID.get()); + if (sType != nullptr) { + mCallbacks.onSpitObject(ObjectEvent::Deleted, true, *sType, *sObject); + } + mRemoteSpitObjects.removeEntry(*sObject); + } else { + // call removeObject, this will notify the server that the object is removed + removeObject(message.getID()); + } +} -// int SProcessor::sendSPITObjectInternal(SObject *ptrSPITObject) { -// if (ptrSPITObject == nullptr) -// return -1; -// Message::ReportObject sMReportSPITObject; -// ptrSPITObject->fillMessageOP(sMReportSPITObject); +int SProcessor::sendObjectInternal(SObject *sObject) { + if (sObject == nullptr) + return -1; + Message::ReportObject reportObject; + sObject->fillMessageOP(reportObject); + return mInternCallbacks.sendMessage(reportObject); +} -// // return sendSPITMessage(sMReportSPITObject); -// return 1; -// } -// /** -// * When the client changes an existing SPITObject (normally the client should not do this), then he should send the changes to the SPITServer. -// * An eventSPITObject occurs. -// * The SPITServer may discard the changes and a second eventSPITObject occurs to correct the changes. -// * @param obj the pointer to the changed SPITObject. -// * CAUTION: The SPITObject must already exist. -// * @return true = SPITObject is changed, false = not changed, maybe obj is NULL or the SPITObject doesn't exists -// */ -// bool SProcessor::changeSPITObject(SObject *obj) { -// if (obj == nullptr) -// return false; -// SObject *ptrSPITObject; -// SType *ptrSPITType; -// { -// ptrSPITObject = mSpitObjects.getEntry(obj->getID()); -// if (ptrSPITObject == nullptr) -// return false; -// ptrSPITType = mSpitTypes.getEntry(obj->getID()); -// if (ptrSPITObject == nullptr) -// return false; +/** + * When the client changes an existing SPITObject (normally the client should not do this), then he should send the changes to the SPITServer. + * An eventSPITObject occurs. + * The SPITServer may discard the changes and a second eventSPITObject occurs to correct the changes. + * @param obj the pointer to the changed SPITObject. + * @return 0 = sended, -1 = not sended + */ +bool SProcessor::changeObject(SObject *obj) { + if (obj == nullptr) + return false; + SObject *sObject; + SType *sType; + { + sObject = mSpitObjects.getEntry(obj->getID()); + if (sObject == nullptr) + return false; + sType = mSpitTypes.getEntry(obj->getID()); + if (sObject == nullptr) + return false; -// ptrSPITObject->setActionAssigned(obj->getActionAssigned()); -// ; -// ptrSPITObject->Delay.set(obj->Delay.get()); -// ptrSPITObject->Duration.set(obj->Delay.get()); -// ptrSPITObject->Fixed.set(obj->Fixed.get()); -// ptrSPITObject->FrameFadeInLength.set(obj->FrameFadeInLength.get()); -// ptrSPITObject->FrameFadeOutLength.set(obj->FrameFadeOutLength.get()); -// ptrSPITObject->FrameLength.set(obj->FrameLength.get()); -// ptrSPITObject->FrameStart.set(obj->FrameStart.get()); -// ptrSPITObject->Name.set(obj->Name.get()); -// ptrSPITObject->Remark.set(obj->Remark.get()); -// ptrSPITObject->SPITTypeID.set(obj->SPITTypeID.get()); -// ptrSPITObject->ServerParams.set(obj->ServerParams.get()); -// ptrSPITObject->Track.set(obj->Track.get()); -// ptrSPITObject->ValueFactor.set(obj->ValueFactor.get()); -// ptrSPITObject->ValueUse.set(obj->ValueUse.get()); + sObject->setActionAssigned(obj->getActionAssigned()); + sObject->Delay.set(obj->Delay.get()); + sObject->Duration.set(obj->Delay.get()); + sObject->Fixed.set(obj->Fixed.get()); + sObject->FrameFadeInLength.set(obj->FrameFadeInLength.get()); + sObject->FrameFadeOutLength.set(obj->FrameFadeOutLength.get()); + sObject->FrameLength.set(obj->FrameLength.get()); + sObject->FrameStart.set(obj->FrameStart.get()); + sObject->Name.set(obj->Name.get()); + sObject->Remark.set(obj->Remark.get()); + sObject->SPITTypeID.set(obj->SPITTypeID.get()); + sObject->ServerParams.set(obj->ServerParams.get()); + sObject->Track.set(obj->Track.get()); + sObject->ValueFactor.set(obj->ValueFactor.get()); + sObject->ValueUse.set(obj->ValueUse.get()); -// mCallbacks.onSpitObject(ObjectEvent::Changed, false, *ptrSPITType, *ptrSPITObject); -// sendSPITObjectInternal(ptrSPITObject); -// } -// return true; -// } + mCallbacks.onSpitObject(ObjectEvent::Changed, false, *sType, *sObject); + sendObjectInternal(sObject); + } + return true; +} -// /** -// * When the client wants to remove a SPITObject with id == p_SPITObjectID (normally the client should not do this), then he should send it to the SPITServer. -// * The corresponding SPITObject if listet in SPITObject will be deleted. -// * An eventRemoveSPITType will occur. -// * If an connection to a SPITServer is established, the SPITServer may discard the deletion and an eventSPITObject occurs -// * -> the SPITObject is listet again. -// * @param objId the id of the SPITObject to remove. -// * @return 0 = sended to the SPITServer, -1 = not sended to the SPITServer or nos SPITObject with id == objId exists. -// */ -// int SProcessor::removeSPITObject(string objId) { -// if (objId.length() <= 0) -// return -1; -// SType *ptrSPITType; -// SObject *ptrSPITObject; -// { -// Message::RemoveObject sMRemoveSPITObject; +/** + * When the client wants to remove a SPITObject with id == p_SPITObjectID (normally the client should not do this), then he should send it to the SPITServer. + * The corresponding SPITObject if listet in SPITObject will be deleted. + * An eventRemoveSPITType will occur. + * If an connection to a SPITServer is established, the SPITServer may discard the deletion and an eventSPITObject occurs + * -> the SPITObject is listet again. + * @param objId the id of the SPITObject to remove. + * @return 0 = sended to the SPITServer, -1 = not sended to the SPITServer or nos SPITObject with id == objId exists. + */ +int SProcessor::removeObject(string objId) { + if (objId.length() <= 0) + return -1; + SType *sType; + SObject *sObject; + { + Message::RemoveObject remObj; -// ptrSPITObject = mSpitObjects.getEntry(objId); -// if (ptrSPITObject == nullptr) -// return -1; -// ptrSPITType = mSpitTypes.getEntry(ptrSPITObject->SPITTypeID.get()); -// if (ptrSPITType == nullptr) -// return -1; -// ptrSPITObject->fillMessageOP(sMRemoveSPITObject); -// mCallbacks.onSpitObject(ObjectEvent::Deleted, false, *ptrSPITType, *ptrSPITObject); -// mSpitObjects.removeEntry(*ptrSPITObject); -// // return sendSPITMessage(sMRemoveSPITObject); -// return 1; -// } -// return -1; -// } + sObject = mSpitObjects.getEntry(objId); + if (sObject == nullptr) + return -1; + sType = mSpitTypes.getEntry(sObject->SPITTypeID.get()); + if (sType == nullptr) + return -1; + sObject->fillMessageOP(remObj); + mCallbacks.onSpitObject(ObjectEvent::Deleted, false, *sType, *sObject); + mSpitObjects.removeEntry(*sObject); + mInternCallbacks.sendMessage(remObj); + } + return -1; +} // //----- Play SPIT Objects ------ -// void SProcessor::parsePlaySPITStart(Message::PlayStart &message) { -// ESP_LOGD(TAG, "parse PlayStart ID: %s Name: %s Running: %d", message.getPlayerID().c_str(), message.getPlayerName().c_str(), (int)message.getPlayerIsRunning()); -// SPlayer &spitPlayer = SPlayer::getSPITPlayer(message.getPlayerID()); -// spitPlayer.setIsRunning(message.getPlayerIsRunning()); -// spitPlayer.setName(message.getPlayerName()); -// spitPlayer.setType(message.getPlayerType()); -// spitPlayer.setTime(message.getTime()); -// spitPlayer.startPlaySequence(); +void SProcessor::parsePlayStart(Message::PlayStart &message) { + ESP_LOGD(TAG, "parse PlayStart ID: %s Name: %s Running: %d", message.getPlayerID().c_str(), message.getPlayerName().c_str(), (int)message.getPlayerIsRunning()); + SPlayer &player = SPlayer::getSPITPlayer(message.getPlayerID()); + player.setIsRunning(message.getPlayerIsRunning()); + player.setName(message.getPlayerName()); + player.setType(message.getPlayerType()); + player.setTime(message.getTime()); + player.startPlaySequence(); -// mCallbacks.onPlay(spitPlayer.getID(), spitPlayer.getName(), spitPlayer.getType(), spitPlayer.getIsRunning(), spitPlayer.getTime()); -// } -// void SProcessor::parsePlaySPITObject(Message::PlayObject &message) { + mCallbacks.onPlay(player.getID(), player.getName(), player.getType(), player.getIsRunning(), player.getTime()); +} -// SPlayer &ptrSPITPlayer = SPlayer::getSPITPlayer(message.getPlayerID()); -// SObject *ptrSPITObject = mSpitObjects.getEntry(message.getSPITObjectID()); +void SProcessor::parsePlayObject(Message::PlayObject &message) { -// if (ptrSPITObject == nullptr) { -// return; -// } -// SPlayer::PlayType *ptrPlaySPITType = ptrSPITPlayer.addTypePlaying(ptrSPITObject->SPITTypeID.get()); -// if (ptrPlaySPITType == nullptr) { -// return; -// } -// ptrPlaySPITType->setPlayerIsRunning(ptrSPITPlayer.getIsRunning()); -// ptrPlaySPITType->addValue(((double)message.getValue() / 1000000), ((double)ptrSPITObject->ValueFactor.get() / 1000000)); -// } + SPlayer &player = SPlayer::getSPITPlayer(message.getPlayerID()); + SObject *sObject = mSpitObjects.getEntry(message.getSPITObjectID()); -// void SProcessor::parsePlaySPITEnd(Message::PlayEnd &message) { -// SPlayer &ptrSPITPlayer = SPlayer::getSPITPlayer(message.getPlayerID()); + if (sObject == nullptr) { + return; + } + SPlayer::PlayType *playType = player.addTypePlaying(sObject->SPITTypeID.get()); + if (playType == nullptr) { + return; + } + playType->setPlayerIsRunning(player.getIsRunning()); + playType->addValue(((double)message.getValue() / 1000000), ((double)sObject->ValueFactor.get() / 1000000)); +} -// auto &ptrPlaySPITTypes = ptrSPITPlayer.getPlaySPITTypes(); -// for (auto i = ptrPlaySPITTypes.begin(); i != ptrPlaySPITTypes.end(); i++) { -// SPlayer::PlayType *ptrPlaySPITType = i->second.get(); -// bool boolStarted = ptrPlaySPITType->getIsNew(); -// bool boolStopped = (ptrPlaySPITType->getIsPlayed() == false); -// SType *ptrSPITType = mSpitTypes.getEntry(ptrPlaySPITType->getSPITTypeID()); -// if (ptrSPITType == nullptr) { -// // set isplayed to false, the ptrPlayObject will be removed by ptrSPITPlayer.endPlaySequence() -// ptrPlaySPITType->setIsPlayed(false); -// continue; -// } -// mCallbacks.onPlaySpitType(ptrPlaySPITType->getPlayerID(), ptrPlaySPITType->getSPITTypeID(), ptrPlaySPITType->getPlayerIsRunning(), boolStarted, boolStopped, ptrPlaySPITType->getValue()); -// } -// ptrSPITPlayer.endPlaySequence(); -// } +void SProcessor::parsePlayEnd(Message::PlayEnd &message) { + SPlayer &sPlayer = SPlayer::getSPITPlayer(message.getPlayerID()); -// void SProcessor::parseReportPlayStatus(Message::ReportPlayStatus &message) { -// SType *ptrSPITType = NULL; + auto &playTypes = sPlayer.getPlaySPITTypes(); + for (auto i = playTypes.begin(); i != playTypes.end(); i++) { + SPlayer::PlayType *playType = i->second.get(); + bool isStarted = playType->getIsNew(); + bool iStopped = (playType->getIsPlayed() == false); + SType *ptrSPITType = mSpitTypes.getEntry(playType->getSPITTypeID()); + if (ptrSPITType == nullptr) { + // set isplayed to false, the ptrPlayObject will be removed by sPlayer.endPlaySequence() + playType->setIsPlayed(false); + continue; + } + mCallbacks.onPlaySpitType(playType->getPlayerID(), playType->getSPITTypeID(), playType->getPlayerIsRunning(), isStarted, iStopped, playType->getValue()); + } + sPlayer.endPlaySequence(); +} -// SObject *ptrSPITObject = mRemoteSpitObjects.getEntry(message.getID()); -// if (ptrSPITObject == nullptr) { -// ptrSPITObject = mSpitObjects.getEntry(message.getID()); -// if (ptrSPITObject == nullptr) { -// return; -// } -// } -// if (ptrSPITObject->ServerRemote.get() == false) { -// ptrSPITType = mSpitTypes.getEntry(ptrSPITObject->SPITTypeID.get()); -// } else { -// ptrSPITType = mRemoteSpitTypes.getEntry(ptrSPITObject->SPITTypeID.get()); -// } +void SProcessor::parseReportPlayStatus(Message::ReportPlayStatus &message) { + SType *sType = NULL; -// if (ptrSPITType == nullptr) { -// return; -// } -// mCallbacks.onPlayRemoteObjectStatus(*ptrSPITType, *ptrSPITObject, message.getFrameInsideObject(), message.getValue()); -// } + SObject *sObject = mRemoteSpitObjects.getEntry(message.getID()); + if (sObject == nullptr) { + sObject = mSpitObjects.getEntry(message.getID()); + if (sObject == nullptr) { + return; + } + } + if (sObject->ServerRemote.get() == false) { + sType = mSpitTypes.getEntry(sObject->SPITTypeID.get()); + } else { + sType = mRemoteSpitTypes.getEntry(sObject->SPITTypeID.get()); + } + + if (sType == nullptr) { + return; + } + mCallbacks.onPlayRemoteObjectStatus(*sType, *sObject, message.getFrameInsideObject(), message.getValue()); +} // //--------- Remote ---------- -// /** -// * Send a remote control command to the SPITServer. -// * There may be different command types: -// * a) Some don't use value e.g. go to next scene, olay a jingle -// * b) Some use values e.g. the main sound fader -// * @param p_SPITObjectID the id of the remote SPITObject (this represents the remote control command) -// * @param valuePpm the value in ppm -// * in case a) the value is ignored -// * in case b) the value is used -// * @param valueFlag indicates how the server should use valuePpm: -// * VALUEFLAG_DIRECT (0x00) The server overwrites its existing value with p_Value -// * VALUEFLAG_INCREASE (0x01) The server increases his existing value by valuePpm -// * VALUEFLAG_DECREASE (0x01) The server decreases his existing value by valuePpm -// */ -// void SProcessor::sendRemoteObject(string p_SPITObjectID, int valuePpm, char valueFlag) { -// SObject *ptrRemoteSPITObject = mRemoteSpitObjects.getEntry(p_SPITObjectID); -// if (ptrRemoteSPITObject == nullptr) -// return; +/** + * Send a remote control command to the SPITServer. + * There may be different command types: + * a) Some don't use value e.g. go to next scene, olay a jingle + * b) Some use values e.g. the main sound fader + * @param sObjectId the id of the remote SPITObject (this represents the remote control command) + * @param valuePpm the value in ppm + * in case a) the value is ignored + * in case b) the value is used + * @param valueFlag indicates how the server should use valuePpm: + * VALUEFLAG_DIRECT (0x00) The server overwrites its existing value with p_Value + * VALUEFLAG_INCREASE (0x01) The server increases his existing value by valuePpm + * VALUEFLAG_DECREASE (0x01) The server decreases his existing value by valuePpm + */ +void SProcessor::sendRemoteObject(string sObjectId, int valuePpm, char valueFlag) { + SObject *remoteObject = mRemoteSpitObjects.getEntry(sObjectId); + if (remoteObject == nullptr) + return; -// Message::PlayStart playSPITStart(mGuid, mProjName, PLAYERTYPE_DISCRETE); -// playSPITStart.setPlayerIsRunning(false); -// playSPITStart.setTime(0); -// // sendSPITMessage(playSPITStart); + Message::PlayStart playSPITStart(mGuid, mProjName, SPlayer::PTYPE_DISCRETE); + playSPITStart.setPlayerIsRunning(false); + playSPITStart.setTime(0); + mInternCallbacks.sendMessage(playSPITStart); -// Message::PlayObject playSPITObject; -// playSPITObject.setID(ptrRemoteSPITObject->getID()); -// playSPITObject.setPlayPrePosition(false); -// playSPITObject.setPlayerID(mGuid); -// playSPITObject.setValue(valuePpm); -// playSPITObject.setValueFlag(valueFlag); -// // sendSPITMessage(playSPITObject); + Message::PlayObject playSPITObject; + playSPITObject.setID(remoteObject->getID()); + playSPITObject.setPlayPrePosition(false); + playSPITObject.setPlayerID(mGuid); + playSPITObject.setValue(valuePpm); + playSPITObject.setValueFlag(valueFlag); + mInternCallbacks.sendMessage(playSPITObject); -// Message::PlayEnd playSPITEnd(mGuid); -// // sendSPITMessage(playSPITEnd); -// } + Message::PlayEnd playSPITEnd(mGuid); + mInternCallbacks.sendMessage(playSPITEnd); +} } // namespace spit \ No newline at end of file diff --git a/components/spit/uTest/spitProcessorTest.cpp b/components/spit/uTest/spitProcessorTest.cpp index 0195019..3c5dbdb 100644 --- a/components/spit/uTest/spitProcessorTest.cpp +++ b/components/spit/uTest/spitProcessorTest.cpp @@ -58,7 +58,13 @@ class SpitClientFix { .onPlayRemoteObjectStatus = [&](const SType &t, const SObject &o, uint64_t p_FrameInsideObject, int value) { client.onPlayRemoteObjectStatus(t, o, p_FrameInsideObject, value); }, .onCheckSpitTypeVeto = [&](bool knownType, bool createdByClient) { return client.onCheckSpitTypeVeto(knownType, createdByClient); }, .onCheckSpitObjectVeto = [&](bool knownType) { return client.onCheckSpitObjectVeto(knownType); }}; - SProcessor sut{"sut", "sutProj", "dev", "##GUID##", callbacks}; + SProcessor::InternalCallbacks intCallbacks { + .delay = [&](int ms){ return ; }, + .sendMessage = [&](Message::OPPart &msg){ return 0; }, + .sendTypeInternal = [&](SType &sType) { return 0; }, + .sendObjectInternal = [&](SObject *sObject) { return 0; } + }; + SProcessor sut{"sut", "sutProj", "dev", "##GUID##", callbacks, intCallbacks}; }; TEST_CASE_FIXTURE(SpitClientFix, "Spit types") { diff --git a/components/spit/uTest/spitProcessor_complexTest.cpp b/components/spit/uTest/spitProcessor_complexTest.cpp index 2b09b6a..9c0ef85 100644 --- a/components/spit/uTest/spitProcessor_complexTest.cpp +++ b/components/spit/uTest/spitProcessor_complexTest.cpp @@ -58,7 +58,13 @@ class SpitClientCmplsFix { .onPlayRemoteObjectStatus = [&](const SType &t, const SObject &o, uint64_t p_FrameInsideObject, int value) { client.onPlayRemoteObjectStatus(t, o, p_FrameInsideObject, value); }, .onCheckSpitTypeVeto = [&](bool knownType, bool createdByClient) { return client.onCheckSpitTypeVeto(knownType, createdByClient); }, .onCheckSpitObjectVeto = [&](bool knownType) { return client.onCheckSpitObjectVeto(knownType); }}; - SProcessor sut{"sut", "sutProj", "dev", "##GUID##", callbacks}; + SProcessor::InternalCallbacks intCallbacks { + .delay = [&](int ms){ return ; }, + .sendMessage = [&](Message::OPPart &msg){ return 0; }, + .sendTypeInternal = [&](SType &sType) { return 0; }, + .sendObjectInternal = [&](SObject *sObject) { return 0; } + }; + SProcessor sut{"sut", "sutProj", "dev", "##GUID##", callbacks, intCallbacks}; }; static void spoofMsgCounter(std::vector &msg, uint8_t cnt) { diff --git a/core b/core index acdd1ee..14491fb 160000 --- a/core +++ b/core @@ -1 +1 @@ -Subproject commit acdd1ee9300d4ab65ad1118dadd497a75e8b86f6 +Subproject commit 14491fb9c745bb3a2b716ac20071897fe06bdf35 diff --git a/main/watchMain.cpp b/main/watchMain.cpp index 3df79a1..e4e9882 100644 --- a/main/watchMain.cpp +++ b/main/watchMain.cpp @@ -854,14 +854,14 @@ void onPlay(string p_PlayerID, string p_PlayerName, char p_PlayerType, bool p_Pl ESP_LOGD(TAG, "eventPlay Player: %s Runs: %d Time: %lld", p_PlayerName.data(), p_PlayerIsRunning, p_TimeFrames); switch (p_PlayerType) { - case SClient::PLAYERTYPE_MAIN: + case SClient::PlayerType::PTYPE_MAIN: // p_FrameTimes contains the position inside the server's project, we can use it like a timecode // int intMilliseconds = (int)(((double)p_TimeFrames / (double)m_ServerFramesPerSecond) * 1000); break; - case SClient::PLAYERTYPE_CONTINOUS: + case SClient::PlayerType::PTYPE_CONTINOUS: // The olayer is playing only single Object sequences sometime during the project break; - case SClient::PLAYERTYPE_DISCRETE: + case SClient::PlayerType::PTYPE_DISCRETE: // Only discrete values where submitted, e.g the fader position of remote faders. break; } @@ -934,7 +934,7 @@ void SpitClientApp() { for (auto &obj : ProvidedObj) { SType *ptrSPITType1Fix = spitClient.createTypeFixed(obj.iD, obj.groupName, obj.name, 0, 0); - spitClient.setActionSPITType(ptrSPITType1Fix->getID(), true); // should be executed whenever a SPITObject with this SPITType is played + spitClient.setActionType(ptrSPITType1Fix->getID(), true); // should be executed whenever a SPITObject with this SPITType is played } spitClient.clientProjectLoaded(); spitClient.startServerAutoDetect();