mirror of
https://github.com/wailsapp/wails.git
synced 2026-03-14 14:45:49 +01:00
Extend call subsystem to support plugins
This commit is contained in:
parent
4300521064
commit
c774af48b7
13 changed files with 93 additions and 52 deletions
|
|
@ -13,6 +13,8 @@ var assets embed.FS
|
|||
|
||||
type RandomNumberPlugin struct{}
|
||||
|
||||
func (r *RandomNumberPlugin) Shutdown() {}
|
||||
|
||||
func (r *RandomNumberPlugin) Name() string {
|
||||
return "Random Number Plugin"
|
||||
}
|
||||
|
|
@ -21,8 +23,8 @@ func (r *RandomNumberPlugin) Init(_ *application.App) error {
|
|||
return nil
|
||||
}
|
||||
|
||||
func (r *RandomNumberPlugin) Call(args []any) (any, error) {
|
||||
return rand.Intn(100), nil
|
||||
func (r *RandomNumberPlugin) RandInt() int {
|
||||
return rand.Intn(100)
|
||||
}
|
||||
|
||||
func main() {
|
||||
|
|
|
|||
|
|
@ -64,5 +64,10 @@ export function Call(options) {
|
|||
}
|
||||
|
||||
export function Plugin(options) {
|
||||
return callBinding("Plugin", options);
|
||||
return callBinding("Call", {
|
||||
packageName: "wails-plugins",
|
||||
structName: options.plugin,
|
||||
methodName: options.methodName,
|
||||
args: options.args,
|
||||
});
|
||||
}
|
||||
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
|
|
@ -57,8 +57,7 @@ func New(appOptions Options) *App {
|
|||
result.fatal(err.Error())
|
||||
}
|
||||
|
||||
pluginManager := NewPluginManager(appOptions.Plugins)
|
||||
srv.UseRuntimeHandler(NewMessageProcessor(pluginManager))
|
||||
srv.UseRuntimeHandler(NewMessageProcessor())
|
||||
result.assets = srv
|
||||
|
||||
globalApplication = result
|
||||
|
|
@ -151,6 +150,7 @@ type App struct {
|
|||
// Running
|
||||
running bool
|
||||
bindings *Bindings
|
||||
plugins *PluginManager
|
||||
|
||||
// platform app
|
||||
impl platformApp
|
||||
|
|
@ -316,6 +316,14 @@ func (a *App) Run() error {
|
|||
return err
|
||||
}
|
||||
|
||||
a.plugins = NewPluginManager(a.options.Plugins)
|
||||
err = a.plugins.Init()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
a.bindings.AddPlugins(a.options.Plugins)
|
||||
|
||||
// run windows
|
||||
for _, window := range a.windows {
|
||||
go window.run()
|
||||
|
|
@ -332,7 +340,14 @@ func (a *App) Run() error {
|
|||
// set the application Icon
|
||||
a.impl.setIcon(a.options.Icon)
|
||||
|
||||
return a.impl.run()
|
||||
err = a.impl.run()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
a.plugins.Shutdown()
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (a *App) handleApplicationEvent(event uint) {
|
||||
|
|
|
|||
|
|
@ -20,6 +20,12 @@ type PluginCallOptions struct {
|
|||
Args []any `json:"args"`
|
||||
}
|
||||
|
||||
var reservedPluginMethods = []string{
|
||||
"Name",
|
||||
"Init",
|
||||
"Shutdown",
|
||||
}
|
||||
|
||||
// Parameter defines a Go method parameter
|
||||
type Parameter struct {
|
||||
Name string `json:"name,omitempty"`
|
||||
|
|
@ -96,7 +102,34 @@ func (b *Bindings) Add(structPtr interface{}) error {
|
|||
b.boundMethods[packageName][structName] = make(map[string]*BoundMethod)
|
||||
}
|
||||
b.boundMethods[packageName][structName][methodName] = method
|
||||
//b.db.AddMethod(packageName, structName, methodName, method)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (b *Bindings) AddPlugins(plugins map[string]Plugin) error {
|
||||
for pluginID, plugin := range plugins {
|
||||
methods, err := b.getMethods(plugin)
|
||||
if err != nil {
|
||||
return fmt.Errorf("cannot add plugin '%s' to app: %s", pluginID, err.Error())
|
||||
}
|
||||
|
||||
for _, method := range methods {
|
||||
if lo.Contains(reservedPluginMethods, method.Name) {
|
||||
continue
|
||||
}
|
||||
packageName := "wails-plugins"
|
||||
structName := pluginID
|
||||
methodName := method.Name
|
||||
|
||||
// Add it as a regular method
|
||||
if _, ok := b.boundMethods[packageName]; !ok {
|
||||
b.boundMethods[packageName] = make(map[string]map[string]*BoundMethod)
|
||||
}
|
||||
if _, ok := b.boundMethods[packageName][structName]; !ok {
|
||||
b.boundMethods[packageName][structName] = make(map[string]*BoundMethod)
|
||||
}
|
||||
b.boundMethods[packageName][structName][methodName] = method
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
|
|
|||
|
|
@ -16,10 +16,8 @@ type MessageProcessor struct {
|
|||
pluginManager *PluginManager
|
||||
}
|
||||
|
||||
func NewMessageProcessor(pluginManager *PluginManager) *MessageProcessor {
|
||||
return &MessageProcessor{
|
||||
pluginManager: pluginManager,
|
||||
}
|
||||
func NewMessageProcessor() *MessageProcessor {
|
||||
return &MessageProcessor{}
|
||||
}
|
||||
|
||||
func (m *MessageProcessor) httpError(rw http.ResponseWriter, message string, args ...any) {
|
||||
|
|
|
|||
|
|
@ -58,28 +58,6 @@ func (m *MessageProcessor) processCallMethod(method string, rw http.ResponseWrit
|
|||
m.callCallback(window, callID, string(jsonResult), true)
|
||||
}()
|
||||
m.ok(rw)
|
||||
case "Plugin":
|
||||
var options PluginCallOptions
|
||||
err := params.ToStruct(&options)
|
||||
if err != nil {
|
||||
m.callErrorCallback(window, "Error parsing plugin options: %s", callID, err)
|
||||
return
|
||||
}
|
||||
go func() {
|
||||
result, err := m.pluginManager.Call(options.Name, options.Args)
|
||||
if err != nil {
|
||||
m.callErrorCallback(window, "Error calling plugin: %s", callID, err)
|
||||
return
|
||||
}
|
||||
// convert result to json
|
||||
jsonResult, err := json.Marshal(result)
|
||||
if err != nil {
|
||||
m.callErrorCallback(window, "Error converting result to json: %s", callID, err)
|
||||
return
|
||||
}
|
||||
m.callCallback(window, callID, string(jsonResult), true)
|
||||
}()
|
||||
m.ok(rw)
|
||||
default:
|
||||
m.httpError(rw, "Unknown dialog method: %s", method)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,13 +1,9 @@
|
|||
package application
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
)
|
||||
|
||||
type Plugin interface {
|
||||
Name() string
|
||||
Init(app *App) error
|
||||
Call(args []any) (any, error)
|
||||
Shutdown()
|
||||
}
|
||||
|
||||
type PluginManager struct {
|
||||
|
|
@ -31,10 +27,9 @@ func (p *PluginManager) Init() error {
|
|||
return nil
|
||||
}
|
||||
|
||||
func (p *PluginManager) Call(name string, args []any) (any, error) {
|
||||
plugin, ok := p.plugins[name]
|
||||
if !ok {
|
||||
return nil, fmt.Errorf("plugin '%s' not found", name)
|
||||
func (p *PluginManager) Shutdown() {
|
||||
for _, plugin := range p.plugins {
|
||||
plugin.Shutdown()
|
||||
globalApplication.info("Plugin '%s' shutdown", plugin.Name())
|
||||
}
|
||||
return plugin.Call(args)
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue