Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

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

Last change on this file since 2352 was 1810, checked in by rgrieder, 16 years ago

merged ceguilua branch back to trunk

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