package subsystem import ( "github.com/wailsapp/wails/v2/internal/binding" "github.com/wailsapp/wails/v2/internal/logger" "github.com/wailsapp/wails/v2/internal/runtime" "github.com/wailsapp/wails/v2/internal/servicebus" "os" "time" ) // Binding is the Binding subsystem. It manages all service bus messages // starting with "binding". type Binding struct { quitChannel <-chan *servicebus.Message bindingChannel <-chan *servicebus.Message running bool // Binding db bindings *binding.Bindings // logger logger logger.CustomLogger // runtime runtime *runtime.Runtime } func showError(err error) { // Add a slight delay so log buffer clears time.Sleep(1 * time.Second) println("\n\n\n\n\n\n") println("Fatal Error in WailsInit(): " + err.Error()) } // NewBinding creates a new binding subsystem. Uses the given bindings db for reference. func NewBinding(bus *servicebus.ServiceBus, logger *logger.Logger, bindings *binding.Bindings, runtime *runtime.Runtime) (*Binding, error) { // Register quit channel quitChannel, err := bus.Subscribe("quit") if err != nil { return nil, err } // Subscribe to event messages bindingChannel, err := bus.Subscribe("binding") if err != nil { return nil, err } result := &Binding{ quitChannel: quitChannel, bindingChannel: bindingChannel, logger: logger.CustomLogger("Binding Subsystem"), bindings: bindings, runtime: runtime, } // Call WailsInit methods once the frontend is loaded runtime.Events.On("wails:loaded", func(...interface{}) { result.logger.Trace("Calling WailsInit() methods") err := result.CallWailsInit() if err != nil { showError(err) os.Exit(1) } }) return result, nil } // Start the subsystem func (b *Binding) Start() error { b.running = true b.logger.Trace("Starting") // Spin off a go routine go func() { for b.running { select { case <-b.quitChannel: b.running = false case bindingMessage := <-b.bindingChannel: b.logger.Trace("Got binding message: %+v", bindingMessage) } } // Call shutdown b.shutdown() }() return nil } // CallWailsInit will callback to the registered WailsInit // methods with the runtime object func (b *Binding) CallWailsInit() error { for _, wailsinit := range b.bindings.DB().WailsInitMethods() { _, err := wailsinit.Call([]interface{}{b.runtime}) if err != nil { return err } } return nil } // CallWailsShutdown will callback to the registered WailsShutdown // methods with the runtime object func (b *Binding) CallWailsShutdown() error { for _, wailsshutdown := range b.bindings.DB().WailsShutdownMethods() { _, err := wailsshutdown.Call([]interface{}{}) if err != nil { return err } } return nil } func (b *Binding) shutdown() { err := b.CallWailsShutdown() if err != nil { showError(err) } b.logger.Trace("Shutdown") }