implement a new tick-timer that doesn't suck
authorterom
Thu, 04 Dec 2008 23:28:52 +0000
changeset 205 905028e58ed1
parent 204 4c386e9c950f
child 206 a1fe1a93ba5a
implement a new tick-timer that doesn't suck
src/Graphics.cc
src/Graphics.hh
src/PhysicsObject.cc
src/PhysicsObject.hh
src/PhysicsWorld.cc
src/PhysicsWorld.hh
src/Player.hh
src/Timer.cc
src/Timer.hh
--- a/src/Graphics.cc	Thu Dec 04 22:59:13 2008 +0000
+++ b/src/Graphics.cc	Thu Dec 04 23:28:52 2008 +0000
@@ -11,10 +11,10 @@
     keyboard(win.get_ic()->get_keyboard()) {
 
     // connect timer signal
-    slots.connect(update_timer.sig_timer(), this, &Graphics::on_update);
+    slots.connect(update_timer.sig_tick(), this, &Graphics::on_update);
 
     // enable
-    update_timer.enable();
+    update_timer.start();
 }
 
 void Graphics::check_input (void) {
@@ -77,7 +77,7 @@
     win.flip(1);
 }
 
-void Graphics::on_update (void) {
+void Graphics::on_update (TimeMS tick_length) {
     // check keyboard input
     check_input();
 
--- a/src/Graphics.hh	Thu Dec 04 22:59:13 2008 +0000
+++ b/src/Graphics.hh	Thu Dec 04 23:28:52 2008 +0000
@@ -5,6 +5,7 @@
 class Graphics;
 
 #include "GameState.hh"
+#include "Timer.hh"
 #include "Engine.hh"
 
 #include <ClanLib/core.h>
@@ -23,7 +24,7 @@
     
     CL_SlotContainer slots;
     
-    CL_Timer update_timer;
+    Timer update_timer;
     
     CL_DisplayWindow win;
     CL_InputDevice &keyboard;
@@ -35,7 +36,7 @@
     void check_input (void);
     void do_redraw (void);
     
-    void on_update (void);
+    void on_update (TimeMS tick_length);
     
 };
 
--- a/src/PhysicsObject.cc	Thu Dec 04 22:59:13 2008 +0000
+++ b/src/PhysicsObject.cc	Thu Dec 04 23:28:52 2008 +0000
@@ -111,10 +111,10 @@
  * Updates object speed and position. This function organises force
  * integration and collision detection.
  */   
-void PhysicsObject::updatePosition () {
+void PhysicsObject::updatePosition (TimeMS dt) {
 
     // Reloads weapon if not reloaded
-    reloadTimer -= PHYSICS_TICK_MS;
+    reloadTimer -= dt;
     if(reloadTimer < 0)
         reloadTimer = 0;
 
@@ -154,7 +154,7 @@
         // It walks only if there's some vertical force
         if (total.x != 0) {
             std::cout << "Succeeding to walk" << std::endl;
-            walk(PHYSICS_TICK_MS, total.x > 0);
+            walk(dt, total.x > 0);
             this->velocity = Vector(0,0);
         }
     }
@@ -166,7 +166,7 @@
     Vector newPosition;
     Vector velAfterTick;
     // Calculate new position and velocity to the given references
-    integrate(total, PHYSICS_TICK_MS, newPosition, velAfterTick);
+    integrate(total, dt, newPosition, velAfterTick);
     this->velocity = velAfterTick;
 
    
@@ -334,8 +334,8 @@
     this->shape = shape;
 }
 
-void PhysicsObject::tick () {
-    this->updatePosition();
+void PhysicsObject::tick (TimeMS tick_length) {
+    this->updatePosition(tick_length);
 }
 
 bool PhysicsObject::canShoot() {
--- a/src/PhysicsObject.hh	Thu Dec 04 22:59:13 2008 +0000
+++ b/src/PhysicsObject.hh	Thu Dec 04 23:28:52 2008 +0000
@@ -9,11 +9,10 @@
 
 #include "PhysicsWorld.hh"
 #include "Vector.hh"
+#include "Timer.hh"
 #include "Config.hh"
-#include "Input.hh"
 
 // Type definitions
-typedef uint16_t TimeMS;
 typedef Vector Force;
 
 
@@ -101,7 +100,7 @@
     /**
      * Handle player movement and apply forces.
      */
-    void updatePosition();
+    void updatePosition(TimeMS dt);
 
     // TODO: Should these be moved to PhysicsWorld?
     /**
@@ -191,7 +190,7 @@
     /**
      * Update object in physics simulation.
      */
-    void tick();
+    void tick(TimeMS tick_length);
 
     /**
      * @return whether this PhysicsObject can shoot or not
--- a/src/PhysicsWorld.cc	Thu Dec 04 22:59:13 2008 +0000
+++ b/src/PhysicsWorld.cc	Thu Dec 04 23:28:52 2008 +0000
@@ -4,10 +4,10 @@
 #include "Engine.hh"
 
 PhysicsWorld::PhysicsWorld (Vector gravity, Vector dimensions)
-    : Terrain(1337), tick_timer(PHYSICS_TICK_MS), tick_counter(0), dimensions(dimensions),
+    : Terrain(1337), tick_timer(PHYSICS_TICK_MS), dimensions(dimensions),
       gravity(gravity) {
-    slots.connect(tick_timer.sig_timer(), this, &PhysicsWorld::tick);
-    tick_timer.enable();
+    slots.connect(tick_timer.sig_tick(), this, &PhysicsWorld::tick);
+    tick_timer.start();
 }
 
 void PhysicsWorld::addPlayerObject (PhysicsObject *object) {
@@ -33,26 +33,20 @@
     }
 }
 
-void PhysicsWorld::tick () {
+void PhysicsWorld::tick (TimeMS tick_length) {
     //    Engine::log(DEBUG, "physics.apply_force") << "*tick*";
 
     for (std::list<PhysicsObject*>::iterator i = players.begin(); i != players.end(); i++) {
-        (*i)->tick(); 
+        (*i)->tick(tick_length); 
     }
 
     for (std::list<Projectile*>::iterator i = projectiles.begin(); i != projectiles.end(); i++) {
-        (*i)->tick();
+        (*i)->tick(tick_length);
     }
 
     // Delete destroyed projectiles
     std::list<Projectile*>::iterator new_end = remove_if(projectiles.begin(), projectiles.end(), isDestroyedProjectile);
     projectiles.erase(new_end, projectiles.end());
-    
-    tick_counter++;
-}
-
-uint32_t PhysicsWorld::getTick (void) {
-    return tick_counter;
 }
 
 void PhysicsWorld::draw(CL_GraphicContext *gc) {
--- a/src/PhysicsWorld.hh	Thu Dec 04 22:59:13 2008 +0000
+++ b/src/PhysicsWorld.hh	Thu Dec 04 23:28:52 2008 +0000
@@ -8,14 +8,15 @@
 #include <functional>
 #include <cmath>
 
+#include "Terrain.hh"          
 
-#include "Terrain.hh"          
 class PhysicsWorld;
 
 #include "PhysicsObject.hh"
+#include "Projectile.hh"
 #include "Vector.hh"
+#include "Timer.hh"
 #include "Config.hh"
-#include "Projectile.hh"
 
 /**
 * PhysicsWorld class. PhysicsWorld contains PhysicsObjects that are
@@ -25,8 +26,7 @@
     friend class PhysicsObject;
 
 private:
-    CL_Timer tick_timer;
-    uint32_t tick_counter;
+    Timer tick_timer;
 
     //    Terrain terrain;
 
@@ -64,7 +64,7 @@
     /**
      * Advance one time step in physics simulation.
      */
-    void tick();
+    void tick(TimeMS tick_length);
 
     /**
      * Get current tick in physics simulation.
--- a/src/Player.hh	Thu Dec 04 22:59:13 2008 +0000
+++ b/src/Player.hh	Thu Dec 04 23:28:52 2008 +0000
@@ -7,6 +7,7 @@
 
 #include "GameState.hh"
 #include "PhysicsObject.hh"
+#include "Input.hh"
 
 class Player : public PhysicsObject {
 protected:
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/Timer.cc	Thu Dec 04 23:28:52 2008 +0000
@@ -0,0 +1,45 @@
+
+#include "Timer.hh"
+
+Timer::Timer (TimeMS interval) :
+    interval(interval), ticks(0), last_tick(0), enabled(false)
+{
+
+}
+
+TickCount Timer::get_ticks (void) {
+    return ticks;
+}
+
+void Timer::start (void) {
+    last_tick = CL_System::get_time();
+
+    enabled = true;
+}
+
+void Timer::keep_alive (void) {
+    // ignore if disabled
+    if (!enabled)
+        return;
+
+    // get current time
+    TimeMS now = CL_System::get_time();
+
+    // handle overflows
+    if (last_tick > now)
+        last_tick = now;
+    
+    // is the tick over?
+    if (last_tick + interval < now) {
+        // the length of this tick
+        TimeMS tick_length = now - last_tick;
+        
+        // trigger our signal
+        _sig_tick(tick_length);
+        
+        // update state
+        last_tick = now;
+        ticks += tick_length / interval;
+    }
+}
+    
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/Timer.hh	Thu Dec 04 23:28:52 2008 +0000
@@ -0,0 +1,47 @@
+#ifndef TIMER_HH
+#define TIMER_HH
+
+#include <ClanLib/core.h>
+
+typedef unsigned long TimeMS;
+typedef uint32_t TickCount;
+
+class Timer : public CL_KeepAlive {
+    protected:
+        // the target tick interval
+        TimeMS interval;
+
+        // number of ticks
+        TickCount ticks;
+
+        bool enabled;
+
+        // time of last tick
+        TimeMS last_tick;
+
+        CL_Signal_v1<TimeMS> _sig_tick;
+        
+    public:
+        /*
+         * Interval is in milliseconds
+         */
+        Timer (TimeMS interval);
+        
+        /*
+         * Returns the tick counter
+         */
+        TickCount get_ticks (void);
+        
+        /*
+         * Start the timer, this should be called once keepalive starts getting called
+         */
+        void start (void);
+        
+    private:
+        void keep_alive (void);
+    
+    public:
+        CL_Signal_v1<TimeMS>& sig_tick (void) { return _sig_tick; }
+};
+
+#endif