Skip to content

Commit cf70198

Browse files
committed
feat(core): add config system, a lot of improvements
1 parent c681764 commit cf70198

10 files changed

Lines changed: 289 additions & 49 deletions

File tree

.luarc.json

Lines changed: 12 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
{
22
"Lua.workspace.library": [
3-
"${addons}/garrysmod/module/library"
4-
],
3+
"${addons}/garrysmod/module/library"
4+
],
55
"Lua.runtime.version": "LuaJIT",
66
"Lua.runtime.special": {
77
"include": "dofile",
@@ -11,13 +11,21 @@
1111
"atomic.loader.server": "dofile"
1212
},
1313
"Lua.runtime.nonstandardSymbol": [
14-
"continue"
14+
"continue",
15+
"!",
16+
"!=",
17+
"&&",
18+
"||",
19+
"//",
20+
"/**/"
1521
],
1622
"Lua.diagnostics.disable": [
1723
"duplicate-set-field"
1824
],
1925
"Lua.workspace.checkThirdParty": false,
2026
"diagnostics.globals": [
21-
"atomic"
27+
"atomic",
28+
"git",
29+
"mysqloo"
2230
]
2331
}

lua/atomic/libraries/class.lua

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,10 @@ function atomic.class.create(name, parent)
3434
return "instance of " .. tostring(self._name)
3535
end
3636

37+
class.__classname = function(self)
38+
return name
39+
end
40+
3741
return class
3842
end
3943

