Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

source: code/trunk/src/external/ceguilua/ceguilua-0.6.0/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 "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.