FSMBase.h

#pragma once

#include<iostream>
#include<string>
#include<vector>

class FSMBase {
public:
	std::string StateName;
	std::string EventName;
	std::vector<FSMBase*> subitem;
	FSMBase* parent;

	FSMBase();
	void getdata();
	virtual void Add(FSMBase* b1);
	~FSMBase();
};






FSMBase.cpp

#include<iostream>
#include<string>
#include<vector>
#include<rapidjson/document.h>
#include<rapidjson/filereadstream.h>
#include<fstream> 
#include "FSMBase.h"
#include "PrimitiveTool.h"
#include "Event.h"
#include "State.h"
#include "FSMBuilder.h"

using namespace std;
using namespace rapidjson;



	FSMBase::FSMBase()
	{
		std::cout << "default constructor called" << std::endl;
	}

	void FSMBase::getdata()
	{
		std::cout << "FSMBase called" << std::endl;
	}


	void FSMBase::Add(FSMBase* b1)
	{
		subitem.push_back(b1);
		b1->getdata();
	
	}

	FSMBase::~FSMBase()
	{
		std::cout << " destructor called" << std::endl;
	}


int main()
{

	Document doc;
	ifstream file("FSMImplementationJSON.json");
	if (!file.is_open()) {
		cerr << "Could not open file: FSMImplementationJSON.json" << endl;
		return 1;
	}

	string json((istreambuf_iterator<char>(file)),
		istreambuf_iterator<char>());

	doc.Parse(json.c_str());

	if (doc.HasParseError()) {
		cerr << "Error parsing JSON: "
			<< doc.GetParseError() << endl;
		return 1;
	}
	 
	PrimitiveTool* prTool1 = new PrimitiveTool();
	FSMBuilder::createStatesFromJson(prTool1, doc);
	std::cout <<" " << std::endl;

	prTool1->SetInitialState("StartToolState");

	std::cout << "Initial Active State : " << (prTool1->GetActiveStatus() ? prTool1->GetActiveStatus()->StateName : "None") << std::endl;

	Event* event1 = new Event("CompleteEvent", "ChangeState", "WaitForAccept");
	
	prTool1->InEvent(event1);

	std::cout << "Active State after CompleteEvent: " << (prTool1->GetActiveStatus() ? prTool1->GetActiveStatus()->StateName : "None") << std::endl;
	Event* event2 = new Event("CompleteEvent", "ChangeState", "AcceptedState");
	prTool1->InEvent(event2);

	std::cout << "Active State after CompleteEvent 2: " << (prTool1->GetActiveStatus() ? prTool1->GetActiveStatus()->StateName : "None") << std::endl;

	delete event1;
	delete prTool1;
	
	return 0;
}


FSMBuilder.cpp


#include "FSMBuilder.h"
#include "rapidjson/document.h"
#include <fstream>

using namespace rapidjson;
using namespace std;

void FSMBuilder::createStatesFromJson(PrimitiveTool* primitiveTool, rapidjson::Document& doc)
{
	if (doc.HasMember("PrimitiveTool") && doc["PrimitiveTool"].HasMember("State") && doc["PrimitiveTool"]["State"].IsArray()) {
		const Value& states = doc["PrimitiveTool"]["State"];
		for (SizeType i = 0; i < states.Size(); ++i) {
			const Value& stateVal = states[i];
			State* StateObj = new State(primitiveTool);
			

			if (stateVal.HasMember("Name") && stateVal["Name"].IsString()) {
				StateObj->StateName = stateVal["Name"].GetString();
				StateObj->EntreyMethodName = stateVal.HasMember("EntryMethodName") ? stateVal["EntryMethodName"].GetString() : "";
				std::cout << "State: " << StateObj->StateName << "\n Entry method : " << StateObj->EntreyMethodName << std::endl;
			}

			if (stateVal.HasMember("Event")) {
				if (stateVal["Event"].IsObject()) {					
					const rapidjson::Value& eventVal = stateVal["Event"];
					Event* eventObj = new Event(StateObj);
					if (eventVal.HasMember("Name") && eventVal["Name"].IsString()) {
						eventObj->EventName = eventVal["Name"].GetString();
						eventObj->ActionType = eventVal.HasMember("ActionType") ? eventVal["ActionType"].GetString() : "";
						eventObj->ActionParam = eventVal.HasMember("ActionParam") ? eventVal["ActionParam"].GetString() : "";
						std::cout << " EventName : " << eventObj->EventName << "\n ActionType : " << eventObj->ActionType << "\n ActionParam :" << eventObj->ActionParam << std::endl;
						StateObj->Add(eventObj);
					}
				}
				else if (stateVal["Event"].IsArray()) {
					const Value& events = stateVal["Event"];
					for (SizeType j = 0; j < events.Size(); ++j) {
						const Value& eventVal = events[j];
						Event* EventObj = new Event(StateObj);

						if (eventVal.HasMember("Name") && eventVal["Name"].IsString()) {
							string eventName = eventVal["Name"].GetString();
							string actionType = eventVal.HasMember("ActionType") ? eventVal["ActionType"].GetString() : "";
							string actionParam = eventVal.HasMember("ActionParam") ? eventVal["ActionParam"].GetString() : "";
							EventObj->EventName = eventName;
							EventObj->ActionType = actionType;
							EventObj->ActionParam = actionParam;
							std::cout << "Created Event: " << EventObj->EventName<< ", Action Type: " << EventObj->ActionType<< ", Action Param: " << EventObj->ActionParam << std::endl;
							StateObj->Add(EventObj);
						}
					}
				}
			}
			primitiveTool->Add(StateObj);
		}
	}
}



