Load Doodads from System Path as well as User Path

physics
Noah 2019-05-05 15:12:15 -07:00
parent f76ba6fbb7
commit ac490473b3
9 changed files with 106 additions and 20 deletions

View File

@ -0,0 +1,80 @@
package doodads
import (
"errors"
"fmt"
"io/ioutil"
"strings"
"git.kirsle.net/apps/doodle/pkg/enum"
"git.kirsle.net/apps/doodle/pkg/filesystem"
"git.kirsle.net/apps/doodle/pkg/log"
"git.kirsle.net/apps/doodle/pkg/userdir"
)
// ListDoodads returns a listing of all available doodads between all locations,
// including user doodads.
func ListDoodads() ([]string, error) {
var names []string
// Read system-level doodads first. Ignore errors, if the system path is
// empty we still go on to read the user directory.
files, _ := ioutil.ReadDir(filesystem.SystemDoodadsPath)
for _, file := range files {
name := file.Name()
if strings.HasSuffix(strings.ToLower(name), enum.DoodadExt) {
names = append(names, name)
}
}
// Append user doodads.
userFiles, err := userdir.ListDoodads()
names = append(names, userFiles...)
return names, err
}
// LoadFile reads a doodad file from disk, checking a few locations.
func LoadFile(filename string) (*Doodad, error) {
if !strings.HasSuffix(filename, enum.DoodadExt) {
filename += enum.DoodadExt
}
// Search the system and user paths for this level.
filename, err := filesystem.FindFile(filename)
if err != nil {
return nil, fmt.Errorf("doodads.LoadFile(%s): %s", filename, err)
}
// Load the JSON format.
if doodad, err := LoadJSON(filename); err == nil {
return doodad, nil
} else {
log.Warn(err.Error())
}
return nil, errors.New("invalid file type")
}
// WriteFile saves a doodad to disk in the user's config directory.
func (d *Doodad) WriteFile(filename string) error {
if !strings.HasSuffix(filename, enum.DoodadExt) {
filename += enum.DoodadExt
}
// bin, err := m.ToBinary()
bin, err := d.ToJSON()
if err != nil {
return err
}
// Save it to their profile directory.
filename = userdir.DoodadPath(filename)
log.Info("Write Doodad: %s", filename)
err = ioutil.WriteFile(filename, bin, 0644)
if err != nil {
return fmt.Errorf("doodads.WriteFile: %s", err)
}
return nil
}

View File

@ -219,7 +219,7 @@ func (s *EditorScene) SaveLevel(filename string) error {
func (s *EditorScene) LoadDoodad(filename string) error { func (s *EditorScene) LoadDoodad(filename string) error {
s.filename = filename s.filename = filename
doodad, err := doodads.LoadJSON(filename) doodad, err := doodads.LoadFile(filename)
if err != nil { if err != nil {
return fmt.Errorf("EditorScene.LoadDoodad(%s): %s", filename, err) return fmt.Errorf("EditorScene.LoadDoodad(%s): %s", filename, err)
} }

View File

@ -14,7 +14,6 @@ import (
"git.kirsle.net/apps/doodle/pkg/level" "git.kirsle.net/apps/doodle/pkg/level"
"git.kirsle.net/apps/doodle/pkg/log" "git.kirsle.net/apps/doodle/pkg/log"
"git.kirsle.net/apps/doodle/pkg/uix" "git.kirsle.net/apps/doodle/pkg/uix"
"git.kirsle.net/apps/doodle/pkg/userdir"
) )
// Width of the panel frame. // Width of the panel frame.
@ -261,7 +260,7 @@ func (u *EditorUI) SetupCanvas(d *Doodle) *uix.Canvas {
// mode when you click an existing Doodad and it "pops" out of the canvas // mode when you click an existing Doodad and it "pops" out of the canvas
// and onto the cursor to be repositioned. // and onto the cursor to be repositioned.
drawing.OnDragStart = func(filename string) { drawing.OnDragStart = func(filename string) {
doodad, err := doodads.LoadJSON(userdir.DoodadPath(filename)) doodad, err := doodads.LoadFile(filename)
if err != nil { if err != nil {
log.Error("drawing.OnDragStart: %s", err.Error()) log.Error("drawing.OnDragStart: %s", err.Error())
} }
@ -293,7 +292,10 @@ func (u *EditorUI) SetupCanvas(d *Doodle) *uix.Canvas {
Filename: actor.doodad.Filename, Filename: actor.doodad.Filename,
}) })
drawing.InstallActors(u.Scene.Level.Actors) err := drawing.InstallActors(u.Scene.Level.Actors)
if err != nil {
log.Error("Error installing actor onDrop to canvas: %s", err)
}
} }
}) })
u.Supervisor.Add(drawing) u.Supervisor.Add(drawing)

