NodePtr CommonBfJlModules::handleResult(int iJId, NodePtr pNode, const std::string& sResult)
{
	m_nDoingJobs--;
	assert(m_pBfsHandler != nullptr);
	assert(m_pGameHandler != nullptr);
	assert(m_pIntegrator != nullptr);
	std::ostringstream oss;
	GameParser* pGameParser = m_pGameHandler->makeGameParser(sResult);
	if (m_pGameHandler->isNodeAlreadyExist(pNode, pGameParser)) {
		if (m_pGameHandler->handleDuplicateNode(pNode)) {
			oss << std::endl << "Handle duplicate node: Set StopExpanding true" << std::endl << "Receive job ID " << iJId 
				<< ": " << sResult << std::endl;
			pNode->appendComment(oss.str());
		} else {
			oss << "Error: New node already exist, JID: " << iJId
					  << ", Result: " << sResult << std::endl;
			std::cerr << oss.str() << "> " << std::flush;
			pNode->appendComment(oss.str());
		}
		restorePreUpdate(pNode);
		return nullptr;
	}
	NodePtr pNewNode = m_pGameHandler->generateNode(pNode, pGameParser);

	oss.str("");
	oss << "Receive job ID " << iJId << ": " << sResult << std::endl;
	pNewNode->appendComment(oss.str());

	if (JobLevelConfigure::g_configure.bUseJobLog) {
		std::ofstream fout(JobLevelConfigure::g_configure.sJobLogFile.c_str(), std::ios::app);
		fout << oss.str();
		fout.close();
	}

	BfsRetriever* pBfsRetriever = m_pIntegrator->makeRetriever(pGameParser);
	m_pBfsHandler->setupBfsData(pNewNode, pBfsRetriever);
	m_pGameHandler->setupGameData(pNewNode, pGameParser);

	delete pGameParser;
	delete pBfsRetriever;

	return pNewNode;
}
bool CommonBfJlModules::dispatch(NodePtr pNode)
{
	assert(m_pBfsHandler != nullptr);
	assert(m_pGameHandler != nullptr);
	std::ostringstream oss;
	if (m_pBfsHandler->isRunningJob(pNode)) {
		oss << "Error : the node to dispathch is running job" << std::endl;
		std::cerr << oss.str() << "> " << std::flush;
		pNode->appendComment(oss.str());
		return false;
	} else if (m_pBfsHandler->isFlagged(pNode)) {
		oss << "Error : the node to dispatch is flagged" << std::endl;
		std::cerr << oss.str() << "> " << std::flush;
		pNode->appendComment(oss.str());
		return false;
	}

	std::string sAppName = m_pGameHandler->getAppName();
	std::string sAppVersion = m_pGameHandler->getAppVersion();
	std::string sArgument = m_pGameHandler->prepareJobCommands(pNode);

	int iJId = submitJob(pNode, sAppName, sAppVersion, sArgument);

	oss.str("");
	oss << "Submit job ID " << iJId << ": " << sArgument << std::endl;
	pNode->appendComment(oss.str());

	if (JobLevelConfigure::g_configure.bUseJobLog) {
		std::ofstream fout(JobLevelConfigure::g_configure.sJobLogFile.c_str(), std::ios::app);
		fout << oss.str();
		fout.close();
	}

	m_nDoingJobs++;
	m_nTotalJobs++;
	return true;
}