feat: finalize with step 5

This commit is contained in:
jonas committed 2026-09-03 23:39:25 +02:00
1 parent 129dd5d8b8
commit aab128b55c
10 files changed
+332 -37

No files matched your search

@@ -0,0 +1,90 @@
package westworldwithmessaging
import (
"fmt"
"sync"
)
// cookStew is the Go version of the (not yet pasted) singleton class
// CookStew from the book. Same pattern as every other state:
// unexported type, one shared instance, reached only through the
// function below.
type cookStew struct{}
var (
cookStewInstance *cookStew
cookStewOnce sync.Once
)
// CookStew is the Go stand-in for "CookStew::Instance()".
func CookStew() *cookStew {
cookStewOnce.Do(func() {
cookStewInstance = &cookStew{}
})
return cookStewInstance
}
var _ State[Elsa] = (*cookStew)(nil)
// Execute and Exit weren't pasted to us directly either, but a
// sample run of the book's program makes their behavior clear
// enough to fill in: Execute prints "Fussin' over food" once per
// tick while the stew is in the oven (waiting for the delayed
// Msg_StewReady reminder to arrive), and Exit announces taking the
// stew out and putting it on the table, right before switching back
// to DoHousework.
// Enter puts the stew in the oven (if one isn't already cooking) and
// sends a delayed message to herself, reminding her to take it out
// once it's ready.
func (s *cookStew) Enter(e *Elsa) {
if !e.Cooking() {
fmt.Printf("\n%s: Puttin' the stew in the oven", GetNameOfEntity(e.ID()))
// send a delayed message to myself so that I know when to take
// the stew out of the oven
Dispatch.DispatchMessage(
1.5, // time delay
e.ID(), // sender ID
e.ID(), // receiver ID
int(MsgStewReady), // the message
NoAdditionalInfo, // no extra info attached
)
e.SetCooking(true)
}
}
func (s *cookStew) Execute(e *Elsa) {
fmt.Printf("\n%s: Fussin' over food", GetNameOfEntity(e.ID()))
}
func (s *cookStew) Exit(e *Elsa) {
fmt.Printf("\n%s: Puttin' the stew on the table", GetNameOfEntity(e.ID()))
}
// OnMessage handles the delayed reminder Enter sent to herself: once
// the stew's ready, take it out, let Bob know dinner's on the table,
// and go back to the ordinary housework state.
func (s *cookStew) OnMessage(e *Elsa, msg Telegram) bool {
switch MessageType(msg.Msg) {
case MsgStewReady:
fmt.Printf("\nMessage received by %s at time: %.5f", GetNameOfEntity(e.ID()), Clock.GetCurrentTime())
fmt.Printf("\n%s: Stew ready! Let's eat", GetNameOfEntity(e.ID()))
// let hubby know the stew is ready
Dispatch.DispatchMessage(
SendMsgImmediately,
e.ID(),
entMinerBob,
int(MsgStewReady),
NoAdditionalInfo,
)
e.SetCooking(false)
e.FSM().ChangeState(DoHousework())
return true
}
return false
}