Refactored event handling, so that now not only Rewinder objects

can store events. This allows e.g. a 'new attachment' event to
be handled entirely in the attachment class, not in the kart
rewinder anymore.
This commit is contained in:
hiker 2016-08-11 17:14:09 +10:00
parent e621e93f4c
commit 239881ef5e
12 changed files with 148 additions and 40 deletions

View File

@ -1,5 +1,5 @@
# Modify this file to change the last-modified date when you add/remove a file. # Modify this file to change the last-modified date when you add/remove a file.
# This will then trigger a new cmake run automatically. # This will then trigger a new cmake run automatically.
file(GLOB_RECURSE STK_HEADERS RELATIVE ${CMAKE_CURRENT_SOURCE_DIR} "src/*.hpp") file(GLOB_RECURSE STK_HEADERS RELATIVE ${CMAKE_CURRENT_SOURCE_DIR} "src/*.hpp")
file(GLOB_RECURSE STK_SOURCES RELATIVE ${CMAKE_CURRENT_SOURCE_DIR} "src/*.cpp") file(GLOB_RECURSE STK_SOURCES RELATIVE ${CMAKE_CURRENT_SOURCE_DIR} "src/*.cpp")
file(GLOB_RECURSE STK_SHADERS RELATIVE ${CMAKE_CURRENT_SOURCE_DIR} "data/shaders/*") file(GLOB_RECURSE STK_SHADERS RELATIVE ${CMAKE_CURRENT_SOURCE_DIR} "data/shaders/*")

View File

