FSMBase.h

#pragma once

#include<iostream>
#include<string>
#include<vector>
#include "InvokeFunction.h"
#include "MethodHolder.h"


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

	FSMBase();
	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"
#include "MethodHolder.h"
#include "InvokeFunction.h"

using namespace std;
using namespace rapidjson;



	FSMBase::FSMBase()
	{
		std::cout << "default constructor 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);

	//InvokeFunction invokeFunc;
	//MethodHolder::GetInstance().RegisterMethod("EnterSVelPointEdit", [&invokeFunc]() {invokeFunc.EnterSVelPointEdit(); });
	//MethodHolder::GetInstance().RegisterMethod("EnterSVelPointEdit",InvokeFunction::&EnterSVelPointEdit());


	InvokeFunction invokeFunc;
	MethodHolder::GetInstance().RegisterMethod("EnterSVelPointEdit", [&invokeFunc]() {invokeFunc.EnterSVelPointEdit(); });

	Event* event3 = new Event("ClickStartPoint", "InvokeMethod", "EnterSVelPointEdit");
	prTool1->InEvent(event3);

	


	Event* event5 = new Event("ClickEndPoint", "InvokeMethod", "EnterEVelPointEdit");
	prTool1->InEvent(event5);

	

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

	delete event1;
	delete event2;
	delete event3;
	delete prTool1;

	
	
	return 0;
}

FSMBuilder.h

#pragma once
#include<rapidjson/document.h>
#include "FSMBase.h"
#include "PrimitiveTool.h"
#include "Event.h"
#include "State.h"
#include<string>



class FSMBuilder
{
public:
	static void createStatesFromJson(PrimitiveTool* primitiveTool, rapidjson::Document& doc);
};

#pragma once
#include "FSMBase.h"
#include "State.h"
#include <unordered_map>

class State;
class Event;

class PrimitiveTool :
    public FSMBase
{
private:
   

    State* currentState = nullptr;
public:

    void Add(FSMBase* b1);
    void SetInitialState(const std::string& stateName);
    void InEvent(Event* event);
    State* GetActiveStatus();
    State* Search(const std::string& name);
    void ChangeState(const std::string& newStateName);

};

PrimitiveTool.cpp
#include "PrimitiveTool.h"

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 "PrimitiveTool.h"

class PrimitiveTool;

class Event;



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 InEvent(Event* event);
    Event* Search(const std::string& name);
    void ChangeState(Event* event);
    

};

State.cpp

#include "State.h"
#include "Event.h"
#include "PrimitiveTool.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"
//#include "State.h"
#include <string>
#include <map>
//#include "InvokeFunction.h"
#include "MethodHolder.h"


class PrimitiveTool;
class State;


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"
#include "MethodHolder.h"
#include "InvokeFunction.h"
#include "State.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;
		MethodHolder::GetInstance().InvokeMethod(ActionParam);

		/*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;
		}*/
	
	}
}




MethodHolder.h

#pragma once
#include <iostream>
#include <map>
#include <string>
#include <functional>
#include "InvokeFunction.h"

class MethodHolder
{

public:
    using MethodPointer = std::function<void()>;

    static MethodHolder& GetInstance() {
        static MethodHolder instance;
        return instance;
    }

    void InvokeMethod(const std::string& methodName);
    void RegisterMethod(const std::string& methodName, MethodPointer methodPtr);

private:
    MethodHolder() {}
    MethodHolder(const MethodHolder&) = delete;
    MethodHolder& operator=(const MethodHolder&) = delete; 

    std::map<std::string, MethodPointer> MethodMap;
};

MethodHolder.cpp

#include "MethodHolder.h"

void MethodHolder::InvokeMethod(const std::string& methodName)
{
    auto it = MethodMap.find(methodName);
    if (it != MethodMap.end()) {
        it->second();

    }
    else {
        std::cout << "Method not found: " << methodName << std::endl;
    }
}

void MethodHolder::RegisterMethod(const std::string& methodName, MethodPointer methodPtr)
{
    MethodMap[methodName] = methodPtr;
}


InvokeFunction.h

#pragma once
#include "Event.h"
#include "MethodHolder.h"
#include "FSMBase.h"


class InvokeFunction
{
public:
	void EnterSVelPointEdit();
	void EnterEVelPointEdit();
	void EncoderInc();


};

InvokeFunction.h


#pragma once
#include "Event.h"
#include "MethodHolder.h"
#include "FSMBase.h"


class InvokeFunction
{
public:
	void EnterSVelPointEdit();
	void EnterEVelPointEdit();
	void EncoderInc();


};


i am getting below errors

Severity	Code	Description	Project	File	Line	Suppression State	Details
Error	C2664	'void State::Add(FSMBase *)': cannot convert argument 1 from 'Event *' to 'FSMBase *'	FsmImplementation	C:\Users\1038586\Downloads\FsmImplementation11142024\FsmImplementation\FsmImplementation\FSMBuilder.cpp	32		
Warning	C26495	Variable 'Event::parentState' is uninitialized. Always initialize a member variable (type.6).	FsmImplementation	C:\Users\1038586\Downloads\FsmImplementation11142024\FsmImplementation\FsmImplementation\Event.cpp	19		
Error	C2504	'FSMBase': base class undefined	FsmImplementation	C:\Users\1038586\Downloads\FsmImplementation11142024\FsmImplementation\FsmImplementation\Event.h	16		
Error	C2504	'FSMBase': base class undefined	FsmImplementation	C:\Users\1038586\Downloads\FsmImplementation11142024\FsmImplementation\FsmImplementation\Event.h	16		
Error	C2664	'void State::Add(FSMBase *)': cannot convert argument 1 from 'Event *' to 'FSMBase *'	FsmImplementation	C:\Users\1038586\Downloads\FsmImplementation11142024\FsmImplementation\FsmImplementation\FSMBuilder.cpp	49		
Error	C2504	'FSMBase': base class undefined	FsmImplementation	C:\Users\1038586\Downloads\FsmImplementation11142024\FsmImplementation\FsmImplementation\Event.h	16		
Error	C2504	'FSMBase': base class undefined	FsmImplementation	C:\Users\1038586\Downloads\FsmImplementation11142024\FsmImplementation\FsmImplementation\Event.h	16