mirror of
				https://github.com/vcmi/vcmi.git
				synced 2025-10-31 00:07:39 +02:00 
			
		
		
		
	Merge pull request #1190 from Nordsoft91/editor-speedup
Smart invalidation for move/erase/new object [1.2]
This commit is contained in:
		| @@ -311,6 +311,7 @@ void MapController::commitObjectErase(int level) | ||||
| 	{ | ||||
| 		//invalidate tiles under objects | ||||
| 		_mapHandler->invalidate(_mapHandler->getTilesUnderObject(obj)); | ||||
| 		_scenes[level]->objectsView.setDirty(obj); | ||||
| 	} | ||||
|  | ||||
| 	_scenes[level]->selectionObjectsView.clear(); | ||||
| @@ -371,7 +372,7 @@ void MapController::commitObstacleFill(int level) | ||||
| 	 | ||||
| 	_scenes[level]->selectionTerrainView.clear(); | ||||
| 	_scenes[level]->selectionTerrainView.draw(); | ||||
| 	_scenes[level]->objectsView.draw(); | ||||
| 	_scenes[level]->objectsView.draw(false); //TODO: enable smart invalidation (setDirty) | ||||
| 	_scenes[level]->passabilityView.update(); | ||||
| 	 | ||||
| 	_miniscenes[level]->updateViews(); | ||||
| @@ -380,8 +381,8 @@ void MapController::commitObstacleFill(int level) | ||||
|  | ||||
| void MapController::commitObjectChange(int level) | ||||
| {	 | ||||
| 	//for( auto * o : _scenes[level]->selectionObjectsView.getSelection()) | ||||
| 		//_mapHandler->invalidate(o); | ||||
| 	for( auto * o : _scenes[level]->selectionObjectsView.getSelection()) | ||||
| 		_scenes[level]->objectsView.setDirty(o); | ||||
| 	 | ||||
| 	_scenes[level]->objectsView.draw(); | ||||
| 	_scenes[level]->selectionObjectsView.draw(); | ||||
| @@ -411,6 +412,7 @@ void MapController::commitObjectShift(int level) | ||||
| 			pos.x += shift.x(); pos.y += shift.y(); | ||||
| 			 | ||||
| 			auto prevPositions = _mapHandler->getTilesUnderObject(obj); | ||||
| 			_scenes[level]->objectsView.setDirty(obj); //set dirty before movement | ||||
| 			_map->getEditManager()->moveObject(obj, pos); | ||||
| 			_mapHandler->invalidate(prevPositions); | ||||
| 			_mapHandler->invalidate(obj); | ||||
| @@ -450,6 +452,7 @@ void MapController::commitObjectCreate(int level) | ||||
| 	 | ||||
| 	_map->getEditManager()->insertObject(newObj); | ||||
| 	_mapHandler->invalidate(newObj); | ||||
| 	_scenes[level]->objectsView.setDirty(newObj); | ||||
| 	 | ||||
| 	_scenes[level]->selectionObjectsView.newObject = nullptr; | ||||
| 	_scenes[level]->selectionObjectsView.shift = QPoint(0, 0); | ||||
| @@ -495,7 +498,7 @@ void MapController::undo() | ||||
| { | ||||
| 	_map->getEditManager()->getUndoManager().undo(); | ||||
| 	resetMapHandler(); | ||||
| 	sceneForceUpdate(); | ||||
| 	sceneForceUpdate(); //TODO: use smart invalidation (setDirty) | ||||
| 	main->mapChanged(); | ||||
| } | ||||
|  | ||||
| @@ -503,6 +506,6 @@ void MapController::redo() | ||||
| { | ||||
| 	_map->getEditManager()->getUndoManager().redo(); | ||||
| 	resetMapHandler(); | ||||
| 	sceneForceUpdate(); | ||||
| 	sceneForceUpdate(); //TODO: use smart invalidation (setDirty) | ||||
| 	main->mapChanged(); | ||||
| } | ||||
|   | ||||
| @@ -295,28 +295,33 @@ void ObjectsLayer::draw(bool onlyDirty) | ||||
| 	if(!map) | ||||
| 		return; | ||||
| 	 | ||||
| 	pixmap->fill(Qt::transparent); | ||||
| 	QPainter painter(pixmap.get()); | ||||
| 	std::set<const CGObjectInstance *> drawen; | ||||
| 	 | ||||
| 	 | ||||
| 	for(int j = 0; j < map->height; ++j) | ||||
| 	if(onlyDirty) | ||||
| 	{ | ||||
| 		for(int i = 0; i < map->width; ++i) | ||||
| 		//objects could be modified | ||||
| 		for(auto * obj : objDirty) | ||||
| 			setDirty(obj); | ||||
| 		 | ||||
| 		//clear tiles which will be redrawn. It's needed because some object could be replaced | ||||
| 		painter.setCompositionMode(QPainter::CompositionMode_Source); | ||||
| 		for(auto & p : dirty) | ||||
| 			painter.fillRect(p.x * 32, p.y * 32, 32, 32, Qt::transparent); | ||||
| 		painter.setCompositionMode(QPainter::CompositionMode_SourceOver); | ||||
| 		 | ||||
| 		for(auto & p : dirty) | ||||
| 			handler->drawObjects(painter, p.x, p.y, p.z); | ||||
| 	} | ||||
| 	else | ||||
| 	{ | ||||
| 		pixmap->fill(Qt::transparent); | ||||
| 		for(int j = 0; j < map->height; ++j) | ||||
| 		{ | ||||
| 			handler->drawObjects(painter, i, j, scene->level); | ||||
| 			/*auto & objects = main->getMapHandler()->getObjects(i, j, scene->level); | ||||
| 			 for(auto & object : objects) | ||||
| 			 { | ||||
| 			 if(!object.obj || drawen.count(object.obj)) | ||||
| 			 continue; | ||||
| 			  | ||||
| 			 if(!onlyDirty || dirty.count(object.obj)) | ||||
| 			 { | ||||
| 			 main->getMapHandler()->drawObject(painter, object); | ||||
| 			 drawen.insert(object.obj); | ||||
| 			 } | ||||
| 			 }*/ | ||||
| 			for(int i = 0; i < map->width; ++i) | ||||
| 			{ | ||||
| 				handler->drawObjects(painter, i, j, scene->level); | ||||
| 			} | ||||
| 		} | ||||
| 	} | ||||
| 	 | ||||
| @@ -326,16 +331,22 @@ void ObjectsLayer::draw(bool onlyDirty) | ||||
|  | ||||
| void ObjectsLayer::setDirty(int x, int y) | ||||
| { | ||||
| 	/*auto & objects = main->getMapHandler()->getObjects(x, y, scene->level); | ||||
| 	for(auto & object : objects) | ||||
| 	{ | ||||
| 		if(object.obj) | ||||
| 			dirty.insert(object.obj); | ||||
| 	}*/ | ||||
| 	int3 pos(x, y, scene->level); | ||||
| 	if(map->isInTheMap(pos)) | ||||
| 		dirty.insert(pos); | ||||
| } | ||||
|  | ||||
| void ObjectsLayer::setDirty(const CGObjectInstance * object) | ||||
| { | ||||
| 	objDirty.insert(object); | ||||
| 	//mark tiles under object as dirty | ||||
| 	for(int j = 0; j < object->getHeight(); ++j) | ||||
| 	{ | ||||
| 		for(int i = 0; i < object->getWidth(); ++i) | ||||
| 		{ | ||||
| 			setDirty(object->getPosition().x - i, object->getPosition().y - j); | ||||
| 		} | ||||
| 	} | ||||
| } | ||||
|  | ||||
| SelectionObjectsLayer::SelectionObjectsLayer(MapSceneBase * s): AbstractLayer(s), newObject(nullptr) | ||||
|   | ||||
		Reference in New Issue
	
	Block a user