diff options
Diffstat (limited to 'acf/model/root.lua')
-rw-r--r-- | acf/model/root.lua | 39 |
1 files changed, 38 insertions, 1 deletions
diff --git a/acf/model/root.lua b/acf/model/root.lua index f0f21c1..f273c4a 100644 --- a/acf/model/root.lua +++ b/acf/model/root.lua @@ -5,11 +5,14 @@ See LICENSE file for license details module(..., package.seeall) -local node = require('acf.model.node') local model = require('acf.model.model') +local node = require('acf.model.node') local object = require('acf.object') local pth = require('acf.path') +local util = require('acf.util') +local setdefault = util.setdefault + RootModel = model.new() @@ -27,7 +30,41 @@ function RootModel:meta(path) return node.mmeta(self:search(pth.parent(path), true), pth.name(path)) end + +local _topology = {} + +function topology(addr, create) + local top = _topology + if type(addr) == 'table' then addr = util.copy(addr) + else addr = pth.split(addr) end + + local function defaults(top) + return util.setdefaults(top, {members={}, paths={}}) + end + + while #addr > 0 do + if create then + top = setdefault(defaults(top).members, addr[1], {}) + else + top = top.members[addr[1]] or top.members[pth.wildcard] + if not top then return end + end + table.remove(addr, 1) + end + + return defaults(top) +end + function register(name, field, params) params.create = true RootModel[name] = model.to_field(field, params) + + _topology = {} + + -- TODO optimize: do not traverse already registered models + for i, record in ipairs(node.topology(RootModel())) do + local top = topology(record.addr, true) + setdefault(top, 'order', i) + table.insert(top.paths, record.path) + end end |