verstak/internal/core/plugins/manager_lifecycle.go

93 lines
2.2 KiB
Go

package plugins
import (
"log"
"os"
"path/filepath"
lua "github.com/yuin/gopher-lua"
)
// ActivatePlugin fully activates a plugin: creates Lua VM, loads main.lua, starts scheduler.
func (m *Manager) ActivatePlugin(name string) {
for i := range m.plugins {
p := &m.plugins[i]
if p.Meta.Name != name || p.Active {
continue
}
p.Active = true
vm, err := NewLuaVM(p)
if err != nil {
log.Printf("[plugins] %s: activate VM error: %v", name, err)
p.Active = false
return
}
p.vm = vm
mainPath := filepath.Join(p.Dir, "main.lua")
if _, err := os.Stat(mainPath); err == nil {
if err := vm.LoadScript("main.lua"); err != nil {
log.Printf("[plugins] %s: load main.lua: %v", name, err)
}
}
p.scheduler = NewScheduler(p, vm)
for _, bg := range p.Meta.Background {
if err := p.scheduler.AddTask(bg); err != nil {
log.Printf("[plugins] %s: add task %s: %v", name, bg.ID, err)
}
}
p.scheduler.Start()
if hookName, ok := p.Meta.Hooks["on_init"]; ok {
if err := vm.CallHook(hookName); err != nil {
log.Printf("[plugins] %s: on_init error: %v", name, err)
}
}
log.Printf("[plugins] %s: activated", name)
return
}
}
// DeactivatePlugin stops a plugin's runtime without removing it.
func (m *Manager) DeactivatePlugin(name string) {
for i := range m.plugins {
p := &m.plugins[i]
if p.Meta.Name != name || !p.Active {
continue
}
if p.scheduler != nil {
p.scheduler.Stop()
p.scheduler = nil
}
if hookName, ok := p.Meta.Hooks["on_shutdown"]; ok && p.vm != nil {
_ = p.vm.CallHook(hookName)
}
if p.vm != nil {
p.vm.Close()
p.vm = nil
}
p.Active = false
log.Printf("[plugins] %s: deactivated", name)
return
}
}
// CallPluginHook calls a named Lua function on a specific plugin.
func (m *Manager) CallPluginHook(name, hookName string, args ...lua.LValue) (lua.LValue, error) {
for i := range m.plugins {
if m.plugins[i].Meta.Name == name && m.plugins[i].Active && m.plugins[i].vm != nil {
if fn, ok := m.plugins[i].Meta.Hooks[hookName]; ok {
return m.plugins[i].vm.CallHookWithResult(fn, args...)
}
return m.plugins[i].vm.CallHookWithResult(hookName, args...)
}
}
return lua.LNil, nil
}