my own uncrustify run
This commit is contained in:
890
radiant/undo.cpp
890
radiant/undo.cpp
@@ -1,23 +1,23 @@
|
||||
/*
|
||||
Copyright (C) 2001-2006, William Joseph.
|
||||
All Rights Reserved.
|
||||
Copyright (C) 2001-2006, William Joseph.
|
||||
All Rights Reserved.
|
||||
|
||||
This file is part of GtkRadiant.
|
||||
This file is part of GtkRadiant.
|
||||
|
||||
GtkRadiant 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 2 of the License, or
|
||||
(at your option) any later version.
|
||||
GtkRadiant 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 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
GtkRadiant 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.
|
||||
GtkRadiant 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 GtkRadiant; if not, write to the Free Software
|
||||
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*/
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with GtkRadiant; if not, write to the Free Software
|
||||
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*/
|
||||
|
||||
#include "undo.h"
|
||||
|
||||
@@ -39,444 +39,374 @@ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
|
||||
class DebugScopeTimer
|
||||
{
|
||||
Timer m_timer;
|
||||
const char* m_operation;
|
||||
Timer m_timer;
|
||||
const char* m_operation;
|
||||
public:
|
||||
DebugScopeTimer(const char* operation)
|
||||
: m_operation(operation)
|
||||
{
|
||||
m_timer.start();
|
||||
}
|
||||
~DebugScopeTimer()
|
||||
{
|
||||
unsigned int elapsed = m_timer.elapsed_msec();
|
||||
if(elapsed > 0)
|
||||
{
|
||||
globalOutputStream() << m_operation << ": " << elapsed << " msec\n";
|
||||
}
|
||||
}
|
||||
DebugScopeTimer( const char* operation )
|
||||
: m_operation( operation ){
|
||||
m_timer.start();
|
||||
}
|
||||
~DebugScopeTimer(){
|
||||
unsigned int elapsed = m_timer.elapsed_msec();
|
||||
if ( elapsed > 0 ) {
|
||||
globalOutputStream() << m_operation << ": " << elapsed << " msec\n";
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
class RadiantUndoSystem : public UndoSystem
|
||||
{
|
||||
INTEGER_CONSTANT(MAX_UNDO_LEVELS, 1024);
|
||||
INTEGER_CONSTANT( MAX_UNDO_LEVELS, 1024 );
|
||||
|
||||
class Snapshot
|
||||
{
|
||||
class StateApplicator
|
||||
{
|
||||
public:
|
||||
Undoable* m_undoable;
|
||||
private:
|
||||
UndoMemento* m_data;
|
||||
public:
|
||||
|
||||
StateApplicator(Undoable* undoable, UndoMemento* data)
|
||||
: m_undoable(undoable), m_data(data)
|
||||
{
|
||||
}
|
||||
void restore()
|
||||
{
|
||||
m_undoable->importState(m_data);
|
||||
}
|
||||
void release()
|
||||
{
|
||||
m_data->release();
|
||||
}
|
||||
};
|
||||
|
||||
typedef std::list<StateApplicator> states_t;
|
||||
states_t m_states;
|
||||
|
||||
public:
|
||||
bool empty() const
|
||||
{
|
||||
return m_states.empty();
|
||||
}
|
||||
std::size_t size() const
|
||||
{
|
||||
return m_states.size();
|
||||
}
|
||||
void save(Undoable* undoable)
|
||||
{
|
||||
m_states.push_front(StateApplicator(undoable, undoable->exportState()));
|
||||
}
|
||||
void restore()
|
||||
{
|
||||
for(states_t::iterator i = m_states.begin(); i != m_states.end(); ++i)
|
||||
{
|
||||
(*i).restore();
|
||||
}
|
||||
}
|
||||
void release()
|
||||
{
|
||||
for(states_t::iterator i = m_states.begin(); i != m_states.end(); ++i)
|
||||
{
|
||||
(*i).release();
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
struct Operation
|
||||
{
|
||||
Snapshot m_snapshot;
|
||||
CopiedString m_command;
|
||||
|
||||
Operation(const char* command)
|
||||
: m_command(command)
|
||||
{
|
||||
}
|
||||
~Operation()
|
||||
{
|
||||
m_snapshot.release();
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
class UndoStack
|
||||
{
|
||||
//! Note: using std::list instead of vector/deque, to avoid copying of undos
|
||||
typedef std::list<Operation*> Operations;
|
||||
|
||||
Operations m_stack;
|
||||
Operation* m_pending;
|
||||
|
||||
public:
|
||||
UndoStack() : m_pending(0)
|
||||
{
|
||||
}
|
||||
~UndoStack()
|
||||
{
|
||||
clear();
|
||||
}
|
||||
bool empty() const
|
||||
{
|
||||
return m_stack.empty();
|
||||
}
|
||||
std::size_t size() const
|
||||
{
|
||||
return m_stack.size();
|
||||
}
|
||||
Operation* back()
|
||||
{
|
||||
return m_stack.back();
|
||||
}
|
||||
const Operation* back() const
|
||||
{
|
||||
return m_stack.back();
|
||||
}
|
||||
Operation* front()
|
||||
{
|
||||
return m_stack.front();
|
||||
}
|
||||
const Operation* front() const
|
||||
{
|
||||
return m_stack.front();
|
||||
}
|
||||
void pop_front()
|
||||
{
|
||||
delete m_stack.front();
|
||||
m_stack.pop_front();
|
||||
}
|
||||
void pop_back()
|
||||
{
|
||||
delete m_stack.back();
|
||||
m_stack.pop_back();
|
||||
}
|
||||
void clear()
|
||||
{
|
||||
if(!m_stack.empty())
|
||||
{
|
||||
for(Operations::iterator i = m_stack.begin(); i != m_stack.end(); ++i)
|
||||
{
|
||||
delete *i;
|
||||
}
|
||||
m_stack.clear();
|
||||
}
|
||||
}
|
||||
void start(const char* command)
|
||||
{
|
||||
if(m_pending != 0)
|
||||
{
|
||||
delete m_pending;
|
||||
}
|
||||
m_pending = new Operation(command);
|
||||
}
|
||||
bool finish(const char* command)
|
||||
{
|
||||
if(m_pending != 0)
|
||||
{
|
||||
delete m_pending;
|
||||
m_pending = 0;
|
||||
return false;
|
||||
}
|
||||
else
|
||||
{
|
||||
ASSERT_MESSAGE(!m_stack.empty(), "undo stack empty");
|
||||
m_stack.back()->m_command = command;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
void save(Undoable* undoable)
|
||||
{
|
||||
if(m_pending != 0)
|
||||
{
|
||||
m_stack.push_back(m_pending);
|
||||
m_pending = 0;
|
||||
}
|
||||
back()->m_snapshot.save(undoable);
|
||||
}
|
||||
};
|
||||
|
||||
UndoStack m_undo_stack;
|
||||
UndoStack m_redo_stack;
|
||||
|
||||
class UndoStackFiller : public UndoObserver
|
||||
{
|
||||
UndoStack* m_stack;
|
||||
public:
|
||||
|
||||
UndoStackFiller()
|
||||
: m_stack(0)
|
||||
{
|
||||
}
|
||||
void save(Undoable* undoable)
|
||||
{
|
||||
ASSERT_NOTNULL(undoable);
|
||||
|
||||
if(m_stack != 0)
|
||||
{
|
||||
m_stack->save(undoable);
|
||||
m_stack = 0;
|
||||
}
|
||||
}
|
||||
void setStack(UndoStack* stack)
|
||||
{
|
||||
m_stack = stack;
|
||||
}
|
||||
};
|
||||
|
||||
typedef std::map<Undoable*, UndoStackFiller> undoables_t;
|
||||
undoables_t m_undoables;
|
||||
|
||||
void mark_undoables(UndoStack* stack)
|
||||
{
|
||||
for(undoables_t::iterator i = m_undoables.begin(); i != m_undoables.end(); ++i)
|
||||
{
|
||||
(*i).second.setStack(stack);
|
||||
}
|
||||
}
|
||||
|
||||
std::size_t m_undo_levels;
|
||||
|
||||
typedef std::set<UndoTracker*> Trackers;
|
||||
Trackers m_trackers;
|
||||
class Snapshot
|
||||
{
|
||||
class StateApplicator
|
||||
{
|
||||
public:
|
||||
Undoable* m_undoable;
|
||||
private:
|
||||
UndoMemento* m_data;
|
||||
public:
|
||||
RadiantUndoSystem()
|
||||
: m_undo_levels(64)
|
||||
{
|
||||
}
|
||||
~RadiantUndoSystem()
|
||||
{
|
||||
clear();
|
||||
}
|
||||
UndoObserver* observer(Undoable* undoable)
|
||||
{
|
||||
ASSERT_NOTNULL(undoable);
|
||||
|
||||
return &m_undoables[undoable];
|
||||
}
|
||||
void release(Undoable* undoable)
|
||||
{
|
||||
ASSERT_NOTNULL(undoable);
|
||||
StateApplicator( Undoable* undoable, UndoMemento* data )
|
||||
: m_undoable( undoable ), m_data( data ){
|
||||
}
|
||||
void restore(){
|
||||
m_undoable->importState( m_data );
|
||||
}
|
||||
void release(){
|
||||
m_data->release();
|
||||
}
|
||||
};
|
||||
|
||||
m_undoables.erase(undoable);
|
||||
}
|
||||
void setLevels(std::size_t levels)
|
||||
{
|
||||
if(levels > MAX_UNDO_LEVELS())
|
||||
{
|
||||
levels = MAX_UNDO_LEVELS();
|
||||
}
|
||||
typedef std::list<StateApplicator> states_t;
|
||||
states_t m_states;
|
||||
|
||||
while(m_undo_stack.size() > levels)
|
||||
{
|
||||
m_undo_stack.pop_front();
|
||||
}
|
||||
m_undo_levels = levels;
|
||||
}
|
||||
std::size_t getLevels() const
|
||||
{
|
||||
return m_undo_levels;
|
||||
}
|
||||
std::size_t size() const
|
||||
{
|
||||
return m_undo_stack.size();
|
||||
}
|
||||
void startUndo()
|
||||
{
|
||||
m_undo_stack.start("unnamedCommand");
|
||||
mark_undoables(&m_undo_stack);
|
||||
}
|
||||
bool finishUndo(const char* command)
|
||||
{
|
||||
bool changed = m_undo_stack.finish(command);
|
||||
mark_undoables(0);
|
||||
return changed;
|
||||
}
|
||||
void startRedo()
|
||||
{
|
||||
m_redo_stack.start("unnamedCommand");
|
||||
mark_undoables(&m_redo_stack);
|
||||
}
|
||||
bool finishRedo(const char* command)
|
||||
{
|
||||
bool changed = m_redo_stack.finish(command);
|
||||
mark_undoables(0);
|
||||
return changed;
|
||||
}
|
||||
void start()
|
||||
{
|
||||
m_redo_stack.clear();
|
||||
if(m_undo_stack.size() == m_undo_levels)
|
||||
{
|
||||
m_undo_stack.pop_front();
|
||||
}
|
||||
startUndo();
|
||||
trackersBegin();
|
||||
}
|
||||
void finish(const char* command)
|
||||
{
|
||||
if(finishUndo(command))
|
||||
{
|
||||
globalOutputStream() << command << '\n';
|
||||
}
|
||||
}
|
||||
void undo()
|
||||
{
|
||||
if(m_undo_stack.empty())
|
||||
{
|
||||
globalOutputStream() << "Undo: no undo available\n";
|
||||
}
|
||||
else
|
||||
{
|
||||
Operation* operation = m_undo_stack.back();
|
||||
globalOutputStream() << "Undo: " << operation->m_command.c_str() << "\n";
|
||||
public:
|
||||
bool empty() const {
|
||||
return m_states.empty();
|
||||
}
|
||||
std::size_t size() const {
|
||||
return m_states.size();
|
||||
}
|
||||
void save( Undoable* undoable ){
|
||||
m_states.push_front( StateApplicator( undoable, undoable->exportState() ) );
|
||||
}
|
||||
void restore(){
|
||||
for ( states_t::iterator i = m_states.begin(); i != m_states.end(); ++i )
|
||||
{
|
||||
( *i ).restore();
|
||||
}
|
||||
}
|
||||
void release(){
|
||||
for ( states_t::iterator i = m_states.begin(); i != m_states.end(); ++i )
|
||||
{
|
||||
( *i ).release();
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
startRedo();
|
||||
trackersUndo();
|
||||
operation->m_snapshot.restore();
|
||||
finishRedo(operation->m_command.c_str());
|
||||
m_undo_stack.pop_back();
|
||||
}
|
||||
}
|
||||
void redo()
|
||||
{
|
||||
if(m_redo_stack.empty())
|
||||
{
|
||||
globalOutputStream() << "Redo: no redo available\n";
|
||||
}
|
||||
else
|
||||
{
|
||||
Operation* operation = m_redo_stack.back();
|
||||
globalOutputStream() << "Redo: " << operation->m_command.c_str() << "\n";
|
||||
struct Operation
|
||||
{
|
||||
Snapshot m_snapshot;
|
||||
CopiedString m_command;
|
||||
|
||||
startUndo();
|
||||
trackersRedo();
|
||||
operation->m_snapshot.restore();
|
||||
finishUndo(operation->m_command.c_str());
|
||||
m_redo_stack.pop_back();
|
||||
}
|
||||
}
|
||||
void clear()
|
||||
{
|
||||
mark_undoables(0);
|
||||
m_undo_stack.clear();
|
||||
m_redo_stack.clear();
|
||||
trackersClear();
|
||||
}
|
||||
void trackerAttach(UndoTracker& tracker)
|
||||
{
|
||||
ASSERT_MESSAGE(m_trackers.find(&tracker) == m_trackers.end(), "undo tracker already attached");
|
||||
m_trackers.insert(&tracker);
|
||||
}
|
||||
void trackerDetach(UndoTracker& tracker)
|
||||
{
|
||||
ASSERT_MESSAGE(m_trackers.find(&tracker) != m_trackers.end(), "undo tracker cannot be detached");
|
||||
m_trackers.erase(&tracker);
|
||||
}
|
||||
void trackersClear() const
|
||||
{
|
||||
for(Trackers::const_iterator i = m_trackers.begin(); i != m_trackers.end(); ++i)
|
||||
{
|
||||
(*i)->clear();
|
||||
}
|
||||
}
|
||||
void trackersBegin() const
|
||||
{
|
||||
for(Trackers::const_iterator i = m_trackers.begin(); i != m_trackers.end(); ++i)
|
||||
{
|
||||
(*i)->begin();
|
||||
}
|
||||
}
|
||||
void trackersUndo() const
|
||||
{
|
||||
for(Trackers::const_iterator i = m_trackers.begin(); i != m_trackers.end(); ++i)
|
||||
{
|
||||
(*i)->undo();
|
||||
}
|
||||
}
|
||||
void trackersRedo() const
|
||||
{
|
||||
for(Trackers::const_iterator i = m_trackers.begin(); i != m_trackers.end(); ++i)
|
||||
{
|
||||
(*i)->redo();
|
||||
}
|
||||
}
|
||||
Operation( const char* command )
|
||||
: m_command( command ){
|
||||
}
|
||||
~Operation(){
|
||||
m_snapshot.release();
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
class UndoStack
|
||||
{
|
||||
//! Note: using std::list instead of vector/deque, to avoid copying of undos
|
||||
typedef std::list<Operation*> Operations;
|
||||
|
||||
Operations m_stack;
|
||||
Operation* m_pending;
|
||||
|
||||
public:
|
||||
UndoStack() : m_pending( 0 ){
|
||||
}
|
||||
~UndoStack(){
|
||||
clear();
|
||||
}
|
||||
bool empty() const {
|
||||
return m_stack.empty();
|
||||
}
|
||||
std::size_t size() const {
|
||||
return m_stack.size();
|
||||
}
|
||||
Operation* back(){
|
||||
return m_stack.back();
|
||||
}
|
||||
const Operation* back() const {
|
||||
return m_stack.back();
|
||||
}
|
||||
Operation* front(){
|
||||
return m_stack.front();
|
||||
}
|
||||
const Operation* front() const {
|
||||
return m_stack.front();
|
||||
}
|
||||
void pop_front(){
|
||||
delete m_stack.front();
|
||||
m_stack.pop_front();
|
||||
}
|
||||
void pop_back(){
|
||||
delete m_stack.back();
|
||||
m_stack.pop_back();
|
||||
}
|
||||
void clear(){
|
||||
if ( !m_stack.empty() ) {
|
||||
for ( Operations::iterator i = m_stack.begin(); i != m_stack.end(); ++i )
|
||||
{
|
||||
delete *i;
|
||||
}
|
||||
m_stack.clear();
|
||||
}
|
||||
}
|
||||
void start( const char* command ){
|
||||
if ( m_pending != 0 ) {
|
||||
delete m_pending;
|
||||
}
|
||||
m_pending = new Operation( command );
|
||||
}
|
||||
bool finish( const char* command ){
|
||||
if ( m_pending != 0 ) {
|
||||
delete m_pending;
|
||||
m_pending = 0;
|
||||
return false;
|
||||
}
|
||||
else
|
||||
{
|
||||
ASSERT_MESSAGE( !m_stack.empty(), "undo stack empty" );
|
||||
m_stack.back()->m_command = command;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
void save( Undoable* undoable ){
|
||||
if ( m_pending != 0 ) {
|
||||
m_stack.push_back( m_pending );
|
||||
m_pending = 0;
|
||||
}
|
||||
back()->m_snapshot.save( undoable );
|
||||
}
|
||||
};
|
||||
|
||||
UndoStack m_undo_stack;
|
||||
UndoStack m_redo_stack;
|
||||
|
||||
class UndoStackFiller : public UndoObserver
|
||||
{
|
||||
UndoStack* m_stack;
|
||||
public:
|
||||
|
||||
UndoStackFiller()
|
||||
: m_stack( 0 ){
|
||||
}
|
||||
void save( Undoable* undoable ){
|
||||
ASSERT_NOTNULL( undoable );
|
||||
|
||||
if ( m_stack != 0 ) {
|
||||
m_stack->save( undoable );
|
||||
m_stack = 0;
|
||||
}
|
||||
}
|
||||
void setStack( UndoStack* stack ){
|
||||
m_stack = stack;
|
||||
}
|
||||
};
|
||||
|
||||
typedef std::map<Undoable*, UndoStackFiller> undoables_t;
|
||||
undoables_t m_undoables;
|
||||
|
||||
void mark_undoables( UndoStack* stack ){
|
||||
for ( undoables_t::iterator i = m_undoables.begin(); i != m_undoables.end(); ++i )
|
||||
{
|
||||
( *i ).second.setStack( stack );
|
||||
}
|
||||
}
|
||||
|
||||
std::size_t m_undo_levels;
|
||||
|
||||
typedef std::set<UndoTracker*> Trackers;
|
||||
Trackers m_trackers;
|
||||
public:
|
||||
RadiantUndoSystem()
|
||||
: m_undo_levels( 64 ){
|
||||
}
|
||||
~RadiantUndoSystem(){
|
||||
clear();
|
||||
}
|
||||
UndoObserver* observer( Undoable* undoable ){
|
||||
ASSERT_NOTNULL( undoable );
|
||||
|
||||
return &m_undoables[undoable];
|
||||
}
|
||||
void release( Undoable* undoable ){
|
||||
ASSERT_NOTNULL( undoable );
|
||||
|
||||
m_undoables.erase( undoable );
|
||||
}
|
||||
void setLevels( std::size_t levels ){
|
||||
if ( levels > MAX_UNDO_LEVELS() ) {
|
||||
levels = MAX_UNDO_LEVELS();
|
||||
}
|
||||
|
||||
while ( m_undo_stack.size() > levels )
|
||||
{
|
||||
m_undo_stack.pop_front();
|
||||
}
|
||||
m_undo_levels = levels;
|
||||
}
|
||||
std::size_t getLevels() const {
|
||||
return m_undo_levels;
|
||||
}
|
||||
std::size_t size() const {
|
||||
return m_undo_stack.size();
|
||||
}
|
||||
void startUndo(){
|
||||
m_undo_stack.start( "unnamedCommand" );
|
||||
mark_undoables( &m_undo_stack );
|
||||
}
|
||||
bool finishUndo( const char* command ){
|
||||
bool changed = m_undo_stack.finish( command );
|
||||
mark_undoables( 0 );
|
||||
return changed;
|
||||
}
|
||||
void startRedo(){
|
||||
m_redo_stack.start( "unnamedCommand" );
|
||||
mark_undoables( &m_redo_stack );
|
||||
}
|
||||
bool finishRedo( const char* command ){
|
||||
bool changed = m_redo_stack.finish( command );
|
||||
mark_undoables( 0 );
|
||||
return changed;
|
||||
}
|
||||
void start(){
|
||||
m_redo_stack.clear();
|
||||
if ( m_undo_stack.size() == m_undo_levels ) {
|
||||
m_undo_stack.pop_front();
|
||||
}
|
||||
startUndo();
|
||||
trackersBegin();
|
||||
}
|
||||
void finish( const char* command ){
|
||||
if ( finishUndo( command ) ) {
|
||||
globalOutputStream() << command << '\n';
|
||||
}
|
||||
}
|
||||
void undo(){
|
||||
if ( m_undo_stack.empty() ) {
|
||||
globalOutputStream() << "Undo: no undo available\n";
|
||||
}
|
||||
else
|
||||
{
|
||||
Operation* operation = m_undo_stack.back();
|
||||
globalOutputStream() << "Undo: " << operation->m_command.c_str() << "\n";
|
||||
|
||||
startRedo();
|
||||
trackersUndo();
|
||||
operation->m_snapshot.restore();
|
||||
finishRedo( operation->m_command.c_str() );
|
||||
m_undo_stack.pop_back();
|
||||
}
|
||||
}
|
||||
void redo(){
|
||||
if ( m_redo_stack.empty() ) {
|
||||
globalOutputStream() << "Redo: no redo available\n";
|
||||
}
|
||||
else
|
||||
{
|
||||
Operation* operation = m_redo_stack.back();
|
||||
globalOutputStream() << "Redo: " << operation->m_command.c_str() << "\n";
|
||||
|
||||
startUndo();
|
||||
trackersRedo();
|
||||
operation->m_snapshot.restore();
|
||||
finishUndo( operation->m_command.c_str() );
|
||||
m_redo_stack.pop_back();
|
||||
}
|
||||
}
|
||||
void clear(){
|
||||
mark_undoables( 0 );
|
||||
m_undo_stack.clear();
|
||||
m_redo_stack.clear();
|
||||
trackersClear();
|
||||
}
|
||||
void trackerAttach( UndoTracker& tracker ){
|
||||
ASSERT_MESSAGE( m_trackers.find( &tracker ) == m_trackers.end(), "undo tracker already attached" );
|
||||
m_trackers.insert( &tracker );
|
||||
}
|
||||
void trackerDetach( UndoTracker& tracker ){
|
||||
ASSERT_MESSAGE( m_trackers.find( &tracker ) != m_trackers.end(), "undo tracker cannot be detached" );
|
||||
m_trackers.erase( &tracker );
|
||||
}
|
||||
void trackersClear() const {
|
||||
for ( Trackers::const_iterator i = m_trackers.begin(); i != m_trackers.end(); ++i )
|
||||
{
|
||||
( *i )->clear();
|
||||
}
|
||||
}
|
||||
void trackersBegin() const {
|
||||
for ( Trackers::const_iterator i = m_trackers.begin(); i != m_trackers.end(); ++i )
|
||||
{
|
||||
( *i )->begin();
|
||||
}
|
||||
}
|
||||
void trackersUndo() const {
|
||||
for ( Trackers::const_iterator i = m_trackers.begin(); i != m_trackers.end(); ++i )
|
||||
{
|
||||
( *i )->undo();
|
||||
}
|
||||
}
|
||||
void trackersRedo() const {
|
||||
for ( Trackers::const_iterator i = m_trackers.begin(); i != m_trackers.end(); ++i )
|
||||
{
|
||||
( *i )->redo();
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
|
||||
void UndoLevels_importString(RadiantUndoSystem& undo, const char* value)
|
||||
{
|
||||
int levels;
|
||||
Int_importString(levels, value);
|
||||
undo.setLevels(levels);
|
||||
void UndoLevels_importString( RadiantUndoSystem& undo, const char* value ){
|
||||
int levels;
|
||||
Int_importString( levels, value );
|
||||
undo.setLevels( levels );
|
||||
}
|
||||
typedef ReferenceCaller1<RadiantUndoSystem, const char*, UndoLevels_importString> UndoLevelsImportStringCaller;
|
||||
void UndoLevels_exportString(const RadiantUndoSystem& undo, const StringImportCallback& importer)
|
||||
{
|
||||
Int_exportString(static_cast<int>(undo.getLevels()), importer);
|
||||
void UndoLevels_exportString( const RadiantUndoSystem& undo, const StringImportCallback& importer ){
|
||||
Int_exportString( static_cast<int>( undo.getLevels() ), importer );
|
||||
}
|
||||
typedef ConstReferenceCaller1<RadiantUndoSystem, const StringImportCallback&, UndoLevels_exportString> UndoLevelsExportStringCaller;
|
||||
|
||||
#include "generic/callback.h"
|
||||
|
||||
void UndoLevelsImport(RadiantUndoSystem& self, int value)
|
||||
{
|
||||
self.setLevels(value);
|
||||
void UndoLevelsImport( RadiantUndoSystem& self, int value ){
|
||||
self.setLevels( value );
|
||||
}
|
||||
typedef ReferenceCaller1<RadiantUndoSystem, int, UndoLevelsImport> UndoLevelsImportCaller;
|
||||
void UndoLevelsExport(const RadiantUndoSystem& self, const IntImportCallback& importCallback)
|
||||
{
|
||||
importCallback(static_cast<int>(self.getLevels()));
|
||||
void UndoLevelsExport( const RadiantUndoSystem& self, const IntImportCallback& importCallback ){
|
||||
importCallback( static_cast<int>( self.getLevels() ) );
|
||||
}
|
||||
typedef ConstReferenceCaller1<RadiantUndoSystem, const IntImportCallback&, UndoLevelsExport> UndoLevelsExportCaller;
|
||||
|
||||
|
||||
void Undo_constructPreferences(RadiantUndoSystem& undo, PreferencesPage& page)
|
||||
{
|
||||
page.appendSpinner("Undo Queue Size", 64, 0, 1024, IntImportCallback(UndoLevelsImportCaller(undo)), IntExportCallback(UndoLevelsExportCaller(undo)));
|
||||
void Undo_constructPreferences( RadiantUndoSystem& undo, PreferencesPage& page ){
|
||||
page.appendSpinner( "Undo Queue Size", 64, 0, 1024, IntImportCallback( UndoLevelsImportCaller( undo ) ), IntExportCallback( UndoLevelsExportCaller( undo ) ) );
|
||||
}
|
||||
void Undo_constructPage(RadiantUndoSystem& undo, PreferenceGroup& group)
|
||||
{
|
||||
PreferencesPage page(group.createPage("Undo", "Undo Queue Settings"));
|
||||
Undo_constructPreferences(undo, page);
|
||||
void Undo_constructPage( RadiantUndoSystem& undo, PreferenceGroup& group ){
|
||||
PreferencesPage page( group.createPage( "Undo", "Undo Queue Settings" ) );
|
||||
Undo_constructPreferences( undo, page );
|
||||
}
|
||||
void Undo_registerPreferencesPage(RadiantUndoSystem& undo)
|
||||
{
|
||||
PreferencesDialog_addSettingsPage(ReferenceCaller1<RadiantUndoSystem, PreferenceGroup&, Undo_constructPage>(undo));
|
||||
void Undo_registerPreferencesPage( RadiantUndoSystem& undo ){
|
||||
PreferencesDialog_addSettingsPage( ReferenceCaller1<RadiantUndoSystem, PreferenceGroup&, Undo_constructPage>( undo ) );
|
||||
}
|
||||
|
||||
class UndoSystemDependencies : public GlobalPreferenceSystemModuleRef
|
||||
@@ -485,21 +415,19 @@ class UndoSystemDependencies : public GlobalPreferenceSystemModuleRef
|
||||
|
||||
class UndoSystemAPI
|
||||
{
|
||||
RadiantUndoSystem m_undosystem;
|
||||
RadiantUndoSystem m_undosystem;
|
||||
public:
|
||||
typedef UndoSystem Type;
|
||||
STRING_CONSTANT(Name, "*");
|
||||
typedef UndoSystem Type;
|
||||
STRING_CONSTANT( Name, "*" );
|
||||
|
||||
UndoSystemAPI()
|
||||
{
|
||||
GlobalPreferenceSystem().registerPreference("UndoLevels", makeIntStringImportCallback(UndoLevelsImportCaller(m_undosystem)), makeIntStringExportCallback(UndoLevelsExportCaller(m_undosystem)));
|
||||
UndoSystemAPI(){
|
||||
GlobalPreferenceSystem().registerPreference( "UndoLevels", makeIntStringImportCallback( UndoLevelsImportCaller( m_undosystem ) ), makeIntStringExportCallback( UndoLevelsExportCaller( m_undosystem ) ) );
|
||||
|
||||
Undo_registerPreferencesPage(m_undosystem);
|
||||
}
|
||||
UndoSystem* getTable()
|
||||
{
|
||||
return &m_undosystem;
|
||||
}
|
||||
Undo_registerPreferencesPage( m_undosystem );
|
||||
}
|
||||
UndoSystem* getTable(){
|
||||
return &m_undosystem;
|
||||
}
|
||||
};
|
||||
|
||||
#include "modulesystem/singletonmodule.h"
|
||||
@@ -507,7 +435,7 @@ public:
|
||||
|
||||
typedef SingletonModule<UndoSystemAPI, UndoSystemDependencies> UndoSystemModule;
|
||||
typedef Static<UndoSystemModule> StaticUndoSystemModule;
|
||||
StaticRegisterModule staticRegisterUndoSystem(StaticUndoSystemModule::instance());
|
||||
StaticRegisterModule staticRegisterUndoSystem( StaticUndoSystemModule::instance() );
|
||||
|
||||
|
||||
|
||||
@@ -520,49 +448,41 @@ StaticRegisterModule staticRegisterUndoSystem(StaticUndoSystemModule::instance()
|
||||
|
||||
class undoable_test : public Undoable
|
||||
{
|
||||
struct state_type : public UndoMemento
|
||||
{
|
||||
state_type() : test_data(0)
|
||||
{
|
||||
}
|
||||
state_type(const state_type& other) : UndoMemento(other), test_data(other.test_data)
|
||||
{
|
||||
}
|
||||
void release()
|
||||
{
|
||||
delete this;
|
||||
}
|
||||
struct state_type : public UndoMemento
|
||||
{
|
||||
state_type() : test_data( 0 ){
|
||||
}
|
||||
state_type( const state_type& other ) : UndoMemento( other ), test_data( other.test_data ){
|
||||
}
|
||||
void release(){
|
||||
delete this;
|
||||
}
|
||||
|
||||
int test_data;
|
||||
};
|
||||
state_type m_state;
|
||||
UndoObserver* m_observer;
|
||||
int test_data;
|
||||
};
|
||||
state_type m_state;
|
||||
UndoObserver* m_observer;
|
||||
public:
|
||||
undoable_test()
|
||||
: m_observer(GlobalUndoSystem().observer(this))
|
||||
{
|
||||
}
|
||||
~undoable_test()
|
||||
{
|
||||
GlobalUndoSystem().release(this);
|
||||
}
|
||||
UndoMemento* exportState() const
|
||||
{
|
||||
return new state_type(m_state);
|
||||
}
|
||||
void importState(const UndoMemento* state)
|
||||
{
|
||||
ASSERT_NOTNULL(state);
|
||||
undoable_test()
|
||||
: m_observer( GlobalUndoSystem().observer( this ) ){
|
||||
}
|
||||
~undoable_test(){
|
||||
GlobalUndoSystem().release( this );
|
||||
}
|
||||
UndoMemento* exportState() const {
|
||||
return new state_type( m_state );
|
||||
}
|
||||
void importState( const UndoMemento* state ){
|
||||
ASSERT_NOTNULL( state );
|
||||
|
||||
m_observer->save(this);
|
||||
m_state = *(static_cast<const state_type*>(state));
|
||||
}
|
||||
m_observer->save( this );
|
||||
m_state = *( static_cast<const state_type*>( state ) );
|
||||
}
|
||||
|
||||
void mutate(unsigned int data)
|
||||
{
|
||||
m_observer->save(this);
|
||||
m_state.test_data = data;
|
||||
}
|
||||
void mutate( unsigned int data ){
|
||||
m_observer->save( this );
|
||||
m_state.test_data = data;
|
||||
}
|
||||
};
|
||||
|
||||
#if 0
|
||||
@@ -570,21 +490,19 @@ public:
|
||||
class TestUndo
|
||||
{
|
||||
public:
|
||||
TestUndo()
|
||||
{
|
||||
undoable_test test;
|
||||
GlobalUndoSystem().begin("bleh");
|
||||
test.mutate(3);
|
||||
GlobalUndoSystem().begin("blah");
|
||||
test.mutate(4);
|
||||
GlobalUndoSystem().undo();
|
||||
GlobalUndoSystem().undo();
|
||||
GlobalUndoSystem().redo();
|
||||
GlobalUndoSystem().redo();
|
||||
}
|
||||
TestUndo(){
|
||||
undoable_test test;
|
||||
GlobalUndoSystem().begin( "bleh" );
|
||||
test.mutate( 3 );
|
||||
GlobalUndoSystem().begin( "blah" );
|
||||
test.mutate( 4 );
|
||||
GlobalUndoSystem().undo();
|
||||
GlobalUndoSystem().undo();
|
||||
GlobalUndoSystem().redo();
|
||||
GlobalUndoSystem().redo();
|
||||
}
|
||||
};
|
||||
|
||||
TestUndo g_TestUndo;
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
Reference in New Issue
Block a user