Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

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

Last change on this file since 5738 was 5738, checked in by landauf, 15 years ago

merged libraries2 back to trunk

  • 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.