//-------------------------------------------------------------------------------------
bool RestoreEntityHandler::process()
{
	Components::COMPONENTS& cts = Components::getSingleton().getComponents(CELLAPP_TYPE);
	Mercury::Channel* pChannel = NULL;

	if(cts.size() > 0)
	{
		Components::COMPONENTS::iterator ctiter = cts.begin();
		if((*ctiter).pChannel == NULL)
			return true;

		pChannel = (*ctiter).pChannel;
	}

	if(pChannel == NULL)
		return true;

	int count = 0;

	// 首先需要找到这个cell上的space
	// KBE_ASSERT(restoreSpaces_.size() > 0);
	// 如果spaceEntity不在这个baseapp上创建则继续等待
	// 当spaceEntity的cell创建好了之后会广播给所有的baseapp, 每个baseapp
	// 去判断是否有需要恢复的entity
	if(restoreSpaces_.size() > 0)
	{
		if(timestamp() - tickReport_ > uint64( 3 * stampsPerSecond() ))
		{
			tickReport_ = timestamp();
			INFO_MSG(boost::format("RestoreEntityHandler::process(%3%): wait for localSpace to get cell!, entitiesSize(%1%), spaceSize=%2%\n") % 
				entities_.size() % restoreSpaces_.size() % cellappID_);
		}

		int spaceCellCount = 0;

		// 必须等待space恢复
		std::vector<RestoreData>::iterator restoreSpacesIter = restoreSpaces_.begin();
		for(; restoreSpacesIter != restoreSpaces_.end(); restoreSpacesIter++)
		{
			Base* pBase = Baseapp::getSingleton().findEntity((*restoreSpacesIter).id);
			
			if(pBase)
			{
				if(++count > (int)g_kbeSrvConfig.getBaseApp().entityRestoreSize)
				{
					return true;
				}

				if((*restoreSpacesIter).creatingCell == false)
				{
					(*restoreSpacesIter).creatingCell = true;
					pBase->restoreCell(NULL);
				}
				else
				{
					if(pBase->cellMailbox() == NULL)
					{
						return true;
					}
					else
					{
						spaceCellCount++;
						if(!(*restoreSpacesIter).processed)
						{
							(*restoreSpacesIter).processed = true;
							pBase->onRestore();
						}
					}
				}
			}
			else
			{
				ERROR_MSG(boost::format("RestoreEntityHandler::process(%1%): lose space(%2%).\n") % cellappID_ % (*restoreSpacesIter).id);
			}
		}
		
		if(spaceCellCount != (int)restoreSpaces_.size())
			return true;

		// 通知其他baseapp, space恢复了cell
		if(!broadcastOtherBaseapps_)
		{
			broadcastOtherBaseapps_ = true;

			INFO_MSG(boost::format("RestoreEntityHandler::process(%1%): begin broadcast-spaceGetCell to otherBaseapps...\n") % cellappID_);

			std::vector<RestoreData>::iterator restoreSpacesIter = restoreSpaces_.begin();
			for(; restoreSpacesIter != restoreSpaces_.end(); restoreSpacesIter++)
			{
				Base* pBase = Baseapp::getSingleton().findEntity((*restoreSpacesIter).id);
				bool destroyed = (pBase == NULL || pBase->isDestroyed());
				COMPONENT_ID baseappID = g_componentID;
				COMPONENT_ID cellappID = 0;
				SPACE_ID spaceID = (*restoreSpacesIter).spaceID;
				ENTITY_ID spaceEntityID = (*restoreSpacesIter).id;
				ENTITY_SCRIPT_UID utype = 0;

				if(!destroyed)
				{
					utype = pBase->scriptModule()->getUType();
					cellappID = pBase->cellMailbox()->componentID();
				}

				spaceIDs_.erase(std::remove(spaceIDs_.begin(), spaceIDs_.end(), spaceID), spaceIDs_.end());

				Mercury::Channel* pChannel = NULL;
				Components::COMPONENTS& cts = Componentbridge::getComponents().getComponents(BASEAPP_TYPE);
				Components::COMPONENTS::iterator comsiter = cts.begin();
				for(; comsiter != cts.end(); comsiter++)
				{
					pChannel = (*comsiter).pChannel;
					
					if(pChannel)
					{
						INFO_MSG(boost::format("RestoreEntityHandler::process(%5%): broadcast baseapp[%1%, %2%], spaceID[%3%], utype[%4%]...\n") % 
							(*comsiter).cid % pChannel->c_str() % spaceID % utype % cellappID_);

						Mercury::Bundle* pBundle = Mercury::Bundle::ObjPool().createObject();
						(*pBundle).newMessage(BaseappInterface::onRestoreSpaceCellFromOtherBaseapp);
						(*pBundle) << baseappID << cellappID << spaceID << spaceEntityID << utype << destroyed;
						pBundle->send(Baseapp::getSingleton().getNetworkInterface(), pChannel);
						Mercury::Bundle::ObjPool().reclaimObject(pBundle);
					}
				}
			}
		}
	}

	if(spaceIDs_.size() > 0)
	{
		if(timestamp() - tickReport_ > uint64( 3 * stampsPerSecond() ))
		{
			tickReport_ = timestamp();
			INFO_MSG(boost::format("RestoreEntityHandler::process(%1%): wait for otherBaseappSpaces to get cell!, entitiesSize(%2%), spaceSize=%3%\n") % 
				cellappID_ % entities_.size() % spaceIDs_.size());
		}

		return true;
	}

	// 恢复其他entity
	std::vector<RestoreData>::iterator iter = entities_.begin();
	for(; iter != entities_.end(); )
	{
		RestoreData& data = (*iter);
		Base* pBase = Baseapp::getSingleton().findEntity(data.id);

		if(pBase)
		{
			if(++count > g_kbeSrvConfig.getBaseApp().entityRestoreSize)
			{
				return true;
			}

			if(pBase->cellMailbox() != NULL)
			{
				if(!data.processed)
				{
					data.processed = true;
					pBase->onRestore();
				}

				iter = entities_.erase(iter);
			}
			else
			{
				if(!data.creatingCell)
				{
					data.creatingCell = true;
					
					EntityMailboxAbstract* cellMailbox = NULL;
					std::vector<RestoreData>::iterator restoreSpacesIter = restoreSpaces_.begin();
					for(; restoreSpacesIter != restoreSpaces_.end(); restoreSpacesIter++)
					{
						Base* pSpace = Baseapp::getSingleton().findEntity((*restoreSpacesIter).id);
						if(pSpace && pBase->spaceID() == pSpace->spaceID())
						{
							cellMailbox = pSpace->cellMailbox();
							break;
						}
					}
					
					if(cellMailbox == NULL)
					{
						restoreSpacesIter = otherRestoredSpaces_.begin();
						for(; restoreSpacesIter != otherRestoredSpaces_.end(); restoreSpacesIter++)
						{
							if(pBase->spaceID() == (*restoreSpacesIter).spaceID && (*restoreSpacesIter).cell)
							{
								cellMailbox = (*restoreSpacesIter).cell;
								break;
							}
						}
					}

					if(cellMailbox)
					{
						pBase->restoreCell(cellMailbox);
					}
					else
					{
						ENTITY_ID delID = pBase->id();

						pBase->destroy();
						WARNING_MSG(boost::format("RestoreEntityHandler::process(%1%): not fount spaceCell, killed base(%2%)!") 
							% cellappID_ % delID);

						if(Baseapp::getSingleton().findEntity(delID) == NULL)
							iter = entities_.erase(iter);

						continue;
					}
				}

				iter++;
			}
		}
		else
		{
			iter = entities_.erase(iter);
		}
	}

	if(entities_.size() == 0)
	{
		std::vector<RestoreData>::iterator restoreSpacesIter = otherRestoredSpaces_.begin();
		for(; restoreSpacesIter != otherRestoredSpaces_.end(); restoreSpacesIter++)
		{
			if((*restoreSpacesIter).cell)
			{
				Py_DECREF((*restoreSpacesIter).cell);
				(*restoreSpacesIter).cell = NULL;
			}
		}
		
		otherRestoredSpaces_.clear();

		inProcess_ = false;
		Baseapp::getSingleton().onRestoreEntitiesOver(this);
		return false;
	}

	return true;
}
Exemple #2
0
//-------------------------------------------------------------------------------------
void ServerApp::onAppActiveTick(Mercury::Channel* pChannel, COMPONENT_TYPE componentType, COMPONENT_ID componentID)
{
    if(pChannel->isExternal())
        return;

    Mercury::Channel* pTargetChannel = NULL;
    if(componentType != CONSOLE_TYPE)
    {
        Components::ComponentInfos* cinfos =
            Componentbridge::getComponents().findComponent(componentType, KBEngine::getUserUID(), componentID);

        KBE_ASSERT(cinfos != NULL);
        pTargetChannel = cinfos->pChannel;
        pTargetChannel->updateLastReceivedTime();
    }
    else
    {
        pChannel->updateLastReceivedTime();
        pTargetChannel = pChannel;
    }

    DEBUG_MSG("ServerApp::onAppActiveTick[%x]: %s:%"PRAppID" lastReceivedTime:%"PRIu64" at %s.\n",
              pChannel, COMPONENT_NAME[componentType], componentID, pChannel->lastReceivedTime(), pTargetChannel->c_str());
}