Comments (5)
@ltinphan @shamim-akhtar This is not the only bug :( ! For this particular point: there is a mixture with the FiniteStateMachine::add
that Shamim probably wanted to call. Since the method is never called and C++ lazy, this code compiles file. A quick fix is mStates[stateID] = state;
But there are plenty of major issues:
- Please do not use
0
(== NULL from C) but use insteadnullptr
(that use type checking by the C++ compiler). State<T>* getState(T stateID)
the presence of stateID should be checked, else themStates[stateID]
will create a new state before returning it (that we do not want).- Preferred to use references than raw pointers (+ constness)
State<T>* getCurrentState()
,void setCurrentState(State<T>* state)
=>void setCurrentState(State<T> const& state)
. virtual State::~State() = default
is missing and needed because of virtual methods + delete called. A real compiler will warn you.- Why calling
new
anddelete
in the main ? 1/ Usestd::unique_ptr
instead ! 2/ If raw pointers are wanted, make the State machine release memory and call delete from its destructor. fsm->add(new TurnstileLockedState(*fsm));
this can be simplified by using 1/ template:fsm->add<TurnstileLockedState>()
and 2/ let theadd
method passthis
for you and let it callnew
(or better std::make_unique) for you. Do not let the user allocating memory for you !virtual ~Functor() {}
this one is useless, you cannot overrideoperator()
class Functor
is not used in the example and cannot be used anyway (and in the case it's possible, please update your blog to give an example) and Functor are in double with virtual methods such asvirtual void enter()
In deed, if derived classes fromState
does not overrideenter(), exit(), update()
(which is the case in the example) methods from State will be called and in this case why having functors is not desiredif (mOnEnter) (*mOnEnter)(*this);
useless. Therefore,State
shall have these methods do nothing ievirtual void enter() {}
and let derived class override them.
I hope I did hurt you, but please fix all these issues: do not let your blog with these major bugs (the article is interesting anyway). You may use the design pattern State instead.
from fsm-cpp.
Thanks for raising the issues. It's strange that I didn't check thoroughly after writing the quick tutorial and I have no excuse for that. I have pushed my amendments to a new branch. https://github.com/shamim-akhtar/fsm-cpp/tree/issues-Lecrapouille-ltinphan. I have yet to address the memory ownership issue. I am aware of the problems raised by @Lecrapouille and I have fixed some of this today morning. I will need to sit down and look thoroughly for the memory ownership, whether to use a shared_ptr for shared instances.
I have also added a simple test for the Functor. @ltinphan and @Lecrapouille please take a look at the changes and let me know your inputs.
Thanks again for your suggestions.
I will amend the tutorial after these fixes.
from fsm-cpp.
@shamim-akhtar no worries ! I made a quick code review. I still do not understand why functors are needed, I think you had them because you forget to make virtual ... override methods on derived classes (see my code review). You should give a try without Functor.
For the fsm->add(new TurnstileLockedState(*fsm));
method fsm->add(state_locked.get());
is not a good way to do it. I was thinking about something like:
template<class T>
T& FiniteStateMachine::add()
{
mStates[id] = std::make_unique<T>(*this);
return *mStates[id];
}
state_locked = fsm->add<TurnstileLockedState>();
With a check that T is a derived class from the State class: maybe using std::is_same
?
You do not need shared_ptr
just use unique_ptr
(but std::make_unique need C++14 or if C++11 is needed see https://en.cppreference.com/w/cpp/memory/unique_ptr/make_unique the Possible Implementation
section) and return the content as references. It's fine to let mCurrentState
as a raw pointer.
State<T>& getState(T stateID)
{
return *mStates[stateID];
}
State<T>& getCurrentState()
{
assert(mCurrentState != nullptr);
return *mCurrentState;
}
Else in main.cpp class TurnstileUnLockedState:
void update()
{
State<TurnstileStateType>::update();
if (KeyPresses['p'])
{
printf(" - pushed, locking turnstile\n");
mFsm.setCurrentState(TurnstileStateType::LOCKED);
}
}
you can add:
if (KeyPresses['p'])
{
...
}
else if (KeyPresses['c'])
{
printf("Coin already inserted. Return the coin\n");
}
from fsm-cpp.
@Lecrapouille Good suggestions. Thanks for the review. The idea of a functor is to allow the update, onEnter and onExit methods without deriving a new State class. I will look into this and implement the necessary. Thanks again for a detailed look into the code. Much appreciated.
from fsm-cpp.
if (KeyPresses['p'])
{
...
}
else if (KeyPresses['c'])
{
printf("Coin already inserted. Return the coin\n");
}
I wanted to show that event handling independent event handling is possible within the update of each state. That's the reason why I have two separate if statements in the individual states. This functionality will be apparent when we have a number of states.
I will be making these changes and making a pull request later today/
I have removed the functor. Yes, I guess it was redundant. It will be easier to just derive from State and implement those virtual functions viz., update, onEnter and onExit.
I think it was necessary to put deeper thought into the implementation. Thanks a lot for your time and your constructive feedback.
from fsm-cpp.
Related Issues (1)
Recommend Projects
-
React
A declarative, efficient, and flexible JavaScript library for building user interfaces.
-
Vue.js
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
-
Typescript
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
-
TensorFlow
An Open Source Machine Learning Framework for Everyone
-
Django
The Web framework for perfectionists with deadlines.
-
Laravel
A PHP framework for web artisans
-
D3
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
-
Recommend Topics
-
javascript
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
-
web
Some thing interesting about web. New door for the world.
-
server
A server is a program made to process requests and deliver data to clients.
-
Machine learning
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
-
Visualization
Some thing interesting about visualization, use data art
-
Game
Some thing interesting about game, make everyone happy.
Recommend Org
-
Facebook
We are working to build community through open source technology. NB: members must have two-factor auth.
-
Microsoft
Open source projects and samples from Microsoft.
-
Google
Google ❤️ Open Source for everyone.
-
Alibaba
Alibaba Open Source for everyone
-
D3
Data-Driven Documents codes.
-
Tencent
China tencent open source team.
from fsm-cpp.