Split App::AutoTransaction into its own file

This commit is contained in:
Zheng, Lei
2019-09-04 20:31:34 +08:00
committed by wmayer
parent 4141242e9d
commit fd0f4f5654
12 changed files with 265 additions and 193 deletions

View File

@@ -849,145 +849,6 @@ void Application::setActiveDocument(const char *Name)
}
}
AutoTransaction::AutoTransaction(const char *name, bool tmpName) {
auto &app = GetApplication();
if(name && app._activeTransactionGuard>=0) {
if(!app.getActiveTransaction()
|| (!tmpName && app._activeTransactionTmpName))
{
FC_LOG("auto transaction '" << name << "', " << tmpName);
tid = app.setActiveTransaction(name);
app._activeTransactionTmpName = tmpName;
}
}
// We use negative transaction guard to disable auto transaction from here
// and any stack below. This is to support user setting active transaction
// before having any existing AutoTransaction on stack, or 'persist'
// transaction that can out live AutoTransaction.
if(app._activeTransactionGuard<0)
--app._activeTransactionGuard;
else if(tid || app._activeTransactionGuard>0)
++app._activeTransactionGuard;
else if(app.getActiveTransaction()) {
FC_LOG("auto transaction disabled because of '" << app._activeTransactionName << "'");
--app._activeTransactionGuard;
} else
++app._activeTransactionGuard;
FC_TRACE("construct auto Transaction " << app._activeTransactionGuard);
}
AutoTransaction::~AutoTransaction() {
auto &app = GetApplication();
FC_TRACE("before destruct auto Transaction " << app._activeTransactionGuard);
if(app._activeTransactionGuard<0)
++app._activeTransactionGuard;
else if(!app._activeTransactionGuard) {
#ifdef FC_DEBUG
FC_ERR("Transaction guard error");
#endif
} else if(--app._activeTransactionGuard == 0) {
try {
// We don't call close() here, because close() only closes
// transaction that we opened during construction time. However,
// when _activeTransactionGuard reaches zero here, we are supposed
// to close any transaction opened.
app.closeActiveTransaction();
} catch(Base::Exception &e) {
e.ReportException();
} catch(...)
{}
}
FC_TRACE("destruct auto Transaction " << app._activeTransactionGuard);
}
void AutoTransaction::close(bool abort) {
if(tid || abort) {
GetApplication().closeActiveTransaction(abort,abort?0:tid);
tid = 0;
}
}
void AutoTransaction::setEnable(bool enable) {
auto &app = GetApplication();
if(!app._activeTransactionGuard)
return;
if((enable && app._activeTransactionGuard>0)
|| (!enable && app._activeTransactionGuard<0))
return;
app._activeTransactionGuard = -app._activeTransactionGuard;
FC_TRACE("toggle auto Transaction " << app._activeTransactionGuard);
if(!enable && app._activeTransactionTmpName) {
bool close = true;
for(auto &v : app.DocMap) {
if(v.second->hasPendingTransaction()) {
close = false;
break;
}
}
if(close)
app.closeActiveTransaction();
}
}
int Application::setActiveTransaction(const char *name, bool persist) {
if(!name || !name[0])
name = "Command";
if(_activeTransactionGuard>0 && getActiveTransaction()) {
if(_activeTransactionTmpName) {
FC_LOG("transaction rename to '" << name << "'");
for(auto &v : DocMap)
v.second->renameTransaction(name,_activeTransactionID);
} else {
if(persist)
AutoTransaction::setEnable(false);
return 0;
}
}else{
FC_LOG("set active transaction '" << name << "'");
_activeTransactionID = 0;
for(auto &v : DocMap)
v.second->_commitTransaction();
_activeTransactionID = Transaction::getNewID();
}
_activeTransactionTmpName = false;
_activeTransactionName = name;
if(persist)
AutoTransaction::setEnable(false);
return _activeTransactionID;
}
const char *Application::getActiveTransaction(int *id) const {
int tid = 0;
if(Transaction::getLastID() == _activeTransactionID)
tid = _activeTransactionID;
if(id) *id = tid;
return tid?_activeTransactionName.c_str():0;
}
void Application::closeActiveTransaction(bool abort, int id) {
if(!id) id = _activeTransactionID;
if(!id) return;
if(_activeTransactionGuard>0 && !abort) {
FC_LOG("ignore close transaction");
return;
}
FC_LOG("close transaction '" << _activeTransactionName << "' " << abort);
_activeTransactionID = 0;
TransactionSignaller siganller(abort,false);
for(auto &v : DocMap) {
if(v.second->getTransactionID(true) != id)
continue;
if(abort)
v.second->_abortTransaction();
else
v.second->_commitTransaction();
}
}
static int _TransSignalCount;
static bool _TransSignalled;
Application::TransactionSignaller::TransactionSignaller(bool abort, bool signal)