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.
# 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_SOURCES RELATIVE ${CMAKE_CURRENT_SOURCE_DIR} "src/*.cpp")
file(GLOB_RECURSE STK_SHADERS RELATIVE ${CMAKE_CURRENT_SOURCE_DIR} "data/shaders/*")

View File

@ -36,6 +36,7 @@
#include "karts/kart_properties.hpp"
#include "modes/three_strikes_battle.hpp"
#include "modes/world.hpp"
#include "network/rewind_manager.hpp"
#include "physics/triangle_mesh.hpp"
#include "tracks/track.hpp"
#include "physics/triangle_mesh.hpp"
@ -45,6 +46,7 @@
/** Initialises the attachment each kart has.
*/
Attachment::Attachment(AbstractKart* kart)
: EventRewinder()
{
m_type = ATTACH_NOTHING;
m_time_left = 0.0;
@ -182,6 +184,15 @@ void Attachment::set(AttachmentType type, float time,
m_node->setVisible(true);
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
// -----------------------------------------------------------------------------
@ -276,6 +287,15 @@ void Attachment::rewindTo(BareNetworkString *buffer)
}
set(new_type, time_left, m_previous_owner);
} // 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

View File

@ -21,6 +21,7 @@
#include "config/stk_config.hpp"
#include "items/attachment_plugin.hpp"
#include "network/event_rewinder.hpp"
#include "utils/no_copy.hpp"
#include "utils/random_generator.hpp"
@ -45,7 +46,8 @@ class SFXBase;
* a scene node).
* \ingroup items
*/
class Attachment: public NoCopy, public scene::IAnimationEndCallBack
class Attachment: public NoCopy, public scene::IAnimationEndCallBack,
public EventRewinder
{
public:
// Some loop in attachment.cpp depend on ATTACH_FIRST and ATTACH_MAX.
@ -114,6 +116,7 @@ public:
void handleCollisionWithKart(AbstractKart *other);
void set (AttachmentType type, float time,
AbstractKart *previous_kart=NULL);
virtual void rewind(BareNetworkString *buffer);
void rewindTo(BareNetworkString *buffer);
void saveState(BareNetworkString *buffer);
@ -142,6 +145,10 @@ public:
// ------------------------------------------------------------------------
/** Implement IAnimatedMeshSceneNode */
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
#endif

View File

@ -25,11 +25,6 @@
* 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/no_copy.hpp"
@ -38,8 +33,14 @@ using namespace irr;
#include <line2d.h>
class AbstractKart;
class LODNode;
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()
{
m_previous_attachment = m_kart->getAttachment()->getType();
m_previous_control = m_kart->getControls();
} // reset
@ -120,10 +119,7 @@ void KartRewinder::update()
// Check if an event has happened that needs to be recorded
bool control_event = !(m_kart->getControls() == m_previous_control);
bool attach_event = m_kart->getAttachment()->getType()
!= m_previous_attachment;
uint8_t type = (control_event ? EVENT_CONTROL : 0) |
(attach_event ? EVENT_ATTACH : 0) ;
uint8_t type = (control_event ? EVENT_CONTROL : 0);
if(type == 0)
return; // no event
@ -136,14 +132,8 @@ void KartRewinder::update()
m_previous_control = m_kart->getControls();
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
RewindManager::get()->addEvent(this, buffer);
//XXXXXXXXXXXXXXX RewindManager::get()->addEvent(this, buffer);
} // update
// ----------------------------------------------------------------------------
@ -153,8 +143,6 @@ void KartRewinder::rewindToEvent(BareNetworkString *buffer)
uint8_t type = buffer->getUInt8();
if(type & EVENT_CONTROL)
m_kart->getControls().setFromBuffer(buffer);
if(type & EVENT_ATTACH)
m_kart->getAttachment()->rewindTo(buffer);
}; // rewindToEvent

View File

@ -19,7 +19,6 @@
#ifndef HEADER_KART_REWINDER_HPP
#define HEADER_KART_REWINDER_HPP
#include "items/attachment.hpp"
#include "karts/controller/kart_control.hpp"
#include "network/rewinder.hpp"
@ -38,10 +37,6 @@ private:
* needs to be created. */
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
enum { EVENT_CONTROL = 0x01,
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
// ============================================================================
RewindInfoEvent::RewindInfoEvent(float time, Rewinder *rewinder,
RewindInfoEvent::RewindInfoEvent(float time, EventRewinder *event_rewinder,
BareNetworkString *buffer, bool is_confirmed)
: RewindInfoRewinder(time, rewinder, buffer, is_confirmed)
: RewindInfo(time, is_confirmed)
{
m_event_rewinder = event_rewinder;
m_buffer = buffer;
} // RewindInfoEvent

View File

@ -19,6 +19,7 @@
#ifndef HEADER_REWIND_INFO_HPP
#define HEADER_REWIND_INFO_HPP
#include "network/event_rewinder.hpp"
#include "network/network_string.hpp"
#include "network/rewinder.hpp"
#include "utils/leak_check.hpp"
@ -156,7 +157,7 @@ public:
virtual void undo()
{
m_rewinder->undoState(getBuffer());
} // undoEvent
} // undo
// ------------------------------------------------------------------------
/** Rewinds to this state. This is called while going forwards in time
* again to reach current time. It will call rewindToState().
@ -174,10 +175,16 @@ public:
}; // 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:
RewindInfoEvent(float time, Rewinder *rewinder,
RewindInfoEvent(float time, EventRewinder *event_rewinder,
BareNetworkString *buffer, bool is_confirmed);
virtual ~RewindInfoEvent() {}
@ -185,10 +192,10 @@ public:
virtual bool isEvent() const { return true; }
// ------------------------------------------------------------------------
/** 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()
{
m_rewinder->undoEvent(getBuffer());
m_event_rewinder->undo(m_buffer);
} // undo
// ------------------------------------------------------------------------
/** This is called while going forwards in time again to reach current
@ -196,8 +203,13 @@ public:
*/
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
// ------------------------------------------------------------------------
/** Returns the buffer with the event information in it. */
BareNetworkString *getBuffer() { return m_buffer; }
}; // class RewindIndoEvent
#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 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;
RewindInfo *ri = new RewindInfoEvent(getCurrentTime(), rewinder,
buffer, /*is_confirmed*/true );
if(m_is_rewinding)
{
delete buffer;
Log::error("RewindManager", "Adding event when rewinding");
return;
}
RewindInfo *ri = new RewindInfoEvent(getCurrentTime(), event_rewinder,
buffer, /*is confirmed*/true);
insertRewindInfo(ri);
} // addEvent

View File

@ -26,6 +26,7 @@
#include <vector>
class RewindInfo;
class EventRewinder;
/** \ingroup network
* This class manages rewinding. It keeps track of:
@ -172,7 +173,7 @@ public:
void reset();
void saveStates();
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.
* \return true If rewinding is enabled, false otherwise.