PrimitiveTool.cpp

void PrimitiveTool::Add(FSMBase* b1)
{

	subitem.push_back(b1);
	if (State* state = dynamic_cast<State*>(b1)) {
		state->parent = this;
		currentState = state;
	}
	
}

void PrimitiveTool::SetInitialState(const std::string& stateName)
{
	State* initialState = Search(stateName);
	if (initialState) {
		currentState = initialState;
		//std::cout << "Initial state set to: " << currentState->StateName << std::endl;
	}
	else {
		std::cout << "State not found: " << stateName << std::endl;
	}
}

void PrimitiveTool::InEvent(Event* event)
{
	if (!currentState)
		return;
	State* state = Search(currentState->StateName);
	if (state) {
		//std::cout << " searched state is : " <<StateName<< std::endl;
		state->InEvent(event);
		
	}
}

State* PrimitiveTool::GetActiveStatus()
{
	return currentState;
}

State* PrimitiveTool::Search(const std::string& name)
{
	for (FSMBase* item : subitem) {
		State* state = dynamic_cast<State*>(item);
		if (state && state->StateName == name) {
			std::cout << "Found STATE :" << name << std::endl;
			return state;
		}
	}
	return nullptr;
}

void PrimitiveTool::ChangeState(const std::string& newStateName)
{
	State* newState = Search(newStateName);
	if (newState) {
		currentState = newState;
		std::cout << "Changed to state: " << currentState->StateName << std::endl;
	}
	else {
		std::cout << "not found state: " << newStateName << std::endl;
	}
}


State.h


#pragma once
#include "FSMBase.h"
#include "Event.h"
#include "PrimitiveTool.h"
class Event;
class PrimitiveTool;
class FSMBase;

class State :
    public FSMBase
{
private:
    PrimitiveTool* parentTool;
    
public:
    State(PrimitiveTool* toolParent) : parentTool(toolParent) {
       
    }


    std::string EntreyMethodName;
    std::vector<Event*> eventitem;

    void Add(FSMBase* fsmbase1);
    void getdata(const std::string Name, const std::string Methodname);
    void InEvent(Event* event);
    Event* Search(const std::string& name);
    

};



State.cpp

#include "State.h"


void State::InEvent(Event* event)
{
	Event* matchedevent = Search(event->EventName);
	if (matchedevent) {
		matchedevent -> InEvent(event);
		std::cout << " matched event is : " << matchedevent->EventName << "action type is : " << matchedevent->ActionType<<std::endl;
	}
	else {
		std::cout << "NO MATCHING EVENT FOUND" << std::endl;
	}
}

Event* State::Search(const std::string& name)
{
	for (Event* event : eventitem) {
		if (event->EventName == name) {
			std::cout << "Found event :" << name << std::endl;
			return event;
		}
	}
	return nullptr;
}

void State::ChangeState(Event* event)
{
	if (event->ActionType == "ChangeState") {
		if (parentTool) {
			parentTool->ChangeState(event->ActionParam);
		}
	}
}

void State::Add(FSMBase* fsmbase1)
{
	subitem.push_back(fsmbase1);
	if (Event* event = dynamic_cast<Event*>(fsmbase1)) {
		eventitem.push_back(event); 
		std::cout << "ADding event:" << event->EventName << " to state : " << StateName << std::endl;
	}	
}





Event.h

#pragma once
#include "FSMBase.h"
#include "PrimitiveTool.h"



class State;
class PrimitiveTool;

class Event :
    public FSMBase
{
private:
    State* parentState;
public:
    Event(const std::string& eventName, const std::string& eventType, const std::string& eventTarget);
    Event(State* stateParent) : parentState(stateParent) {}

    std::string EventName;
    std::string ActionType;
    std::string ActionParam;
   
   
    std::string getActionType() const;
    std::string getName() const;
    void InEvent(Event* event);

       
};





Event.cpp
#include "Event.h"

typedef void(*FunctionPointer)();

std::map<std::string, FunctionPointer>

functionmap = {
	{"EnterSVelPointEdit",&EnterSVelPointEdit},{"EnterEVelPointEdit", &EnterEVelPointEdit},{"EncoderInc",&EncoderInc}
};

Event::Event(const std::string& eventName, const std::string& eventType, const std::string& eventTarget)
{
	EventName = eventName;
	ActionType = eventType;
	ActionParam = eventTarget;
}

std::string Event::getActionType() const
{
	return ActionType;
}

std::string Event::getName() const
{
	return EventName;
}


void Event::InEvent(Event* event)
{
	if (ActionType=="ChangeState") {	
		if (parentState) {	
			parentState->ChangeState(event);
		}

	}
	else if(ActionType=="InvokeMethod")
	{
		std::cout << "Invoke method called" << std::endl;

		auto it = functionmap.find(event->ActionParam);
		if (it != functionmap.end()) {
			FunctionPointer func = it->second;
			func();
		}
	
		else {
			std::cout << "no action method set for InvokeMethod" << std::endl;
		}
	
	}
}

In the above fsm implementation code i want to add a class called MethodHolder class in singleton design pattern.And MethodHolder class having InvokeMethod function.
And there is another class called polygon where 

class Polygon{
void getWell();
Void SetWell();
};

MethodHolder mh;
mh.RegisterMethod["MotionEvent",&getWell()];
mh.RegisterMethod["ClickEvent",&setWell()];


In the fsm implementation,Inevent class when the ActionType=="InvokeMethod" and the if the ActionParam=MotionEvent,it should call and implement the getWell() defined in eg; polygon class or any other class where the getWell() is defined