@ -36,6 +36,7 @@
#include "karts/kart_properties.hpp" #include "karts/kart_properties.hpp"
#include "modes/three_strikes_battle.hpp" #include "modes/three_strikes_battle.hpp"
#include "modes/world.hpp" #include "modes/world.hpp"
#include "network/rewind_manager.hpp"
#include "physics/triangle_mesh.hpp" #include "physics/triangle_mesh.hpp"
#include "tracks/track.hpp" #include "tracks/track.hpp"
#include "physics/triangle_mesh.hpp" #include "physics/triangle_mesh.hpp"
@ -45,6 +46,7 @@
/** Initialises the attachment each kart has. /** Initialises the attachment each kart has.
*/ */
Attachment::Attachment(AbstractKart* kart) Attachment::Attachment(AbstractKart* kart)
: EventRewinder()
{ {
m_type = ATTACH_NOTHING; m_type = ATTACH_NOTHING;
m_time_left = 0.0; m_time_left = 0.0;
@ -182,6 +184,15 @@ void Attachment::set(AttachmentType type, float time,
m_node->setVisible(true); m_node->setVisible(true);
irr_driver->applyObjectPassShader(m_node); irr_driver->applyObjectPassShader(m_node);
// Save event about the new attachment
RewindManager *rwm = RewindManager::get();
if(rwm->isEnabled() && !rwm->isRewinding())
{
BareNetworkString *buffer = new BareNetworkString(2);
saveState(buffer);
rwm->addEvent(this, buffer);
}
} // set } // set
// ----------------------------------------------------------------------------- // -----------------------------------------------------------------------------
@ -276,6 +287,15 @@ void Attachment::rewindTo(BareNetworkString *buffer)
} }
set(new_type, time_left, m_previous_owner); set(new_type, time_left, m_previous_owner);
} // rewindTo } // rewindTo
// -----------------------------------------------------------------------------
/** Called when going forwards in time during a rewind.
* \param buffer Buffer with the rewind information.
*/
void Attachment::rewind(BareNetworkString *buffer)
{
// Event has same info as a state, so re-use the restore function
rewindTo(buffer);
} // rewind
// ----------------------------------------------------------------------------- // -----------------------------------------------------------------------------
/** Randomly selects the new attachment. For a server process, the /** Randomly selects the new attachment. For a server process, the

View File

@ -21,6 +21,7 @@
#include "config/stk_config.hpp" #include "config/stk_config.hpp"
#include "items/attachment_plugin.hpp" #include "items/attachment_plugin.hpp"
#include "network/event_rewinder.hpp"
#include "utils/no_copy.hpp" #include "utils/no_copy.hpp"
#include "utils/random_generator.hpp" #include "utils/random_generator.hpp"
@ -45,7 +46,8 @@ class SFXBase;
* a scene node). * a scene node).
* \ingroup items * \ingroup items
*/ */
class Attachment: public NoCopy, public scene::IAnimationEndCallBack class Attachment: public NoCopy, public scene::IAnimationEndCallBack,
public EventRewinder
{ {
public: public:
// Some loop in attachment.cpp depend on ATTACH_FIRST and ATTACH_MAX. // Some loop in attachment.cpp depend on ATTACH_FIRST and ATTACH_MAX.
@ -114,6 +116,7 @@ public:
void handleCollisionWithKart(AbstractKart *other); void handleCollisionWithKart(AbstractKart *other);
void set (AttachmentType type, float time, void set (AttachmentType type, float time,
AbstractKart *previous_kart=NULL); AbstractKart *previous_kart=NULL);
virtual void rewind(BareNetworkString *buffer);
void rewindTo(BareNetworkString *buffer); void rewindTo(BareNetworkString *buffer);
void saveState(BareNetworkString *buffer); void saveState(BareNetworkString *buffer);
@ -142,6 +145,10 @@ public:
// ------------------------------------------------------------------------ // ------------------------------------------------------------------------
/** Implement IAnimatedMeshSceneNode */ /** Implement IAnimatedMeshSceneNode */
virtual void OnAnimationEnd(scene::IAnimatedMeshSceneNode* node); virtual void OnAnimationEnd(scene::IAnimatedMeshSceneNode* node);
// ------------------------------------------------------------------------
/** Nothing to undo when going back during a rewind, the full state info
* will take care of creating the right attachment. */
virtual void undo(BareNetworkString *buffer) { }
}; // Attachment }; // Attachment
#endif #endif

View File

@ -25,11 +25,6 @@
* Defines the various collectibles and weapons of STK. * Defines the various collectibles and weapons of STK.
*/ */
namespace irr
{
namespace scene { class IMesh; class ISceneNode; }
}
using namespace irr;
#include "utils/leak_check.hpp" #include "utils/leak_check.hpp"
#include "utils/no_copy.hpp" #include "utils/no_copy.hpp"
@ -38,8 +33,14 @@ using namespace irr;
#include <line2d.h> #include <line2d.h>
class AbstractKart; class AbstractKart;
class LODNode;
class Item; class Item;
class LODNode;
namespace irr
{
namespace scene { class IMesh; class ISceneNode; }
}
using namespace irr;
// ----------------------------------------------------------------------------- // -----------------------------------------------------------------------------

View File

@ -37,7 +37,6 @@ KartRewinder::KartRewinder(AbstractKart *kart) : Rewinder(/*can_be_destroyed*/ f
*/ */
void KartRewinder::reset() void KartRewinder::reset()
{ {
m_previous_attachment = m_kart->getAttachment()->getType();
m_previous_control = m_kart->getControls(); m_previous_control = m_kart->getControls();
} // reset } // reset
@ -120,10 +119,7 @@ void KartRewinder::update()
// Check if an event has happened that needs to be recorded // Check if an event has happened that needs to be recorded
bool control_event = !(m_kart->getControls() == m_previous_control); bool control_event = !(m_kart->getControls() == m_previous_control);
bool attach_event = m_kart->getAttachment()->getType() uint8_t type = (control_event ? EVENT_CONTROL : 0);
!= m_previous_attachment;
uint8_t type = (control_event ? EVENT_CONTROL : 0) |
(attach_event ? EVENT_ATTACH : 0) ;
if(type == 0) if(type == 0)
return; // no event return; // no event
@ -136,14 +132,8 @@ void KartRewinder::update()
m_previous_control = m_kart->getControls(); m_previous_control = m_kart->getControls();
m_previous_control.copyToBuffer(buffer); m_previous_control.copyToBuffer(buffer);
} }
if(attach_event)
{
m_kart->getAttachment()->saveState(buffer);
m_previous_attachment = m_kart->getAttachment()->getType();
}
// The rewind manager will free the memory once it's not needed anymore // The rewind manager will free the memory once it's not needed anymore
RewindManager::get()->addEvent(this, buffer); //XXXXXXXXXXXXXXX RewindManager::get()->addEvent(this, buffer);
} // update } // update
// ---------------------------------------------------------------------------- // ----------------------------------------------------------------------------
@ -153,8 +143,6 @@ void KartRewinder::rewindToEvent(BareNetworkString *buffer)
uint8_t type = buffer->getUInt8(); uint8_t type = buffer->getUInt8();
if(type & EVENT_CONTROL) if(type & EVENT_CONTROL)
m_kart->getControls().setFromBuffer(buffer); m_kart->getControls().setFromBuffer(buffer);
if(type & EVENT_ATTACH)
m_kart->getAttachment()->rewindTo(buffer);
}; // rewindToEvent }; // rewindToEvent

