annotate semiconginev2/resources.nim @ 1236:176383220123

add: first font-rendering test
author sam <sam@basx.dev>
date Sat, 20 Jul 2024 17:45:44 +0700
parents 5dcb503ef0c0
children e8b3dc80e48e
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
1225
27cd1c21290e did: refactor resources
sam <sam@basx.dev>
parents:
diff changeset
1 type
27cd1c21290e did: refactor resources
sam <sam@basx.dev>
parents:
diff changeset
2 ResourceBundlingType = enum
27cd1c21290e did: refactor resources
sam <sam@basx.dev>
parents:
diff changeset
3 Dir # Directories
27cd1c21290e did: refactor resources
sam <sam@basx.dev>
parents:
diff changeset
4 Zip # Zip files
27cd1c21290e did: refactor resources
sam <sam@basx.dev>
parents:
diff changeset
5 Exe # Embeded in executable
27cd1c21290e did: refactor resources
sam <sam@basx.dev>
parents:
diff changeset
6
27cd1c21290e did: refactor resources
sam <sam@basx.dev>
parents:
diff changeset
7 const
27cd1c21290e did: refactor resources
sam <sam@basx.dev>
parents:
diff changeset
8 thebundletype = parseEnum[ResourceBundlingType](PACKAGETYPE.toLowerAscii().capitalizeAscii())
27cd1c21290e did: refactor resources
sam <sam@basx.dev>
parents:
diff changeset
9 ASCII_CHARSET = PrintableChars.toSeq.toRunes
27cd1c21290e did: refactor resources
sam <sam@basx.dev>
parents:
diff changeset
10 DEFAULT_PACKAGE = "default"
27cd1c21290e did: refactor resources
sam <sam@basx.dev>
parents:
diff changeset
11
27cd1c21290e did: refactor resources
sam <sam@basx.dev>
parents:
diff changeset
12 # resource loading
27cd1c21290e did: refactor resources
sam <sam@basx.dev>
parents:
diff changeset
13
27cd1c21290e did: refactor resources
sam <sam@basx.dev>
parents:
diff changeset
14 func normalizeDir(dir: string): string =
27cd1c21290e did: refactor resources
sam <sam@basx.dev>
parents:
diff changeset
15 result = dir
27cd1c21290e did: refactor resources
sam <sam@basx.dev>
parents:
diff changeset
16 if result.startsWith("./"):
27cd1c21290e did: refactor resources
sam <sam@basx.dev>
parents:
diff changeset
17 result = result[2 .. ^1]
27cd1c21290e did: refactor resources
sam <sam@basx.dev>
parents:
diff changeset
18 if result.startsWith("/"):
27cd1c21290e did: refactor resources
sam <sam@basx.dev>
parents:
diff changeset
19 result = result[1 .. ^1]
27cd1c21290e did: refactor resources
sam <sam@basx.dev>
parents:
diff changeset
20 result = dir.replace('\\', '/')
27cd1c21290e did: refactor resources
sam <sam@basx.dev>
parents:
diff changeset
21 if not result.endsWith("/") and result != "":
27cd1c21290e did: refactor resources
sam <sam@basx.dev>
parents:
diff changeset
22 result = result & "/"
27cd1c21290e did: refactor resources
sam <sam@basx.dev>
parents:
diff changeset
23
27cd1c21290e did: refactor resources
sam <sam@basx.dev>
parents:
diff changeset
24 when thebundletype == Dir:
27cd1c21290e did: refactor resources
sam <sam@basx.dev>
parents:
diff changeset
25
27cd1c21290e did: refactor resources
sam <sam@basx.dev>
parents:
diff changeset
26 proc resourceRoot(): string =
27cd1c21290e did: refactor resources
sam <sam@basx.dev>
parents:
diff changeset
27 getAppDir().absolutePath().joinPath(RESOURCEROOT)
27cd1c21290e did: refactor resources
sam <sam@basx.dev>
parents:
diff changeset
28 proc packageRoot(package: string): string =
27cd1c21290e did: refactor resources
sam <sam@basx.dev>
parents:
diff changeset
29 resourceRoot().joinPath(package)
27cd1c21290e did: refactor resources
sam <sam@basx.dev>
parents:
diff changeset
30
27cd1c21290e did: refactor resources
sam <sam@basx.dev>
parents:
diff changeset
31 proc loadResource_intern(path: string, package: string): Stream =
27cd1c21290e did: refactor resources
sam <sam@basx.dev>
parents:
diff changeset
32 let realpath = package.packageRoot().joinPath(path)
27cd1c21290e did: refactor resources
sam <sam@basx.dev>
parents:
diff changeset
33 if not realpath.fileExists():
27cd1c21290e did: refactor resources
sam <sam@basx.dev>
parents:
diff changeset
34 raise newException(Exception, &"Resource {path} not found (checked {realpath})")
27cd1c21290e did: refactor resources
sam <sam@basx.dev>
parents:
diff changeset
35 newFileStream(realpath, fmRead)
27cd1c21290e did: refactor resources
sam <sam@basx.dev>
parents:
diff changeset
36
27cd1c21290e did: refactor resources
sam <sam@basx.dev>
parents:
diff changeset
37 proc modList_intern(): seq[string] =
27cd1c21290e did: refactor resources
sam <sam@basx.dev>
parents:
diff changeset
38 for kind, file in walkDir(resourceRoot(), relative = true):
27cd1c21290e did: refactor resources
sam <sam@basx.dev>
parents:
diff changeset
39 if kind == pcDir:
27cd1c21290e did: refactor resources
sam <sam@basx.dev>
parents:
diff changeset
40 result.add file
27cd1c21290e did: refactor resources
sam <sam@basx.dev>
parents:
diff changeset
41
27cd1c21290e did: refactor resources
sam <sam@basx.dev>
parents:
diff changeset
42 iterator walkResources_intern(dir: string, package = DEFAULT_PACKAGE): string =
27cd1c21290e did: refactor resources
sam <sam@basx.dev>
parents:
diff changeset
43 for file in walkDirRec(package.packageRoot().joinPath(dir), relative = true):
27cd1c21290e did: refactor resources
sam <sam@basx.dev>
parents:
diff changeset
44 yield file
27cd1c21290e did: refactor resources
sam <sam@basx.dev>
parents:
diff changeset
45
27cd1c21290e did: refactor resources
sam <sam@basx.dev>
parents:
diff changeset
46 iterator ls_intern(dir: string, package: string): tuple[kind: PathComponent, path: string] =
27cd1c21290e did: refactor resources
sam <sam@basx.dev>
parents:
diff changeset
47 for i in walkDir(package.packageRoot().joinPath(dir), relative = true):
27cd1c21290e did: refactor resources
sam <sam@basx.dev>
parents:
diff changeset
48 yield i
27cd1c21290e did: refactor resources
sam <sam@basx.dev>
parents:
diff changeset
49
27cd1c21290e did: refactor resources
sam <sam@basx.dev>
parents:
diff changeset
50 elif thebundletype == Zip:
27cd1c21290e did: refactor resources
sam <sam@basx.dev>
parents:
diff changeset
51
27cd1c21290e did: refactor resources
sam <sam@basx.dev>
parents:
diff changeset
52 import ./thirdparty/zippy/zippy/ziparchives
27cd1c21290e did: refactor resources
sam <sam@basx.dev>
parents:
diff changeset
53
27cd1c21290e did: refactor resources
sam <sam@basx.dev>
parents:
diff changeset
54 proc resourceRoot(): string =
27cd1c21290e did: refactor resources
sam <sam@basx.dev>
parents:
diff changeset
55 absolutePath(getAppDir()).joinPath(RESOURCEROOT)
27cd1c21290e did: refactor resources
sam <sam@basx.dev>
parents:
diff changeset
56 proc packageRoot(package: string): string =
27cd1c21290e did: refactor resources
sam <sam@basx.dev>
parents:
diff changeset
57 resourceRoot().joinPath(package)
27cd1c21290e did: refactor resources
sam <sam@basx.dev>
parents:
diff changeset
58
27cd1c21290e did: refactor resources
sam <sam@basx.dev>
parents:
diff changeset
59 proc loadResource_intern(path: string, package: string): Stream =
27cd1c21290e did: refactor resources
sam <sam@basx.dev>
parents:
diff changeset
60 let archive = openZipArchive(package.packageRoot() & ".zip")
27cd1c21290e did: refactor resources
sam <sam@basx.dev>
parents:
diff changeset
61 try:
27cd1c21290e did: refactor resources
sam <sam@basx.dev>
parents:
diff changeset
62 result = newStringStream(archive.extractFile(path))
27cd1c21290e did: refactor resources
sam <sam@basx.dev>
parents:
diff changeset
63 except ZippyError:
27cd1c21290e did: refactor resources
sam <sam@basx.dev>
parents:
diff changeset
64 raise newException(Exception, &"Resource {path} not found")
27cd1c21290e did: refactor resources
sam <sam@basx.dev>
parents:
diff changeset
65 archive.close()
27cd1c21290e did: refactor resources
sam <sam@basx.dev>
parents:
diff changeset
66
27cd1c21290e did: refactor resources
sam <sam@basx.dev>
parents:
diff changeset
67 proc modList_intern(): seq[string] =
27cd1c21290e did: refactor resources
sam <sam@basx.dev>
parents:
diff changeset
68 for kind, file in walkDir(resourceRoot(), relative = true):
27cd1c21290e did: refactor resources
sam <sam@basx.dev>
parents:
diff changeset
69 if kind == pcFile and file.endsWith(".zip"):
27cd1c21290e did: refactor resources
sam <sam@basx.dev>
parents:
diff changeset
70 result.add file[0 ..< ^4]
27cd1c21290e did: refactor resources
sam <sam@basx.dev>
parents:
diff changeset
71
27cd1c21290e did: refactor resources
sam <sam@basx.dev>
parents:
diff changeset
72 iterator walkResources_intern(dir: string, package = DEFAULT_PACKAGE): string =
27cd1c21290e did: refactor resources
sam <sam@basx.dev>
parents:
diff changeset
73 let archive = openZipArchive(package.packageRoot() & ".zip")
27cd1c21290e did: refactor resources
sam <sam@basx.dev>
parents:
diff changeset
74 let normDir = dir.normalizeDir()
27cd1c21290e did: refactor resources
sam <sam@basx.dev>
parents:
diff changeset
75 for i in archive.walkFiles:
27cd1c21290e did: refactor resources
sam <sam@basx.dev>
parents:
diff changeset
76 if i.startsWith(normDir):
27cd1c21290e did: refactor resources
sam <sam@basx.dev>
parents:
diff changeset
77 yield i
27cd1c21290e did: refactor resources
sam <sam@basx.dev>
parents:
diff changeset
78 archive.close()
27cd1c21290e did: refactor resources
sam <sam@basx.dev>
parents:
diff changeset
79
27cd1c21290e did: refactor resources
sam <sam@basx.dev>
parents:
diff changeset
80 iterator ls_intern(dir: string, package: string): tuple[kind: PathComponent, path: string] =
27cd1c21290e did: refactor resources
sam <sam@basx.dev>
parents:
diff changeset
81 let archive = openZipArchive(package.packageRoot() & ".zip")
27cd1c21290e did: refactor resources
sam <sam@basx.dev>
parents:
diff changeset
82 let normDir = dir.normalizeDir()
27cd1c21290e did: refactor resources
sam <sam@basx.dev>
parents:
diff changeset
83 var yielded: HashSet[string]
27cd1c21290e did: refactor resources
sam <sam@basx.dev>
parents:
diff changeset
84
27cd1c21290e did: refactor resources
sam <sam@basx.dev>
parents:
diff changeset
85 for i in archive.walkFiles:
27cd1c21290e did: refactor resources
sam <sam@basx.dev>
parents:
diff changeset
86 if i.startsWith(normDir):
27cd1c21290e did: refactor resources
sam <sam@basx.dev>
parents:
diff changeset
87 let components = i[normDir.len .. ^1].split('/', maxsplit = 1)
27cd1c21290e did: refactor resources
sam <sam@basx.dev>
parents:
diff changeset
88 if components.len == 1:
27cd1c21290e did: refactor resources
sam <sam@basx.dev>
parents:
diff changeset
89 if not (components[0] in yielded):
27cd1c21290e did: refactor resources
sam <sam@basx.dev>
parents:
diff changeset
90 yield (kind: pcFile, path: components[0])
27cd1c21290e did: refactor resources
sam <sam@basx.dev>
parents:
diff changeset
91 else:
27cd1c21290e did: refactor resources
sam <sam@basx.dev>
parents:
diff changeset
92 if not (components[0] in yielded):
27cd1c21290e did: refactor resources
sam <sam@basx.dev>
parents:
diff changeset
93 yield (kind: pcDir, path: components[0])
27cd1c21290e did: refactor resources
sam <sam@basx.dev>
parents:
diff changeset
94 yielded.incl components[0]
27cd1c21290e did: refactor resources
sam <sam@basx.dev>
parents:
diff changeset
95 archive.close()
27cd1c21290e did: refactor resources
sam <sam@basx.dev>
parents:
diff changeset
96
27cd1c21290e did: refactor resources
sam <sam@basx.dev>
parents:
diff changeset
97 elif thebundletype == Exe:
27cd1c21290e did: refactor resources
sam <sam@basx.dev>
parents:
diff changeset
98
27cd1c21290e did: refactor resources
sam <sam@basx.dev>
parents:
diff changeset
99 const BUILD_RESOURCEROOT* {.strdefine.}: string = ""
27cd1c21290e did: refactor resources
sam <sam@basx.dev>
parents:
diff changeset
100
27cd1c21290e did: refactor resources
sam <sam@basx.dev>
parents:
diff changeset
101 proc loadResources(): Table[string, Table[string, string]] {.compileTime.} =
27cd1c21290e did: refactor resources
sam <sam@basx.dev>
parents:
diff changeset
102 when BUILD_RESOURCEROOT == "":
27cd1c21290e did: refactor resources
sam <sam@basx.dev>
parents:
diff changeset
103 {.warning: "BUILD_RESOURCEROOT is empty, no resources will be packaged".}
27cd1c21290e did: refactor resources
sam <sam@basx.dev>
parents:
diff changeset
104 return
27cd1c21290e did: refactor resources
sam <sam@basx.dev>
parents:
diff changeset
105 else:
27cd1c21290e did: refactor resources
sam <sam@basx.dev>
parents:
diff changeset
106 for kind, packageDir in walkDir(BUILD_RESOURCEROOT):
27cd1c21290e did: refactor resources
sam <sam@basx.dev>
parents:
diff changeset
107 if kind == pcDir:
27cd1c21290e did: refactor resources
sam <sam@basx.dev>
parents:
diff changeset
108 let package = packageDir.splitPath.tail
27cd1c21290e did: refactor resources
sam <sam@basx.dev>
parents:
diff changeset
109 result[package] = Table[string, string]()
27cd1c21290e did: refactor resources
sam <sam@basx.dev>
parents:
diff changeset
110 for resourcefile in walkDirRec(packageDir, relative = true):
27cd1c21290e did: refactor resources
sam <sam@basx.dev>
parents:
diff changeset
111 result[package][resourcefile.replace('\\', '/')] = staticRead(packageDir.joinPath(resourcefile))
27cd1c21290e did: refactor resources
sam <sam@basx.dev>
parents:
diff changeset
112 const bundledResources = loadResources()
27cd1c21290e did: refactor resources
sam <sam@basx.dev>
parents:
diff changeset
113
27cd1c21290e did: refactor resources
sam <sam@basx.dev>
parents:
diff changeset
114 proc loadResource_intern(path: string, package: string): Stream =
27cd1c21290e did: refactor resources
sam <sam@basx.dev>
parents:
diff changeset
115 if not (path in bundledResources[package]):
27cd1c21290e did: refactor resources
sam <sam@basx.dev>
parents:
diff changeset
116 raise newException(Exception, &"Resource {path} not found")
27cd1c21290e did: refactor resources
sam <sam@basx.dev>
parents:
diff changeset
117 newStringStream(bundledResources[package][path])
27cd1c21290e did: refactor resources
sam <sam@basx.dev>
parents:
diff changeset
118
27cd1c21290e did: refactor resources
sam <sam@basx.dev>
parents:
diff changeset
119 proc modList_intern(): seq[string] =
27cd1c21290e did: refactor resources
sam <sam@basx.dev>
parents:
diff changeset
120 result = bundledResources.keys().toSeq()
27cd1c21290e did: refactor resources
sam <sam@basx.dev>
parents:
diff changeset
121
27cd1c21290e did: refactor resources
sam <sam@basx.dev>
parents:
diff changeset
122 iterator walkResources_intern(dir: string, package = DEFAULT_PACKAGE): string =
27cd1c21290e did: refactor resources
sam <sam@basx.dev>
parents:
diff changeset
123 for i in bundledResources[package].keys:
27cd1c21290e did: refactor resources
sam <sam@basx.dev>
parents:
diff changeset
124 yield i
27cd1c21290e did: refactor resources
sam <sam@basx.dev>
parents:
diff changeset
125
27cd1c21290e did: refactor resources
sam <sam@basx.dev>
parents:
diff changeset
126 iterator ls_intern(dir: string, package: string): tuple[kind: PathComponent, path: string] =
27cd1c21290e did: refactor resources
sam <sam@basx.dev>
parents:
diff changeset
127 let normDir = dir.normalizeDir()
27cd1c21290e did: refactor resources
sam <sam@basx.dev>
parents:
diff changeset
128 var yielded: HashSet[string]
27cd1c21290e did: refactor resources
sam <sam@basx.dev>
parents:
diff changeset
129
27cd1c21290e did: refactor resources
sam <sam@basx.dev>
parents:
diff changeset
130 for i in bundledResources[package].keys:
27cd1c21290e did: refactor resources
sam <sam@basx.dev>
parents:
diff changeset
131 if i.startsWith(normDir):
27cd1c21290e did: refactor resources
sam <sam@basx.dev>
parents:
diff changeset
132 let components = i[normDir.len .. ^1].split('/', maxsplit = 1)
27cd1c21290e did: refactor resources
sam <sam@basx.dev>
parents:
diff changeset
133 if components.len == 1:
27cd1c21290e did: refactor resources
sam <sam@basx.dev>
parents:
diff changeset
134 if not (components[0] in yielded):
27cd1c21290e did: refactor resources
sam <sam@basx.dev>
parents:
diff changeset
135 yield (kind: pcFile, path: components[0])
27cd1c21290e did: refactor resources
sam <sam@basx.dev>
parents:
diff changeset
136 else:
27cd1c21290e did: refactor resources
sam <sam@basx.dev>
parents:
diff changeset
137 if not (components[0] in yielded):
27cd1c21290e did: refactor resources
sam <sam@basx.dev>
parents:
diff changeset
138 yield (kind: pcDir, path: components[0])
27cd1c21290e did: refactor resources
sam <sam@basx.dev>
parents:
diff changeset
139 yielded.incl components[0]
27cd1c21290e did: refactor resources
sam <sam@basx.dev>
parents:
diff changeset
140
27cd1c21290e did: refactor resources
sam <sam@basx.dev>
parents:
diff changeset
141 proc LoadResource*(path: string, package = DEFAULT_PACKAGE): Stream =
27cd1c21290e did: refactor resources
sam <sam@basx.dev>
parents:
diff changeset
142 loadResource_intern(path, package = package)
27cd1c21290e did: refactor resources
sam <sam@basx.dev>
parents:
diff changeset
143
27cd1c21290e did: refactor resources
sam <sam@basx.dev>
parents:
diff changeset
144 #[
27cd1c21290e did: refactor resources
sam <sam@basx.dev>
parents:
diff changeset
145 proc LoadImage*[T](path: string, package = DEFAULT_PACKAGE): Image[RGBAPixel] =
27cd1c21290e did: refactor resources
sam <sam@basx.dev>
parents:
diff changeset
146 if path.splitFile().ext.toLowerAscii == ".bmp":
27cd1c21290e did: refactor resources
sam <sam@basx.dev>
parents:
diff changeset
147 loadResource_intern(path, package = package).ReadBMP()
27cd1c21290e did: refactor resources
sam <sam@basx.dev>
parents:
diff changeset
148 elif path.splitFile().ext.toLowerAscii == ".png":
27cd1c21290e did: refactor resources
sam <sam@basx.dev>
parents:
diff changeset
149 loadResource_intern(path, package = package).ReadPNG()
27cd1c21290e did: refactor resources
sam <sam@basx.dev>
parents:
diff changeset
150 else:
27cd1c21290e did: refactor resources
sam <sam@basx.dev>
parents:
diff changeset
151 raise newException(Exception, "Unsupported image file type: " & path)
27cd1c21290e did: refactor resources
sam <sam@basx.dev>
parents:
diff changeset
152
27cd1c21290e did: refactor resources
sam <sam@basx.dev>
parents:
diff changeset
153 proc LoadJson*(path: string, package = DEFAULT_PACKAGE): JsonNode =
27cd1c21290e did: refactor resources
sam <sam@basx.dev>
parents:
diff changeset
154 path.loadResource_intern(package = package).readAll().parseJson()
27cd1c21290e did: refactor resources
sam <sam@basx.dev>
parents:
diff changeset
155
27cd1c21290e did: refactor resources
sam <sam@basx.dev>
parents:
diff changeset
156 proc LoadConfig*(path: string, package = DEFAULT_PACKAGE): Config =
27cd1c21290e did: refactor resources
sam <sam@basx.dev>
parents:
diff changeset
157 path.loadResource_intern(package = package).loadConfig(filename = path)
27cd1c21290e did: refactor resources
sam <sam@basx.dev>
parents:
diff changeset
158
27cd1c21290e did: refactor resources
sam <sam@basx.dev>
parents:
diff changeset
159 proc LoadMeshes*(path: string, defaultMaterial: MaterialType, package = DEFAULT_PACKAGE): seq[MeshTree] =
27cd1c21290e did: refactor resources
sam <sam@basx.dev>
parents:
diff changeset
160 loadResource_intern(path, package = package).ReadglTF(defaultMaterial)
27cd1c21290e did: refactor resources
sam <sam@basx.dev>
parents:
diff changeset
161
27cd1c21290e did: refactor resources
sam <sam@basx.dev>
parents:
diff changeset
162 proc LoadFirstMesh*(path: string, defaultMaterial: MaterialType, package = DEFAULT_PACKAGE): Mesh =
27cd1c21290e did: refactor resources
sam <sam@basx.dev>
parents:
diff changeset
163 loadResource_intern(path, package = package).ReadglTF(defaultMaterial)[0].toSeq[0]
27cd1c21290e did: refactor resources
sam <sam@basx.dev>
parents:
diff changeset
164
27cd1c21290e did: refactor resources
sam <sam@basx.dev>
parents:
diff changeset
165 ]#
27cd1c21290e did: refactor resources
sam <sam@basx.dev>
parents:
diff changeset
166
27cd1c21290e did: refactor resources
sam <sam@basx.dev>
parents:
diff changeset
167 proc Packages*(): seq[string] =
27cd1c21290e did: refactor resources
sam <sam@basx.dev>
parents:
diff changeset
168 modList_intern()
27cd1c21290e did: refactor resources
sam <sam@basx.dev>
parents:
diff changeset
169
27cd1c21290e did: refactor resources
sam <sam@basx.dev>
parents:
diff changeset
170 proc WalkResources*(dir = "", package = DEFAULT_PACKAGE): seq[string] =
27cd1c21290e did: refactor resources
sam <sam@basx.dev>
parents:
diff changeset
171 for i in walkResources_intern(dir, package = package):
27cd1c21290e did: refactor resources
sam <sam@basx.dev>
parents:
diff changeset
172 if i.startsWith(dir):
27cd1c21290e did: refactor resources
sam <sam@basx.dev>
parents:
diff changeset
173 result.add i
27cd1c21290e did: refactor resources
sam <sam@basx.dev>
parents:
diff changeset
174 result.sort()
27cd1c21290e did: refactor resources
sam <sam@basx.dev>
parents:
diff changeset
175
27cd1c21290e did: refactor resources
sam <sam@basx.dev>
parents:
diff changeset
176 proc List*(dir: string, package = DEFAULT_PACKAGE): seq[tuple[kind: PathComponent, path: string]] =
27cd1c21290e did: refactor resources
sam <sam@basx.dev>
parents:
diff changeset
177 for i in ls_intern(dir = dir, package = package):
27cd1c21290e did: refactor resources
sam <sam@basx.dev>
parents:
diff changeset
178 result.add i
27cd1c21290e did: refactor resources
sam <sam@basx.dev>
parents:
diff changeset
179 result.sort()