diff options
-rw-r--r-- | .gitignore | 2 | ||||
-rw-r--r-- | SConstruct | 6 | ||||
-rw-r--r-- | gui.cpp | 20 | ||||
-rw-r--r-- | gui.h | 9 | ||||
-rw-r--r-- | scene.cpp | 9 | ||||
-rw-r--r-- | scene.h | 4 | ||||
-rw-r--r-- | scripting.cpp | 61 | ||||
-rw-r--r-- | scripting.h | 30 | ||||
-rw-r--r-- | scripting/SConscript | 22 | ||||
-rw-r--r-- | scripting/test.cpp | 11 | ||||
-rw-r--r-- | scripting/test.h | 8 |
11 files changed, 174 insertions, 8 deletions
@@ -9,3 +9,5 @@ /map *.dll *.exe +/scripting/tolua_* +/scripting/*.pkg @@ -8,7 +8,7 @@ AddOption('--release', action = 'store_true') AddOption('--profiling', action = 'store_true') env.Append(CPPPATH = ['.']) -env.Append(LIBS = ['GL', 'GLU', 'noise', 'boost_filesystem']) +env.Append(LIBS = ['GL', 'GLU', 'noise', 'boost_filesystem', 'tolua++', 'lua']) env.ParseConfig('sdl-config --cflags --libs') env.ParseConfig('pkg-config --cflags --libs SDL_image') env.ParseConfig('pkg-config --cflags --libs ftgl') @@ -24,6 +24,8 @@ if GetOption('profiling'): Export('env') -env.Program('foo', Glob('*.cpp') + ['noiseutils/noiseutils.cpp'] + Glob('widgets/*.cpp')) +env.SConscript('scripting/SConscript') + +env.Program('foo', Glob('*.cpp') + ['noiseutils/noiseutils.cpp'] + Glob('widgets/*.cpp') + Glob('scripting/*.cpp')) # vim: syn=python @@ -68,7 +68,9 @@ bool GUI::showing() { /* ConsoleWindow */ -ConsoleWindow::ConsoleWindow() { +ConsoleWindow::ConsoleWindow(Lua *lua) { + this->lua = lua; + WindowManager& wmgr(WindowManager::getSingleton()); wnd = wmgr.loadWindowLayout("console.layout"); @@ -128,7 +130,21 @@ void ConsoleWindow::handle_input() { if(!s.size()) return; - FormattedListboxTextItem *item = new FormattedListboxTextItem(String((utf8*)s.c_str()), HTF_WORDWRAP_LEFT_ALIGNED); + add_line(s); + + try { + lua->dostring(s); + } catch(LuaError& e) { + add_line(e.what()); + } +} + +void ConsoleWindow::add_line(const std::string& line) { + add_line(line.c_str()); +} + +void ConsoleWindow::add_line(const char *line) { + FormattedListboxTextItem *item = new FormattedListboxTextItem(String((utf8*)line), HTF_WORDWRAP_LEFT_ALIGNED); listbox->addItem(item); listbox->ensureItemIsVisible(item); } @@ -1,6 +1,8 @@ #ifndef GUI_H #define GUI_H +#include "scripting.h" + // TODO: Remove temporary workaround for CEGUI + GCC 4.6 #include <cstddef> #include <CEGUI.h> @@ -29,6 +31,8 @@ class ConsoleWindow : public GUI { CEGUI::Window *editbox; CEGUI::Listbox *listbox; + Lua *lua; + bool clicked(const CEGUI::EventArgs& e); bool keydown(const CEGUI::EventArgs& e); @@ -36,10 +40,13 @@ class ConsoleWindow : public GUI { void handle_input(); public: - ConsoleWindow(); + ConsoleWindow(Lua *lua); virtual ~ConsoleWindow(); virtual void update(); + + void add_line(const std::string& line); + void add_line(const char *line); }; class RaiseWindow : public GUI { @@ -4,6 +4,7 @@ #include <SDL_image.h> #include <boost/format.hpp> +#include <boost/bind.hpp> #include "gl.h" @@ -55,13 +56,19 @@ Scene::Scene() { font = new FTTextureFont("fonts/VeraMono.ttf"); font->FaceSize(10); + lua = new Lua(); + GUI::init(); - console = new ConsoleWindow(); + console = new ConsoleWindow(lua); console->hide(); + + void (ConsoleWindow::*add_line)(const char*) = &ConsoleWindow::add_line; + lua->set_log_func(boost::bind(add_line, console, _1)); } Scene::~Scene() { + delete lua; if(tool) delete tool; if(terrain) @@ -7,6 +7,7 @@ #include "shader.h" #include "gui.h" #include "tool.h" +#include "scripting.h" #include <FTGL/ftgl.h> @@ -20,6 +21,7 @@ class Scene { GUI *gui; Tool *tool; ConsoleWindow *console; + Lua *lua; bool running; bool grid; @@ -37,8 +39,6 @@ class Scene { int sx, sy; GLShaderProgram terrain_program; - //GLVertexShader terrain_vertex; - //GLFragmentShader terrain_fragment; GLuint grass_texture, rock_texture, soil_texture, marker_texture; diff --git a/scripting.cpp b/scripting.cpp new file mode 100644 index 0000000..ed671a2 --- /dev/null +++ b/scripting.cpp @@ -0,0 +1,61 @@ +#include "scripting.h" + +#include "tolua++.h" +#include "scripting/tolua_test.h" + +#include <boost/algorithm/string/join.hpp> + +#include <iostream> +#include <list> + +Lua::Lua() { + L = luaL_newstate(); + luaL_openlibs(L); + tolua_test_open(L); + + /* store a pointer to 'this' in the lua state */ + lua_pushlightuserdata(L, this); + lua_setglobal(L, "lua_instance"); +} + +Lua::~Lua() { + lua_close(L); +} + +void Lua::set_log_func(boost::function<void (const char*)> log_func) { + this->log_func = log_func; + log_func("Lua::set_log_func() called"); +} + +void Lua::print(const char *s) { + if(log_func) + log_func(s); + else + std::cout << s << std::endl; +} + +void Lua::dostring(std::string s) { + int before = lua_gettop(L); + int err = luaL_dostring(L, s.c_str()); + if(err == 1) { + std::string s= lua_tostring(L, -1); + lua_pop(L, 1); + throw(LuaError(s)); + } else { + int after = lua_gettop(L); + std::list<std::string> vals; + for(int i = before; i < after; i++) { + const char *s = lua_tostring(L, -1); + std::string str; + if(s == NULL) { + str = lua_typename(L, lua_type(L, -1)); + } else { + str = s; + } + vals.push_front(str); + lua_pop(L, 1); + } + + this->print(boost::algorithm::join(vals, ",").c_str()); + } +} diff --git a/scripting.h b/scripting.h new file mode 100644 index 0000000..d14aa3c --- /dev/null +++ b/scripting.h @@ -0,0 +1,30 @@ +#ifndef SCRIPTING_H +#define SCRIPTING_H + +#include <lua.hpp> +#include <boost/function.hpp> + +#include <string> +#include <stdexcept> + +class LuaError : public std::runtime_error { + public: + LuaError(const std::string& s) : std::runtime_error(s) {}; +}; + +class Lua { + protected: + lua_State *L; + boost::function<void (const char*)> log_func; + + public: + Lua(); + virtual ~Lua(); + + void set_log_func(boost::function<void (const char*)> log_func); + void print(const char *s); + + void dostring(std::string s); +}; + +#endif diff --git a/scripting/SConscript b/scripting/SConscript new file mode 100644 index 0000000..eaf9f21 --- /dev/null +++ b/scripting/SConscript @@ -0,0 +1,22 @@ +Import('env') + +def tolua_generator(source, target, env, for_signature): + name = str(source[0]).rsplit('/', 1)[-1].rsplit('.' , 1)[0] + return 'tolua++ -o %s -H %s -n %s %s' % (target[1], target[2], name, source[0]) + +def tolua_emitter(target, source, env): + target.append('tolua_%s.cpp' % target[0]) + target.append('tolua_%s.h' % target[0]) + return target, source + +tolua_bld = Builder( + generator = tolua_generator, + emitter = tolua_emitter, + src_suffix = '.pkg', +) + +env.Append(BUILDERS = {'tolua': tolua_bld}) + +env.tolua('test') + +# vim: syn=python diff --git a/scripting/test.cpp b/scripting/test.cpp new file mode 100644 index 0000000..1a378b7 --- /dev/null +++ b/scripting/test.cpp @@ -0,0 +1,11 @@ +#include "scripting/test.h" +#include "scripting.h" + +#include <iostream> + +void print(lua_State *L, const char *s) { + lua_getglobal(L, "lua_instance"); + Lua *lua = static_cast<Lua*>(lua_touserdata(L, -1)); + lua_pop(L, 1); + lua->print(s); +} diff --git a/scripting/test.h b/scripting/test.h new file mode 100644 index 0000000..48f560e --- /dev/null +++ b/scripting/test.h @@ -0,0 +1,8 @@ +#ifndef TEST_H +#define TEST_H + +#include <lua.hpp> + +void print(lua_State *L, const char *s); + +#endif |