View File

@ -19,7 +19,6 @@
#ifndef HEADER_KART_REWINDER_HPP #ifndef HEADER_KART_REWINDER_HPP
#define HEADER_KART_REWINDER_HPP #define HEADER_KART_REWINDER_HPP
#include "items/attachment.hpp"
#include "karts/controller/kart_control.hpp" #include "karts/controller/kart_control.hpp"
#include "network/rewinder.hpp" #include "network/rewinder.hpp"
@ -38,10 +37,6 @@ private:
* needs to be created. */ * needs to be created. */
KartControl m_previous_control; KartControl m_previous_control;
/** The previous attachment type, used to detect if a new event
* needs to be created. */
Attachment::AttachmentType m_previous_attachment;
// Flags to indicate the different event types // Flags to indicate the different event types
enum { EVENT_CONTROL = 0x01, enum { EVENT_CONTROL = 0x01,
EVENT_ATTACH = 0x02 }; EVENT_ATTACH = 0x02 };

View File

@ -0,0 +1,35 @@
//
// SuperTuxKart - a fun racing game with go-kart
// Copyright (C) 2016 Joerg Henrichs
//
// This program is free software; you can redistribute it and/or
// modify it under the terms of the GNU General Public License
// as published by the Free Software Foundation; either version 3
// of the License, or (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program; if not, write to the Free Software
// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
#include "network/event_rewinder.hpp"
#include "network/rewind_manager.hpp"
/** Constructor. It will add this object to the list of all rewindable
* objects in the rewind manager.
*/
EventRewinder::EventRewinder()
{
} // Rewinder
// ----------------------------------------------------------------------------
/** Destructor.
*/
EventRewinder::~EventRewinder()
{
} // ~EventRewinder

View File

@ -0,0 +1,41 @@
//
// SuperTuxKart - a fun racing game with go-kart
// Copyright (C) 2016 Joerg Henrichs
//
// This program is free software; you can redistribute it and/or
// modify it under the terms of the GNU General Public License
// as published by the Free Software Foundation; either version 3
// of the License, or (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program; if not, write to the Free Software
// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
#ifndef HEADER_EVENT_REWINDER_HPP
#define HEADER_EVENT_REWINDER_HPP
class BareNetworkString;
class EventRewinder
{
public:
EventRewinder();
virtual ~EventRewinder();
/** Called when an event needs to be undone. This is called while going
* backwards for rewinding - all stored events will get an 'undo' call.
*/
virtual void undo(BareNetworkString *buffer) = 0;
/** Called when an event needs to be replayed. This is called during
* rewind, i.e. when going forward in time again.
*/
virtual void rewind(BareNetworkString *buffer) = 0;
}; // EventRewinder
#endif

View File

