Noah Petherbridge
1a8a5eb94b
- Fix a memory sharing bug in the Giant Screenshot feature. - Main Menu to eagerload chunks in the background to make scrolling less jittery. No time for a loadscreen! - Extra script debugging: names/IDs of doodads are shown when they send messages to one another. - Level Properties: you can edit the Bounded max width/height values for the level. Doodad changes: - Buttons: fix a timing bug and keep better track of who is stepping on it, only popping up when all colliders have left. The effect: they pop up immediately (not after 200ms) and are more reliable. - Keys: zero-qty keys will no longer put themselves into the inventory of characters who already have one except for the player character. So the Thief will not steal them if she already has the key. Added to the JavaScript API: * time.Hour, time.Minute, time.Second, time.Millisecond, time.Microsecond
84 lines
2.0 KiB
Go
84 lines
2.0 KiB
Go
package scripting
|
|
|
|
import (
|
|
"git.kirsle.net/apps/doodle/pkg/log"
|
|
"github.com/robertkrimen/otto"
|
|
)
|
|
|
|
// Message holds data being published from one script VM with information sent
|
|
// to the linked VMs.
|
|
type Message struct {
|
|
Name string
|
|
SenderID string
|
|
Args []interface{}
|
|
}
|
|
|
|
/*
|
|
RegisterPublishHooks adds the pub/sub hooks to a JavaScript VM.
|
|
|
|
This adds the global methods `Message.Subscribe(name, func)` and
|
|
`Message.Publish(name, args)` to the JavaScript VM's scope.
|
|
*/
|
|
func RegisterPublishHooks(s *Supervisor, vm *VM) {
|
|
// Goroutine to watch the VM's inbound channel and invoke Subscribe handlers
|
|
// for any matching messages received.
|
|
go func() {
|
|
for msg := range vm.Inbound {
|
|
vm.muSubscribe.Lock()
|
|
|
|
if _, ok := vm.subscribe[msg.Name]; ok {
|
|
for _, callback := range vm.subscribe[msg.Name] {
|
|
log.Debug("PubSub: %s receives from %s: %s", vm.Name, msg.SenderID, msg.Name)
|
|
callback.Call(otto.Value{}, msg.Args...)
|
|
}
|
|
}
|
|
|
|
vm.muSubscribe.Unlock()
|
|
}
|
|
}()
|
|
|
|
// Register the Message.Subscribe and Message.Publish functions.
|
|
vm.vm.Set("Message", map[string]interface{}{
|
|
"Subscribe": func(name string, callback otto.Value) {
|
|
vm.muSubscribe.Lock()
|
|
defer vm.muSubscribe.Unlock()
|
|
|
|
if !callback.IsFunction() {
|
|
log.Error("SUBSCRIBE(%s): callback is not a function", name)
|
|
return
|
|
}
|
|
if _, ok := vm.subscribe[name]; !ok {
|
|
vm.subscribe[name] = []otto.Value{}
|
|
}
|
|
|
|
vm.subscribe[name] = append(vm.subscribe[name], callback)
|
|
},
|
|
|
|
"Publish": func(name string, v ...interface{}) {
|
|
for _, channel := range vm.Outbound {
|
|
channel <- Message{
|
|
Name: name,
|
|
SenderID: vm.Name,
|
|
Args: v,
|
|
}
|
|
}
|
|
},
|
|
|
|
"Broadcast": func(name string, v ...interface{}) {
|
|
// Send the message to all actor VMs.
|
|
for _, toVM := range s.scripts {
|
|
if vm.Name == toVM.Name {
|
|
log.Debug("Broadcast(%s): skip to vm '%s' cuz it is the sender", name, toVM.Name)
|
|
continue
|
|
}
|
|
|
|
toVM.Inbound <- Message{
|
|
Name: name,
|
|
SenderID: vm.Name,
|
|
Args: v,
|
|
}
|
|
}
|
|
},
|
|
})
|
|
}
|