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 << "calling...................." << std::endl;


	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->getdata(stateVal["Name"].GetString(), stateVal["EntryMethodName"].GetString());
			}

			if (stateVal.HasMember("Event")) {
				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->getdata(eventName, actionType, actionParam);
							StateObj->Add(EventObj);
						}
					}
				}
			}
			primitiveTool->Add(StateObj);
		}
	}
}


PrimitiveTool.cpp

#include "PrimitiveTool.h"

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

	if (State* state = dynamic_cast<State*>(b1)) {
		currentState = state; 
	}
}

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

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 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::getdata(const std::string Name, const std::string Methodname)
{
	StateName = Name;
	EntreyMethodName = Methodname;
	std::cout <<"state name: "<< StateName << "Entry method :  " << EntreyMethodName << std::endl;
}

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->getName() == EventName) {
			std::cout << "Found event :" << name << std::endl;
			return event;
		}
	}
	return nullptr;
}

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







Event.h


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


class State;

class Event :
    public FSMBase
{
private:
    State* parentState;
public:
    Event(State* stateParent) : parentState(stateParent) {}

    std::string EventName;
    std::string ActionType;
    std::string ActionParam;
   
   
    std::string getActionType() const;
    std::string getName() const;
    void getdata(const std::string Name, const std::string ActType, const std::string ActPar);
    void InEvent(Event* event);

       
};





Event.cpp

#include "Event.h"



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

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

void Event::getdata(const std::string Name, const std::string ActType, const std::string ActPar)
{
	EventName = Name;
	ActionType = ActType;
	ActionParam = ActPar;

	std::cout << "Event: " << EventName << " ActionType " << ActionType << " ActionParam:  " << ActionParam << std::endl;
}

void Event::InEvent(Event* event)
{
	if (ActionType=="ChangeState") {
		if (parentState) {
			PrimitiveTool* pTool = dynamic_cast<PrimitiveTool*>(parentState->parent);
			if (pTool) {
				pTool->ChangeState(ActionParam);
			}
		}

	}
}

provide the code to add in main() just to check the working of fsm implemention of change state happens or not