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:
parent
e621e93f4c
commit
239881ef5e
@ -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/*")
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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;
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
|
||||
|
@ -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
|
||||
|
||||
|
||||
|
@ -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 };
|
||||
|
35
src/network/event_rewinder.cpp
Normal file
35
src/network/event_rewinder.cpp
Normal 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
|
41
src/network/event_rewinder.hpp
Normal file
41
src/network/event_rewinder.hpp
Normal 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
|
||||
|
@ -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
|
||||
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
||||
|
@ -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.
|
||||
|
Loading…
x
Reference in New Issue
Block a user