simplify module registry
This commit is contained in:
parent
abf3aaba35
commit
09bfd24c8d
@ -4,9 +4,6 @@ import (
|
||||
"embed"
|
||||
"fmt"
|
||||
"maps"
|
||||
"path/filepath"
|
||||
"strings"
|
||||
"sync"
|
||||
|
||||
"Moonshark/modules/crypto"
|
||||
"Moonshark/modules/fs"
|
||||
@ -27,100 +24,60 @@ var embeddedModules embed.FS
|
||||
type Registry struct {
|
||||
modules map[string]string
|
||||
goFuncs map[string]luajit.GoFunction
|
||||
mutex sync.RWMutex
|
||||
}
|
||||
|
||||
// New creates a new registry with all Go functions loaded
|
||||
// New creates a new registry with all modules loaded
|
||||
func New() *Registry {
|
||||
r := &Registry{
|
||||
modules: make(map[string]string),
|
||||
goFuncs: make(map[string]luajit.GoFunction),
|
||||
}
|
||||
|
||||
// Load all Go functions from each module
|
||||
// Load all Go functions
|
||||
maps.Copy(r.goFuncs, json.GetFunctionList())
|
||||
maps.Copy(r.goFuncs, lua_string.GetFunctionList())
|
||||
maps.Copy(r.goFuncs, math.GetFunctionList())
|
||||
maps.Copy(r.goFuncs, fs.GetFunctionList())
|
||||
maps.Copy(r.goFuncs, crypto.GetFunctionList())
|
||||
|
||||
r.loadEmbeddedModules()
|
||||
return r
|
||||
}
|
||||
|
||||
// LoadEmbeddedModules loads all .lua files from embedded filesystem
|
||||
func (r *Registry) LoadEmbeddedModules() error {
|
||||
r.mutex.Lock()
|
||||
defer r.mutex.Unlock()
|
||||
// loadEmbeddedModules discovers and loads all .lua files
|
||||
func (r *Registry) loadEmbeddedModules() {
|
||||
// Discover all directories from embed
|
||||
dirs, _ := embeddedModules.ReadDir(".")
|
||||
|
||||
// Load modules from subdirectories
|
||||
subdirs := []string{"crypto", "fs", "json", "math", "string"}
|
||||
for _, subdir := range subdirs {
|
||||
if err := r.loadModulesFromDir(subdir); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// loadModulesFromDir loads all .lua files from a specific directory
|
||||
func (r *Registry) loadModulesFromDir(dir string) error {
|
||||
entries, err := embeddedModules.ReadDir(dir)
|
||||
if err != nil {
|
||||
return nil // Skip missing directories
|
||||
}
|
||||
|
||||
for _, entry := range entries {
|
||||
if entry.IsDir() || !strings.HasSuffix(entry.Name(), ".lua") {
|
||||
for _, dir := range dirs {
|
||||
if !dir.IsDir() {
|
||||
continue
|
||||
}
|
||||
|
||||
fileName := strings.TrimSuffix(entry.Name(), ".lua")
|
||||
|
||||
// If filename matches directory name (e.g., math/math.lua),
|
||||
// register as just the directory name for require("math")
|
||||
var moduleName string
|
||||
if fileName == dir {
|
||||
moduleName = dir
|
||||
} else {
|
||||
moduleName = dir + "/" + fileName
|
||||
// Assume one module file per directory: dirname/dirname.lua
|
||||
modulePath := fmt.Sprintf("%s/%s.lua", dir.Name(), dir.Name())
|
||||
if source, err := embeddedModules.ReadFile(modulePath); err == nil {
|
||||
r.modules[dir.Name()] = string(source)
|
||||
}
|
||||
|
||||
source, err := embeddedModules.ReadFile(filepath.Join(dir, entry.Name()))
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to read module %s: %w", moduleName, err)
|
||||
}
|
||||
|
||||
r.modules[moduleName] = string(source)
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// InstallInState sets up the complete module system in a Lua state
|
||||
func (r *Registry) InstallInState(state *luajit.State) error {
|
||||
r.mutex.RLock()
|
||||
defer r.mutex.RUnlock()
|
||||
|
||||
// Create moonshark global table
|
||||
// Create moonshark global table with Go functions
|
||||
state.NewTable()
|
||||
state.SetGlobal("moonshark")
|
||||
|
||||
// Install Go functions
|
||||
state.GetGlobal("moonshark")
|
||||
for name, fn := range r.goFuncs {
|
||||
if err := state.PushGoFunction(fn); err != nil {
|
||||
return fmt.Errorf("failed to register Go function '%s': %w", name, err)
|
||||
}
|
||||
state.SetField(-2, name)
|
||||
}
|
||||
state.Pop(1) // Remove moonshark table
|
||||
state.SetGlobal("moonshark")
|
||||
|
||||
// Backup original require
|
||||
// Backup original require and install custom one
|
||||
state.GetGlobal("require")
|
||||
state.SetGlobal("_require_original")
|
||||
|
||||
// Install custom require function
|
||||
return state.RegisterGoFunction("require", func(s *luajit.State) int {
|
||||
if err := s.CheckMinArgs(1); err != nil {
|
||||
return s.PushError("require: %v", err)
|
||||
@ -132,11 +89,7 @@ func (r *Registry) InstallInState(state *luajit.State) error {
|
||||
}
|
||||
|
||||
// Check built-in modules first
|
||||
r.mutex.RLock()
|
||||
source, exists := r.modules[moduleName]
|
||||
r.mutex.RUnlock()
|
||||
|
||||
if exists {
|
||||
if source, exists := r.modules[moduleName]; exists {
|
||||
if err := s.LoadString(source); err != nil {
|
||||
return s.PushError("require: failed to load module '%s': %v", moduleName, err)
|
||||
}
|
||||
@ -160,8 +113,8 @@ func (r *Registry) InstallInState(state *luajit.State) error {
|
||||
})
|
||||
}
|
||||
|
||||
// Initialize sets up the global registry with all modules loaded
|
||||
// Initialize sets up the global registry
|
||||
func Initialize() error {
|
||||
Global = New()
|
||||
return Global.LoadEmbeddedModules()
|
||||
return nil
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user