Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

source: code/branches/ceguilua/src/ceguilua-0.6.1/ceguilua/CEGUILua.cpp @ 1804

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

Implemented lua and ceguilua as far as it works now with visual studio. Next (not so big) step is to integrate it in CMake (already did the most part).

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