示例#1
0
/// Performs an document-change undo.
void TextUndoStack::undoDocumentChange()
{
    // first make sure ALL controller-changes are back to the document change-level
    QMap<TextEditorController*, int>::iterator itr;
    for( itr = controllerIndexMap_.begin(); itr != controllerIndexMap_.end(); ++itr) {
        TextEditorController* controller = itr.key();
        while( undoControllerChange(controller) ) {};  // undo all controller operations
    }

    // next perform an undo of the document operations
    Change* change = findUndoChange();
    if( change ) {
        Q_ASSERT( change->controllerContext() == 0 );
        change->revert( documentRef_ );

        // next move the pointers to first 'related' change
        for( itr = controllerIndexMap_.begin(); itr != controllerIndexMap_.end(); ++itr) {
            TextEditorController* controller = itr.key();
            controllerIndexMap_[controller] = findUndoIndex( changeIndex_-1, controller ) + 1; // +1 because the pointer points AFTER the found index
        }

        // and finally move the document pointer
        setChangeIndex( findUndoIndex( changeIndex_-1 ) + 1 );  // +1 because the pointer points AFTER the found index
        emit undoExecuted( change);
    }

}
示例#2
0
int main()
{
    cout << "\n";
    
    Create create;
    Change change;
    
    create.fillPointerBuffer();

    cout << "main()---------------------------------" << endl;
    //cout << "create.num:     " << create.num << endl;
    cout << "create.bufferPtr:  " << create.bufferPtr << endl;
    cout << "change.process(create.bufferPtr, create.size)" << endl;
    cout << "---------------------------------------" << endl;
    cout << "\n";
    
    change.process(create.bufferPtr, create.size);
    
    cout << "\n";
    cout << "main()---------------------------------" << endl;
    cout << "create.bufferPtr:  " << create.bufferPtr << endl;
    cout << "create.size: " << create.size << endl;
    cout << "---------------------------------------" << endl;
    cout << "\n";
    cout << "----------SUMMARY-------------" << endl;
    cout << "create.bufferPtr: " << create.bufferPtr << endl;
    cout << "create.size: " << create.size << endl;
    for (int i=0; i<create.size; i++) {
        cout << "create.bufferPtr[" << i << "]: " << create.bufferPtr[i] << endl;
    }
    cout << "------------------------------" << endl;
    cout << "\n";
    
    return 0;
}
void WiredTigerRecoveryUnit::_abort() {
    try {
        bool notifyDone = !_prepareTimestamp.isNull();
        if (_session && _isActive()) {
            _txnClose(false);
        }
        _setState(State::kAborting);

        if (MONGO_FAIL_POINT(WTAlwaysNotifyPrepareConflictWaiters)) {
            notifyDone = true;
        }

        if (notifyDone) {
            _sessionCache->notifyPreparedUnitOfWorkHasCommittedOrAborted();
        }

        for (Changes::const_reverse_iterator it = _changes.rbegin(), end = _changes.rend();
             it != end;
             ++it) {
            Change* change = it->get();
            LOG(2) << "CUSTOM ROLLBACK " << redact(demangleName(typeid(*change)));
            change->rollback();
        }
        _changes.clear();
    } catch (...) {
        std::terminate();
    }

    _setState(State::kInactive);
}
示例#4
0
void Reduce::on_pushButton_clicked()
{
    Change *win = new Change() ;
    win->show();
    win->setWindowTitle("bazgasht");
    win->resize(700,600);
    close();
}
示例#5
0
 void pass_mock_by_ref()
 {
     Mock<Change> mock;
     Change* change = &mock.get();
     When(Method(mock, change)).AlwaysReturn();
     change->change(1, 2, 3);
     assertChanged(mock, 1, 2, 3);
 }
示例#6
0
void KConfigPropagator::commit()
{
  updateChanges();

  Change *c;
  for( c = mChanges.first(); c; c = mChanges.next() ) {
    c->apply();
  }
}
示例#7
0
文件: move.cpp 项目: gitesei/faunus
 void Movebase::move(Change &change) {
     timer.start();
     timer_move.start();
     cnt++;
     change.clear();
     _move(change);
     if (change.empty())
         timer.stop();
     timer_move.stop();
 }
