Welcome, Guest. Please login or register. Did you miss your activation email?

Author Topic: A Simple and Easy to Use State Manager  (Read 3475 times)

0 Members and 1 Guest are viewing this topic.

Furkanzmc

  • Newbie
  • *
  • Posts: 13
    • View Profile
A Simple and Easy to Use State Manager
« on: March 18, 2014, 09:27:57 am »
Hello people.
I've written a simple, yet efficient, state manager. I'm relatively new to game development so I'm trying to learn as much as I can by creating as much as I can. I'm hoping it could do some good to some of you.
Here's the code: https://github.com/Furkanzmc/FUStateManager
« Last Edit: March 18, 2014, 09:32:48 am by Furkanzmc »

eXpl0it3r

  • SFML Team
  • Hero Member
  • *****
  • Posts: 10815
    • View Profile
    • development blog
    • Email
Re: A Simple and Easy to Use State Manager
« Reply #1 on: March 18, 2014, 10:17:44 am »
Cool! :)

Here a few points you might want to think about:

Your mixing of iterating over the states and std::find_if is flawed (afaik). You go through all states, then std::find_if will return the first occurrence where getDrawOverOtherStates() returns true for the given iterator till the end of the map. So if we have the following list where each digit represents the function return value: 10001100
Thus the iteration of std::find if would work like this:
1
0001
001
01
1
1
00
0
Not sure if that made sense, but what I'm trying to point out is, that you do too many iterations for nothing. You could use find_if and a while loop on its own, without having to iterate over all elements additionally.

A std::map has a function empty(), thus it would be more expressive to use that instead of site() == 0.

Is a std::shared_ptr needed? Shouldn't the state manager be the full owner of the state? If so, you might want to use std::unique_ptr.

get/setDrawOverOthers(States) is quite a long name and the "draw" is a bit misleading since it also applies for updating and event handling. Thus you might want to find something shorter and more precise.

isStateStackEmpty "reveals" an implementation detail, although you don't really use a stack internal. You might want to use something more generic.
Official FAQ: https://www.sfml-dev.org/faq.php
Official Discord Server: https://discord.gg/nr4X7Fh
——————————————————————
Dev Blog: https://duerrenberger.dev/blog/

Furkanzmc

  • Newbie
  • *
  • Posts: 13
    • View Profile
Re: A Simple and Easy to Use State Manager
« Reply #2 on: March 18, 2014, 11:32:54 am »
Thanks for your feedback!
I did correct the things you mentioned except the iteration thing. I get what you by that. I'll fix it in an hour.
Thank you again!!

EDIT:
Thank you. I corrected the problem.
« Last Edit: March 18, 2014, 01:52:43 pm by Furkanzmc »

MorleyDev

  • Full Member
  • ***
  • Posts: 219
  • "It is not enough for code to work."
    • View Profile
    • http://www.morleydev.co.uk/
Re: A Simple and Easy to Use State Manager
« Reply #3 on: March 19, 2014, 11:18:46 am »
The example is a unclear about what functions/interfaces the 'states' need to implement.

The basic functionality is neat, but why the need for a Context?

Are contexts maintained separately? If so, wouldn't different managers for different windows make more sense? Or just passing the window into the draw function as a reference, since drawing should be the only thing that depends on the Window.
Can I have duplicate state classes with different enumerators?
Does the system handle adding states with the same enumerator but different context?
Is there any way to pass parameters to states when constructing them? Not allowing this forces some really nasty hacks to achieve Dependency Injections.

Yes I could get many of these answers by looking at the implementation, but ideally I could get it from either Examples or Tests (or Tests as examples).

As an aside, I've come to hate the phrase "Manager". It tells me nothing about the class, it just tells me it "manages stuff", which can mean anything and ends up a magnet of functionality. Often it's a sign SRP is being broken or about to be broken. Trying to come up with a more descriptive name, and from the looks of this "FiniteStateMachine" is the best I can come up with, but it's also a lie if each context is a separate FSM.
« Last Edit: March 19, 2014, 11:25:06 am by MorleyDev »
UnitTest11 - A unit testing library in C++ written to take advantage of C++11.

All code is guilty until proven innocent, unworthy until tested, and pointless without singular and well-defined purpose.

Furkanzmc

  • Newbie
  • *
  • Posts: 13
    • View Profile
Re: A Simple and Easy to Use State Manager
« Reply #4 on: March 19, 2014, 02:59:29 pm »
Hi. You did bring up some interesting questions.  :)
Actually, I thought I could pass parameters using Contexts but considering it again now it's a bad way to pass parameters. I'll implement a new way to do that.
- You are right, the example isn't a good example. I'll update it.
- You can actually have duplicate states with different enumerators
- The system does not handle adding states with the same enumerator. Actually, the system does nothing with the context. The states use the context to get the some common parameters (like sf::RenderWindow, TextureHolder etc...) and use them inside the state. So there's no differentiation with the contexts.
- I, now, don't think Contexts are the way to pass parameters, although you can tweak it to pass parameters but that defeats the purpose of having a "Finite State Machine", so I'll think of a better way but if you have any suggestions I'd appreciate it. ;)
- I agree about the name too, now.

EDIT:
You can now pass parameters to a state on initialization. You can also get an individual state from the state manager and call the functions you want.

Thank you so much for your input!
« Last Edit: March 23, 2014, 09:18:12 pm by Furkanzmc »