Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

source: code/branches/tutorial/src/ceguilua/ceguilua-0.5.0/ceguilua/CEGUILua.cpp @ 3050

Last change on this file since 3050 was 2710, checked in by rgrieder, 16 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.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#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    LuaFunctor::pushNamedFunction(d_state, handler_name);
211
212    // push EventArgs as the first parameter
213    tolua_pushusertype(d_state,(void*)&e,"const CEGUI::EventArgs");
214
215    // call it
216    int error = lua_pcall(d_state,1,0,0);
217
218    // handle errors
219    if (error)
220    {
221        String errStr(lua_tostring(d_state,-1));
222        lua_pop(d_state,1);
223        throw ScriptException("Unable to evaluate the Lua event handler: '"+handler_name+"'\n\n"+errStr+"\n");
224    }
225
226    return true;
227}
228
229
230/*************************************************************************
231        Execute script code string
232*************************************************************************/
233void LuaScriptModule::executeString(const String& str)
234{
235    int top = lua_gettop(d_state);
236
237    // load code into lua and call it
238    int error = luaL_loadbuffer(d_state, str.c_str(), str.length(), str.c_str()) || lua_pcall(d_state,0,0,0);
239
240    // handle errors
241    if (error)
242    {
243        String errMsg = lua_tostring(d_state,-1);
244        lua_settop(d_state,top);
245        throw ScriptException("Unable to execute Lua script string: '"+str+"'\n\n"+errMsg+"\n");
246    }
247}
248       
249
250/*************************************************************************
251        Create Lua bindings
252*************************************************************************/
253void LuaScriptModule::createBindings(void)
254{
255        CEGUI::Logger::getSingleton().logEvent( "---- Creating Lua bindings ----" );
256        // init CEGUI module
257        tolua_CEGUI_open(d_state);
258}
259
260
261/*************************************************************************
262        Destroy Lua bindings
263*************************************************************************/
264void LuaScriptModule::destroyBindings(void)
265{
266        CEGUI::Logger::getSingleton().logEvent( "---- Destroying Lua bindings ----" );
267        // is this ok ?
268        lua_pushnil(d_state);
269        lua_setglobal(d_state,"CEGUI");
270}
271
272
273/*************************************************************************
274        Set the ID string for the module
275*************************************************************************/
276void LuaScriptModule::setModuleIdentifierString()
277{
278    // set ID string
279    d_identifierString = "CEGUI::LuaScriptModule - Official Lua based scripting module for CEGUI";
280}
281
282
283/*************************************************************************
284        Subscribe to a scripted event handler
285*************************************************************************/
286Event::Connection LuaScriptModule::subscribeEvent(EventSet* target, const String& event_name, const String& subscriber_name)
287{
288    // do the real subscription
289    LuaFunctor functor(d_state,subscriber_name,LUA_NOREF);
290    Event::Connection con = target->subscribeEvent(event_name, Event::Subscriber(functor));
291    // make sure we don't release the reference we just made when this call returns
292    functor.index = LUA_NOREF;
293
294    // return the event connection
295    return con;
296}
297
298
299/*************************************************************************
300        Subscribe to a scripted event handler
301*************************************************************************/
302Event::Connection LuaScriptModule::subscribeEvent(EventSet* target, const String& event_name, Event::Group group, const String& subscriber_name)
303{
304    // do the real subscription
305    LuaFunctor functor(d_state,subscriber_name,LUA_NOREF);
306    Event::Connection con = target->subscribeEvent(event_name, group, Event::Subscriber(functor));
307
308    // return the event connection
309    return con;
310}
311
312} // namespace CEGUI
Note: See TracBrowser for help on using the repository browser.