示例#8
0
/// This method finds the index of the given stackitem from the given index
/// @param  index the previous index
/// @param controller the controller context
/// @return the previous index -1, if there's no previous index
int TextUndoStack::findUndoIndex( int index, TextEditorController* controller)
{
    if( index > 0 ) {
        for( --index; index >= 0; --index ) {
            Change* change = at(index);
            TextEditorController* context = change->controllerContext();
            if( context == 0 || context == controller ) { return index; }
        }
    }
    return -1;
}
示例#9
0
/// This method finds the next redo-item
/// @param index the index to search it from
/// @param controller the controller context
/// @return the next change index. Or changeList_.size() if there's no next change
int TextUndoStack::findRedoIndex(int index, TextEditorController* controller)
{
    if( index < changeList_.size() ) {
        int size = changeList_.size();
        for( ; index < size; ++index ) {
            Change* change = at(index);
            TextEditorController* context = change->controllerContext();
            if( context == 0 || context == controller ) { return index; }
        }
    }
    return changeList_.size();
}
示例#10
0
/// This method undos the given controller change. This method does NOT undo document changes
/// @param controller the controller to undo the change form
/// @return true if a change has been undone.
bool TextUndoStack::undoControllerChange(TextEditorController* controller)
{
    Q_ASSERT(controller);
    int changeIdx = controllerIndexMap_.value(controller)-1;    // -1, because the index is directly AFTER the item
    Change* changeToUndo = findUndoChange( controller );

    if( changeToUndo && changeToUndo->controllerContext() ) {
        Q_ASSERT( changeToUndo->controllerContext() == controller );
        changeToUndo->revert( documentRef_ );
        controllerIndexMap_[controller] = findUndoIndex( changeIdx, controller )+1;
        emit undoExecuted( changeToUndo );
        return true;
    }
    return false;
}
示例#11
0
/// undo's the given controller change
bool TextUndoStack::redoControllerChange(TextEditorController *controller)
{
    Q_ASSERT(controller);
    int changeIdx = findRedoIndex( currentIndex(controller), controller);
    Change* changeToRedo = findRedoChange( controller );
    if( changeToRedo && changeToRedo->controllerContext() ) {
        Q_ASSERT( changeToRedo->controllerContext() == controller );
        changeToRedo->execute( documentRef_ );

        // move the pointer to the next
        controllerIndexMap_[controller] = changeIdx+1;
        emit redoExecuted( changeToRedo );
    }
    return false;
}
		//calculate the heuristic value of a pile of change
		inline int ChangeHeuristic( const Change& change, const int* heuristic ) const 
		{
			int score = 0;
			for (const Coin *c=&COINLIST[0];c!=&COINLIST[COIN_COUNT];++c){
				score += *heuristic++ * change.GetCount(*c);
			}
			return score;
		}
示例#13
0
/// performs the redo operation for the given controller
/// @param controller the controller to execute the redo for
/// @param controllerOnly undo controller undo's only?
void TextUndoStack::redo(TextEditorController* controller, bool controllerOnly )
{
    Q_ASSERT(!redoRunning_);
    redoRunning_ = true;
    resetAllLastCoalesceIds();

    Change* changeToRedo = findRedoChange( controller );
    if( changeToRedo && changeToRedo->controllerContext() ) {
        Q_ASSERT(changeToRedo->controllerContext() == controller );
        redoControllerChange( controller );

    } else if( !controllerOnly ){
        redoDocumentChange();

    }
    dumpStackInternal();
    redoRunning_ = false;
}
示例#14
0
/// performs an undo operation
/// @param controller this method is called
void TextUndoStack::undo(TextEditorController* controller, bool controllerOnly )
{
    Q_ASSERT(!undoRunning_);
    undoRunning_ = true;
    resetAllLastCoalesceIds();

    Change* changeToUndo = this->findUndoChange( controller );
    // only for the current controller
    if( changeToUndo && changeToUndo->controllerContext() ) {
        Q_ASSERT(changeToUndo->controllerContext() == controller );
        undoControllerChange( controller );

    // else we need to undo ALL other controller changes
    } else if( !controllerOnly ) {
        undoDocumentChange( );
    }
    dumpStackInternal();

    undoRunning_ = false;
}
示例#15
0
  bool
  operator== (const Change& x, const Change& y)
  {
    if (!(x.effects () == y.effects ()))
      return false;

    if (!(x.script () == y.script ()))
      return false;

    if (!(x.extension () == y.extension ()))
      return false;

    if (!(x.type () == y.type ()))
      return false;

    if (!(x.object () == y.object ()))
      return false;

    return true;
  }
