doodle/pkg/level/filesystem.go
Noah Petherbridge 1cc6eee5c8 Refactor Level Publishing + MagicForm
* magicform is a helper package that may eventually be part of the go/ui
  library, for easily creating structured form layouts.
* The Level Publisher UI is the first to utilize magicform.

Refactor how level publishing works:

* Level data now stores SaveDoodads and SaveBuiltins (bools) and when
  the level editor saves the file, it will attach custom and/or builtin
  doodads just before save.
* Move the menu item from the File menu to Level->Publish
* The Publisher UI just shows the checkboxes to toggle the level
  settings and a convenient Save button along with descriptive text.
* Free versions get the "Register" window popping up if they click the
  Save Now button from within the publisher window.

Note: free versions can still toggle the booleans on/off but their game
will not attach any new doodads on save.

* Free games which open a level w/ embedded doodads will get a pop-up
  warning that the doodads aren't available.
* If they DON'T turn off the SaveDoodads option, they can still edit and
  save the level and keep the existing doodads attached.
* If they UNCHECK the option and save, all attached doodads are removed
  from the level.
2022-01-17 18:51:11 -08:00

94 lines
1.8 KiB
Go

package level
import (
"errors"
"sort"
"strings"
)
// FileSystem embeds a map of files inside a parent drawing.
type FileSystem map[string]File
// File holds details about a file in the FileSystem.
type File struct {
Data []byte `json:"data"`
}
// SetFile sets a file's data in the level.
func (l *Level) SetFile(filename string, data []byte) {
if l.Files == nil {
l.Files = map[string]File{}
}
l.Files[filename] = File{
Data: data,
}
}
// GetFile looks up an embedded file.
func (l *Level) GetFile(filename string) ([]byte, error) {
if l.Files == nil {
l.Files = map[string]File{}
}
if result, ok := l.Files[filename]; ok {
return result.Data, nil
}
return []byte{}, errors.New("not found")
}
// DeleteFile removes an embedded file.
func (l *Level) DeleteFile(filename string) bool {
if l.Files == nil {
l.Files = map[string]File{}
}
if _, ok := l.Files[filename]; ok {
delete(l.Files, filename)
return true
}
return false
}
// DeleteFiles removes all files beginning with the prefix.
func (l *Level) DeleteFiles(prefix string) int {
var count int
for filename := range l.Files {
if strings.HasPrefix(filename, prefix) {
delete(l.Files, filename)
count++
}
}
return count
}
// ListFiles returns the list of all embedded file names, alphabetically.
func (l *Level) ListFiles() []string {
var files []string
if l == nil || l.Files == nil {
return files
}
for name := range l.Files {
files = append(files, name)
}
sort.Strings(files)
return files
}
// ListFilesAt returns the list of files having a common prefix.
func (l *Level) ListFilesAt(prefix string) []string {
var (
files = l.ListFiles()
match = []string{}
)
for _, name := range files {
if strings.HasPrefix(name, prefix) {
match = append(match, name)
}
}
return match
}