Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

source: code/trunk/src/ceguilua/ceguilua-0.6.0/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 "CEGUIPropertyHelper.h"
32#include "CEGUILua.h"
33#include "CEGUILuaFunctor.h"
34#include <vector>
35
36// include Lua libs and tolua++
37extern "C" {
38#include "lua.h"
39#include "lualib.h"
40#include "lauxlib.h"
41}
42
43#include "tolua/tolua++.h"
44
45// prototype for bindings initialisation function
46int tolua_CEGUI_open(lua_State* tolua_S);
47
48
49// Start of CEGUI namespace section
50namespace CEGUI
51{
52
53/*************************************************************************
54        Constructor (creates Lua state)
55*************************************************************************/
56LuaScriptModule::LuaScriptModule()
57{
58    #if LUA_VERSION_NUM >= 501
59        static const luaL_Reg lualibs[] = {
60            {"", luaopen_base},
61            {LUA_LOADLIBNAME, luaopen_package},
62            {LUA_TABLIBNAME, luaopen_table},
63            {LUA_IOLIBNAME, luaopen_io},
64            {LUA_OSLIBNAME, luaopen_os},
65            {LUA_STRLIBNAME, luaopen_string},
66            {LUA_MATHLIBNAME, luaopen_math},
67        #if defined(DEBUG) || defined (_DEBUG)
68                {LUA_DBLIBNAME, luaopen_debug},
69        #endif
70            {0, 0}
71        };
72    #endif /* LUA_VERSION_NUM >= 501 */
73
74    // create a lua state
75    d_ownsState = true;
76    d_state = lua_open();
77
78    // init all standard libraries
79    #if LUA_VERSION_NUM >= 501
80            const luaL_Reg *lib = lualibs;
81            for (; lib->func; lib++)
82            {
83                lua_pushcfunction(d_state, lib->func);
84                lua_pushstring(d_state, lib->name);
85                lua_call(d_state, 1, 0);
86            }
87    #else /* LUA_VERSION_NUM >= 501 */
88        luaopen_base(d_state);
89        luaopen_io(d_state);
90        luaopen_string(d_state);
91        luaopen_table(d_state);
92        luaopen_math(d_state);
93        #if defined(DEBUG) || defined (_DEBUG)
94            luaopen_debug(d_state);
95        #endif
96    #endif /* LUA_VERSION_NUM >= 501 */
97
98    setModuleIdentifierString();
99}
100
101
102/*************************************************************************
103        Constructor (uses given Lua state)
104*************************************************************************/
105LuaScriptModule::LuaScriptModule(lua_State* state)
106{
107        // just use the given state
108        d_ownsState = false;
109        d_state = state;
110
111        setModuleIdentifierString();
112}
113
114
115/*************************************************************************
116        Destructor
117*************************************************************************/
118LuaScriptModule::~LuaScriptModule()
119{
120        if ( d_ownsState && d_state )
121        {
122                lua_close( d_state );
123        }
124}
125
126
127/*************************************************************************
128        Execute script file
129*************************************************************************/
130void LuaScriptModule::executeScriptFile(const String& filename, const String& resourceGroup)
131{
132        // load file
133        RawDataContainer raw;
134        System::getSingleton().getResourceProvider()->loadRawDataContainer(filename,
135        raw, resourceGroup.empty() ? d_defaultResourceGroup : resourceGroup);
136
137        // load code into lua
138        int top = lua_gettop(d_state);
139        int loaderr = luaL_loadbuffer(d_state, (char*)raw.getDataPtr(), raw.getSize(), filename.c_str());
140        System::getSingleton().getResourceProvider()->unloadRawDataContainer( raw );
141        if (loaderr)
142        {
143            String errMsg = lua_tostring(d_state,-1);
144                lua_settop(d_state,top);
145                throw ScriptException("Unable to execute Lua script file: '"+filename+"'\n\n"+errMsg+"\n");
146        }
147
148    // call it
149        if (lua_pcall(d_state,0,0,0))
150        {
151            String errMsg = lua_tostring(d_state,-1);
152                lua_settop(d_state,top);
153                throw ScriptException("Unable to execute Lua script file: '"+filename+"'\n\n"+errMsg+"\n");
154        }
155
156        lua_settop(d_state,top); // just in case :P
157}
158
159
160/*************************************************************************
161        Execute global script function
162*************************************************************************/
163int     LuaScriptModule::executeScriptGlobal(const String& function_name)
164{
165    int top = lua_gettop(d_state);
166
167    // get the function from lua
168    lua_getglobal(d_state, function_name.c_str());
169
170    // is it a function
171    if (!lua_isfunction(d_state,-1))
172    {
173        lua_settop(d_state,top);
174        throw ScriptException("Unable to get Lua global: '"+function_name+"' as name not represent a global Lua function" );
175    }
176
177    // call it
178    int error = lua_pcall(d_state,0,1,0);
179
180    // handle errors
181    if (error)
182    {
183        String errMsg = lua_tostring(d_state,-1);
184        lua_pop(d_state,1);
185        throw ScriptException("Unable to evaluate Lua global: '"+function_name+"\n\n"+errMsg+"\n");
186    }
187
188    // get return value
189    if (!lua_isnumber(d_state,-1))
190    {
191        // log that return value is invalid. return -1 and move on.
192        lua_settop(d_state,top);
193        ScriptException("Unable to get Lua global : '"+function_name+"' return value as it's not a number" );
194        return -1;
195    }
196
197    int ret = (int)lua_tonumber(d_state,-1);
198    lua_pop(d_state,1);
199
200    // return it
201    return ret;
202}
203
204
205/*************************************************************************
206        Execute scripted event handler
207*************************************************************************/
208bool LuaScriptModule::executeScriptedEventHandler(const String& handler_name, const EventArgs& e)
209{
210
211        LuaFunctor::pushNamedFunction(d_state, handler_name);
212
213        ScriptWindowHelper* helper = 0;
214        //If this is an event that was triggered by a window then make a "this" pointer to the window for the script.
215        if(e.d_hasWindow)
216        {
217                WindowEventArgs& we = (WindowEventArgs&)e;
218                helper = new ScriptWindowHelper(we.window);
219                lua_pushlightuserdata(d_state,(void*)helper);
220                lua_setglobal(d_state,"this");
221        } // if(e.d_hasWindow)
222
223    // push EventArgs as the first parameter
224    tolua_pushusertype(d_state,(void*)&e,"const CEGUI::EventArgs");
225
226    // call it
227    int error = lua_pcall(d_state,1,0,0);
228
229    // handle errors
230    if (error)
231    {
232        String errStr(lua_tostring(d_state,-1));
233        lua_pop(d_state,1);
234                //cleanup the helper object if any
235                if(helper)
236                {
237                        delete helper;
238                        helper = 0;
239                }
240        throw ScriptException("Unable to evaluate the Lua event handler: '"+handler_name+"'\n\n"+errStr+"\n");
241    } // if (error)
242
243        if(helper)
244        {
245                delete helper;
246                helper = 0;
247        }
248
249    return true;
250}
251
252
253/*************************************************************************
254        Execute script code string
255*************************************************************************/
256void LuaScriptModule::executeString(const String& str)
257{
258    int top = lua_gettop(d_state);
259
260    // load code into lua and call it
261    int error = luaL_loadbuffer(d_state, str.c_str(), str.length(), str.c_str()) || lua_pcall(d_state,0,0,0);
262
263    // handle errors
264    if (error)
265    {
266        String errMsg = lua_tostring(d_state,-1);
267        lua_settop(d_state,top);
268        throw ScriptException("Unable to execute Lua script string: '"+str+"'\n\n"+errMsg+"\n");
269    }
270}
271
272
273/*************************************************************************
274        Create Lua bindings
275*************************************************************************/
276void LuaScriptModule::createBindings(void)
277{
278        CEGUI::Logger::getSingleton().logEvent( "---- Creating Lua bindings ----" );
279        // init CEGUI module
280        tolua_CEGUI_open(d_state);
281}
282
283
284/*************************************************************************
285        Destroy Lua bindings
286*************************************************************************/
287void LuaScriptModule::destroyBindings(void)
288{
289        CEGUI::Logger::getSingleton().logEvent( "---- Destroying Lua bindings ----" );
290        // is this ok ?
291        lua_pushnil(d_state);
292        lua_setglobal(d_state,"CEGUI");
293}
294
295
296/*************************************************************************
297        Set the ID string for the module
298*************************************************************************/
299void LuaScriptModule::setModuleIdentifierString()
300{
301    // set ID string
302    d_identifierString = "CEGUI::LuaScriptModule - Official Lua based scripting module for CEGUI";
303        d_language = "Lua";
304}
305
306
307/*************************************************************************
308        Subscribe to a scripted event handler
309*************************************************************************/
310Event::Connection LuaScriptModule::subscribeEvent(EventSet* target, const String& event_name, const String& subscriber_name)
311{
312    // do the real subscription
313    LuaFunctor functor(d_state,subscriber_name,LUA_NOREF);
314    Event::Connection con = target->subscribeEvent(event_name, Event::Subscriber(functor));
315    // make sure we don't release the reference we just made when this call returns
316    functor.index = LUA_NOREF;
317
318    // return the event connection
319    return con;
320}
321
322
323/*************************************************************************
324        Subscribe to a scripted event handler
325*************************************************************************/
326Event::Connection LuaScriptModule::subscribeEvent(EventSet* target, const String& event_name, Event::Group group, const String& subscriber_name)
327{
328    // do the real subscription
329    LuaFunctor functor(d_state,subscriber_name,LUA_NOREF);
330    Event::Connection con = target->subscribeEvent(event_name, group, Event::Subscriber(functor));
331
332    // return the event connection
333    return con;
334}
335
336} // namespace CEGUI
Note: See TracBrowser for help on using the repository browser.