aboutsummaryrefslogtreecommitdiff
path: root/src/FbTk
diff options
context:
space:
mode:
Diffstat (limited to 'src/FbTk')
-rw-r--r--src/FbTk/LuaUtil.cc104
-rw-r--r--src/FbTk/LuaUtil.hh78
-rw-r--r--src/FbTk/Makefile.am1
3 files changed, 183 insertions, 0 deletions
diff --git a/src/FbTk/LuaUtil.cc b/src/FbTk/LuaUtil.cc
new file mode 100644
index 0000000..456abac
--- /dev/null
+++ b/src/FbTk/LuaUtil.cc
@@ -0,0 +1,104 @@
1// LuaUtil: Various additional functions for working with lua
2// Copyright (C) 2011 Pavel Labath
3//
4// Permission is hereby granted, free of charge, to any person obtaining a
5// copy of this software and associated documentation files (the "Software"),
6// to deal in the Software without restriction, including without limitation
7// the rights to use, copy, modify, merge, publish, distribute, sublicense,
8// and/or sell copies of the Software, and to permit persons to whom the
9// Software is furnished to do so, subject to the following conditions:
10//
11// The above copyright notice and this permission notice shall be included in
12// all copies or substantial portions of the Software.
13//
14// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
17// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
18// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
19// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
20// DEALINGS IN THE SOFTWARE.
21
22#ifdef HAVE_CONFIG_H
23#include "config.h"
24#endif
25
26#include "LuaUtil.hh"
27
28namespace {
29 int newindexDenyWrite(lua::state *l) {
30 if(l->isstring(-2))
31 throw std::runtime_error("Cannot modify field '" + l->tostring(-2) + "'.");
32 else
33 throw std::runtime_error("Cannot modify this field.");
34 }
35
36 int newindexDenyModify(lua::state *l) {
37 bool ok = false;
38 l->getmetatable(-1); {
39 l->rawgetfield(-1, "__index"); {
40 l->pushvalue(-4); l->rawget(-2); {
41 if(l->isnil(-1))
42 ok = true;
43 } l->pop();
44 } l->pop();
45 } l->pop();
46
47 if(ok) {
48 l->pushvalue(-2);
49 l->pushvalue(-4);
50 l->rawset(-3);
51 } else
52 newindexDenyWrite(l);
53
54 return 0;
55 }
56}
57
58namespace FbTk {
59
60Lua::InitFunctions Lua::s_init_functions;
61
62Lua::Lua() {
63 InitFunctions::const_iterator it_end = s_init_functions.end();
64 for(InitFunctions::const_iterator it = s_init_functions.begin(); it != it_end; ++it)
65 (**it)(*this);
66}
67
68void Lua::makeReadOnly(int index, bool only_existing_fields) {
69 checkstack(6);
70 lua::stack_sentry s(*this);
71 index = absindex(index);
72
73 newtable(); {
74 newtable(); {
75 pushnil(); while(next(index)) {
76 pushvalue(-2); pushvalue(-2); rawset(-5);
77
78 pop(); pushnil(); rawset(index);
79
80 pushnil();
81 }
82 } rawsetfield(-2, "__index");
83
84 pushfunction(only_existing_fields ? &newindexDenyModify : &newindexDenyWrite);
85 rawsetfield(-2, "__newindex");
86
87 pushboolean(false);
88 rawsetfield(-2, "__metatable");
89 } setmetatable(index);
90}
91
92void Lua::readOnlySet(int index) {
93 checkstack(2);
94 lua::stack_sentry s(*this, -2);
95
96 getmetatable(index); {
97 rawgetfield(-1, "__index"); insert(-4);
98 } pop();
99
100 rawset(-3);
101 pop();
102}
103
104} // namespace FbTk
diff --git a/src/FbTk/LuaUtil.hh b/src/FbTk/LuaUtil.hh
new file mode 100644
index 0000000..cdd1934
--- /dev/null
+++ b/src/FbTk/LuaUtil.hh
@@ -0,0 +1,78 @@
1// LuaUtil: Various additional functions for working with lua
2// Copyright (C) 2011 Pavel Labath
3//
4// Permission is hereby granted, free of charge, to any person obtaining a
5// copy of this software and associated documentation files (the "Software"),
6// to deal in the Software without restriction, including without limitation
7// the rights to use, copy, modify, merge, publish, distribute, sublicense,
8// and/or sell copies of the Software, and to permit persons to whom the
9// Software is furnished to do so, subject to the following conditions:
10//
11// The above copyright notice and this permission notice shall be included in
12// all copies or substantial portions of the Software.
13//
14// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
17// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
18// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
19// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
20// DEALINGS IN THE SOFTWARE.
21
22#ifndef FBTK_LUAUTIL_HH
23#define FBTK_LUAUTIL_HH
24
25#include <vector>
26
27#include "Luamm.hh"
28
29namespace FbTk {
30
31/*
32 * This class augments lua::state with additional functions/features. Every object automatically
33 * calls registered init functions, which can be used to initialize/create global variables in
34 * the lua state. Functions can be registered by calling registerInitFunction or by creating
35 * objects of type RegisterInitFunction.
36 */
37class Lua: public lua::state {
38public:
39 Lua();
40
41 /*
42 * makeReadOnly() makes the table at the specified index "read only". This means that any
43 * attempt to modify a table entry will result in an error (if only_existing_fields is
44 * false). If only_existing_fields is true then only fields that were present at the time of
45 * the call will be protected - user can add new entries and modify them afterwards. You
46 * should avoid raw access to "read only" tables -- it might not do what you think it will.
47 */
48 void makeReadOnly(int index, bool only_existing_fields = false);
49
50 /*
51 * readOnlySet() is the equivalent of settable, except that it works on "read only" tables.
52 * It can be used to modify protected entries or create new ones.
53 */
54 void readOnlySet(int index);
55
56 template<typename Functor>
57 static void registerInitFunction(const Functor &fn) {
58 s_init_functions.push_back(new SlotImpl<Functor, void, Lua &>(fn));
59 }
60
61 class RegisterInitFunction {
62 public:
63 template<typename Functor>
64 RegisterInitFunction(const Functor &fn) {
65 registerInitFunction(fn);
66 }
67 };
68
69private:
70 typedef Slot<void, Lua &> InitFunction;
71 typedef std::vector<InitFunction *> InitFunctions;
72
73 static InitFunctions s_init_functions;
74};
75
76} // namespace FbTk
77
78#endif // FBTK_LUAUTIL_HH
diff --git a/src/FbTk/Makefile.am b/src/FbTk/Makefile.am
index 5146810..dba4478 100644
--- a/src/FbTk/Makefile.am
+++ b/src/FbTk/Makefile.am
@@ -67,6 +67,7 @@ libFbTk_a_SOURCES = App.hh App.cc Color.cc Color.hh Command.hh \
67 Slot.hh Signal.hh MemFun.hh SelectArg.hh \ 67 Slot.hh Signal.hh MemFun.hh SelectArg.hh \
68 Util.hh \ 68 Util.hh \
69 Luamm.cc Luamm.hh LResource.cc LResource.hh LResourceHelper-lua.cc \ 69 Luamm.cc Luamm.hh LResource.cc LResource.hh LResourceHelper-lua.cc \
70 LuaUtil.cc LuaUtil.hh \
70 ${xpm_SOURCE} \ 71 ${xpm_SOURCE} \
71 ${xft_SOURCE} \ 72 ${xft_SOURCE} \
72 ${xmb_SOURCE} \ 73 ${xmb_SOURCE} \