From: Charles McGarvey Date: Sat, 7 Aug 2010 18:16:39 +0000 (-0600) Subject: initial runloop implementation X-Git-Url: https://git.brokenzipper.com/gitweb?a=commitdiff_plain;h=d6990468d297a6cbee98e4d0d33ab37e1b2352c9;p=chaz%2Fyoink initial runloop implementation --- diff --git a/src/Main.cc b/src/Main.cc index c76a614..e168037 100644 --- a/src/Main.cc +++ b/src/Main.cc @@ -40,8 +40,8 @@ inline int isatty(int dummy) { return 0; } #include "version.h" -Main::Main(moof::settings& settings, moof::video& video) : - moof::view(settings, video) +Main::Main(moof::settings& settings) : + moof::application(settings) { moof::dispatcher& dispatcher = moof::dispatcher::global(); video_reloaded_ = dispatcher.add_target("video.newcontext", @@ -58,15 +58,6 @@ Main::Main(moof::settings& settings, moof::video& video) : void Main::update(moof::scalar t, moof::scalar dt) { - if (children().size() == 0) - { - //moof::log_warning("main view has no children"); - //stop(); - //return; - add_child(TitleLayer::alloc()); - } - - moof::view::update(t, dt); } void Main::draw(moof::scalar alpha) const @@ -78,38 +69,38 @@ void Main::draw(moof::scalar alpha) const glMatrixMode(GL_MODELVIEW); glLoadIdentity(); - - moof::view::draw(alpha); } -bool Main::handle_event(const moof::event& event) +void Main::handle_event(const moof::event& event) { - if (moof::view::handle_event(event)) return true; - switch (event.type) { case SDL_KEYUP: + if (event.key.keysym.sym == SDLK_f) { - video().toggle_fullscreen(); + moof::video::current()->toggle_fullscreen(); } else if (event.key.keysym.sym == SDLK_l) { - video().toggle_cursor_captured(); - video().toggle_cursor_visible(); + moof::video::current()->toggle_cursor_captured(); + moof::video::current()->toggle_cursor_visible(); + } + else if (event.key.keysym.sym == SDLK_ESCAPE) + { + stop(); } break; case SDL_VIDEORESIZE: + glViewport(0, 0, event.resize.w, event.resize.h); break; case SDL_QUIT: + stop(); - return true; } - - return false; } @@ -173,7 +164,7 @@ void Main::setup_opengl() glEnable(GL_ALPHA_TEST); glAlphaFunc(GL_GREATER, 0.0); - glClearColor(0.0, 0.0, 0.0, 1.0); + glClearColor(1.0, 0.0, 0.0, 1.0); //glEnable(GL_LIGHTING); glEnable(GL_LIGHT0); @@ -279,7 +270,7 @@ void Main::print_info(int argc, char* argv[]) #else print_option("hotload", false); #endif -#if PROFILING_ENABLED +#if ENABLE_PROFILING print_option("profile", true); #else print_option("profile", false); @@ -331,7 +322,7 @@ void goodbye() int main(int argc, char* argv[]) { - //moof::backend backend; + moof::backend backend; if (argc > 1) { @@ -361,10 +352,6 @@ int main(int argc, char* argv[]) try { - //std::string iconPath(PACKAGE".png"); - //iconPath = moof::resource::find_file(iconPath); - //moof::image icon(iconPath); - //icon.set_as_icon(); moof::image_handle icon(PACKAGE, "png"); if (icon) icon->set_as_icon(); else moof::log_error("no icon loaded"); @@ -372,10 +359,9 @@ int main(int argc, char* argv[]) class moof::video::attributes attributes(settings); moof::video video(PACKAGE_STRING, attributes); - Main mainView(settings, video); - mainView.run(); - return 0; + Main app(settings); + return app.run(); } catch (const std::exception& e) { diff --git a/src/Main.hh b/src/Main.hh index 4532e41..47163d1 100644 --- a/src/Main.hh +++ b/src/Main.hh @@ -22,31 +22,21 @@ #include +#include #include #include #include -#include -namespace moof -{ - class settings; - class view; -} - - -class Main; -typedef boost::shared_ptr
MainP; - -class Main : public moof::view +class Main : public moof::application { public: - Main(moof::settings& settings, moof::video& video); + Main(moof::settings& settings); void update(moof::scalar t, moof::scalar dt); void draw(moof::scalar alpha) const; - bool handle_event(const moof::event& event); + void handle_event(const moof::event& event); static std::string search_paths(); static std::string config_paths(); diff --git a/src/moof/application.cc b/src/moof/application.cc new file mode 100644 index 0000000..fd9ea45 --- /dev/null +++ b/src/moof/application.cc @@ -0,0 +1,105 @@ + +/*] Copyright (c) 2009-2010, Charles McGarvey [************************** +**] All rights reserved. +* +* vi:ts=4 sw=4 tw=75 +* +* Distributable under the terms and conditions of the 2-clause BSD license; +* see the file COPYING for a complete text of the license. +* +**************************************************************************/ + +#include // exit, srand +#include + +#include +#include "fastevents.h" + +#include "application.hh" +#include "log.hh" +#include "settings.hh" +#include "timer.hh" +#include "video.hh" + + +namespace moof { + + +application::application(settings& settings) : + next_update_(timer::ticks()), + total_time_(SCALAR(0.0)) +{ + unsigned random_seed; + if (settings.get("rngseed", random_seed)) srand(random_seed); + else srand(time(0)); + + scalar timestep = SCALAR(80.0); + settings.get("timestep", timestep); + timestep_ = SCALAR(1.0) / timestep; + inverse_timestep_ = timestep; + + scalar framerate = SCALAR(40.0); + settings.get("framerate", framerate); + framerate = SCALAR(1.0) / framerate; + + update_timer_.init(boost::bind(&application::dispatch_update, this, _1, _2), + timestep_, timer::repeat, this); + draw_timer_.init(boost::bind(&application::dispatch_draw, this, _1, _2), + framerate, timer::repeat, this); +} + + +void application::dispatch_update(timer& timer, scalar t) +{ + event event; + + while (FE_PollEvent(&event) == 1) + { + switch (event.type) + { + case SDL_KEYDOWN: + + if (event.key.keysym.sym == SDLK_ESCAPE && + (SDL_GetModState() & KMOD_CTRL) ) + { + // emergency escape + log_warning("escape forced"); + exit(1); + } + break; + + case SDL_VIDEORESIZE: + + video::current()->resize(event.resize.w, event.resize.h); + break; + } + + handle_event(event); + } + + + const int MAX_FRAMESKIP = 15; + + int i = 0; + while (next_update_ < t && ++i < MAX_FRAMESKIP) + { + total_time_ += timestep_; + update(total_time_, timestep_); + + next_update_ += timestep_; + } +} + +void application::dispatch_draw(timer& timer, scalar t) +{ + scalar alpha = (t + timestep_ - next_update_) * inverse_timestep_; + if (alpha < SCALAR(0.0)) log_error("UH OH!!!!! It's NEGATIVE", alpha); + if (alpha > SCALAR(1.0)) log_error("UH OH!!!!! It's POSITIVE", alpha); + + draw(alpha); + video::current()->swap(); +} + + +} // namespace moof + diff --git a/src/moof/application.hh b/src/moof/application.hh new file mode 100644 index 0000000..671011f --- /dev/null +++ b/src/moof/application.hh @@ -0,0 +1,65 @@ + +/*] Copyright (c) 2009-2010, Charles McGarvey [************************** +**] All rights reserved. +* +* vi:ts=4 sw=4 tw=75 +* +* Distributable under the terms and conditions of the 2-clause BSD license; +* see the file COPYING for a complete text of the license. +* +**************************************************************************/ + +#ifndef _MOOF_APPLICATION_HH_ +#define _MOOF_APPLICATION_HH_ + +/** + * \file application.hh + * The main loop. + */ + +#include + +#include +#include +#include +#include + + +namespace moof { + + +class settings; + +class application : public runloop +{ +public: + + application(settings& settings); + virtual ~application() {} + + virtual void update(scalar t, scalar dt) = 0; + virtual void draw(scalar alpha) const = 0; + virtual void handle_event(const event& event) = 0; + + +private: + + void dispatch_update(timer& timer, scalar t); + void dispatch_draw(timer& timer, scalar t); + + scalar next_update_; + scalar total_time_; + + timer update_timer_; + timer draw_timer_; + + + scalar timestep_; + scalar inverse_timestep_; +}; + + +} // namespace moof + +#endif // _MOOF_APPLICATION_HH_ + diff --git a/src/moof/modal_dialog.hh b/src/moof/modal_dialog.hh index e1d7739..c537662 100644 --- a/src/moof/modal_dialog.hh +++ b/src/moof/modal_dialog.hh @@ -24,9 +24,9 @@ #if defined(_WIN32) #include -#elif USE_GTK +#elif WITH_GTK #include -#elif USE_QT4 +#elif WITH_QT4 #include #include #include @@ -113,7 +113,7 @@ struct modal_dialog MessageBox(0, (text1 + "\n" + text2).c_str(), title.c_str(), MB_OK | icon_type); -#elif USE_GTK +#elif WITH_GTK int argc = 0; char** argv; @@ -153,7 +153,7 @@ struct modal_dialog // FIXME - this doesn't seem to actually remove the window from the // screen when it closes -#elif USE_QT4 +#elif WITH_QT4 int argc = 0; char** argv; diff --git a/src/moof/opengl.hh b/src/moof/opengl.hh index 06ffbaa..3367bc8 100644 --- a/src/moof/opengl.hh +++ b/src/moof/opengl.hh @@ -59,7 +59,7 @@ #define PASS_V4 v[0], v[1], v[2], v[3] -#if USE_DOUBLE_PRECISION +#if ENABLE_DOUBLE_PRECISION #define OPENGL_GENERIC_FUNC(R, N, L) \ inline R gl##N(ARGS_##L) { gl##N##d(PASS_##L); }// @@ -114,7 +114,7 @@ inline void glMaterial(GLenum face, GLenum pname, moof::scalar s) inline void glMaterial(GLenum face, GLenum pname, const moof::vector4& v) { -#if USE_DOUBLE_PRECISION +#if ENABLE_DOUBLE_PRECISION float f[] = {v[0], v[1], v[2], v[3]}; glMaterialfv(face, pname, f); #else @@ -137,7 +137,7 @@ inline void glDrawElements(GLenum type, const std::vector& v) } -#if USE_DOUBLE_PRECISION +#if ENABLE_DOUBLE_PRECISION inline void glGetScalar(GLenum a, GLscalar* b) { glGetDoublev(a, b); } #else inline void glGetScalar(GLenum a, GLscalar* b) { glGetFloatv(a, b); } diff --git a/src/moof/resource.cc b/src/moof/resource.cc index 35cd663..95b4c69 100644 --- a/src/moof/resource.cc +++ b/src/moof/resource.cc @@ -13,7 +13,7 @@ #include -#ifdef USE_HOTLOADING +#if ENABLE_HOTLOADING #include #include #endif @@ -112,7 +112,7 @@ static struct rsrc_list #endif } rsrc_list; -#ifdef USE_HOTLOADING +#if ENABLE_HOTLOADING static struct watch_list { // this table associates a watch descriptor with a loaded resource @@ -179,7 +179,7 @@ resource_ptr resource::load_with_path(const std::string& path, rsrc_list.table[path] = rsrc; rsrc->path_ = path; rsrc->type_ = ext; -#ifdef USE_HOTLOADING +#if ENABLE_HOTLOADING rsrc->wd_ = watch_list.add(rsrc); #endif return rsrc; @@ -197,7 +197,7 @@ int resource::reload_as_needed() { int count = 0; -#ifdef USE_HOTLOADING +#if ENABLE_HOTLOADING char bytes[BUF_SIZE]; int num_bytes; // an inotify file descriptor lets your read inotify_event structures @@ -255,7 +255,7 @@ void resource::reload() resource::~resource() { rsrc_list.table.erase(path_); -#ifdef USE_HOTLOADING +#if ENABLE_HOTLOADING watch_list.remove(wd_); #endif } diff --git a/src/moof/runloop.cc b/src/moof/runloop.cc new file mode 100644 index 0000000..db59814 --- /dev/null +++ b/src/moof/runloop.cc @@ -0,0 +1,148 @@ + +/*] Copyright (c) 2009-2010, Charles McGarvey [************************** +**] All rights reserved. +* +* vi:ts=4 sw=4 tw=75 +* +* Distributable under the terms and conditions of the 2-clause BSD license; +* see the file COPYING for a complete text of the license. +* +**************************************************************************/ + +#include "hash.hh" +#include "runloop.hh" +#include "timer.hh" + + +namespace moof { + + +enum registry_action +{ + lookup, + set +}; + +static uint32_t call_registry(runloop*& runloop, registry_action action) +{ + typedef stlplus::hash table_t; + static table_t table; + + uint32_t thread_id = thread::current_identifier(); + + static MOOF_DECLARE_MUTEX(table_mutex); + MOOF_MUTEX_LOCK(table_mutex); + + switch (action) + { + case set: + { + if (runloop) table[thread_id] = runloop; + else table.erase(thread_id); + break; + } + + case lookup: + { + table_t::iterator it = table.find(thread_id); + if (it != table.end()) runloop = (*it).second; + break; + } + } + + return thread_id; +} + + +int runloop::run() +{ +#if ENABLE_THREADS + runloop* runloop = this; + thread_id_ = call_registry(runloop, set); +#endif + + stop_ = false; + while (!stop_) + { + scalar next_event = SCALAR(0.0); + { + MOOF_MUTEX_LOCK(timers_mutex_); + + for (timers_it_ = timers_.begin(); + timers_it_ != timers_.end(); + ++timers_it_) + { + scalar absolute = (*timers_it_)->fire_if_expired(); + if (next_event == SCALAR(0.0) || + (absolute != SCALAR(0.0) && absolute < next_event)) + { + next_event = absolute; + } + } + } + timer::sleep(next_event, timer::absolute); + } + + return code_; +} + + +runloop::~runloop() +{ + runloop* runloop = 0; + call_registry(runloop, set); +} + + +void runloop::stop(int code) +{ + code_ = code; + stop_ = true; +} + + +runloop* runloop::current() +{ + runloop* runloop; + call_registry(runloop, lookup); + return runloop; +} + + +void runloop::add_timer(timer* timer) +{ +#if ENABLE_THREADS + if (thread_id_ != thread::current_identifier()) + { + MOOF_MUTEX_LOCK(timers_mutex_); + timers_.insert(timer); + timers_it_ = timers_.end(); + } + else +#endif + { + timers_.insert(timer); + timers_it_ = timers_.end(); + } +} + +void runloop::remove_timer(timer* timer) +{ +#if ENABLE_THREADS + if (thread_id_ != thread::current_identifier()) + { + MOOF_MUTEX_LOCK(timers_mutex_); + timers_.erase(timer); + timers_it_ = timers_.end(); + } + else +#endif + { + timers_.erase(timer); + timers_it_ = timers_.end(); + } +} + + +} // namespace moof + diff --git a/src/moof/runloop.hh b/src/moof/runloop.hh new file mode 100644 index 0000000..0aad06d --- /dev/null +++ b/src/moof/runloop.hh @@ -0,0 +1,103 @@ + +/*] Copyright (c) 2009-2010, Charles McGarvey [************************** +**] All rights reserved. +* +* vi:ts=4 sw=4 tw=75 +* +* Distributable under the terms and conditions of the 2-clause BSD license; +* see the file COPYING for a complete text of the license. +* +**************************************************************************/ + +#ifndef _MOOF_RUNLOOP_HH_ +#define _MOOF_RUNLOOP_HH_ + +/** + * \file runloop.hh + * Thread timer management class. + */ + +#include + +#include + +#include +#include + + +namespace moof { + + +// forward declarations +class timer; + + +/** + * A runloop is a loop with scheduled timers. + */ +class runloop +{ +public: + + /** + * Construct a runloop. + */ + runloop() : + stop_(false), + thread_id_(0) {} + + /** + * Deconstruct the runloop. + */ + ~runloop(); + + + /** + * Start running the runloop. + * \return The exit code. + */ + int run(); + + /** + * Stop the runloop. + * \param code The exit code. + */ + void stop(int code = 0); + + + /** Get the runloop of the current thread. + * \return The current runloop or 0 if none is running in the current + * thread. + */ + static runloop* current(); + + +private: + + friend class timer; + + void add_timer(timer* timer); + void remove_timer(timer* timer); + + + bool stop_; + int code_; + + typedef std::set timer_table; + timer_table timers_; + timer_table::iterator timers_it_; + +#if ENABLE_THREADS + MOOF_DECLARE_MUTEX(timers_mutex_); + uint32_t thread_id_; +#endif + + + backend backend_; +}; + + +} // namespace moof + +#endif // _MOOF_RUNLOOP_HH_ + diff --git a/src/moof/timer.cc b/src/moof/timer.cc index f16a962..9b105b4 100644 --- a/src/moof/timer.cc +++ b/src/moof/timer.cc @@ -24,24 +24,15 @@ namespace moof { -scalar timer::next_event_ = std::numeric_limits::max(); -hash timer::timers_; - - -unsigned timer::new_identifier() -{ - static unsigned id = 1; - return id++; -} - - -void timer::init(const function& function, scalar seconds, mode mode) +void timer::init(const function& function, + scalar seconds, + mode mode, + runloop* runloop) { invalidate(); + ASSERT(runloop && "can't schedule timer without a runloop"); - mode_ = mode; - - if (mode_ != invalid) + if ((mode_ = mode) != invalid) { function_ = function; @@ -55,111 +46,39 @@ void timer::init(const function& function, scalar seconds, mode mode) interval_ = seconds; } - id_ = new_identifier(); - timers_.insert(std::pair(id_, this)); - - if (absolute_ < next_event_) next_event_ = absolute_; + runloop->add_timer(this); + runloop_ = runloop; } } -bool timer::is_valid() const -{ - return mode_ != invalid; -} - void timer::invalidate() { if (mode_ != invalid) { - timers_.erase(id_); mode_ = invalid; + absolute_ = SCALAR(0.0); - if (is_equal(absolute_, next_event_)) - { - next_event_ = find_next_event(); - } + runloop_->remove_timer(this); + runloop_ = 0; } } -void timer::fire() +void timer::fire(scalar t) { - scalar t = ticks(); - if (function_) function_(*this, t); if (is_repeating()) { - scalar absolute = absolute_; - if (is_equal(absolute_, t, 1.0)) absolute_ += interval_; else absolute_ = interval_ + t; - - if (is_equal(absolute, next_event_)) - { - next_event_ = find_next_event(); - } - } - else - { - invalidate(); - } -} - - -scalar timer::find_next_event() -{ - scalar next_fire = std::numeric_limits::max(); - - hash::iterator it; - for (it = timers_.begin(); it.valid(); ++it) - { - scalar absolute = (*it).second->absolute_; - if (absolute < next_fire) next_fire = absolute; - } - - return next_fire; -} - - -scalar timer::seconds_remaining() const -{ - return absolute_ - ticks(); -} - -scalar timer::next_expiration() const -{ - return absolute_; -} - -bool timer::is_expired() const -{ - return seconds_remaining() < 0.0; -} - -bool timer::is_repeating() const -{ - return mode_ == repeat; -} - - -void timer::fire_expired_timers(scalar t) -{ - if (t < next_event_) return; - - hash::iterator it; - for (it = timers_.begin(); it.valid(); ++it) - { - timer* timer = (*it).second; - if (timer->is_expired()) timer->fire(); - - if (it.end()) break; } + else invalidate(); } -#if USE_CLOCK_GETTIME +#if ENABLE_CLOCK_GETTIME // Since the monotonic clock will provide us with the time since the // computer started, the number of seconds since that time could easily @@ -208,7 +127,7 @@ void timer::sleep(scalar seconds, mode mode) } -#else // ! USE_CLOCK_GETTIME +#else // ! ENABLE_CLOCK_GETTIME // If we don't have posix timers, we'll have to use a different timing @@ -227,7 +146,7 @@ void timer::sleep(scalar seconds, mode mode) SDL_Delay(seconds * SCALAR(1000.0)); } -#endif // USE_CLOCK_GETTIME +#endif // ENABLE_CLOCK_GETTIME } // namespace moof diff --git a/src/moof/timer.hh b/src/moof/timer.hh index 3ec4ef9..90c53ce 100644 --- a/src/moof/timer.hh +++ b/src/moof/timer.hh @@ -23,6 +23,7 @@ #include #include +#include namespace moof { @@ -80,9 +81,12 @@ public: * again at that many seconds from the expiration time. A repeating * timer can be invalidated manually using invalidate(). */ - timer(const function& function, scalar seconds, mode mode = relative) + timer(const function& function, + scalar seconds, + mode mode = relative, + runloop* runloop = runloop::current()) { - init(function, seconds, mode); + init(function, seconds, mode, runloop); } /** @@ -114,7 +118,8 @@ public: */ void init(const function& function, scalar seconds, - mode mode = relative); + mode mode = relative, + runloop* runloop = runloop::current()); /** @@ -122,7 +127,10 @@ public: * still scheduled to expired. You can get the time remaining from * seconds_remaining(). */ - bool is_valid() const; + bool is_valid() const + { + return mode_ != invalid; + } /** * Manually invalidated the timer, removing any schedule such that the @@ -137,23 +145,46 @@ public: * prematurely. If the timer is scheduled, it will be invalidated. If * the timer is already invalid (but is initialized with an event * handler), the event will be fired and the timer will remain invalid. + * \param t The absolute time passed to the timer event function. */ - void fire(); + void fire(scalar t = ticks()); + + + /** + * Fire the timer event if it is expired. + * \param t The absolute time used as a reference to determine if the + * timer is expired; defaults to the current time. + * \return The absolute time of the next expiration (if repeating), or + * 0.0 otherwise. + */ + scalar fire_if_expired(scalar t = ticks()) + { + if (is_expired()) fire(); + return absolute_; + } /** * Get the number of seconds remaining before the timer is scheduled to * expired. If the timer is invalid, the retured value will be * negative. + * \param t The absolute time used as a reference to determine the + * amount of time left; defaults to the current time. * \return Seconds. */ - scalar seconds_remaining() const; + scalar seconds_remaining(scalar t = ticks()) const + { + return next_expiration() - t; + } /** * Get the absolute time of the next expiration of this timer. * \return Seconds. */ - scalar next_expiration() const; + scalar next_expiration() const + { + return absolute_; + } /** @@ -162,15 +193,23 @@ public: * expiration time in the future. If the timer is expired but not * invalid, the timer event has not yet fired; the timer will be * invalidated when it does fire. + * \param t The absolute time used as a reference to determine if the + * timer is expired; defaults to the current time. * \return True if the timer is expired, false otherwise. */ - bool is_expired() const; + bool is_expired(scalar t = ticks()) const + { + return seconds_remaining(t) < SCALAR(0.0); + } /** * Get whether or not the timer is on a repeating schedule. * \return True if the timer is repeating, false otherwise. */ - bool is_repeating() const; + bool is_repeating() const + { + return mode_ == repeat; + } /** @@ -195,45 +234,13 @@ public: static void sleep(scalar seconds, mode mode = relative); - /** - * Get the absolute time when the next timer is scheduled to expire. - * \return Absolute time, in seconds. - */ - static scalar next_event() - { - return next_event_; - } - - - /** - * Fire any timers which are not yet invalidated but have an expiration - * time in the past. - */ - static void fire_expired_timers() - { - fire_expired_timers(ticks()); - } - - /** - * Fire any timers which are not yet invalidated but have an expiration - * time before a given absolute time. - */ - static void fire_expired_timers(scalar t); - - private: - static unsigned new_identifier(); - static scalar find_next_event(); - function function_; mode mode_; scalar absolute_; scalar interval_; - unsigned id_; - - static scalar next_event_; - static hash timers_; + runloop* runloop_; }; diff --git a/src/moof/view.cc b/src/moof/view.cc index ab0058b..62fcd93 100644 --- a/src/moof/view.cc +++ b/src/moof/view.cc @@ -209,26 +209,26 @@ public: nextUpdate = timer::ticks(); - scalar totalTime = 0.0; - scalar ticks = timer::ticks(); + //scalar totalTime = 0.0; + //scalar ticks = timer::ticks(); - scalar nextUpdate = ticks; - scalar nextDraw = ticks; - scalar nextSecond = ticks + SCALAR(1.0); + //scalar nextUpdate = ticks; + //scalar nextDraw = ticks; + //scalar nextSecond = ticks + SCALAR(1.0); fps_ = 0; - int frameCount = 0; + //int frameCount = 0; - const scalar timestep = SCALAR(0.01);//timestep_; - const scalar framerate = framerate_; + //const scalar timestep = SCALAR(0.01);//timestep_; + //const scalar framerate = framerate_; - const int MAX_FRAMESKIP = 15; - const scalar inverseTimestep = SCALAR(1.0) / timestep; + //const int MAX_FRAMESKIP = 15; + //const scalar inverseTimestep = SCALAR(1.0) / timestep; is_running_ = true; for (;;) { - timer::fire_expired_timers(); // 1. fire timers + //timer::fire_expired_timers(); // 1. fire timers dispatch_events(); // 2. dispatch events //if (!is_running_) break; @@ -313,7 +313,7 @@ public: //next = std::min(next, timer::next_event()); //if (ticks < next) timer::sleep(next, timer::absolute); - timer::sleep(timer::next_event(), timer::absolute); + //timer::sleep(timer::next_event(), timer::absolute); // Animation is choppy... the sound timer makes the draw occur // late. It's not usually enough to make the FPS drop, but it