@@ -70,11 +74,11 @@ end
7074
--- local animal = atomic.class.new(animalClass)
7175
--- ```
7276
---
77+
---@generic T
7378
---@param class Atomic.Class
74-
---@param tab table? Content of the instance
79+
---@param tab T? Content of the instance
7580
---@vararg any
76-
---@generic T
77-
---@return Atomic.Class
81+
---@return T: Atomic.Class
7882
function atomic.class.new(class, tab, ...)
7983
local instance = setmetatable(tab or {}, class)
8084

lua/atomic/libraries/loader.lua

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ function atomic.loader.client(path)
99
return AddCSLuaFile(path)
1010
end
1111

12-
atomic.loader.logger:debug("including client file `%s`", path)
12+
atomic.loader.logger:trace("including client file `%s`", path)
1313

1414
return include(path)
1515
end
@@ -21,7 +21,7 @@ function atomic.loader.shared(path)
2121
AddCSLuaFile(path)
2222
end
2323

24-
atomic.loader.logger:debug("including shared file `%s`", path)
24+
atomic.loader.logger:trace("including shared file `%s`", path)
2525

2626
return include(path)
2727
end
@@ -30,7 +30,7 @@ end
3030
---@return ...?
3131
function atomic.loader.server(path)
3232
if (SERVER) then
33-
atomic.loader.logger:debug("including server file `%s`", path)
33+
atomic.loader.logger:trace("including server file `%s`", path)
3434
return include(path)
3535
end
3636
end

lua/atomic/libraries/logger.lua

Lines changed: 15 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -35,19 +35,21 @@ local iswin = jit.os == "Windows"
3535

3636
-- colors
3737
local white = iswin and Color(255, 255, 255) or "\27[37m"
38-
local info = iswin and Color(0, 255, 0) or "\27[32m"
38+
local trace = iswin and Color(128, 128, 128) or "\27[90m"
3939
local debug = iswin and Color(0, 255, 255) or "\27[36m"
40+
local info = iswin and Color(0, 255, 0) or "\27[32m"
4041
local warn = iswin and Color(255, 255, 0) or "\27[33m"
4142
local err = iswin and Color(255, 0, 0) or "\27[31m"
4243

4344
local levels = {
44-
DEBUG = 1,
45-
INFO = 2,
46-
WARN = 3,
47-
ERR = 4,
45+
TRACE = 1,
46+
DEBUG = 2,
47+
INFO = 3,
48+
WARN = 4,
49+
ERR = 5,
4850
}
4951

50-
local logvar = CreateConVar("atomic_log", "INFO", FCVAR_ARCHIVE + FCVAR_PROTECTED, "Minimum log level (INFO, DEBUG, WARN, ERR)")
52+
local logvar = CreateConVar("atomic_log", "INFO", {FCVAR_ARCHIVE, FCVAR_PROTECTED}, "Minimum log level (INFO, DEBUG, WARN, ERR)")
5153

5254
---@param prefix string
5355
function loggerClass:init(prefix)
@@ -70,14 +72,19 @@ function loggerClass:log(color, level, message, ...)
7072
MsgN()
7173
end
7274

73-
function loggerClass:info(message, ...)
74-
self:log(info, "INFO", message, ...)
75+
function loggerClass:trace(message, ...)
76+
self:log(trace, "TRACE", message, ...)
7577
end
7678

7779
function loggerClass:debug(message, ...)
7880
self:log(debug, "DEBUG", message, ...)
7981
end
8082

83+
84+
function loggerClass:info(message, ...)
85+
self:log(info, "INFO", message, ...)
86+
end
87+
8188
function loggerClass:warn(message, ...)
8289
self:log(warn, "WARN", message, ...)
8390
end

lua/atomic/libraries/package/class.lua

Lines changed: 38 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44
---@field description string?
55
---@field version string
66
---@field documentation string?
7-
-- @field configuration table<string, any>?
7+
-- @field configuration Atomic.Package.Configuration?
88
---@field files table<"client" | "shared" | "server", string[]>
99
---@field dependencies table<string, string>?
1010
---@field atomic { version: string }?
@@ -18,14 +18,15 @@
1818
local package = atomic.class.create("Package")
1919
atomic.class.register(package, atomic.class.pseudo)
2020

21-
local logger = atomic.class.get("Logger")
22-
23-
---@cast logger Atomic.Logger
21+
local configClass = atomic.class.get("Configuration")
22+
---@cast configClass Atomic.Package
2423

2524
function package:init()
26-
local prefix = (self.id:Split(".")[3] or ""):lower()
25+
local prefix = (self.id:Split(".")[3] or "n/a"):lower()
26+
27+
local config = self.configuration or {}
2728

28-
self.configuration = self.configuration or {}
29+
self.configuration = atomic.class.new(configClass, nil, config, self)
2930
self._isLoaded = false
3031
self._events = {}
3132
self._commands = {}
@@ -101,11 +102,15 @@ end
101102
---@param callback fun(player: Player)
102103
---@return integer registrationId
103104
function package:bind(key, callback)
104-
self._binds[#self._binds+1] = {
105+
local id = #self._binds+1
106+
107+
self._binds[id] = {
105108
key = key,
106109
callback = callback,
107110
registrationId = 0
108111
}
112+
113+
return id
109114
end
110115

111116
--- Commands
@@ -173,4 +178,29 @@ end
173178
---@param eventName string
174179
function package:unlisten(eventName)
175180
self._events[eventName] = nil
176-
end
181+
end
182+
183+
--- Classes
184+
185+
--- Creates new class and automatically registeres it
186+
---@param name string
187+
---@generic T
188+
---@return T: Atomic.Class
189+
function package:newClass(name)
190+
local class = atomic.class.create(name)
191+
atomic.class.register(class, self)
192+
193+
return class
194+
end
195+
196+
--- Return package's registered class
197+
---@param class Atomic.Class
198+
function package:registerClass(class)
199+
return atomic.class.register(class, self)
200+
end
201+
202+
--- Return package's registered class
203+
---@param name string
204+
function package:getClass(name)
205+
return atomic.class.get(name, self)
206+
end

lua/atomic/libraries/package/common.lua

Lines changed: 49 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,10 @@ atomic.package = atomic.package or {
55
_pathMap = {}
66
}
77

8+
---@include
9+
atomic.loader.shared("config.lua")
10+
atomic.loader.shared("class.lua")
11+
812
local packageClass = atomic.class.get("Package")
913

1014
---@cast packageClass Atomic.Package
@@ -30,7 +34,17 @@ end
3034
---@param id string
3135
---@param version string
3236
function atomic.package.get(id, version)
33-
return (atomic.package._storage[id] or {})[version]
37+
local packages = atomic.package._storage[id]
38+
39+
if (not packages) then
40+
return
41+
end
42+
43+
for ver, package in pairs(packages) do
44+
if (util.IsVersionSuitable(ver, version)) then
45+
return package
46+
end
47+
end
3448
end
3549

3650
--- Searches for packages along the specified path
@@ -93,10 +107,11 @@ function atomic.package.load(package)
93107

94108
local packageInstance = atomic.package.new(package)
95109

110+
---@diagnostic disable-next-line
96111
atomic.package._pathMap[package._path] = { package.id, package.version }
97112

98113
---@cast packageInstance Atomic.Package
99-
if packageInstance.atomic and not util.IsVersionSuitable(packageInstance.atomic.version, atomic.meta.version) then
114+
if packageInstance.atomic and not util.IsVersionSuitable(atomic.meta.version, packageInstance.atomic.version) then
100115
atomic.log:err(
101116
"package `%s` requires atomic %s, but current is %s",
102117
packageInstance.id, tostring(packageInstance.atomic.version), tostring(atomic.meta.version)
@@ -128,17 +143,32 @@ function atomic.package.loadMany(packages)
128143

129144
local packagesCache = {}
130145

146+
local findPackage = function(id, version)
147+
local packagesCached = packagesCache[id]
148+
local cached = packagesCached and packagesCached[version]
149+
150+
return cached or atomic.package.get(id, version)
151+
end
152+
153+
local insertPackage = function(id, version, package)
154+
if (not packagesCache[id]) then
155+
packagesCache[id] = {}
156+
end
157+
158+
packagesCache[id][version] = package
159+
end
160+
131161
for _, pkg in ipairs(packages) do
132-
if not pkg.id or not pkg.version then
162+
local id, version = pkg.id, pkg.version
163+
if not id or not version then
133164
atomic.log:err("invalid package detected (missing id/version), skipping.")
134165
continue
135166
end
136167

137-
local key = pkg.id .. "@" .. pkg.version
138-
if packagesCache[key] then
168+
if findPackage(id, version) then
139169
atomic.log:warn("duplicate package `%s@%s` ignored.", pkg.id, pkg.version)
140170
else
141-
packagesCache[key] = pkg
171+
insertPackage(id, version, pkg)
142172
end
143173
end
144174

@@ -148,7 +178,7 @@ function atomic.package.loadMany(packages)
148178
local deps = pkg.dependencies
149179
if type(deps) == "table" then
150180
for depId, depVersion in pairs(deps) do
151-
if not packagesCache[depId .. "@" .. depVersion] then
181+
if not findPackage(depId, depVersion) then
152182
atomic.log:err("dependency `%s` version %s is required for `%s`, but was not found.", depId, depVersion, pkg.id)
153183
table.insert(toRemove, id)
154184
break
@@ -166,15 +196,15 @@ function atomic.package.loadMany(packages)
166196
end
167197

168198
local indegree = {}
169-
for _, pkg in pairs(packagesCache) do
170-
indegree[pkg.id] = 0
199+
for id in pairs(packagesCache) do
200+
-- todo version
201+
indegree[id] = 0
171202
end
172203

173204
for _, pkg in pairs(packagesCache) do
174205
if type(pkg.dependencies) == "table" then
175206
for depId, depVersion in pairs(pkg.dependencies) do
176-
local depKey = depId .. "@" .. depVersion
177-
if packagesCache[depKey] then
207+
if findPackage(depId, depVersion) then
178208
indegree[pkg.id] = (indegree[pkg.id] or 0) + 1
179209
end
180210
end
@@ -192,8 +222,8 @@ function atomic.package.loadMany(packages)
192222
for _, pkg in pairs(packagesCache) do
193223
if type(pkg.dependencies) == "table" then
194224
for depId, depVersion in pairs(pkg.dependencies) do
195-
local depKey = depId .. "@" .. depVersion
196-
if packagesCache[depKey] and depId == id then
225+
local depdendency = findPackage(depId, depVersion)
226+
if depdendency and depId == depdendency.id then
197227
indegree[pkg.id] = indegree[pkg.id] - 1
198228
if indegree[pkg.id] == 0 then table.insert(queue, pkg.id) end
199229
end
@@ -208,10 +238,12 @@ function atomic.package.loadMany(packages)
208238
return
209239
end
210240

211-
for _, id in ipairs(loadOrder) do
212-
for _, pkg in pairs(packagesCache) do
213-
if pkg.id == id then
214-
atomic.package.load(pkg)
241+
for _, orderId in ipairs(loadOrder) do
242+
for id, pkgs in pairs(packagesCache) do
243+
for _version, pkg in pairs(pkgs) do
244+
if id == orderId then
245+
atomic.package.load(pkg)
246+
end
215247
end
216248
end
217249
end

0 commit comments

Comments
 (0)