From: Christoph Sommer Date: Fri, 27 Oct 2006 14:19:47 +0000 (+0000) Subject: Made LevelTime object scriptable (start, stop, get_time, set_time) X-Git-Url: https://git.verplant.org/?a=commitdiff_plain;h=cc2776a002549ae37ecf78be1333e66282780064;p=supertux.git Made LevelTime object scriptable (start, stop, get_time, set_time) SVN-Revision: 4422 --- diff --git a/src/object/level_time.cpp b/src/object/level_time.cpp index 233e40020..bf86db633 100644 --- a/src/object/level_time.cpp +++ b/src/object/level_time.cpp @@ -33,6 +33,8 @@ #include "video/drawing_context.hpp" #include "lisp/list_iterator.hpp" #include "log.hpp" +#include "scripting/level_time.hpp" +#include "scripting/squirrel_util.hpp" /** When to alert player they're low on time! */ static const float TIME_WARNING = 20; @@ -40,12 +42,28 @@ static const float TIME_WARNING = 20; LevelTime::LevelTime(const lisp::Lisp& reader) : running(true), time_left(0) { + reader.get("name", name); reader.get("time", time_left); if(time_left <= 0) throw std::runtime_error("No or invalid leveltime specified"); time_surface.reset(new Surface("images/engine/hud/time-0.png")); } void +LevelTime::expose(HSQUIRRELVM vm, SQInteger table_idx) +{ + if (name.empty()) return; + Scripting::LevelTime* interface = new Scripting::LevelTime(this); + expose_object(vm, table_idx, interface, name, true); +} + +void +LevelTime::unexpose(HSQUIRRELVM vm, SQInteger table_idx) +{ + if (name.empty()) return; + Scripting::unexpose_object(vm, table_idx, name); +} + +void LevelTime::update(float elapsed_time) { if (!running) return; @@ -80,9 +98,27 @@ LevelTime::draw(DrawingContext& context) } void +LevelTime::start() +{ + running = true; +} + +void LevelTime::stop() { running = false; } + +float +LevelTime::get_time() +{ + return time_left; +} + +void +LevelTime::set_time(float time_left) +{ + this->time_left = std::min(std::max(time_left, 0.0f), 999.0f); +} IMPLEMENT_FACTORY(LevelTime, "leveltime"); diff --git a/src/object/level_time.hpp b/src/object/level_time.hpp index b96709adc..98c792622 100644 --- a/src/object/level_time.hpp +++ b/src/object/level_time.hpp @@ -25,16 +25,39 @@ #include "timer.hpp" #include "lisp/lisp.hpp" #include "video/surface.hpp" +#include "script_interface.hpp" -class LevelTime : public GameObject +class LevelTime : public GameObject, public ScriptInterface { public: LevelTime(const lisp::Lisp& reader); + + virtual void expose(HSQUIRRELVM vm, SQInteger table_idx); + virtual void unexpose(HSQUIRRELVM vm, SQInteger table_idx); void update(float elapsed_time); void draw(DrawingContext& context); + + /** + * Resumes the countdown + */ + void start(); + + /** + * Pauses the countdown + */ void stop(); + /** + * Returns the number of seconds left on the clock + */ + float get_time(); + + /** + * Changes the number of seconds left on the clock + */ + void set_time(float time_left); + private: std::auto_ptr time_surface; bool running; diff --git a/src/scripting/wrapper.cpp b/src/scripting/wrapper.cpp index 0ee38e155..8307bacc4 100644 --- a/src/scripting/wrapper.cpp +++ b/src/scripting/wrapper.cpp @@ -2449,6 +2449,115 @@ static SQInteger SSector_get_ambient_blue_wrapper(HSQUIRRELVM vm) } +static SQInteger LevelTime_release_hook(SQUserPointer ptr, SQInteger ) +{ + Scripting::LevelTime* _this = reinterpret_cast (ptr); + delete _this; + return 0; +} + +static SQInteger LevelTime_start_wrapper(HSQUIRRELVM vm) +{ + SQUserPointer data; + if(SQ_FAILED(sq_getinstanceup(vm, 1, &data, 0))) { + sq_throwerror(vm, _SC("'start' called without instance")); + return SQ_ERROR; + } + Scripting::LevelTime* _this = reinterpret_cast (data); + + try { + _this->start(); + + return 0; + + } catch(std::exception& e) { + sq_throwerror(vm, e.what()); + return SQ_ERROR; + } catch(...) { + sq_throwerror(vm, _SC("Unexpected exception while executing function 'start'")); + return SQ_ERROR; + } + +} + +static SQInteger LevelTime_stop_wrapper(HSQUIRRELVM vm) +{ + SQUserPointer data; + if(SQ_FAILED(sq_getinstanceup(vm, 1, &data, 0))) { + sq_throwerror(vm, _SC("'stop' called without instance")); + return SQ_ERROR; + } + Scripting::LevelTime* _this = reinterpret_cast (data); + + try { + _this->stop(); + + return 0; + + } catch(std::exception& e) { + sq_throwerror(vm, e.what()); + return SQ_ERROR; + } catch(...) { + sq_throwerror(vm, _SC("Unexpected exception while executing function 'stop'")); + return SQ_ERROR; + } + +} + +static SQInteger LevelTime_get_time_wrapper(HSQUIRRELVM vm) +{ + SQUserPointer data; + if(SQ_FAILED(sq_getinstanceup(vm, 1, &data, 0))) { + sq_throwerror(vm, _SC("'get_time' called without instance")); + return SQ_ERROR; + } + Scripting::LevelTime* _this = reinterpret_cast (data); + + try { + float return_value = _this->get_time(); + + sq_pushfloat(vm, return_value); + return 1; + + } catch(std::exception& e) { + sq_throwerror(vm, e.what()); + return SQ_ERROR; + } catch(...) { + sq_throwerror(vm, _SC("Unexpected exception while executing function 'get_time'")); + return SQ_ERROR; + } + +} + +static SQInteger LevelTime_set_time_wrapper(HSQUIRRELVM vm) +{ + SQUserPointer data; + if(SQ_FAILED(sq_getinstanceup(vm, 1, &data, 0))) { + sq_throwerror(vm, _SC("'set_time' called without instance")); + return SQ_ERROR; + } + Scripting::LevelTime* _this = reinterpret_cast (data); + SQFloat arg0; + if(SQ_FAILED(sq_getfloat(vm, 2, &arg0))) { + sq_throwerror(vm, _SC("Argument 1 not a float")); + return SQ_ERROR; + } + + try { + _this->set_time(static_cast (arg0)); + + return 0; + + } catch(std::exception& e) { + sq_throwerror(vm, e.what()); + return SQ_ERROR; + } catch(...) { + sq_throwerror(vm, _SC("Unexpected exception while executing function 'set_time'")); + return SQ_ERROR; + } + +} + static SQInteger display_wrapper(HSQUIRRELVM vm) { return Scripting::display(vm); @@ -3403,6 +3512,32 @@ void create_squirrel_instance(HSQUIRRELVM v, Scripting::SSector* object, bool se sq_remove(v, -2); // remove root table } +void create_squirrel_instance(HSQUIRRELVM v, Scripting::LevelTime* object, bool setup_releasehook) +{ + using namespace Wrapper; + + sq_pushroottable(v); + sq_pushstring(v, "LevelTime", -1); + if(SQ_FAILED(sq_get(v, -2))) { + std::ostringstream msg; + msg << "Couldn't resolved squirrel type 'LevelTime'"; + throw SquirrelError(v, msg.str()); + } + + if(SQ_FAILED(sq_createinstance(v, -1)) || SQ_FAILED(sq_setinstanceup(v, -1, object))) { + std::ostringstream msg; + msg << "Couldn't setup squirrel instance for object of type 'LevelTime'"; + throw SquirrelError(v, msg.str()); + } + sq_remove(v, -2); // remove object name + + if(setup_releasehook) { + sq_setreleasehook(v, -1, LevelTime_release_hook); + } + + sq_remove(v, -2); // remove root table +} + void register_supertux_wrapper(HSQUIRRELVM v) { using namespace Wrapper; @@ -4299,6 +4434,41 @@ void register_supertux_wrapper(HSQUIRRELVM v) throw SquirrelError(v, "Couldn't register class 'SSector'"); } + // Register class LevelTime + sq_pushstring(v, "LevelTime", -1); + if(sq_newclass(v, SQFalse) < 0) { + std::ostringstream msg; + msg << "Couldn't create new class 'LevelTime'"; + throw SquirrelError(v, msg.str()); + } + sq_pushstring(v, "start", -1); + sq_newclosure(v, &LevelTime_start_wrapper, 0); + if(SQ_FAILED(sq_createslot(v, -3))) { + throw SquirrelError(v, "Couldn't register function 'start'"); + } + + sq_pushstring(v, "stop", -1); + sq_newclosure(v, &LevelTime_stop_wrapper, 0); + if(SQ_FAILED(sq_createslot(v, -3))) { + throw SquirrelError(v, "Couldn't register function 'stop'"); + } + + sq_pushstring(v, "get_time", -1); + sq_newclosure(v, &LevelTime_get_time_wrapper, 0); + if(SQ_FAILED(sq_createslot(v, -3))) { + throw SquirrelError(v, "Couldn't register function 'get_time'"); + } + + sq_pushstring(v, "set_time", -1); + sq_newclosure(v, &LevelTime_set_time_wrapper, 0); + if(SQ_FAILED(sq_createslot(v, -3))) { + throw SquirrelError(v, "Couldn't register function 'set_time'"); + } + + if(SQ_FAILED(sq_createslot(v, -3))) { + throw SquirrelError(v, "Couldn't register class 'LevelTime'"); + } + } } // end of namespace Scripting diff --git a/src/scripting/wrapper.hpp b/src/scripting/wrapper.hpp index 84d822df1..2143f4978 100644 --- a/src/scripting/wrapper.hpp +++ b/src/scripting/wrapper.hpp @@ -28,6 +28,7 @@ void create_squirrel_instance(HSQUIRRELVM v, Scripting::AmbientSound* object, bo void create_squirrel_instance(HSQUIRRELVM v, Scripting::Thunderstorm* object, bool setup_releasehook = false); void create_squirrel_instance(HSQUIRRELVM v, Scripting::TileMap* object, bool setup_releasehook = false); void create_squirrel_instance(HSQUIRRELVM v, Scripting::SSector* object, bool setup_releasehook = false); +void create_squirrel_instance(HSQUIRRELVM v, Scripting::LevelTime* object, bool setup_releasehook = false); } diff --git a/src/scripting/wrapper.interface.hpp b/src/scripting/wrapper.interface.hpp index 8ad88c5e4..c28ce590e 100644 --- a/src/scripting/wrapper.interface.hpp +++ b/src/scripting/wrapper.interface.hpp @@ -15,3 +15,4 @@ #include "thunderstorm.hpp" #include "tilemap.hpp" #include "ssector.hpp" +#include "level_time.hpp"