Compare commits

..

2 Commits

Author SHA1 Message Date
b13cd05b45 wip: experimental branch with finite-state machine processor (doesn't work yet) 2024-05-14 15:29:35 +03:00
2cd46585a8 add hot-reload & debugger
All checks were successful
continuous-integration/drone/push Build is passing
2024-05-14 15:26:28 +03:00
4 changed files with 22 additions and 4 deletions

View File

@ -82,3 +82,7 @@ func (s State) LogError(err error) {
func (s State) Move(mc fsm.MachineControls[Wizard], stateID fsm.StateID, pl *Wizard) {
s.LogError(mc.Move(stateID, pl))
}
func (s State) MoveForHandle(mc fsm.MachineControls[Wizard], stateID fsm.StateID, pl *Wizard) {
s.LogError(mc.MoveForHandle(stateID, pl))
}

View File

@ -24,12 +24,12 @@ func (s *WaitingForMemberWebhookState) Enter(pl *Wizard, mc fsm.MachineControls[
}
if !cm.OldChatMember.MemberIsMember() && cm.OldChatMember.MemberUser().ID == s.App.TGProfile().ID &&
cm.NewChatMember.MemberIsMember() && cm.NewChatMember.MemberUser().ID == s.App.TGProfile().ID {
s.Move(mc, AddChatMemberStateID, pl)
s.MoveForHandle(mc, AddChatMemberStateID, pl)
return nil
}
if cm.OldChatMember.MemberIsMember() && cm.OldChatMember.MemberUser().ID == s.App.TGProfile().ID &&
!cm.NewChatMember.MemberIsMember() && cm.NewChatMember.MemberUser().ID == s.App.TGProfile().ID {
s.Move(mc, RemoveChatMemberStateID, pl)
s.MoveForHandle(mc, RemoveChatMemberStateID, pl)
return nil
}

View File

@ -43,6 +43,7 @@ type Machine[T any] struct {
initialState StateID
states *types.Map[StateID, IState[T]]
errHandler ErrorState[T]
handleNow bool
}
// New machine.
@ -89,6 +90,11 @@ func (m *Machine[T]) Move(id StateID, payload *T) error {
return nil
}
func (m *Machine[T]) MoveForHandle(id StateID, payload *T) error {
m.handleNow = true
return m.Move(id, payload)
}
// Handle the input.
func (m *Machine[T]) Handle(provider MachineStateProvider[T]) error {
if provider != nil {
@ -101,8 +107,14 @@ func (m *Machine[T]) Handle(provider MachineStateProvider[T]) error {
if st == nil || err != nil {
return err
}
st.Handle(m.payload, m)
return nil
for {
st.Handle(m.payload, m)
if m.handleNow { // MoveForHandle was called, trying to handle again.
m.handleNow = false
continue
}
return nil
}
}
// State of the Machine.

View File

@ -10,6 +10,8 @@ const NilStateID = StateID("")
// It may fail with an error which should be handled by the IState implementation.
type MachineControls[T any] interface {
Move(StateID, *T) error
// MoveForHandle is the same as Move but it also triggers Handle immediately for the next state.
MoveForHandle(StateID, *T) error
Reset()
}