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.
|
# 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/*")
|
||||||
|
@ -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
|
||||||
|
@ -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
|
||||||
|
@ -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;
|
||||||
|
|
||||||
// -----------------------------------------------------------------------------
|
// -----------------------------------------------------------------------------
|
||||||
|
|
||||||
|
@ -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
|
||||||
|
|
||||||
|
|
||||||
|
@ -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 };
|
||||||
|
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
|
} // 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
|
||||||
|
|
||||||
|
@ -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
|
||||||
|
@ -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
|
||||||
|
|
||||||
|
@ -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.
|
||||||
|
Loading…
x
Reference in New Issue
Block a user