Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

source: code/trunk/src/ceguilua-0.5.0b/ceguilua/CEGUILua.cpp @ 1936

Last change on this file since 1936 was 1832, checked in by rgrieder, 16 years ago

bug fix

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