diff options
author | Pavel Labath <pavelo@centrum.sk> | 2011-06-05 12:27:13 (GMT) |
---|---|---|
committer | Pavel Labath <pavelo@centrum.sk> | 2011-06-15 23:07:49 (GMT) |
commit | de1e05cec6b26f6a7f398a9ea64f38fa0943f9c0 (patch) | |
tree | 6c5cb813d5cf4bad3c620fb42a2fb4236b9f9ec1 /src/FbTk/LResourceHelper.lua | |
parent | f7981d4a85985b4862af0036b7728f8543706374 (diff) | |
download | fluxbox_pavel-de1e05cec6b26f6a7f398a9ea64f38fa0943f9c0.zip fluxbox_pavel-de1e05cec6b26f6a7f398a9ea64f38fa0943f9c0.tar.bz2 |
A rough version of resource implementation in lua
I added a new class, LResourceManager, which should handle loading and saving of resources like
the old ResourceManager, only it does that with the help of lua. I moved the common features of
the two managers (interface + a few functions) to a common base class ResourceManager_base. I
augmented the Resource_base class with two new functions (setFromLua and pushToLua) which are
used by the lua RM instead of getString and setFromString.
Parts of the new RM are written in lua. To avoid loading scripts from a file at runtime I decided
to link compiled lua code straight into the executable. For this purpose I created a small script
which converts a binary file into a declaration of a C array of bytes.
Diffstat (limited to 'src/FbTk/LResourceHelper.lua')
-rw-r--r-- | src/FbTk/LResourceHelper.lua | 135 |
1 files changed, 135 insertions, 0 deletions
diff --git a/src/FbTk/LResourceHelper.lua b/src/FbTk/LResourceHelper.lua new file mode 100644 index 0000000..f336e05 --- /dev/null +++ b/src/FbTk/LResourceHelper.lua | |||
@@ -0,0 +1,135 @@ | |||
1 | read_resource, write_resource, res_magic = ...; | ||
2 | |||
3 | local cat_magic = {}; | ||
4 | |||
5 | local function myerror(table, msg) | ||
6 | error(getmetatable(table)._fullname .. ': ' .. msg); | ||
7 | end; | ||
8 | |||
9 | local function check_arg(table, key) | ||
10 | if type(key) ~= 'string' then | ||
11 | myerror(table, 'expecting strings as keys.'); | ||
12 | end; | ||
13 | if string.match(key, "^_") then | ||
14 | myerror(table, 'resource names must not begin with "_".'); | ||
15 | end; | ||
16 | local t = getmetatable(table)[key]; | ||
17 | return t, getmetatable(t); | ||
18 | end; | ||
19 | |||
20 | local new_cat; | ||
21 | local function newindex(table, key, value) | ||
22 | local meta = getmetatable(table); | ||
23 | local t, mt = check_arg(table, key); | ||
24 | |||
25 | if type(value) == 'table' then | ||
26 | if mt == res_magic then | ||
27 | myerror(table, '"' .. key .. '" is a resource.'); | ||
28 | end; | ||
29 | if mt == nil or mt._magic ~= cat_magic then | ||
30 | t = new_cat(table, key); | ||
31 | end; | ||
32 | for k,v in pairs(value) do | ||
33 | t[k] = v; | ||
34 | end; | ||
35 | else | ||
36 | if mt ~= nil and mt._magic == cat_magic and mt._state == 1 then | ||
37 | myerror(table, '"' .. key .. '" is a category.'); | ||
38 | elseif mt == res_magic then | ||
39 | write_resource(t, value); | ||
40 | else | ||
41 | meta[key] = value; | ||
42 | end; | ||
43 | end; | ||
44 | end; | ||
45 | |||
46 | local function index(table, key) | ||
47 | local t, mt = check_arg(table, key); | ||
48 | |||
49 | if mt == res_magic then | ||
50 | return read_resource(t); | ||
51 | end; | ||
52 | |||
53 | return t; | ||
54 | end; | ||
55 | |||
56 | new_cat = function(table, key) | ||
57 | local meta = getmetatable(table); | ||
58 | local mt = { | ||
59 | __newindex = newindex, __index = index, | ||
60 | _magic = cat_magic, _fullname = meta._fullname .. '.' .. key, _state = 0 | ||
61 | }; | ||
62 | meta[key] = setmetatable({}, mt); | ||
63 | return meta[key]; | ||
64 | end; | ||
65 | |||
66 | local function register_resource(root, name, object) | ||
67 | local meta = getmetatable(root); | ||
68 | meta._state = 1; | ||
69 | |||
70 | local head, tail = string.match(name, '^(%a+)%.?(.*)'); | ||
71 | local t = meta[head]; | ||
72 | if tail == '' then | ||
73 | meta[head] = object; | ||
74 | if getmetatable(object) == res_magic then | ||
75 | write_resource(object, t); | ||
76 | end; | ||
77 | return t; | ||
78 | end; | ||
79 | |||
80 | if t == nil then | ||
81 | t = new_cat(root, head); | ||
82 | end; | ||
83 | return register_resource(t, tail, object); | ||
84 | end; | ||
85 | |||
86 | local function dump_value(val) | ||
87 | if type(val) == "string" then | ||
88 | return string.format('%q', val); | ||
89 | elseif type(val) == "number" then | ||
90 | return string.format('%g', val); | ||
91 | else | ||
92 | error('Unsupported value type: ' .. type(val)); | ||
93 | end; | ||
94 | end; | ||
95 | |||
96 | local function dump_(root, fd) | ||
97 | local meta = getmetatable(root); | ||
98 | if not string.match(meta._fullname, "^[%a.]+$") then | ||
99 | error("Someone has been messing with metatables."); | ||
100 | end; | ||
101 | |||
102 | for k, v in pairs(meta) do | ||
103 | if type(k) == "string" and string.match(k, "^%a+$") then | ||
104 | local mt = getmetatable(v); | ||
105 | |||
106 | fd:write(meta._fullname, '.', k, ' = '); | ||
107 | if mt ~= nil and mt._magic == cat_magic then | ||
108 | fd:write('{}\n'); | ||
109 | dump(v); | ||
110 | fd:write('\n'); | ||
111 | else | ||
112 | if mt == res_magic then | ||
113 | v = read_resource(v); | ||
114 | end; | ||
115 | fd:write(dump_value(v), '\n'); | ||
116 | end; | ||
117 | end; | ||
118 | end; | ||
119 | end; | ||
120 | |||
121 | local function dump(root, file) | ||
122 | local fd = io.open(file, 'w'); | ||
123 | dump_(root, fd); | ||
124 | fd:close(); | ||
125 | end; | ||
126 | |||
127 | local function make_root(name) | ||
128 | local t = { | ||
129 | __newindex = newindex, __index = index, | ||
130 | _magic = cat_magic, _fullname = name, _state = 0 | ||
131 | }; | ||
132 | getfenv()[name] = setmetatable({}, t); | ||
133 | end; | ||
134 | |||
135 | return make_root, register_resource, dump; | ||