// +build desktop,!server package app import ( "fmt" goruntime "runtime" "github.com/wailsapp/wails/v2/internal/binding" "github.com/wailsapp/wails/v2/internal/ffenestri" "github.com/wailsapp/wails/v2/internal/logger" "github.com/wailsapp/wails/v2/internal/messagedispatcher" "github.com/wailsapp/wails/v2/internal/runtime" "github.com/wailsapp/wails/v2/internal/servicebus" "github.com/wailsapp/wails/v2/internal/signal" "github.com/wailsapp/wails/v2/internal/subsystem" "github.com/wailsapp/wails/v2/pkg/menu" "github.com/wailsapp/wails/v2/pkg/options" ) // App defines a Wails application structure type App struct { window *ffenestri.Application servicebus *servicebus.ServiceBus logger *logger.Logger signal *signal.Manager options *options.App // Subsystems log *subsystem.Log runtime *subsystem.Runtime event *subsystem.Event binding *subsystem.Binding call *subsystem.Call menu *subsystem.Menu dispatcher *messagedispatcher.Dispatcher // Indicates if the app is in debug mode debug bool // This is our binding DB bindings *binding.Bindings // Application Stores loglevelStore *runtime.Store appconfigStore *runtime.Store } // Create App func CreateApp(options *options.App) *App { // Merge default options options.MergeDefaults() // Set up logger myLogger := logger.New(options.Logger) myLogger.SetLogLevel(options.LogLevel) window := ffenestri.NewApplicationWithConfig(options, myLogger) result := &App{ window: window, servicebus: servicebus.New(myLogger), logger: myLogger, bindings: binding.NewBindings(myLogger), } result.options = options // Initialise the app result.Init() return result } // Run the application func (a *App) Run() error { // Setup signal handler signalsubsystem, err := signal.NewManager(a.servicebus, a.logger) if err != nil { return err } a.signal = signalsubsystem a.signal.Start() // Start the service bus a.servicebus.Debug() a.servicebus.Start() // Start the runtime runtimesubsystem, err := subsystem.NewRuntime(a.servicebus, a.logger, a.options.Mac.Menu) if err != nil { return err } a.runtime = runtimesubsystem a.runtime.Start() // Application Stores a.loglevelStore = a.runtime.GoRuntime().Store.New("wails:loglevel", a.options.LogLevel) a.appconfigStore = a.runtime.GoRuntime().Store.New("wails:appconfig", a.options) // Start the binding subsystem bindingsubsystem, err := subsystem.NewBinding(a.servicebus, a.logger, a.bindings, a.runtime.GoRuntime()) if err != nil { return err } a.binding = bindingsubsystem a.binding.Start() // Start the logging subsystem log, err := subsystem.NewLog(a.servicebus, a.logger, a.loglevelStore) if err != nil { return err } a.log = log a.log.Start() // create the dispatcher dispatcher, err := messagedispatcher.New(a.servicebus, a.logger) if err != nil { return err } a.dispatcher = dispatcher dispatcher.Start() // Start the eventing subsystem event, err := subsystem.NewEvent(a.servicebus, a.logger) if err != nil { return err } a.event = event a.event.Start() // Start the menu subsystem var platformMenu *menu.Menu switch goruntime.GOOS { case "darwin": platformMenu = a.options.Mac.Menu // case "linux": // platformMenu = a.options.Linux.Menu // case "windows": // platformMenu = a.options.Windows.Menu default: return fmt.Errorf("unsupported OS: %s", goruntime.GOOS) } menusubsystem, err := subsystem.NewMenu(platformMenu, a.servicebus, a.logger) if err != nil { return err } a.menu = menusubsystem a.menu.Start() // Start the call subsystem call, err := subsystem.NewCall(a.servicebus, a.logger, a.bindings.DB(), a.runtime.GoRuntime()) if err != nil { return err } a.call = call a.call.Start() // Dump bindings as a debug bindingDump, err := a.bindings.ToJSON() if err != nil { return err } result := a.window.Run(dispatcher, bindingDump, a.debug) a.logger.Trace("Ffenestri.Run() exited") a.servicebus.Stop() return result } // Bind a struct to the application by passing in // a pointer to it func (a *App) Bind(structPtr interface{}) { // Add the struct to the bindings err := a.bindings.Add(structPtr) if err != nil { a.logger.Fatal("Error during binding: " + err.Error()) } }