get LStates into goroutines
parent
d006c992ec
commit
5456518feb
|
@ -74,7 +74,6 @@ type gameWorldServer struct {
|
||||||
db db.DB
|
db db.DB
|
||||||
msgRouterMutex sync.Mutex
|
msgRouterMutex sync.Mutex
|
||||||
msgRouter map[string]func(*proto.ClientMessage) error
|
msgRouter map[string]func(*proto.ClientMessage) error
|
||||||
Gateway *witch.Gateway
|
|
||||||
scripts map[int]*witch.ScriptContext
|
scripts map[int]*witch.ScriptContext
|
||||||
scriptsMutex sync.RWMutex
|
scriptsMutex sync.RWMutex
|
||||||
}
|
}
|
||||||
|
@ -105,17 +104,14 @@ func newServer() (*gameWorldServer, error) {
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *gameWorldServer) verbHandler(verb, rest string, sender, target db.Object) error {
|
func (s *gameWorldServer) verbHandler(verb, rest string, sender, target db.Object) error {
|
||||||
/*
|
// I think i should rethink this. sc should maybe be permanent and then they re-create LStates
|
||||||
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
|
|
||||||
*/
|
|
||||||
s.scriptsMutex.RLock()
|
s.scriptsMutex.RLock()
|
||||||
sc, ok := s.scripts[target.ID]
|
sc, ok := s.scripts[target.ID]
|
||||||
s.scriptsMutex.RUnlock()
|
s.scriptsMutex.RUnlock()
|
||||||
|
var err error
|
||||||
|
|
||||||
if !ok || sc.NeedsRefresh(target) {
|
if !ok {
|
||||||
sc, err := witch.NewScriptContext(target)
|
sc, err = witch.NewScriptContext()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
@ -125,7 +121,16 @@ func (s *gameWorldServer) verbHandler(verb, rest string, sender, target db.Objec
|
||||||
s.scriptsMutex.Unlock()
|
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) {
|
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)
|
affected, err := s.db.Earshot(*avatar)
|
||||||
|
|
||||||
for _, o := range affected {
|
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
|
// TODO figure out pointer shit
|
||||||
|
|
||||||
for _, h := range heard {
|
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
|
// TODO once we have a script engine, deliver the HEARS event
|
||||||
for _, sess := range as {
|
for _, sess := range as {
|
||||||
if sess.AccountID == h.OwnerID {
|
if sess.AccountID == h.OwnerID {
|
||||||
|
|
|
@ -1,13 +1,16 @@
|
||||||
package witch
|
package witch
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"log"
|
||||||
|
|
||||||
"github.com/vilmibm/hermeticum/server/db"
|
"github.com/vilmibm/hermeticum/server/db"
|
||||||
lua "github.com/yuin/gopher-lua"
|
lua "github.com/yuin/gopher-lua"
|
||||||
)
|
)
|
||||||
|
|
||||||
func hasWrapper(obj db.Object) func(*lua.LState) int {
|
func hasWrapper(obj db.Object) func(*lua.LState) int {
|
||||||
return func(ls *lua.LState) int {
|
return func(ls *lua.LState) int {
|
||||||
//lv := ls.ToTable(1)
|
lv := ls.ToTable(1)
|
||||||
|
log.Println(lv)
|
||||||
return 0
|
return 0
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,6 +1,8 @@
|
||||||
package witch
|
package witch
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"log"
|
||||||
|
|
||||||
"github.com/vilmibm/hermeticum/server/db"
|
"github.com/vilmibm/hermeticum/server/db"
|
||||||
lua "github.com/yuin/gopher-lua"
|
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
|
// TODO using a dummy script for now
|
||||||
|
|
||||||
const dummyScript = `
|
const dummyScript = `
|
||||||
|
@ -60,21 +51,51 @@ end)
|
||||||
// - do i inject from Go or prepend some Lua code?
|
// - do i inject from Go or prepend some Lua code?
|
||||||
// TODO figure out how the Lua code can affect Go and thus the database
|
// TODO figure out how the Lua code can affect Go and thus the database
|
||||||
|
|
||||||
func NewScriptContext(obj db.Object) (*ScriptContext, error) {
|
type VerbContext struct {
|
||||||
l := lua.NewState()
|
Verb string
|
||||||
|
Rest string
|
||||||
l.SetGlobal("has", l.NewFunction(hasWrapper(obj)))
|
Sender db.Object
|
||||||
l.SetGlobal("_handlers", l.NewTable())
|
Target db.Object
|
||||||
|
|
||||||
//if err := l.DoString(obj.Script); err != nil {
|
|
||||||
if err := l.DoString(dummyScript); err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
return &ScriptContext{}, nil
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func (sc *ScriptContext) Handle(verb, rest string, sender, target db.Object) error {
|
type ScriptContext struct {
|
||||||
// TODO call _handle function from the Lstate
|
script string
|
||||||
return nil
|
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