mirror of
https://github.com/wailsapp/wails.git
synced 2025-05-02 06:19:43 +08:00
Extend call subsystem to support plugins
This commit is contained in:
parent
4300521064
commit
c774af48b7
@ -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…
Reference in New Issue
Block a user