View File

@ -13,7 +13,6 @@ import (
"git.kirsle.net/apps/doodle/pkg/doodads" "git.kirsle.net/apps/doodle/pkg/doodads"
"git.kirsle.net/apps/doodle/pkg/log" "git.kirsle.net/apps/doodle/pkg/log"
"git.kirsle.net/apps/doodle/pkg/uix" "git.kirsle.net/apps/doodle/pkg/uix"
"git.kirsle.net/apps/doodle/pkg/userdir"
) )
// DraggableActor is a Doodad being dragged from the Doodad palette. // DraggableActor is a Doodad being dragged from the Doodad palette.
@ -50,10 +49,10 @@ func (u *EditorUI) setupDoodadFrame(e render.Engine, window *ui.Window) (*ui.Fra
perRow = balance.UIDoodadsPerRow perRow = balance.UIDoodadsPerRow
) )
doodadsAvailable, err := userdir.ListDoodads() doodadsAvailable, err := doodads.ListDoodads()
if err != nil { if err != nil {
return frame, fmt.Errorf( return frame, fmt.Errorf(
"setupDoodadFrame: userdir.ListDoodads: %s", "setupDoodadFrame: doodads.ListDoodads: %s",
err, err,
) )
} }
@ -77,7 +76,7 @@ func (u *EditorUI) setupDoodadFrame(e render.Engine, window *ui.Window) (*ui.Fra
} }
func(filename string) { func(filename string) {
doodad, err := doodads.LoadJSON(userdir.DoodadPath(filename)) doodad, err := doodads.LoadFile(filename)
if err != nil { if err != nil {
log.Error(err.Error()) log.Error(err.Error())
doodad = doodads.New(balance.DoodadSize) doodad = doodads.New(balance.DoodadSize)

View File

@ -1,4 +1,4 @@
package balance package filesystem
import ( import (
"errors" "errors"
@ -22,6 +22,12 @@ const (
BinDoodadType uint8 = 2 BinDoodadType uint8 = 2
) )
// Paths to system-level assets bundled with the application.
var (
SystemDoodadsPath = filepath.Join(".", "assets", "doodads")
SystemLevelsPath = filepath.Join(".", "assets", "levels")
)
// MakeHeader creates the binary file header. // MakeHeader creates the binary file header.
func MakeHeader(filetype uint8) []byte { func MakeHeader(filetype uint8) []byte {
header := make([]byte, len(BinMagic)+2) header := make([]byte, len(BinMagic)+2)
@ -87,7 +93,7 @@ func FindFile(filename string) (string, error) {
// Search level directories. // Search level directories.
if filetype == enum.LevelExt || filetype == "" { if filetype == enum.LevelExt || filetype == "" {
// system levels // system levels
candidate := filepath.Join(".", "assets", "levels", filename) candidate := filepath.Join(SystemLevelsPath, filename)
if _, err := os.Stat(candidate); !os.IsNotExist(err) { if _, err := os.Stat(candidate); !os.IsNotExist(err) {
return candidate, nil return candidate, nil
} }
@ -102,7 +108,7 @@ func FindFile(filename string) (string, error) {
// Search doodad directories. // Search doodad directories.
if filetype == enum.DoodadExt || filetype == "" { if filetype == enum.DoodadExt || filetype == "" {
// system doodads // system doodads
candidate := filepath.Join(".", "assets", "doodads", filename) candidate := filepath.Join(SystemDoodadsPath, filename)
if _, err := os.Stat(candidate); !os.IsNotExist(err) { if _, err := os.Stat(candidate); !os.IsNotExist(err) {
return candidate, nil return candidate, nil
} }
@ -114,5 +120,5 @@ func FindFile(filename string) (string, error) {
} }
} }
return "", errors.New("file not found") return filename, errors.New("file not found")
} }

View File

@ -6,13 +6,13 @@ import (
"io/ioutil" "io/ioutil"
"os" "os"
"git.kirsle.net/apps/doodle/pkg/balance" "git.kirsle.net/apps/doodle/pkg/filesystem"
"github.com/vmihailenco/msgpack" "github.com/vmihailenco/msgpack"
) )
// ToBinary serializes the level to binary format. // ToBinary serializes the level to binary format.
func (m *Level) ToBinary() ([]byte, error) { func (m *Level) ToBinary() ([]byte, error) {
header := balance.MakeHeader(balance.BinLevelType) header := filesystem.MakeHeader(filesystem.BinLevelType)
out := bytes.NewBuffer(header) out := bytes.NewBuffer(header)
encoder := msgpack.NewEncoder(out) encoder := msgpack.NewEncoder(out)
err := encoder.Encode(m) err := encoder.Encode(m)
@ -43,7 +43,7 @@ func LoadBinary(filename string) (*Level, error) {
defer fh.Close() defer fh.Close()
// Read and verify the file header from the binary format. // Read and verify the file header from the binary format.
err = balance.ReadHeader(balance.BinLevelType, fh) err = filesystem.ReadHeader(filesystem.BinLevelType, fh)
if err != nil { if err != nil {
return nil, err return nil, err
} }

View File

@ -6,8 +6,8 @@ import (
"io/ioutil" "io/ioutil"
"strings" "strings"
"git.kirsle.net/apps/doodle/pkg/balance"
"git.kirsle.net/apps/doodle/pkg/enum" "git.kirsle.net/apps/doodle/pkg/enum"
"git.kirsle.net/apps/doodle/pkg/filesystem"
"git.kirsle.net/apps/doodle/pkg/log" "git.kirsle.net/apps/doodle/pkg/log"
"git.kirsle.net/apps/doodle/pkg/userdir" "git.kirsle.net/apps/doodle/pkg/userdir"
) )
@ -19,7 +19,7 @@ func LoadFile(filename string) (*Level, error) {
} }
// Search the system and user paths for this level. // Search the system and user paths for this level.
filename, err := balance.FindFile(filename) filename, err := filesystem.FindFile(filename)
if err != nil { if err != nil {
return nil, err return nil, err
} }

View File

@ -88,7 +88,7 @@ func (s *PlayScene) Setup(d *Doodle) error {
} }
// Load in the player character. // Load in the player character.
player, err := doodads.LoadJSON("./assets/doodads/azu-blu.doodad") player, err := doodads.LoadFile("./assets/doodads/azu-blu.doodad")
if err != nil { if err != nil {
log.Error("PlayScene.Setup: failed to load player doodad: %s", err) log.Error("PlayScene.Setup: failed to load player doodad: %s", err)
player = doodads.NewDummy(32) player = doodads.NewDummy(32)

View File

@ -9,7 +9,6 @@ import (
"git.kirsle.net/apps/doodle/pkg/level" "git.kirsle.net/apps/doodle/pkg/level"
"git.kirsle.net/apps/doodle/pkg/log" "git.kirsle.net/apps/doodle/pkg/log"
"git.kirsle.net/apps/doodle/pkg/scripting" "git.kirsle.net/apps/doodle/pkg/scripting"
"git.kirsle.net/apps/doodle/pkg/userdir"
) )
// InstallActors adds external Actors to the canvas to be superimposed on top // InstallActors adds external Actors to the canvas to be superimposed on top
@ -17,7 +16,7 @@ import (
func (w *Canvas) InstallActors(actors level.ActorMap) error { func (w *Canvas) InstallActors(actors level.ActorMap) error {
w.actors = make([]*Actor, 0) w.actors = make([]*Actor, 0)
for id, actor := range actors { for id, actor := range actors {
doodad, err := doodads.LoadJSON(userdir.DoodadPath(actor.Filename)) doodad, err := doodads.LoadFile(actor.Filename)
if err != nil { if err != nil {
return fmt.Errorf("InstallActors: %s", err) return fmt.Errorf("InstallActors: %s", err)
} }