Ik heb een FSM simulatie applicatie die opzich OK werkt, maar in deze applicatie zitten de states, events en de GUI in dezelfde assembly. Ik wil dit opsplitsen, maar loop tegen een probleem waar ik zo niet uitkom.
Ik wil dus een aparte DLL (assembly) voor de FSM specifieke code (states, events & actions),
en de applicatie (die met reflectie die FSM specifieke zaken ophaalt (initial state, events, e.d.).
De GUI moet dus reflecteren op de FSM assembly en de events ophalen, zodat ik deze in mijn GUI kan zien en afvuren. Zoals ik het nu heb moeten zowel de FSM als GUI assembly kennis hebben van de Event enum.
states.cs
GUI.cs
Zoals te zien is, moet ook de GUI kennis hebben van de states en events. De states vallen met reflectie nog wel uit de assembly te halen en middels het attribuut (InitialStateAttribute) kan ik de FSM opstarten.
Ik weet echter niet hoe ik die events bekend moet maken bij beide assemblies.
Ik heb gepoogd om een shared library te maken die de event enum en de context klasse heeft.
Maar omdat iemand zelf een FSM moet kunnen opbouwen, zonder mijn FSM simulator is dit
geen oplossing.
Hoe moet ik mijn architectuur opbouwen zodat dit goed gaat?
Ik dacht iets als het ophalen van de enum waardes en deze aan de gebruiker tonen. Als de gebruiker een event kiest en afvuurt deze dan naar de context klasse te sturen. Maar dit zijn geen echte events, maar string representaties. Deze strings via Enum.Parse() te versturen.
Maar helaas krijg ik dit niet voor elkaar omdat ik nog kennis moet hebben van de echte enum, omdat je die Enum.Parse() moet casten naar de juiste enum.
Nadeel is wel dat ten alle tijden, alle events voor de gebruiker zichtbaar zijn en niet alleen die events die de huidige state ook werkelijk kan ontvangen.
Ik wil dus een aparte DLL (assembly) voor de FSM specifieke code (states, events & actions),
en de applicatie (die met reflectie die FSM specifieke zaken ophaalt (initial state, events, e.d.).
De GUI moet dus reflecteren op de FSM assembly en de events ophalen, zodat ik deze in mijn GUI kan zien en afvuren. Zoals ik het nu heb moeten zowel de FSM als GUI assembly kennis hebben van de Event enum.
states.cs
C#:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
| [InitialState] class TestState : IState { public TestState() {} public void Handle(Context c, Event e) { // handle event af en ga naar nieuwe state } } enum Event { EventOne, EventTwo } |
GUI.cs
C#:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
| // dient als 'controller' class Context { private IState _state; public Context() { } public IState State { get { return _state; } set { _state = value; } } public Event FireEvent { State.Handle(this, value); } } class UI { // instantieert Context object // roept events aan, bv. Context c = new Context(); c.FireEvent = Event.Aan; } |
Zoals te zien is, moet ook de GUI kennis hebben van de states en events. De states vallen met reflectie nog wel uit de assembly te halen en middels het attribuut (InitialStateAttribute) kan ik de FSM opstarten.
Ik weet echter niet hoe ik die events bekend moet maken bij beide assemblies.
Ik heb gepoogd om een shared library te maken die de event enum en de context klasse heeft.
Maar omdat iemand zelf een FSM moet kunnen opbouwen, zonder mijn FSM simulator is dit
geen oplossing.
Hoe moet ik mijn architectuur opbouwen zodat dit goed gaat?
Ik dacht iets als het ophalen van de enum waardes en deze aan de gebruiker tonen. Als de gebruiker een event kiest en afvuurt deze dan naar de context klasse te sturen. Maar dit zijn geen echte events, maar string representaties. Deze strings via Enum.Parse() te versturen.
Maar helaas krijg ik dit niet voor elkaar omdat ik nog kennis moet hebben van de echte enum, omdat je die Enum.Parse() moet casten naar de juiste enum.
Nadeel is wel dat ten alle tijden, alle events voor de gebruiker zichtbaar zijn en niet alleen die events die de huidige state ook werkelijk kan ontvangen.