Skip to content

Commit

Permalink
perf: vastly speed up loading of resource folder
Browse files Browse the repository at this point in the history
Signed-off-by: Rachel Powers <[email protected]>
  • Loading branch information
Ryex committed Sep 30, 2024
1 parent 5203473 commit 9df726b
Show file tree
Hide file tree
Showing 8 changed files with 76 additions and 60 deletions.
2 changes: 1 addition & 1 deletion .github/workflows/build.yml
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,7 @@ jobs:
- name: Build gui
run: |
cp FyneApp.toml ./cmd/dungeondraft-packager
fyne package -src ./cmd/dungeondraft-packager -appID io.github.ryex.dungondraft-gopackager
fyne package -src ./cmd/dungeondraft-packager --release -appID io.github.ryex.dungondraft-gopackager
- name: Build cli
run: |
go build -ldflags "-s -w" ./cmd/dungeondraft-packager-cli
Expand Down
2 changes: 1 addition & 1 deletion internal/cmd/list.go
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,7 @@ func (lsf *ListFilesCmd) printList(pkg *ddpackage.Package) {
filesCount := len(fileList)
for i, fi := range fileList {
fmt.Printf(
"File [%d/%d] Name: %s Size: %d Offset %d ResourcePath: %s\n",
"File [%-5d/%-5d] Name: %-38s Size: %-8d Offset %-8d ResourcePath: %s\n",
i+1,
filesCount,
filepath.Base(fi.ResPath),
Expand Down
6 changes: 3 additions & 3 deletions internal/gui/pack.go
Original file line number Diff line number Diff line change
Expand Up @@ -406,7 +406,7 @@ func (a *App) packPackage(path string, options ddpackage.PackOptions, genThumbna
"pack.thumbnails.error.text",
"Error generating thumbnails for {{.Path}}",
map[string]any{
"Path": a.pkg.UnpackedPath,
"Path": a.pkg.UnpackedPath(),
},
))),
a.window,
Expand All @@ -430,7 +430,7 @@ func (a *App) packPackage(path string, options ddpackage.PackOptions, genThumbna
"pack.package.error.text",
"Error packing {{.Path}} to {{.Pack}}",
map[string]any{
"Path": a.pkg.UnpackedPath,
"Path": a.pkg.UnpackedPath(),
"Pack": targetPath,
},
))),
Expand All @@ -446,7 +446,7 @@ func (a *App) packPackage(path string, options ddpackage.PackOptions, genThumbna
"pack.success.dlg.text",
"{{.Path}} Packaged to {{.Pack}} successfully",
map[string]any{
"Path": a.pkg.UnpackedPath,
"Path": a.pkg.UnpackedPath(),
"Pack": targetPath,
}),
a.window,
Expand Down
3 changes: 2 additions & 1 deletion internal/gui/translation/en-US.json
Original file line number Diff line number Diff line change
Expand Up @@ -125,5 +125,6 @@
"Redo": "Redo",
"Cut": "Cut",
"file.parent": "Parent",
"file.name": "Name"
"file.name": "Name",
"OK": "Ok"
}
24 changes: 12 additions & 12 deletions pkg/ddpackage/ddpackage.go
Original file line number Diff line number Diff line change
Expand Up @@ -330,7 +330,7 @@ func (p *Package) NewFileInfo(options NewFileInfoOptions) (*structures.FileInfo,
return nil, ErrUnsetUnpackedPath
}

