Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

source: code/trunk/src/ceguilua/ceguilua-0.6.1/ceguilua/CEGUILua.cpp @ 2710

Last change on this file since 2710 was 2710, checked in by rgrieder, 15 years ago

Merged buildsystem3 containing buildsystem2 containing Adi's buildsystem branch back to the trunk.
Please update the media directory if you were not using buildsystem3 before.

  • Property svn:eol-style set to native
File size: 10.7 KB
Line 
1/***********************************************************************
2        filename: CEGUILua.cpp
3        created:  16/3/2005
4        author:   Tomas Lindquist Olsen
5
6        purpose:  Implementation for LuaScriptModule class
7*************************************************************************/
8/***************************************************************************
9 *   Copyright (C) 2004 - 2006 Paul D Turner & The CEGUI Development Team
10 *
11 *   Permission is hereby granted, free of charge, to any person obtaining
12 *   a copy of this software and associated documentation files (the
13 *   "Software"), to deal in the Software without restriction, including
14 *   without limitation the rights to use, copy, modify, merge, publish,
15 *   distribute, sublicense, and/or sell copies of the Software, and to
16 *   permit persons to whom the Software is furnished to do so, subject to
17 *   the following conditions:
18 *
19 *   The above copyright notice and this permission notice shall be
20 *   included in all copies or substantial portions of the Software.
21 *
22 *   THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
23 *   EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
24 *   MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
25 *   IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR
26 *   OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
27 *   ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
28 *   OTHER DEALINGS IN THE SOFTWARE.
29 ***************************************************************************/
30#include "CEGUI.h"
31#include "CEGUIConfig.h"
32#include "CEGUIPropertyHelper.h"
33#include "CEGUILua.h"
34#include "CEGUILuaFunctor.h"
35#include <vector>
36
37// include Lua libs and tolua++
38extern "C" {
39#include "lua.h"
40#include "lualib.h"
41#include "lauxlib.h"
42}
43
44#include "tolua/tolua++.h"
45
46// prototype for bindings initialisation function
47int tolua_CEGUI_open(lua_State* tolua_S);
48
49
50// Start of CEGUI namespace section
51namespace CEGUI
52{
53
54/*************************************************************************
55        Constructor (creates Lua state)
56*************************************************************************/
57LuaScriptModule::LuaScriptModule()
58{
59    #if LUA_VERSION_NUM >= 501
60        static const luaL_Reg lualibs[] = {
61            {"", luaopen_base},
62            {LUA_LOADLIBNAME, luaopen_package},
63            {LUA_TABLIBNAME, luaopen_table},
64            {LUA_IOLIBNAME, luaopen_io},
65            {LUA_OSLIBNAME, luaopen_os},
66            {LUA_STRLIBNAME, luaopen_string},
67            {LUA_MATHLIBNAME, luaopen_math},
68        #if defined(DEBUG) || defined (_DEBUG)
69                {LUA_DBLIBNAME, luaopen_debug},
70        #endif
71            {0, 0}
72        };
73    #endif /* LUA_VERSION_NUM >= 501 */
74
75    // create a lua state
76    d_ownsState = true;
77    d_state = lua_open();
78
79    // init all standard libraries
80    #if LUA_VERSION_NUM >= 501
81            const luaL_Reg *lib = lualibs;
82            for (; lib->func; lib++)
83            {
84                lua_pushcfunction(d_state, lib->func);
85                lua_pushstring(d_state, lib->name);
86                lua_call(d_state, 1, 0);
87            }
88    #else /* LUA_VERSION_NUM >= 501 */
89        luaopen_base(d_state);
90        luaopen_io(d_state);
91        luaopen_string(d_state);
92        luaopen_table(d_state);
93        luaopen_math(d_state);
94        #if defined(DEBUG) || defined (_DEBUG)
95            luaopen_debug(d_state);
96        #endif
97    #endif /* LUA_VERSION_NUM >= 501 */
98
99    setModuleIdentifierString();
100}
101
102
103/*************************************************************************
104        Constructor (uses given Lua state)
105*************************************************************************/
106LuaScriptModule::LuaScriptModule(lua_State* state)
107{
108        // just use the given state
109        d_ownsState = false;
110        d_state = state;
111
112        setModuleIdentifierString();
113}
114
115
116/*************************************************************************
117        Destructor
118*************************************************************************/
119LuaScriptModule::~LuaScriptModule()
120{
121        if ( d_ownsState && d_state )
122        {
123                lua_close( d_state );
124        }
125}
126
127
128/*************************************************************************
129        Execute script file
130*************************************************************************/
131void LuaScriptModule::executeScriptFile(const String& filename, const String& resourceGroup)
132{
133        // load file
134        RawDataContainer raw;
135        System::getSingleton().getResourceProvider()->loadRawDataContainer(filename,
136        raw, resourceGroup.empty() ? d_defaultResourceGroup : resourceGroup);
137
138        // load code into lua
139        int top = lua_gettop(d_state);
140        int loaderr = luaL_loadbuffer(d_state, (char*)raw.getDataPtr(), raw.getSize(), filename.c_str());
141        System::getSingleton().getResourceProvider()->unloadRawDataContainer( raw );
142        if (loaderr)
143        {
144            String errMsg = lua_tostring(d_state,-1);
145                lua_settop(d_state,top);
146                throw ScriptException("Unable to execute Lua script file: '"+filename+"'\n\n"+errMsg+"\n");
147        }
148
149    // call it
150        if (lua_pcall(d_state,0,0,0))
151        {
152            String errMsg = lua_tostring(d_state,-1);
153                lua_settop(d_state,top);
154                throw ScriptException("Unable to execute Lua script file: '"+filename+"'\n\n"+errMsg+"\n");
155        }
156
157        lua_settop(d_state,top); // just in case :P
158}
159
160
161/*************************************************************************
162        Execute global script function
163*************************************************************************/
164int     LuaScriptModule::executeScriptGlobal(const String& function_name)
165{
166    int top = lua_gettop(d_state);
167
168    // get the function from lua
169    lua_getglobal(d_state, function_name.c_str());
170
171    // is it a function
172    if (!lua_isfunction(d_state,-1))
173    {
174        lua_settop(d_state,top);
175        throw ScriptException("Unable to get Lua global: '"+function_name+"' as name not represent a global Lua function" );
176    }
177
178    // call it
179    int error = lua_pcall(d_state,0,1,0);
180
181    // handle errors
182    if (error)
183    {
184        String errMsg = lua_tostring(d_state,-1);
185        lua_pop(d_state,1);
186        throw ScriptException("Unable to evaluate Lua global: '"+function_name+"\n\n"+errMsg+"\n");
187    }
188
189    // get return value
190    if (!lua_isnumber(d_state,-1))
191    {
192        // log that return value is invalid. return -1 and move on.
193        lua_settop(d_state,top);
194        ScriptException("Unable to get Lua global : '"+function_name+"' return value as it's not a number" );
195        return -1;
196    }
197
198    int ret = (int)lua_tonumber(d_state,-1);
199    lua_pop(d_state,1);
200
201    // return it
202    return ret;
203}
204
205
206/*************************************************************************
207        Execute scripted event handler
208*************************************************************************/
209bool LuaScriptModule::executeScriptedEventHandler(const String& handler_name, const EventArgs& e)
210{
211
212        LuaFunctor::pushNamedFunction(d_state, handler_name);
213
214        ScriptWindowHelper* helper = 0;
215        //If this is an event that was triggered by a window then make a "this" pointer to the window for the script.
216        if(e.d_hasWindow)
217        {
218                WindowEventArgs& we = (WindowEventArgs&)e;
219                helper = new ScriptWindowHelper(we.window);
220                lua_pushlightuserdata(d_state,(void*)helper);
221                lua_setglobal(d_state,"this");
222        } // if(e.d_hasWindow)
223
224    // push EventArgs as the first parameter
225    tolua_pushusertype(d_state,(void*)&e,"const CEGUI::EventArgs");
226
227    // call it
228    int error = lua_pcall(d_state,1,0,0);
229
230    // handle errors
231    if (error)
232    {
233        String errStr(lua_tostring(d_state,-1));
234        lua_pop(d_state,1);
235                //cleanup the helper object if any
236                if(helper)
237                {
238                        delete helper;
239                        helper = 0;
240                }
241        throw ScriptException("Unable to evaluate the Lua event handler: '"+handler_name+"'\n\n"+errStr+"\n");
242    } // if (error)
243
244        if(helper)
245        {
246                delete helper;
247                helper = 0;
248        }
249
250    return true;
251}
252
253
254/*************************************************************************
255        Execute script code string
256*************************************************************************/
257void LuaScriptModule::executeString(const String& str)
258{
259    int top = lua_gettop(d_state);
260
261    // load code into lua and call it
262    int error = luaL_loadbuffer(d_state, str.c_str(), str.length(), str.c_str()) || lua_pcall(d_state,0,0,0);
263
264    // handle errors
265    if (error)
266    {
267        String errMsg = lua_tostring(d_state,-1);
268        lua_settop(d_state,top);
269        throw ScriptException("Unable to execute Lua script string: '"+str+"'\n\n"+errMsg+"\n");
270    }
271}
272
273
274/*************************************************************************
275        Create Lua bindings
276*************************************************************************/
277void LuaScriptModule::createBindings(void)
278{
279        CEGUI::Logger::getSingleton().logEvent( "---- Creating Lua bindings ----" );
280        // init CEGUI module
281        tolua_CEGUI_open(d_state);
282}
283
284
285/*************************************************************************
286        Destroy Lua bindings
287*************************************************************************/
288void LuaScriptModule::destroyBindings(void)
289{
290        CEGUI::Logger::getSingleton().logEvent( "---- Destroying Lua bindings ----" );
291        // is this ok ?
292        lua_pushnil(d_state);
293        lua_setglobal(d_state,"CEGUI");
294}
295
296
297/*************************************************************************
298        Set the ID string for the module
299*************************************************************************/
300void LuaScriptModule::setModuleIdentifierString()
301{
302    // set ID string
303    d_identifierString = "CEGUI::LuaScriptModule - Official Lua based scripting module for CEGUI";
304        d_language = "Lua";
305}
306
307
308/*************************************************************************
309        Subscribe to a scripted event handler
310*************************************************************************/
311Event::Connection LuaScriptModule::subscribeEvent(EventSet* target, const String& event_name, const String& subscriber_name)
312{
313    // do the real subscription
314    LuaFunctor functor(d_state,subscriber_name,LUA_NOREF);
315    Event::Connection con = target->subscribeEvent(event_name, Event::Subscriber(functor));
316    // make sure we don't release the reference we just made when this call returns
317    functor.index = LUA_NOREF;
318
319    // return the event connection
320    return con;
321}
322
323
324/*************************************************************************
325        Subscribe to a scripted event handler
326*************************************************************************/
327Event::Connection LuaScriptModule::subscribeEvent(EventSet* target, const String& event_name, Event::Group group, const String& subscriber_name)
328{
329    // do the real subscription
330    LuaFunctor functor(d_state,subscriber_name,LUA_NOREF);
331    Event::Connection con = target->subscribeEvent(event_name, group, Event::Subscriber(functor));
332
333    // return the event connection
334    return con;
335}
336
337} // namespace CEGUI
Note: See TracBrowser for help on using the repository browser.