Mercurial > games > semicongine
annotate src/semicongine/settings.nim @ 308:c73224f9d38f
add: some API improvments for vector, entity, and some other stuff
author | Sam <sam@basx.dev> |
---|---|
date | Sat, 08 Jul 2023 18:52:34 +0700 |
parents | da0bd61abe91 |
children |
rev | line source |
---|---|
194
93f661a20f74
did: a bit of cleanup with the config, also add some documentation
Sam <sam@basx.dev>
parents:
diff
changeset
|
1 import std/logging |
257
d6d48c7cc141
fix: issue with shared heap memory in settings
Sam <sam@basx.dev>
parents:
254
diff
changeset
|
2 import std/streams |
194
93f661a20f74
did: a bit of cleanup with the config, also add some documentation
Sam <sam@basx.dev>
parents:
diff
changeset
|
3 import std/parsecfg |
93f661a20f74
did: a bit of cleanup with the config, also add some documentation
Sam <sam@basx.dev>
parents:
diff
changeset
|
4 import std/strutils |
93f661a20f74
did: a bit of cleanup with the config, also add some documentation
Sam <sam@basx.dev>
parents:
diff
changeset
|
5 import std/parseutils |
93f661a20f74
did: a bit of cleanup with the config, also add some documentation
Sam <sam@basx.dev>
parents:
diff
changeset
|
6 import std/strformat |
93f661a20f74
did: a bit of cleanup with the config, also add some documentation
Sam <sam@basx.dev>
parents:
diff
changeset
|
7 import std/tables |
93f661a20f74
did: a bit of cleanup with the config, also add some documentation
Sam <sam@basx.dev>
parents:
diff
changeset
|
8 import std/os |
93f661a20f74
did: a bit of cleanup with the config, also add some documentation
Sam <sam@basx.dev>
parents:
diff
changeset
|
9 |
206
7f921d7d0a2b
did: small refactoring of module structure
Sam <sam@basx.dev>
parents:
194
diff
changeset
|
10 import ./core |
194
93f661a20f74
did: a bit of cleanup with the config, also add some documentation
Sam <sam@basx.dev>
parents:
diff
changeset
|
11 |
93f661a20f74
did: a bit of cleanup with the config, also add some documentation
Sam <sam@basx.dev>
parents:
diff
changeset
|
12 when CONFIGHOTRELOAD: |
254 | 13 var |
257
d6d48c7cc141
fix: issue with shared heap memory in settings
Sam <sam@basx.dev>
parents:
254
diff
changeset
|
14 configUpdates: Channel[(string, string)] |
194
93f661a20f74
did: a bit of cleanup with the config, also add some documentation
Sam <sam@basx.dev>
parents:
diff
changeset
|
15 configUpdates.open() |
93f661a20f74
did: a bit of cleanup with the config, also add some documentation
Sam <sam@basx.dev>
parents:
diff
changeset
|
16 |
93f661a20f74
did: a bit of cleanup with the config, also add some documentation
Sam <sam@basx.dev>
parents:
diff
changeset
|
17 # runtime configuration |
93f661a20f74
did: a bit of cleanup with the config, also add some documentation
Sam <sam@basx.dev>
parents:
diff
changeset
|
18 # ===================== |
93f661a20f74
did: a bit of cleanup with the config, also add some documentation
Sam <sam@basx.dev>
parents:
diff
changeset
|
19 # namespace is the path from the CONFIGROOT to the according settings file without the file extension |
93f661a20f74
did: a bit of cleanup with the config, also add some documentation
Sam <sam@basx.dev>
parents:
diff
changeset
|
20 # a settings file must always have the extension CONFIGEXTENSION |
93f661a20f74
did: a bit of cleanup with the config, also add some documentation
Sam <sam@basx.dev>
parents:
diff
changeset
|
21 # a fully qualified settings identifier can be in the form {namespace}.{section}.{key} |
93f661a20f74
did: a bit of cleanup with the config, also add some documentation
Sam <sam@basx.dev>
parents:
diff
changeset
|
22 # {key} and {section} may not contain dots |
93f661a20f74
did: a bit of cleanup with the config, also add some documentation
Sam <sam@basx.dev>
parents:
diff
changeset
|
23 |
93f661a20f74
did: a bit of cleanup with the config, also add some documentation
Sam <sam@basx.dev>
parents:
diff
changeset
|
24 # a "namespace" is the path from the settings root to an *.CONFIGEXTENSION file, without the file extension |
93f661a20f74
did: a bit of cleanup with the config, also add some documentation
Sam <sam@basx.dev>
parents:
diff
changeset
|
25 # settings is a namespace <-> settings mapping |
93f661a20f74
did: a bit of cleanup with the config, also add some documentation
Sam <sam@basx.dev>
parents:
diff
changeset
|
26 var allsettings: Table[string, Config] |
93f661a20f74
did: a bit of cleanup with the config, also add some documentation
Sam <sam@basx.dev>
parents:
diff
changeset
|
27 |
93f661a20f74
did: a bit of cleanup with the config, also add some documentation
Sam <sam@basx.dev>
parents:
diff
changeset
|
28 proc configRoot(): string = |
93f661a20f74
did: a bit of cleanup with the config, also add some documentation
Sam <sam@basx.dev>
parents:
diff
changeset
|
29 joinPath(absolutePath(getAppDir()), CONFIGROOT) |
93f661a20f74
did: a bit of cleanup with the config, also add some documentation
Sam <sam@basx.dev>
parents:
diff
changeset
|
30 |
93f661a20f74
did: a bit of cleanup with the config, also add some documentation
Sam <sam@basx.dev>
parents:
diff
changeset
|
31 proc getFile(namespace: string): string = |
93f661a20f74
did: a bit of cleanup with the config, also add some documentation
Sam <sam@basx.dev>
parents:
diff
changeset
|
32 joinPath(configRoot(), namespace & "." & CONFIGEXTENSION) |
93f661a20f74
did: a bit of cleanup with the config, also add some documentation
Sam <sam@basx.dev>
parents:
diff
changeset
|
33 |
93f661a20f74
did: a bit of cleanup with the config, also add some documentation
Sam <sam@basx.dev>
parents:
diff
changeset
|
34 iterator walkConfigNamespaces(): string = |
93f661a20f74
did: a bit of cleanup with the config, also add some documentation
Sam <sam@basx.dev>
parents:
diff
changeset
|
35 for file in walkDirRec(dir=configRoot(), relative=true, checkDir=true): |
93f661a20f74
did: a bit of cleanup with the config, also add some documentation
Sam <sam@basx.dev>
parents:
diff
changeset
|
36 if file.endsWith("." & CONFIGEXTENSION): |
93f661a20f74
did: a bit of cleanup with the config, also add some documentation
Sam <sam@basx.dev>
parents:
diff
changeset
|
37 yield file[0 ..< ^(CONFIGEXTENSION.len + 1)] |
93f661a20f74
did: a bit of cleanup with the config, also add some documentation
Sam <sam@basx.dev>
parents:
diff
changeset
|
38 |
93f661a20f74
did: a bit of cleanup with the config, also add some documentation
Sam <sam@basx.dev>
parents:
diff
changeset
|
39 proc loadAllConfig(): Table[string, Config] = |
93f661a20f74
did: a bit of cleanup with the config, also add some documentation
Sam <sam@basx.dev>
parents:
diff
changeset
|
40 for ns in walkConfigNamespaces(): |
93f661a20f74
did: a bit of cleanup with the config, also add some documentation
Sam <sam@basx.dev>
parents:
diff
changeset
|
41 result[ns] = ns.getFile().loadConfig() |
93f661a20f74
did: a bit of cleanup with the config, also add some documentation
Sam <sam@basx.dev>
parents:
diff
changeset
|
42 |
93f661a20f74
did: a bit of cleanup with the config, also add some documentation
Sam <sam@basx.dev>
parents:
diff
changeset
|
43 proc reloadSettings*() = |
93f661a20f74
did: a bit of cleanup with the config, also add some documentation
Sam <sam@basx.dev>
parents:
diff
changeset
|
44 allsettings = loadAllConfig() |
93f661a20f74
did: a bit of cleanup with the config, also add some documentation
Sam <sam@basx.dev>
parents:
diff
changeset
|
45 |
308
c73224f9d38f
add: some API improvments for vector, entity, and some other stuff
Sam <sam@basx.dev>
parents:
302
diff
changeset
|
46 proc configStr(key, section, namespace: string): string = |
194
93f661a20f74
did: a bit of cleanup with the config, also add some documentation
Sam <sam@basx.dev>
parents:
diff
changeset
|
47 when CONFIGHOTRELOAD: |
93f661a20f74
did: a bit of cleanup with the config, also add some documentation
Sam <sam@basx.dev>
parents:
diff
changeset
|
48 while configUpdates.peek() > 0: |
93f661a20f74
did: a bit of cleanup with the config, also add some documentation
Sam <sam@basx.dev>
parents:
diff
changeset
|
49 let (updatedNamespace, updatedConfig) = configUpdates.recv() |
257
d6d48c7cc141
fix: issue with shared heap memory in settings
Sam <sam@basx.dev>
parents:
254
diff
changeset
|
50 allsettings[updatedNamespace] = loadConfig(newStringStream(updatedConfig)) |
194
93f661a20f74
did: a bit of cleanup with the config, also add some documentation
Sam <sam@basx.dev>
parents:
diff
changeset
|
51 if not allsettings.hasKey(namespace): |
308
c73224f9d38f
add: some API improvments for vector, entity, and some other stuff
Sam <sam@basx.dev>
parents:
302
diff
changeset
|
52 raise newException(Exception, &"Settings {namespace}.{section}.{key} was not found") |
c73224f9d38f
add: some API improvments for vector, entity, and some other stuff
Sam <sam@basx.dev>
parents:
302
diff
changeset
|
53 allsettings[namespace].getSectionValue(section, key) |
194
93f661a20f74
did: a bit of cleanup with the config, also add some documentation
Sam <sam@basx.dev>
parents:
diff
changeset
|
54 |
308
c73224f9d38f
add: some API improvments for vector, entity, and some other stuff
Sam <sam@basx.dev>
parents:
302
diff
changeset
|
55 proc setting*[T: int|float|string](key, section, namespace: string): T = |
194
93f661a20f74
did: a bit of cleanup with the config, also add some documentation
Sam <sam@basx.dev>
parents:
diff
changeset
|
56 when T is int: |
308
c73224f9d38f
add: some API improvments for vector, entity, and some other stuff
Sam <sam@basx.dev>
parents:
302
diff
changeset
|
57 let value = configStr(key, section, namespace) |
194
93f661a20f74
did: a bit of cleanup with the config, also add some documentation
Sam <sam@basx.dev>
parents:
diff
changeset
|
58 if parseInt(value, result) == 0: |
93f661a20f74
did: a bit of cleanup with the config, also add some documentation
Sam <sam@basx.dev>
parents:
diff
changeset
|
59 raise newException(Exception, &"Unable to parse int from settings {namespace}.{section}.{key}: {value}") |
93f661a20f74
did: a bit of cleanup with the config, also add some documentation
Sam <sam@basx.dev>
parents:
diff
changeset
|
60 elif T is float: |
308
c73224f9d38f
add: some API improvments for vector, entity, and some other stuff
Sam <sam@basx.dev>
parents:
302
diff
changeset
|
61 let value = configStr(key, section, namespace) |
194
93f661a20f74
did: a bit of cleanup with the config, also add some documentation
Sam <sam@basx.dev>
parents:
diff
changeset
|
62 if parseFloat(value, result) == 0: |
93f661a20f74
did: a bit of cleanup with the config, also add some documentation
Sam <sam@basx.dev>
parents:
diff
changeset
|
63 raise newException(Exception, &"Unable to parse float from settings {namespace}.{section}.{key}: {value}") |
93f661a20f74
did: a bit of cleanup with the config, also add some documentation
Sam <sam@basx.dev>
parents:
diff
changeset
|
64 else: |
308
c73224f9d38f
add: some API improvments for vector, entity, and some other stuff
Sam <sam@basx.dev>
parents:
302
diff
changeset
|
65 result = configStr(key, section, namespace) |
194
93f661a20f74
did: a bit of cleanup with the config, also add some documentation
Sam <sam@basx.dev>
parents:
diff
changeset
|
66 |
308
c73224f9d38f
add: some API improvments for vector, entity, and some other stuff
Sam <sam@basx.dev>
parents:
302
diff
changeset
|
67 proc setting*[T: int|float|string](identifier: string): T = |
194
93f661a20f74
did: a bit of cleanup with the config, also add some documentation
Sam <sam@basx.dev>
parents:
diff
changeset
|
68 # identifier can be in the form: |
254 | 69 # {namespace}.{key} |
194
93f661a20f74
did: a bit of cleanup with the config, also add some documentation
Sam <sam@basx.dev>
parents:
diff
changeset
|
70 # {namespace}.{section}.{key} |
93f661a20f74
did: a bit of cleanup with the config, also add some documentation
Sam <sam@basx.dev>
parents:
diff
changeset
|
71 let parts = identifier.rsplit(".") |
254 | 72 if parts.len == 1: |
73 raise newException(Exception, &"Setting with name {identifier} has no namespace") | |
308
c73224f9d38f
add: some API improvments for vector, entity, and some other stuff
Sam <sam@basx.dev>
parents:
302
diff
changeset
|
74 if parts.len == 2: result = setting[T](parts[1], "", parts[0]) |
c73224f9d38f
add: some API improvments for vector, entity, and some other stuff
Sam <sam@basx.dev>
parents:
302
diff
changeset
|
75 else: result = setting[T](parts[^1], parts[^2], joinPath(parts[0 .. ^3])) |
194
93f661a20f74
did: a bit of cleanup with the config, also add some documentation
Sam <sam@basx.dev>
parents:
diff
changeset
|
76 |
254 | 77 proc hadConfigUpdate*(): bool = |
259 | 78 when CONFIGHOTRELOAD == true: |
280
913b831465a0
did: simplify config-changed-check, enforce settings-query to always pass default value
Sam <sam@basx.dev>
parents:
259
diff
changeset
|
79 result = configUpdates.peek() > 0 |
254 | 80 |
194
93f661a20f74
did: a bit of cleanup with the config, also add some documentation
Sam <sam@basx.dev>
parents:
diff
changeset
|
81 allsettings = loadAllConfig() |
93f661a20f74
did: a bit of cleanup with the config, also add some documentation
Sam <sam@basx.dev>
parents:
diff
changeset
|
82 |
93f661a20f74
did: a bit of cleanup with the config, also add some documentation
Sam <sam@basx.dev>
parents:
diff
changeset
|
83 when CONFIGHOTRELOAD == true: |
93f661a20f74
did: a bit of cleanup with the config, also add some documentation
Sam <sam@basx.dev>
parents:
diff
changeset
|
84 import std/times |
93f661a20f74
did: a bit of cleanup with the config, also add some documentation
Sam <sam@basx.dev>
parents:
diff
changeset
|
85 |
93f661a20f74
did: a bit of cleanup with the config, also add some documentation
Sam <sam@basx.dev>
parents:
diff
changeset
|
86 proc configFileWatchdog() {.thread.} = |
93f661a20f74
did: a bit of cleanup with the config, also add some documentation
Sam <sam@basx.dev>
parents:
diff
changeset
|
87 var configModTimes: Table[string, Time] |
93f661a20f74
did: a bit of cleanup with the config, also add some documentation
Sam <sam@basx.dev>
parents:
diff
changeset
|
88 while true: |
93f661a20f74
did: a bit of cleanup with the config, also add some documentation
Sam <sam@basx.dev>
parents:
diff
changeset
|
89 for namespace in walkConfigNamespaces(): |
93f661a20f74
did: a bit of cleanup with the config, also add some documentation
Sam <sam@basx.dev>
parents:
diff
changeset
|
90 if not (namespace in configModTimes): |
93f661a20f74
did: a bit of cleanup with the config, also add some documentation
Sam <sam@basx.dev>
parents:
diff
changeset
|
91 configModTimes[namespace] = Time() |
93f661a20f74
did: a bit of cleanup with the config, also add some documentation
Sam <sam@basx.dev>
parents:
diff
changeset
|
92 let lastMod = namespace.getFile().getLastModificationTime() |
280
913b831465a0
did: simplify config-changed-check, enforce settings-query to always pass default value
Sam <sam@basx.dev>
parents:
259
diff
changeset
|
93 if lastMod > configModTimes[namespace]: |
913b831465a0
did: simplify config-changed-check, enforce settings-query to always pass default value
Sam <sam@basx.dev>
parents:
259
diff
changeset
|
94 configModTimes[namespace] = lastMod |
257
d6d48c7cc141
fix: issue with shared heap memory in settings
Sam <sam@basx.dev>
parents:
254
diff
changeset
|
95 let configStr = newFileStream(namespace.getFile()).readAll() |
d6d48c7cc141
fix: issue with shared heap memory in settings
Sam <sam@basx.dev>
parents:
254
diff
changeset
|
96 configUpdates.send((namespace, configStr)) |
194
93f661a20f74
did: a bit of cleanup with the config, also add some documentation
Sam <sam@basx.dev>
parents:
diff
changeset
|
97 sleep CONFIGHOTRELOADINTERVAL |
93f661a20f74
did: a bit of cleanup with the config, also add some documentation
Sam <sam@basx.dev>
parents:
diff
changeset
|
98 var thethread: Thread[void] |
93f661a20f74
did: a bit of cleanup with the config, also add some documentation
Sam <sam@basx.dev>
parents:
diff
changeset
|
99 createThread(thethread, configFileWatchdog) |
93f661a20f74
did: a bit of cleanup with the config, also add some documentation
Sam <sam@basx.dev>
parents:
diff
changeset
|
100 |
93f661a20f74
did: a bit of cleanup with the config, also add some documentation
Sam <sam@basx.dev>
parents:
diff
changeset
|
101 if DEBUG: |
93f661a20f74
did: a bit of cleanup with the config, also add some documentation
Sam <sam@basx.dev>
parents:
diff
changeset
|
102 setLogFilter(lvlAll) |
93f661a20f74
did: a bit of cleanup with the config, also add some documentation
Sam <sam@basx.dev>
parents:
diff
changeset
|
103 else: |
93f661a20f74
did: a bit of cleanup with the config, also add some documentation
Sam <sam@basx.dev>
parents:
diff
changeset
|
104 setLogFilter(lvlWarn) |