if options.Path != "" {
if options.Path != "" && (options.ResPath == nil || options.RelPath == nil) {

l := p.log.WithField("filePath", options.Path)
relPath, err := filepath.Rel(p.unpackedPath, options.Path)
Expand Down Expand Up @@ -365,7 +365,7 @@ func (p *Package) NewFileInfo(options NewFileInfoOptions) (*structures.FileInfo,
Size: options.Size,
}

if options.Path != "" && ddimage.PathIsSupportedImage(options.Path) {
if options.Path != "" && info.IsTexture() && ddimage.PathIsSupportedImage(options.Path) {

l := p.log.WithField("filePath", options.Path)

Expand All @@ -376,16 +376,16 @@ func (p *Package) NewFileInfo(options NewFileInfoOptions) (*structures.FileInfo,
info.ThumbnailPath = thumbnailPath
info.ThumbnailResPath = fmt.Sprintf("res://packs/%s/thumbnails/%s", p.id, thumbnailName)

img, format, err := ddimage.OpenImage(options.Path)
if err != nil {
l.WithError(err).Error("can not open path with image extension as image")
err = errors.Join(err, fmt.Errorf("failed to open %s as an image", options.Path))
// log but let info construction continue
} else {
l.WithField("imageFormat", format).Trace("read image")
info.ImageFormat = format

if !ddimage.PathIsSupportedDDImage(options.Path) {
if !ddimage.PathIsSupportedDDImage(options.Path) {
img, format, err := ddimage.OpenImage(options.Path)
if err != nil {
l.WithError(err).Error("can not open path with image extension as image")
err = errors.Join(err, fmt.Errorf("failed to open %s as an image", options.Path))
// log but let info construction continue
} else {
l.WithField("imageFormat", format).Trace("read image")
info.ImageFormat = format

info.Image = img
l.WithField("imageFormat", format).
Info("format is not supported by dungeondraft, converting to png")
Expand Down
12 changes: 9 additions & 3 deletions pkg/ddpackage/pack.go
Original file line number Diff line number Diff line change
Expand Up @@ -216,6 +216,10 @@ func (p *Package) updateFromPaths(paths []string, progressCallback func(p float6
}
}

p.fileList.SetCapacity(files.Size())

cbPoint := max(files.Size()/200, 1)

for i, file := range files.AsSlice() {
// filter extensions
ext := strings.ToLower(filepath.Ext(file))
Expand Down Expand Up @@ -246,8 +250,10 @@ func (p *Package) updateFromPaths(paths []string, progressCallback func(p float6
p.log.Infof("including %s", file)
p.addResource(fInfo)
}
if progressCallback != nil {
progressCallback(float64(i)/float64(files.Size()), file)
if i%cbPoint == 0 {
if progressCallback != nil {
progressCallback(float64(i)/float64(files.Size()), file)
}
}
}

Expand Down Expand Up @@ -280,7 +286,7 @@ func (p *Package) updateFromPaths(paths []string, progressCallback func(p float6
}
p.resourceMap[packJSONResPath] = packJSONInfo

//remove duplicates
// remove duplicates
p.fileList = slices.CompactFunc(p.fileList, func(a, b *structures.FileInfo) bool {
return a.ResPath == b.ResPath
})
Expand Down
8 changes: 0 additions & 8 deletions pkg/ddpackage/thumbnails.go
Original file line number Diff line number Diff line change
Expand Up @@ -25,14 +25,6 @@ func (p *Package) GenerateThumbnails(progressCallbacks ...func(p float64)) error
}
}

thumbnailPrefix := fmt.Sprintf("res://packs/%s/thumbnails/", p.id)
terrainPrefix := fmt.Sprintf("res://packs/%s/%s/textures/terrain/", p.id, p.name)
wallsPrefix := fmt.Sprintf("res://packs/%s/%s/textures/walls/", p.id, p.name)
pathsPrefix := fmt.Sprintf("res://packs/%s/%s/textures/paths/", p.id, p.name)
fmt.Println(thumbnailPrefix)
fmt.Println(terrainPrefix)
fmt.Println(wallsPrefix)
fmt.Println(pathsPrefix)
for i, info := range p.fileList {
if info.IsTexture() {
p.log.WithField("res", info.ResPath).Trace("generating thumbnail")
Expand Down
79 changes: 48 additions & 31 deletions pkg/structures/files.go
Original file line number Diff line number Diff line change
Expand Up @@ -306,6 +306,17 @@ func (fil FileInfoList) RelPaths() (paths []string) {
return
}

func (fil FileInfoList) SetCapacity(capacity int) {
if capacity < len(fil) {
capacity = len(fil)
}
if capacity > cap(fil) {
sized := make([]*FileInfo, len(fil), capacity)
copy(sized, fil)
fil = sized
}
}

func (fil FileInfoList) UpdateThumbnailRefrences() {
thumbnailMap := make(map[string]string)
for _, fi := range fil {
Expand All @@ -323,41 +334,47 @@ func (fil FileInfoList) UpdateThumbnailRefrences() {
}
}

// places the file list
func (fil FileInfoList) Sort() {
fil.UpdateThumbnailRefrences()
cmpResPaths := func(a, b string) int {
if a < b {
return -1
}
if a > b {
return 1
}
return 0
func cmpResPaths(a, b string) int {
if a < b {
return -1
}
slices.SortFunc(fil, func(a, b *FileInfo) int {
aIsThumb := a.IsThumbnail()
bIsThumb := b.IsThumbnail()
if (aIsThumb && bIsThumb) || (!aIsThumb && !bIsThumb) {
return cmpResPaths(a.ResPath, b.ResPath)
} else if aIsThumb && !bIsThumb {
if a.ThubnailFor != "" {
if a.ThubnailFor == b.ResPath {
return -1
}
return cmpResPaths(a.ThubnailFor, b.ResPath)
if a > b {
return 1
}
return 0
}

func cmpResAndThumb(a, b *FileInfo) int {
aIsThumb := a.IsThumbnail()
bIsThumb := b.IsThumbnail()
if (aIsThumb && bIsThumb) || (!aIsThumb && !bIsThumb) {
return cmpResPaths(a.ResPath, b.ResPath)
} else if aIsThumb && !bIsThumb {
if a.ThubnailFor != "" {
if a.ThubnailFor == b.ResPath {
return -1
}
return -1
} else if !aIsThumb && bIsThumb {
if b.ThubnailFor != "" {
if a.ResPath == b.ThubnailFor {
return 1
}
return cmpResPaths(a.ResPath, b.ThubnailFor)
return cmpResPaths(a.ThubnailFor, b.ResPath)
}
return -1
} else if !aIsThumb && bIsThumb {
if b.ThubnailFor != "" {
if a.ResPath == b.ThubnailFor {
return 1
}
return -1
return cmpResPaths(a.ResPath, b.ThubnailFor)
}
return 0
return -1
}
return 0
}

// places the file list
func (fil FileInfoList) Sort() {
fil.UpdateThumbnailRefrences()

slices.SortFunc(fil, func(a, b *FileInfo) int {
return cmpResPaths(a.ResPath, b.ResPath)
})
}

Expand Down

0 comments on commit 9df726b

Please sign in to comment.