Haha, er barst een leuke discussie los, volledig volgens verwachting en precies de bedoeling. Interessant om te zien hoe anderen denken en werken. Dat helpt bij het vinden van oplossingen voor de nadelen van deze code.
Misschien goed om te vermelden, dit is natuurlijk voor een knipperledje totaal overbodig. Voor kleine statemachines is een switch case prima.
Complexiteit:
Ja, deze implementatie gebruikt pointers, waaronder functiepointers. Persoonlijk vind ik dat dit bij de basiskennis van een C-programmeur hoort. De pijlnotatie en het werken met functiepointers zijn nu eenmaal onderdeel van de taal. Zoals ik in mijn startpost al aangaf, kun je met helperfuncties de complexiteit verder abstraheren. Denk bijvoorbeeld aan een helperfunctie `SetNextState(context, MyState);`, die het instellen van de volgende state makkelijker maakt zonder direct met functiepointers te werken.
isFirstRun:
@Kortsluiting_Online: Ik begrijp je voorstel als alternatief voor `isFirstRun` niet helemaal. Zou je een voorbeeld kunnen geven om dit verder toe te lichten?
Structuur en Volgorde van Code:
Ik ben het eens met de opmerkingen over het opsplitsen van de code. Normaal gesproken houd ik de `main` klein. In dit specifieke voorbeeld zou ik de code opdelen in drie delen:
State Machine Code: Een bestand met de logica van de state machine zelf.
Main Code: Een bestand voor de `main` functie.
State Logic: Een bestand voor de verschillende states en hun specifieke logica.
TimeInState:
De manier waarop `TimeInState` is opgezet voorkomt overflow problemen, zoals deKees ook al aangeeft. Omdat de waarden unsigned zijn, wordt de berekening bij overflow automatisch gecorrigeerd. Dit is robuuster dan werken met absolute tijdsverschillen. Bovendien geeft het je flexibiliteit om bijvoorbeeld met echte timestamps te werken (zoals `time()`), wat handig kan zijn bij logging of bij andere applicaties. Als je enkel bijhoudt hoelang je al in een state zit, verlies je de precieze starttijd en daarmee een stuk detail. Met de starttijd kan je de rest berekenen.
C++:
Op mijn werk programmeren we in C++, en dat biedt extra mogelijkheden om dit concept mooier te maken. Ik zou bijvoorbeeld kiezen voor een `StateMachine` class, waarin de states en context beter gestructureerd zijn via templates. De states zelf zouden ook classes kunnen zijn, al brengt dat extra overhead met zich mee. Voor complexe state machines kan dit nuttig zijn. In dit voorbeeld houd ik het echter bewust simpel om het concept goed over te brengen.
Een extra voordeel in C++: je kunt variabelen in de context private maken en enkel toegankelijk via functies zoals `SetNextState(MyState);`. Dat houdt de context en de statemachine interface schoon.
Uitleg:
Ik zal inderdaad nog een korte uitleg toevoegen aan de startpost om de structuur en werkwijze van de code toe te lichten.