forked from aya/aya
Initial commit
This commit is contained in:
166
engine/app/src/DataModel/ChangeHistory.hpp
Normal file
166
engine/app/src/DataModel/ChangeHistory.hpp
Normal file
@@ -0,0 +1,166 @@
|
||||
#pragma once
|
||||
|
||||
#include "Tree/Service.hpp"
|
||||
#include "Utility/RunStateOwner.hpp"
|
||||
#include "Voxel/Cell.hpp"
|
||||
#include "Voxel/CellChangeListener.hpp"
|
||||
#include "Utility/SpatialRegion.hpp"
|
||||
#include <queue>
|
||||
|
||||
#include "Voxel2/GridListener.hpp"
|
||||
|
||||
namespace Aya
|
||||
{
|
||||
|
||||
class DataModel;
|
||||
class MegaClusterInstance;
|
||||
|
||||
extern const char* const sChangeHistoryService;
|
||||
class ChangeHistoryService
|
||||
: public DescribedCreatable<ChangeHistoryService, Instance, sChangeHistoryService, Reflection::ClassDescriptor::INTERNAL>
|
||||
, public Service
|
||||
, public Voxel::CellChangeListener
|
||||
, public Voxel2::GridListener
|
||||
{
|
||||
private:
|
||||
typedef DescribedCreatable<ChangeHistoryService, Instance, sChangeHistoryService, Reflection::ClassDescriptor::INTERNAL> Super;
|
||||
DataModel* dataModel;
|
||||
|
||||
class Item;
|
||||
class Waypoint;
|
||||
|
||||
shared_ptr<MegaClusterInstance> megaClusterInstance;
|
||||
|
||||
Waypoint* recording;
|
||||
|
||||
typedef std::list<Waypoint*> Waypoints; // must be a list and not a vector because we maintain iterators after reallocs
|
||||
Waypoints waypoints;
|
||||
|
||||
Waypoints::iterator playWaypoint; // playing nextWaypoint is a "redo"
|
||||
Waypoints::iterator unplayWaypoint; // unplaying unplayWaypoint is an "undo"
|
||||
Waypoints::iterator runStartWaypoint; // unplaying up to runStartWaypoint is a "reset"
|
||||
bool playing;
|
||||
bool enabled;
|
||||
int dataSize;
|
||||
shared_ptr<RunService> runService;
|
||||
shared_ptr<Instance> statsItem;
|
||||
|
||||
Aya::signals::scoped_connection itemAddedConnection;
|
||||
Aya::signals::scoped_connection itemRemovedConnection;
|
||||
Aya::signals::scoped_connection itemChangedConnection;
|
||||
Aya::signals::scoped_connection runTransitionConnection;
|
||||
|
||||
public:
|
||||
static const int minWaypoints = 3;
|
||||
static const int maxWaypoints = 250;
|
||||
static const int maxMemoryUsage = 250 * 1024 * 1024;
|
||||
|
||||
typedef enum
|
||||
{
|
||||
Aggregate, // Don't allow waypoints while running. All changes are recorded and made part of the reset waypoint
|
||||
Snapshot, // When recording waypoints while running, take a snapshot of positions and velocities
|
||||
Hybrid // When recording waypoints while running, ignore unrelated position and velocity changes
|
||||
} RuntimeUndoBehavior;
|
||||
static RuntimeUndoBehavior runtimeUndoBehavior;
|
||||
|
||||
ChangeHistoryService();
|
||||
~ChangeHistoryService();
|
||||
|
||||
static void requestWaypoint(const char* name, const Instance* context);
|
||||
void resetBaseWaypoint();
|
||||
void clearWaypoints();
|
||||
|
||||
void setEnabled(bool state);
|
||||
bool isEnabled() const
|
||||
{
|
||||
return enabled;
|
||||
}
|
||||
void requestWaypoint(const char* name);
|
||||
void requestWaypoint2(std::string name)
|
||||
{
|
||||
requestWaypoint(name.c_str());
|
||||
}
|
||||
|
||||
// TODO: rename play-->redo unplay-->undo???
|
||||
bool getPlayWaypoint(std::string& name, int steps = 0) const;
|
||||
bool getUnplayWaypoint(std::string& name, int steps = 0) const;
|
||||
bool canPlay() const
|
||||
{
|
||||
std::string name;
|
||||
return getPlayWaypoint(name);
|
||||
}
|
||||
bool canUnplay() const
|
||||
{
|
||||
std::string name;
|
||||
return getUnplayWaypoint(name);
|
||||
}
|
||||
|
||||
// returns a tuple: bool state, [string name]
|
||||
shared_ptr<const Reflection::Tuple> canUnplay2();
|
||||
shared_ptr<const Reflection::Tuple> canPlay2();
|
||||
// std::string getPlayName() const { std::string name; getPlayWaypoint(name); return name; }
|
||||
// std::string getUnplayName() const { std::string name; getUnplayWaypoint(name); return name; }
|
||||
|
||||
void play();
|
||||
void playLua();
|
||||
void unplay();
|
||||
void unplayLua();
|
||||
|
||||
// to show progress dialog in studio
|
||||
boost::function<void(boost::function<void()>, std::string)> withLongRunningOperation;
|
||||
|
||||
bool isResetEnabled() const;
|
||||
void reset();
|
||||
|
||||
int getWaypointDataSize() const
|
||||
{
|
||||
return dataSize;
|
||||
}
|
||||
int getWaypointCount() const
|
||||
{
|
||||
return waypoints.size();
|
||||
}
|
||||
|
||||
Aya::signal<void()> waypointChangedSignal;
|
||||
Aya::signal<void(std::string)> undoSignal;
|
||||
Aya::signal<void(std::string)> redoSignal;
|
||||
|
||||
MegaClusterInstance* getTerrain() const
|
||||
{
|
||||
return megaClusterInstance.get();
|
||||
}
|
||||
|
||||
protected:
|
||||
virtual void onServiceProvider(ServiceProvider* oldProvider, ServiceProvider* newProvider);
|
||||
|
||||
private:
|
||||
void attach();
|
||||
void dettach();
|
||||
void trimWaypoints();
|
||||
void mergeFirstTwoWaypoints();
|
||||
void computeDataSize();
|
||||
|
||||
virtual void onItemAdded(shared_ptr<Aya::Instance> item);
|
||||
virtual void onItemRemoved(shared_ptr<Aya::Instance> item);
|
||||
virtual void onItemChanged(shared_ptr<Aya::Instance> item, const Reflection::PropertyDescriptor* descriptor);
|
||||
bool isRecordable(Instance* instance);
|
||||
|
||||
/*override*/ virtual void terrainCellChanged(const Voxel::CellChangeInfo& cell);
|
||||
/*override*/ virtual void onTerrainRegionChanged(const Voxel2::Region& region);
|
||||
|
||||
void setCell(const SpatialRegion::Id& chunkPos, const Vector3int16& cellInChunk, Voxel::Cell detail, Voxel::CellMaterial material);
|
||||
|
||||
typedef enum
|
||||
{
|
||||
Accept,
|
||||
Reject
|
||||
} CheckResult;
|
||||
CheckResult checkSettingWaypoint();
|
||||
|
||||
void onRunTransition(RunTransition event);
|
||||
void setWaypoint(const char* name);
|
||||
void setRunWaypoint();
|
||||
void reportMissedPhysicsChanges(shared_ptr<Aya::Instance> instance);
|
||||
};
|
||||
|
||||
} // namespace Aya
|
||||
Reference in New Issue
Block a user