My state machine handles requests and returns the next state. In the below simplification, I've got two states here, CreatedState and RunningState. Running state is the end state, and just returns itself. Running state has state (as in memebers) that need to be preseved, I'll use the integer count to represent them.
std::unique_pointer<StateBase> handle();
// Caller
void Call(){
_currentState = _currentState->handle();
}
// Created State Implementation
std::unique_pointer<StateBase> CreatedState::handle(){
return std::make_unique<RunningState>();
}
// Running State Implementation (option 1: create a new one)
std::unique_pointer<StateBase> RunningState::handle(){
return std::make_unique<RunningState>(RunningState(int count));
}
The problem here is that creating a new RunningState with a memento/all-of-the-private-members of the old RunningState is messy and probably inefficient(?).
In a managed language I might just return this, but if I did something like that: return std::make_unique<RunningState>(&this) I would have two pointers to the same object and the destruction of the lhs _currentState in the Call() would leave me with nothing to point at.
How can I cleanly and efficiently leave _currentState unchanged?
Edit: As much as passing things for the called method to alter pains me, I think it may be best to pass a reference to the pointer and let the handle() method alter it as it sees fit:
#include <iostream>
#include <string>
#include <memory>
void handle2(std::unique_ptr<int>& current, bool changePtr)
{
(*current)++;
if(changePtr){
auto foo = std::make_unique<int>(200);
(*foo)++;
current = std::move(foo); //destruction of lhs only happens if I want to change state
}
}
int main()
{
auto currentState = std::make_unique<int>(100);
handle2(currentState, true);
handle2(currentState, false);
std::cout << *currentState << std::endl;
}