2019-04-16 06:07:15 +00:00
|
|
|
// Package scripting manages the JavaScript VMs for Doodad
|
|
|
|
// scripts.
|
|
|
|
package scripting
|
|
|
|
|
|
|
|
import (
|
|
|
|
"errors"
|
|
|
|
"fmt"
|
2019-04-19 01:15:05 +00:00
|
|
|
"time"
|
2019-04-16 06:07:15 +00:00
|
|
|
|
|
|
|
"git.kirsle.net/apps/doodle/pkg/level"
|
|
|
|
"git.kirsle.net/apps/doodle/pkg/log"
|
|
|
|
)
|
|
|
|
|
|
|
|
// Supervisor manages the JavaScript VMs for each doodad by its
|
|
|
|
// unique ID.
|
|
|
|
type Supervisor struct {
|
|
|
|
scripts map[string]*VM
|
|
|
|
}
|
|
|
|
|
|
|
|
// NewSupervisor creates a new JavaScript Supervior.
|
|
|
|
func NewSupervisor() *Supervisor {
|
|
|
|
return &Supervisor{
|
|
|
|
scripts: map[string]*VM{},
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2019-04-19 01:15:05 +00:00
|
|
|
// Loop the supervisor to invoke timer events in any running scripts.
|
|
|
|
func (s *Supervisor) Loop() error {
|
|
|
|
now := time.Now()
|
|
|
|
for _, vm := range s.scripts {
|
|
|
|
vm.TickTimer(now)
|
|
|
|
}
|
|
|
|
return nil
|
|
|
|
}
|
|
|
|
|
2019-04-16 06:07:15 +00:00
|
|
|
// InstallScripts loads scripts for all actors in the level.
|
|
|
|
func (s *Supervisor) InstallScripts(level *level.Level) error {
|
|
|
|
for _, actor := range level.Actors {
|
2019-05-02 01:30:30 +00:00
|
|
|
if err := s.AddLevelScript(actor.ID()); err != nil {
|
2019-04-16 06:07:15 +00:00
|
|
|
return err
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return nil
|
|
|
|
}
|
|
|
|
|
2019-05-02 01:30:30 +00:00
|
|
|
// AddLevelScript adds a script to the supervisor with level hooks.
|
|
|
|
func (s *Supervisor) AddLevelScript(id string) error {
|
|
|
|
log.Debug("InstallScripts: load script from Actor %s", id)
|
|
|
|
|
|
|
|
if _, ok := s.scripts[id]; ok {
|
|
|
|
return fmt.Errorf("duplicate actor ID %s in level", id)
|
|
|
|
}
|
|
|
|
|
|
|
|
s.scripts[id] = NewVM(id)
|
|
|
|
if err := s.scripts[id].RegisterLevelHooks(); err != nil {
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
|
|
|
|
return nil
|
|
|
|
}
|
|
|
|
|
2019-04-16 06:07:15 +00:00
|
|
|
// To returns the VM for a named script.
|
|
|
|
func (s *Supervisor) To(name string) *VM {
|
|
|
|
if vm, ok := s.scripts[name]; ok {
|
|
|
|
return vm
|
|
|
|
}
|
|
|
|
|
2019-04-19 01:15:05 +00:00
|
|
|
// TODO: put this log back in, but add PLAYER script so it doesn't spam
|
|
|
|
// the console for missing PLAYER.
|
|
|
|
// log.Error("scripting.Supervisor.To(%s): no such VM but returning blank VM",
|
|
|
|
// name,
|
|
|
|
// )
|
2019-04-16 06:07:15 +00:00
|
|
|
return NewVM(name)
|
|
|
|
}
|
|
|
|
|
|
|
|
// GetVM returns a script VM from the supervisor.
|
|
|
|
func (s *Supervisor) GetVM(name string) (*VM, error) {
|
|
|
|
if vm, ok := s.scripts[name]; ok {
|
|
|
|
return vm, nil
|
|
|
|
}
|
|
|
|
return nil, errors.New("not found")
|
|
|
|
}
|