void TerarkDbRecoveryUnit::_abort() {
    try {
        if (_active) {
            _txnClose(false);
        }

        for (Changes::const_reverse_iterator it = _changes.rbegin(), end = _changes.rend();
             it != end;
             ++it) {
            Change* change = *it;
            LOG(2) << "CUSTOM ROLLBACK " << demangleName(typeid(*change));
            change->rollback();
        }
        _changes.clear();

        invariant(!_active);
    } catch (...) {
        std::terminate();
    }
}
示例#17
0
IChange* Changes::Item(LONG Index)
{
	AFX_MANAGE_STATE(AfxGetAppModuleState());

	if (m_pDocument == NULL)
	{
		AfxThrowOleDispatchException(1100, L"The object has been deleted.");
	}

	if (Index <= 0 || Index > GetCount())
		AfxThrowOleDispatchException(1103, L"Index out of range.");

	if (m_vChanges[Index-1] == NULL)
	{
		Change* pChange = new Change(m_pDocument, Index-1);
		pChange->InternalAddRef();
		m_vChanges[Index - 1] = pChange;
	}

	return m_vChanges[Index-1]->GetComObject();
}
示例#18
0
/// returns true if the undo-stack is on a persisted index
bool TextUndoStack::isPersisted()
{
    int curIdx = currentIndex();
    if( persistedIndex_ == curIdx ) { return true; }
    if( persistedIndex_ < 0 ) { return false;}

    // check if all changes are non-persistable
    int startIdx = qMax( 0, qMin( curIdx, persistedIndex_ ));
    int endIdx   = qMin( qMax( curIdx, persistedIndex_ ), changeList_.size());

    for( int idx=startIdx; idx<endIdx; ++idx ) {
        Change* change = changeList_.at(idx);

        // only check document changes
        if( change->isDocumentChange() ) {
            if( change->isPersistenceRequired() ) {
                return false;
            }
        }
    }
    return true;
}
示例#19
0
/// redo a document change
void TextUndoStack::redoDocumentChange()
{
    // first find the redo operation
    int redoIndex = findRedoIndex( currentIndex(0), 0 );
    Change* redo = findRedoChange(0);
    if( redo ) { ++redoIndex; }

    // first move all controller redo-operation to the given redo found redo location
    QMap<TextEditorController*, int>::iterator itr;
    for( itr = controllerIndexMap_.begin(); itr != controllerIndexMap_.end(); ++itr) {
        TextEditorController* controller = itr.key();
        while( redoControllerChange(controller) ) {};  // undo all controller operations
        itr.value() = redoIndex;    // move the position after the DOC operation
    }

    // is there a document redo? execute it
    if( redo ) {
        redo->execute(documentRef_);
        setChangeIndex(redoIndex);
        emit redoExecuted( redo );
    }
}
示例#20
0
bool Operators::runOnModule(Module &module) {

	doInitialization(module);

	// iterate through operator set
	
	vector<Change*>::iterator it;
	for (it = changes[OP].begin(); it != changes[OP].end(); it++) {
		Change *change = *it;
		Value *target = change->getValue();
		Type *new_type = change->getType().at(0);

		if (target) {
			if (FCmpInst* old_target = dyn_cast<FCmpInst>(target)) {
				changeFCmpInst(old_target, new_type);
			} else if (BinaryOperator* old_target = dyn_cast<BinaryOperator>(target)) {
				changeBinaryOperator(old_target, new_type);
			}
		}
	}

	return true;
}
示例#21
0
/*!

The compute method
save all possible move results into mChanges

i-1
|
|
|
i.......c
|       .
|       .
|       .
i+1.....l

i-1 --> c
i -- > l
*/
void DoublePullMove::compute(Conf & theConf, Pos const thePos)
{
    WatchError
    mChanges.clear(); // reset previous info
    if (!thePos || thePos >= Protein::p().Span()) return;
	Change tChange;
    for(Int pullDir = -1; pullDir <= 1; pullDir+=2)
    {
		for(Dir tDir1=0; tDir1 < Lattice::l().NeighCount(); ++tDir1)
		{
			for(Dir tDir2=0; tDir2 < Lattice::l().NeighCount(); ++tDir2)
			{
				tChange.reset();
				Point l = theConf.Coord(thePos + pullDir) + Lattice::l().DirVec(tDir1);
				if(theConf.occupied(l))continue;
				Point c = theConf.Coord(thePos) + Lattice::l().DirVec(tDir2);
				if(theConf.occupied(c))continue;
				if(!Lattice::l().areNeighbors(l,c)) continue;

				Pos tPos = thePos;

				while(tPos <= Protein::p().Span()&& l!=theConf.Coord(tPos))
				{
					tChange.add(tPos,l);
					if((Idx)(tPos-pullDir) <=Protein::p().Span() && Lattice::l().areNeighbors(l,theConf.Coord(tPos-pullDir))) // keeps the move local
						break;
					l=c;
					c=theConf.Coord(tPos);
					tPos-=pullDir;
				}
				mChanges.insertMem(tChange);
			}
		}
    }
    CatchError
}
void display_normalized(
    Change& result,
    const dStorm::Image<PixelType,Image::Dim>& i
)
{
    typename dStorm::Image<PixelType,Image::Dim>::PixelPair p = i.minmax();
    result.do_resize = true;
    result.resize_image.size = i.sizes();
    result.resize_image.keys.clear();
    result.resize_image.keys.push_back(
        KeyDeclaration("ADC", "A/D counts per pixel", 256) );
    result.do_change_image = true;
    result.image_change.new_image = i.template normalize<uint8_t>(p).template convert<dStorm::Pixel>();
    result.make_linear_key( p );
}
示例#23
0
  void
  operator<< (::xercesc::DOMElement& e, const Change& i)
  {
    e << static_cast< const ::xml_schema::Type& > (i);

    // effects
    //
    if (i.effects ())
    {
      ::xercesc::DOMElement& s (
        ::xsd::cxx::xml::dom::create_element (
          "effects",
          "artofsequence.org/aosl/1.0",
          e));

      s << *i.effects ();
    }

    // script
    //
    if (i.script ())
    {
      ::xercesc::DOMElement& s (
        ::xsd::cxx::xml::dom::create_element (
          "script",
          "artofsequence.org/aosl/1.0",
          e));

      s << *i.script ();
    }

    // extension
    //
    if (i.extension ())
    {
      ::xercesc::DOMElement& s (
        ::xsd::cxx::xml::dom::create_element (
          "extension",
          "artofsequence.org/aosl/1.0",
          e));

      s << *i.extension ();
    }

    // type
    //
    {
      ::xercesc::DOMAttr& a (
        ::xsd::cxx::xml::dom::create_attribute (
          "type",
          e));

      a << i.type ();
    }

    // object
    //
    {
      ::xercesc::DOMAttr& a (
        ::xsd::cxx::xml::dom::create_attribute (
          "object",
          e));

      a << i.object ();
    }
  }
