get LStates into goroutines
parent
d006c992ec
commit
5456518feb
|
@ -74,7 +74,6 @@ type gameWorldServer struct {
|
|||
db db.DB
|
||||
msgRouterMutex sync.Mutex
|
||||
msgRouter map[string]func(*proto.ClientMessage) error
|
||||
Gateway *witch.Gateway
|
||||
scripts map[int]*witch.ScriptContext
|
||||
scriptsMutex sync.RWMutex
|
||||
}
|
||||
|
@ -105,17 +104,14 @@ func newServer() (*gameWorldServer, error) {
|
|||
}
|
||||
|
||||
func (s *gameWorldServer) verbHandler(verb, rest string, sender, target db.Object) error {
|
||||
/*
|
||||
So right here is a problem: we are definitely making >1 LuaState per
|
||||
goroutine. Top priority before anything else is getting a goroutine made
|
||||
for the script contexts
|
||||
*/
|
||||
// I think i should rethink this. sc should maybe be permanent and then they re-create LStates
|
||||
s.scriptsMutex.RLock()
|
||||
sc, ok := s.scripts[target.ID]
|
||||
s.scriptsMutex.RUnlock()
|
||||
var err error
|
||||
|
||||
if !ok || sc.NeedsRefresh(target) {
|
||||
sc, err := witch.NewScriptContext(target)
|
||||
if !ok {
|
||||
sc, err = witch.NewScriptContext()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
@ -125,7 +121,16 @@ func (s *gameWorldServer) verbHandler(verb, rest string, sender, target db.Objec
|
|||
s.scriptsMutex.Unlock()
|
||||
}
|
||||
|
||||
return sc.Handle(verb, rest, sender, target)
|
||||
vc := witch.VerbContext{
|
||||
Verb: verb,
|
||||
Rest: rest,
|
||||
Sender: sender,
|
||||
Target: target,
|
||||
}
|
||||
|
||||
sc.Handle(vc)
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (s *gameWorldServer) HandleCmd(verb, rest string, sender *db.Object) {
|
||||
|
@ -187,10 +192,10 @@ func (s *gameWorldServer) Commands(stream proto.GameWorld_CommandsServer) error
|
|||
affected, err := s.db.Earshot(*avatar)
|
||||
|
||||
for _, o := range affected {
|
||||
err = s.Gateway.VerbHandler(cmd.Verb, cmd.Rest, *avatar, o)
|
||||
err = s.verbHandler(cmd.Verb, cmd.Rest, *avatar, o)
|
||||
}
|
||||
|
||||
s.HandleCmd(cmd.Verb, cmd.Rest, avatar)
|
||||
//s.HandleCmd(cmd.Verb, cmd.Rest, avatar)
|
||||
|
||||
/*
|
||||
|
||||
|
@ -355,7 +360,7 @@ func (s *gameWorldServer) HandleSay(sender *db.Object, msg string) error {
|
|||
// TODO figure out pointer shit
|
||||
|
||||
for _, h := range heard {
|
||||
s.Gateway.VerbHandler("hears", msg, sender, &h)
|
||||
s.verbHandler("hears", msg, *sender, h)
|
||||
// TODO once we have a script engine, deliver the HEARS event
|
||||
for _, sess := range as {
|
||||
if sess.AccountID == h.OwnerID {
|
||||
|
|
|
@ -1,13 +1,16 @@
|
|||
package witch
|
||||
|
||||
import (
|
||||
"log"
|
||||
|
||||
"github.com/vilmibm/hermeticum/server/db"
|
||||
lua "github.com/yuin/gopher-lua"
|
||||
)
|
||||
|
||||
func hasWrapper(obj db.Object) func(*lua.LState) int {
|
||||
return func(ls *lua.LState) int {
|
||||
//lv := ls.ToTable(1)
|
||||
lv := ls.ToTable(1)
|
||||
log.Println(lv)
|
||||
return 0
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,6 +1,8 @@
|
|||
package witch
|
||||
|
||||
import (
|
||||
"log"
|
||||
|
||||
"github.com/vilmibm/hermeticum/server/db"
|
||||
lua "github.com/yuin/gopher-lua"
|
||||
)
|
||||
|
@ -13,17 +15,6 @@ import (
|
|||
|
||||
*/
|
||||
|
||||
type ScriptContext struct {
|
||||
script string
|
||||
l *lua.LState
|
||||
incoming chan string
|
||||
// TODO whatever is needed to support calling a Go API
|
||||
}
|
||||
|
||||
func (sc *ScriptContext) NeedsRefresh(obj db.Object) bool {
|
||||
return sc.script != obj.Script
|
||||
}
|
||||
|
||||
// TODO using a dummy script for now
|
||||
|
||||
const dummyScript = `
|
||||
|
@ -60,21 +51,51 @@ end)
|
|||
// - do i inject from Go or prepend some Lua code?
|
||||
// TODO figure out how the Lua code can affect Go and thus the database
|
||||
|
||||
func NewScriptContext(obj db.Object) (*ScriptContext, error) {
|
||||
l := lua.NewState()
|
||||
|
||||
l.SetGlobal("has", l.NewFunction(hasWrapper(obj)))
|
||||
l.SetGlobal("_handlers", l.NewTable())
|
||||
|
||||
//if err := l.DoString(obj.Script); err != nil {
|
||||
if err := l.DoString(dummyScript); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return &ScriptContext{}, nil
|
||||
type VerbContext struct {
|
||||
Verb string
|
||||
Rest string
|
||||
Sender db.Object
|
||||
Target db.Object
|
||||
}
|
||||
|
||||
func (sc *ScriptContext) Handle(verb, rest string, sender, target db.Object) error {
|
||||
// TODO call _handle function from the Lstate
|
||||
return nil
|
||||
type ScriptContext struct {
|
||||
script string
|
||||
incoming chan VerbContext
|
||||
}
|
||||
|
||||
func NewScriptContext() (*ScriptContext, error) {
|
||||
sc := &ScriptContext{}
|
||||
sc.incoming = make(chan VerbContext)
|
||||
|
||||
go func() {
|
||||
var l *lua.LState
|
||||
var err error
|
||||
var vc VerbContext
|
||||
for {
|
||||
vc = <-sc.incoming
|
||||
//if vc.Target.Script != sc.script {
|
||||
if dummyScript != sc.script {
|
||||
//sc.script = vc.Target.Script
|
||||
sc.script = dummyScript
|
||||
l = lua.NewState()
|
||||
l.SetGlobal("has", l.NewFunction(hasWrapper(vc.Target)))
|
||||
l.SetGlobal("hears", l.NewFunction(hearsWrapper(vc.Target)))
|
||||
l.SetGlobal("_handlers", l.NewTable())
|
||||
// TODO other setup
|
||||
//if err := l.DoString(obj.Script); err != nil {
|
||||
if err = l.DoString(dummyScript); err != nil {
|
||||
log.Printf("error parsing script %s: %s", dummyScript, err.Error())
|
||||
}
|
||||
}
|
||||
|
||||
// TODO actually trigger the Lua script
|
||||
}
|
||||
}()
|
||||
|
||||
return sc, nil
|
||||
}
|
||||
|
||||
func (sc *ScriptContext) Handle(vc VerbContext) {
|
||||
log.Printf("%#v %#v", sc, vc)
|
||||
sc.incoming <- vc
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue