Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

source: code/branches/ceguilua/src/ceguilua-0.5.0b/ceguilua/CEGUILua.cpp @ 1803

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

added files for lua 5.1.3, lua 5.0.3, CEGUILua-0.6.1 and CEGUILua-0.5.0b

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