示例#24
0
/// This method gives the command and tries to coalesce the command if possible
/// Warning when a change is MERGED, the original change is deleted!!! And the original pointer is invalid!!!!
///
/// @param change the change that's added
/// @param coalesceId the coalseceId to use for this text change.
/// @return the merge status (this method returns TRUE, if the command has been merged)
bool TextUndoStack::giveChange(Change* change, int coalesceId )
{
    // when undo-collection is disabled. don't record the change
    if( !collectionEnabled_ ) {
        delete change;
        return false;
    }

    ChangeGroup* group = undoGroupStack_.isEmpty() ? 0 : undoGroupStack_.top();

    int lastCoalesceId = lastCoalesceIdAtCurrentLevel();
    bool merge = lastCoalesceId && lastCoalesceIdStack_.top() == coalesceId;
    setLastCoalesceIdAtCurrentLevel(coalesceId);
    if( coalesceId == CoalesceId_ForceMerge ) { merge = true; }

    // still an undogroup active ?
    //----------------------------
    if( group ) {
        //TextEditorController* controller = change->controllerContext();
        // try to merge the operation
        if( merge ) {
            Change* lastChange = group->last();
            if( lastChange && lastChange->giveAndMerge( documentRef_, change ) ) {
                return true;
            }
        }
        group->giveChange( document(), change);
        return false;

    // normal operation
    //-----------------
    } else {

        // get the optional controller context
        TextEditorController* controller = change->controllerContext();
        clearRedo( controller );

        // try to merge the operation
        if( merge ) {
            Change* lastChange = this->findUndoChange(controller);
            if( lastChange && lastChange->giveAndMerge( documentRef_, change ) ) {
                //emit changeMerged( lastChange, change );
                dumpStackInternal();
                return true;
            }
        }

        // execut the operation
        changeList_.append(change);

        // increase the pointers
        // controller-only change, only update the controller pointer
        if( controller ) {
            controllerIndexMap_[controller] = changeList_.size();

        // model-change update the model-pointer and ALL controller pointers
        } else {
            setChangeIndex( changeList_.size() );
            QMap<TextEditorController*, int>::iterator i;
            for (i = controllerIndexMap_.begin(); i != controllerIndexMap_.end(); ++i) {
                i.value() = changeIndex_;
            }
        }
        emit changeAdded( change );

    }
    dumpStackInternal();
    return false;
}
示例#25
0
void guiChangeIP(Frame *frame, int eventId){
    Change c;
    HANDLE tibia = c.getTibiaProcess();
    if(!tibia){
        frame->sb->SetStatusText(wxT("Tibia process not found!"),0);
        if(eventId == MENU_CHANGE_IP)
            sendDialog(wxT("Tibia process not found!"), wxOK | wxICON_ERROR);
        CloseHandle(tibia);
        return;
    }
    std::string sip = std::string(frame->ip->GetValue().mb_str());
    int sport = frame->host->GetValue();
    std::string client = std::string(frame->clients->GetValue().mb_str());
    if(sip == ""){
        frame->sb->SetStatusText(wxT("IP adress not found!"),0);
        if(eventId == MENU_CHANGE_IP)
        	sendDialog(wxT("IP adress not found!"), wxOK | wxICON_ERROR);
        return;
    }
    size_t found = sip.find(":");
    if(found != string::npos){
        sport = atoi(sip.substr(found+1, sip.size()).c_str());
        sip = sip.substr(0, found);
        frame->ip->SetValue(sip);
        frame->host->SetValue(sport);
    }
        
    if(client != "Auto"){
        std::string s ="";
        s += client.at(1);
        if(s == ".")
        	client = client.erase(1,1);
    }
        	
    bool ret = c.changeIP(sip, sport, client);
        
    if(ret){
        frame->sb->SetStatusText(wxT("IP Changed!"),0);
        if(eventId == MENU_CHANGE_IP)
        	sendDialog(wxT("IP Changed!"), wxOK);
    }else{
        frame->sb->SetStatusText(wxT("IP not Changed!"),0);
        if(eventId == MENU_CHANGE_IP)
        	sendDialog(wxT("IP not Changed!"), wxOK | wxICON_ERROR);
        return;
    }
    
    char buf[4];
    itoa(sport, buf, 10);
    std::string save;
    save += sip + ":" + buf;
	h.saveHistory(save);
	frame->ip->Clear();
	vector<string>z;
	z = h.getHistory();
	for(int i = 0; i < int(z.size()); i++){
		wxString wxs(z[i].c_str(), wxConvUTF8);
		frame->ip->Append(wxs);
	}
	std::string tmp = z[0].substr(0, z[0].size()-5);
	wxString last(tmp.c_str(), wxConvUTF8);
	frame->ip->SetValue(last);
}
示例#26
0
void BackBonePullMove::compute(Conf & theConf, Pos const thePos)
{
    WatchError
    mChanges.clear(); // reset previous info
    if (!thePos || thePos >= Protein::p().Span()) return;
	Change tChange;
    for(Int pullDir = -1; pullDir <= 1; pullDir+=2)
    {
		for(Dir tDir1=0; tDir1 < Lattice::l().NeighCount(); ++tDir1)
		{
			for(Dir tDir2=0; tDir2 < Lattice::l().NeighCount(); ++tDir2)
			{





                for(Dir tDir3=0;tDir3<Lattice::l().NeighCount(); ++tDir3)
                {
                    for(Dir tDir4=0;tDir4<Lattice::l().NeighCount(); ++tDir4)
                    {
                        Point l = theConf.Coord(thePos + pullDir) + Lattice::l().DirVec(tDir1);
                        if(theConf.occupied(l))continue;
                        Point c = theConf.Coord(thePos) + Lattice::l().DirVec(tDir2);
                        if(theConf.occupied(c))continue;
                        if(!Lattice::l().areNeighbors(l,c)) continue;

                        // at this situation we also need two more positions
                        // lS and cS that are free and not equal to c and l respectively
                        // then we can start the pull, otherwise not

                        // check for side chains

                        tChange.reset();
                        Point lS=l+Lattice::l().DirVec(tDir3);
                        if(theConf.occupied(lS)||lS==c)continue;
                        Point cS=c+Lattice::l().DirVec(tDir4);
                        if(theConf.occupied(cS)||cS==l)continue;

                        // lS and CS cant be the same position
                        if(lS==cS) continue;

                        // else move possible
                        Pos tPos = thePos;

                        while(tPos>=0 && tPos <= (Protein::p().Length()/2-1) && l!=theConf.Coord(tPos))
                        {
                            tChange.add(tPos,l);
                            tChange.add(tPos+Protein::p().Length()/2,lS);
                            if((Idx)(tPos-pullDir) <=(Protein::p().Length()/2-1) &&
                                (tPos-pullDir) >=0 &&
                                Lattice::l().areNeighbors(l,theConf.Coord(tPos-pullDir))) // keeps the move local
                                break;
                            l=c;
                            lS=cS;
                            c=theConf.Coord(tPos);
                            cS=theConf.Coord(tPos+Protein::p().Length()/2);
                            tPos-=pullDir;

                        }
                        mChanges.insertMem(tChange);

                    }

                }




			}
		}
    }
    CatchError
}
示例#27
0
void OsmApiDbSqlChangesetFileWriter::write(const QString path,
                                           ChangesetProviderPtr changesetProvider)
{
  LOG_DEBUG("Writing changeset to " << path);

  LOG_VARD(path);
  LOG_VARD(changesetProvider->hasMoreChanges());

  _changesetBounds.init();

  _outputSql.setFileName(path);
  if (_outputSql.open(QIODevice::WriteOnly | QIODevice::Text) == false)
  {
    throw HootException(QObject::tr("Error opening %1 for writing").arg(path));
  }

  int changes = 0;
  _createChangeSet();

  while (changesetProvider->hasMoreChanges())
  {
    LOG_TRACE("Reading next SQL change...");
    Change change = changesetProvider->readNextChange();
    switch (change.getType())
    {
      case Change::Create:
        _createNewElement(change.getElement());
        break;
      case Change::Modify:
        _updateExistingElement(change.getElement());
        break;
      case Change::Delete:
        _deleteExistingElement(change.getElement());
        break;
      case Change::Unknown:
        //see comment in ChangesetDeriver::_nextChange() when
        //_fromE->getElementId() < _toE->getElementId() as to why we do a no-op here.
        break;
      default:
        throw IllegalArgumentException("Unexpected change type.");
    }

    if (change.getType() != Change::Unknown)
    {
      if (change.getElement()->getElementType().getEnum() == ElementType::Node)
      {
        ConstNodePtr node = boost::dynamic_pointer_cast<const Node>(change.getElement());
        _changesetBounds.expandToInclude(node->getX(), node->getY());
      }
      changes++;
    }

    if (changes > _changesetMaxSize)
    {
      _updateChangeset(changes);
      _createChangeSet();
      changes = 0;
    }
  }

  _updateChangeset(changes);

  _outputSql.close();
}
示例#28
0
文件: action.cpp 项目: Arydia/rme
void Action::undo(DirtyList* dirty_list)
{
	if(changes.empty())
		return;

	editor.selection.start(Selection::INTERNAL);
	ChangeList::reverse_iterator it = changes.rbegin();

	while(it != changes.rend())
	{
		Change* c = *it;
		switch(c->type)
		{
			case CHANGE_TILE:
			{
				void** data = &c->data;
				Tile* oldtile = reinterpret_cast<Tile*>(*data);
				ASSERT(oldtile);
				Position pos = oldtile->getPosition();
				
				if(editor.IsLiveClient())
				{
					QTreeNode* nd = editor.map.getLeaf(pos.x, pos.y);
					if(!nd || !nd->isVisible(pos.z > 7))
					{
						// Delete all changes that affect tiles outside our view
						c->clear();
						++it;
						continue;
					}
				}

				Tile* newtile = editor.map.swapTile(pos, oldtile);

				// Update server side change list (for broadcast)
				if(editor.IsLiveServer() && dirty_list)
					dirty_list->AddPosition(pos.x, pos.y, pos.z);


				if(oldtile->isSelected())
					editor.selection.addInternal(oldtile);
				if(newtile->isSelected())
					editor.selection.removeInternal(newtile);

				if(newtile->getHouseID() != oldtile->getHouseID())
				{
					// oooooomggzzz we need to remove it from the appropriate house!
					House* house = editor.map.houses.getHouse(newtile->getHouseID());
					if(house)
					{
						house->removeTile(newtile);
					}
					else
					{
						// Set tile house to 0, house has been removed
						newtile->setHouse(nullptr);
					}

					house = editor.map.houses.getHouse(oldtile->getHouseID());
					if(house)
					{
						house->addTile(oldtile);
					}
				}
				if(oldtile->spawn)
				{
					if(newtile->spawn)
					{
						if(*oldtile->spawn != *newtile->spawn)
						{
							editor.map.removeSpawn(newtile);
							editor.map.addSpawn(oldtile);
						}
					}
					else
					{
						editor.map.addSpawn(oldtile);
					}
				}
				else if(newtile->spawn)
				{
					editor.map.removeSpawn(newtile);
				}
				*data = newtile;
				
				
				// Update client dirty list
				if(editor.IsLiveClient() && dirty_list && type != ACTION_REMOTE)
				{
					// Local action, assemble changes
					dirty_list->AddChange(c);
				}
			} break;
			case CHANGE_MOVE_HOUSE_EXIT:
			{
				std::pair<uint32_t, Position>* p = reinterpret_cast<std::pair<uint32_t, Position>* >(c->data);
				ASSERT(p);
				House* whathouse = editor.map.houses.getHouse(p->first);
				if(whathouse)
				{
					Position oldpos = whathouse->getExit();
					whathouse->setExit(p->second);
					p->second = oldpos;
				}
			} break;
			case CHANGE_MOVE_WAYPOINT:
			{
				std::pair<std::string, Position>* p = reinterpret_cast<std::pair<std::string, Position>* >(c->data);
				ASSERT(p);
				Waypoint* wp = editor.map.waypoints.getWaypoint(p->first);

				if(wp)
				{
					// Change the tiles
					TileLocation* oldtile = editor.map.getTileL(wp->pos);
					TileLocation* newtile = editor.map.getTileL(p->second);
					
					// Only need to remove from old if it actually exists
					if(p->second != Position())
						if(oldtile && oldtile->getWaypointCount() > 0)
							oldtile->decreaseWaypointCount();

					newtile->increaseWaypointCount();

					// Update shit
					Position oldpos = wp->pos;
					wp->pos = p->second;
					p->second = oldpos;
				}
			} break;
			default:
			break;
		}
		++it;
	}
	editor.selection.finish(Selection::INTERNAL);
	commited = false;
}
示例#29
0
文件: action.cpp 项目: Arydia/rme
void Action::commit(DirtyList* dirty_list)
{
	editor.selection.start(Selection::INTERNAL);
	ChangeList::const_iterator it = changes.begin();
	while(it != changes.end())
	{
		Change* c = *it;
		switch(c->type) {
			case CHANGE_TILE:
			{
				void** data = &c->data;
				Tile* newtile = reinterpret_cast<Tile*>(*data);
				ASSERT(newtile);
				Position pos = newtile->getPosition();
				
				if(editor.IsLiveClient())
				{
					QTreeNode* nd = editor.map.getLeaf(pos.x, pos.y);
					if(!nd || !nd->isVisible(pos.z > 7))
					{
						// Delete all changes that affect tiles outside our view
						c->clear();
						++it;
						continue;
					}
				}

				Tile* oldtile = editor.map.swapTile(pos, newtile);
				TileLocation* location = newtile->getLocation();
				
				// Update other nodes in the network
				if(editor.IsLiveServer() && dirty_list)
					dirty_list->AddPosition(pos.x, pos.y, pos.z);


				newtile->update();

				//std::cout << "\tSwitched tile at " << pos.x << ";" << pos.y << ";" << pos.z << " from " << (void*)oldtile << " to " << *data <<  std::endl;
				if(newtile->isSelected())
					editor.selection.addInternal(newtile);

				if(oldtile)
				{
					if(newtile->getHouseID() != oldtile->getHouseID())
					{
						// oooooomggzzz we need to add it to the appropriate house!
						House* house = editor.map.houses.getHouse(oldtile->getHouseID());
						if(house)
							house->removeTile(oldtile);

						house = editor.map.houses.getHouse(newtile->getHouseID());
						if(house)
							house->addTile(newtile);
					}
					if(oldtile->spawn)
					{
						if(newtile->spawn)
						{
							if(*oldtile->spawn != *newtile->spawn)
							{
								editor.map.removeSpawn(oldtile);
								editor.map.addSpawn(newtile);
							}
						}
						else
						{
							// Spawn has been removed
							editor.map.removeSpawn(oldtile);
						}
					}
					else if(newtile->spawn)
					{
						editor.map.addSpawn(newtile);
					}

					//oldtile->update();
					if(oldtile->isSelected())
						editor.selection.removeInternal(oldtile);

					*data = oldtile;
				}
				else
				{
					*data = editor.map.allocator(location);
					if(newtile->getHouseID() != 0)
					{
						// oooooomggzzz we need to add it to the appropriate house!
						House* house = editor.map.houses.getHouse(newtile->getHouseID());
						if(house)
						{
							house->addTile(newtile);
						}
					}

					if(newtile->spawn)
						editor.map.addSpawn(newtile);

				}
				// Mark the tile as modified
				newtile->modify();

				// Update client dirty list
				if(editor.IsLiveClient() && dirty_list && type != ACTION_REMOTE)
				{
					// Local action, assemble changes
					dirty_list->AddChange(c);
				}
			} break;
			case CHANGE_MOVE_HOUSE_EXIT:
			{
				std::pair<uint32_t, Position>* p = reinterpret_cast<std::pair<uint32_t, Position>* >(c->data);
				ASSERT(p);
				House* whathouse = editor.map.houses.getHouse(p->first);

				if(whathouse)
				{
					Position oldpos = whathouse->getExit();
					whathouse->setExit(p->second);
					p->second = oldpos;
				}
			} break;
			case CHANGE_MOVE_WAYPOINT:
			{
				std::pair<std::string, Position>* p = reinterpret_cast<std::pair<std::string, Position>* >(c->data);
				ASSERT(p);
				Waypoint* wp = editor.map.waypoints.getWaypoint(p->first);

				if(wp) {
					// Change the tiles
					TileLocation* oldtile = editor.map.getTileL(wp->pos);
					TileLocation* newtile = editor.map.getTileL(p->second);
					
					// Only need to remove from old if it actually exists
					if(p->second != Position())
						if(oldtile && oldtile->getWaypointCount() > 0)
							oldtile->decreaseWaypointCount();

					newtile->increaseWaypointCount();

					// Update shit
					Position oldpos = wp->pos;
					wp->pos = p->second;
					p->second = oldpos;
				}
			} break;
			default:
				break;
		}
		++it;
	}
	editor.selection.finish(Selection::INTERNAL);
	commited = true;
}