package westworldwithmessaging import ( "fmt" "sync" ) // visitBathroom is a "blip" state: it interrupts whatever Elsa was // doing, does its one bit of business, and immediately hands control // straight back to whatever she was doing before - it never leads // anywhere new on its own. type visitBathroom struct{} var ( visitBathroomInstance *visitBathroom visitBathroomOnce sync.Once ) // VisitBathroom is the Go stand-in for "VisitBathroom::Instance()". func VisitBathroom() *visitBathroom { visitBathroomOnce.Do(func() { visitBathroomInstance = &visitBathroom{} }) return visitBathroomInstance } var _ State[Elsa] = (*visitBathroom)(nil) // Enter announces the trip to the bathroom. func (s *visitBathroom) Enter(e *Elsa) { fmt.Printf("\n%s: Walkin' to the can. Need to powda mah pretty li'l nose", GetNameOfEntity(e.ID())) } // Execute is the entire "blip": do the business, then immediately // revert to whatever state was active before VisitBathroom // interrupted it. RevertToPreviousState runs the normal ChangeState // dance (Exit here, Enter there), so nothing extra is needed. func (s *visitBathroom) Execute(e *Elsa) { fmt.Printf("\n%s: Ahhhhhh! Sweet relief!", GetNameOfEntity(e.ID())) e.FSM().RevertToPreviousState() } // Exit announces leaving the bathroom - this runs automatically as // part of the RevertToPreviousState call above. func (s *visitBathroom) Exit(e *Elsa) { fmt.Printf("\n%s: Leavin' the john", GetNameOfEntity(e.ID())) } // OnMessage is required now that State[T] includes it. This state // doesn't handle any messages yet - false ("not handled") is the // correct default until the book shows otherwise. func (s *visitBathroom) OnMessage(e *Elsa, msg Telegram) bool { return false }