@ -47,9 +47,11 @@ RewindInfoState::RewindInfoState(float time, Rewinder *rewinder,
} // RewindInfoState } // RewindInfoState
// ============================================================================ // ============================================================================
RewindInfoEvent::RewindInfoEvent(float time, Rewinder *rewinder, RewindInfoEvent::RewindInfoEvent(float time, EventRewinder *event_rewinder,
BareNetworkString *buffer, bool is_confirmed) BareNetworkString *buffer, bool is_confirmed)
: RewindInfoRewinder(time, rewinder, buffer, is_confirmed) : RewindInfo(time, is_confirmed)
{ {
m_event_rewinder = event_rewinder;
m_buffer = buffer;
} // RewindInfoEvent } // RewindInfoEvent

View File

@ -19,6 +19,7 @@
#ifndef HEADER_REWIND_INFO_HPP #ifndef HEADER_REWIND_INFO_HPP
#define HEADER_REWIND_INFO_HPP #define HEADER_REWIND_INFO_HPP
#include "network/event_rewinder.hpp"
#include "network/network_string.hpp" #include "network/network_string.hpp"
#include "network/rewinder.hpp" #include "network/rewinder.hpp"
#include "utils/leak_check.hpp" #include "utils/leak_check.hpp"
@ -156,7 +157,7 @@ public:
virtual void undo() virtual void undo()
{ {
m_rewinder->undoState(getBuffer()); m_rewinder->undoState(getBuffer());
} // undoEvent } // undo
// ------------------------------------------------------------------------ // ------------------------------------------------------------------------
/** Rewinds to this state. This is called while going forwards in time /** Rewinds to this state. This is called while going forwards in time
* again to reach current time. It will call rewindToState(). * again to reach current time. It will call rewindToState().
@ -174,10 +175,16 @@ public:
}; // class RewindInfoState }; // class RewindInfoState
// ============================================================================ // ============================================================================
class RewindInfoEvent : public RewindInfoRewinder class RewindInfoEvent : public RewindInfo
{ {
private:
/** Pointer to the event rewinder responsible for this event. */
EventRewinder *m_event_rewinder;
/** Buffer with the event data. */
BareNetworkString *m_buffer;
public: public:
RewindInfoEvent(float time, Rewinder *rewinder, RewindInfoEvent(float time, EventRewinder *event_rewinder,
BareNetworkString *buffer, bool is_confirmed); BareNetworkString *buffer, bool is_confirmed);
virtual ~RewindInfoEvent() {} virtual ~RewindInfoEvent() {}
@ -185,10 +192,10 @@ public:
virtual bool isEvent() const { return true; } virtual bool isEvent() const { return true; }
// ------------------------------------------------------------------------ // ------------------------------------------------------------------------
/** Called when going back in time to undo any rewind information. /** Called when going back in time to undo any rewind information.
* It calls undoEvent in the rewinder. */ * It calls undoEvent in the rewinder. */
virtual void undo() virtual void undo()
{ {
m_rewinder->undoEvent(getBuffer()); m_event_rewinder->undo(m_buffer);
} // undo } // undo
// ------------------------------------------------------------------------ // ------------------------------------------------------------------------
/** This is called while going forwards in time again to reach current /** This is called while going forwards in time again to reach current
@ -196,8 +203,13 @@ public:
*/ */
virtual void rewind() virtual void rewind()
{ {
m_rewinder->rewindToEvent(getBuffer()); // Make sure to reset the buffer so we read from the beginning
m_buffer->reset();
m_event_rewinder->rewind(getBuffer());
} // rewind } // rewind
// ------------------------------------------------------------------------
/** Returns the buffer with the event information in it. */
BareNetworkString *getBuffer() { return m_buffer; }
}; // class RewindIndoEvent }; // class RewindIndoEvent
#endif #endif

View File

@ -210,11 +210,17 @@ unsigned int RewindManager::findFirstIndex(float target_time) const
* \param time Time at which the event was recorded. * \param time Time at which the event was recorded.
* \param buffer Pointer to the event data. * \param buffer Pointer to the event data.
*/ */
void RewindManager::addEvent(Rewinder *rewinder, BareNetworkString *buffer) void RewindManager::addEvent(EventRewinder *event_rewinder,
BareNetworkString *buffer)
{ {
if(m_is_rewinding) return; if(m_is_rewinding)
RewindInfo *ri = new RewindInfoEvent(getCurrentTime(), rewinder, {
buffer, /*is_confirmed*/true ); delete buffer;
Log::error("RewindManager", "Adding event when rewinding");
return;
}
RewindInfo *ri = new RewindInfoEvent(getCurrentTime(), event_rewinder,
buffer, /*is confirmed*/true);
insertRewindInfo(ri); insertRewindInfo(ri);
} // addEvent } // addEvent

View File

@ -26,6 +26,7 @@
#include <vector> #include <vector>
class RewindInfo; class RewindInfo;
class EventRewinder;
/** \ingroup network /** \ingroup network
* This class manages rewinding. It keeps track of: * This class manages rewinding. It keeps track of:
@ -172,7 +173,7 @@ public:
void reset(); void reset();
void saveStates(); void saveStates();
void rewindTo(float target_time); void rewindTo(float target_time);
void addEvent(Rewinder *rewinder, BareNetworkString *buffer); void addEvent(EventRewinder *event_rewinder, BareNetworkString *buffer);
// ------------------------------------------------------------------------ // ------------------------------------------------------------------------
/** Adds a Rewinder to the list of all rewinders. /** Adds a Rewinder to the list of all rewinders.
* \return true If rewinding is enabled, false otherwise. * \return true If rewinding is enabled, false otherwise.