void CPigEngine::RemoveInvokeCommands(CPigBehaviorScriptType* pType) { // Get the collection of invoke commands for the object ITCStringsPtr spInvokeCommands; _SVERIFYE(pType->get_InvokeCommands(&spInvokeCommands)); assert(NULL != spInvokeCommands); // Iterate through each one and erase it from the map long cInvokeCommands = 0; _SVERIFYE(spInvokeCommands->get_Count(&cInvokeCommands)); XLock lock(this); for (_variant_t i(0L); V_I4(&i) < cInvokeCommands; ++V_I4(&i)) { CComBSTR bstrCommand; _SVERIFYE(spInvokeCommands->get_Item(&i, &bstrCommand)); USES_CONVERSION; tstring strCommand(OLE2CT(bstrCommand)); XBehaviorMapIt it = m_mapBehaviors.find(strCommand); if (m_mapBehaviors.end() != it) { it->second->Release(); m_mapBehaviors.erase(it); } } }
HRESULT CPigEngine::CreatePig(BSTR bstrType, BSTR bstrCommandLine, IPig** ppPig) { // Initialize the [out] parameter CLEAROUT(ppPig, (IPig*)NULL); // Lock the object for the following validation checks { XLock lock(this); // Ensure that the scripts have been loaded RETURN_FAILED(EnsureScriptsAreLoaded()); // Ensure that the MissionServer property is not empty if (!m_bstrMissionServer.Length()) return AtlReportError(CLSID_PigSession, IDS_E_NO_MISSIONSRV, IID_IPigSession, 0, _Module.GetResourceInstance()); // Get the number of pigs that exist long cPigs = 0; if (m_pPigs) _SVERIFYE(m_pPigs->get_Count(&cPigs)); // Get the maximum number of pigs allowed long nMaxPigs = 0; _SVERIFYE(get_MaxPigs(&nMaxPigs)); // Check for maximum pigs if (nMaxPigs >= 0 && cPigs >= nMaxPigs) return AtlReportError(CLSID_PigSession, IDS_E_TOOMANYPIGS, IID_IPigSession, 0, _Module.GetResourceInstance()); } // bstrType is optional, so assign a default value if not specified CComBSTR bstrTheType(bstrType); if (!bstrTheType.Length()) bstrTheType = L"Default"; // Find the specified behavior type CPigBehaviorScriptType* pBehaviorType = GetBehaviorType(bstrTheType); if (!pBehaviorType) return AtlReportError(CLSID_PigSession, IDS_E_CREATE_BEHAVIOR_TYPE, IID_IPigSession, 0, _Module.GetResourceInstance()); // Create a new pig thread object and it's associated pig player object DWORD dwGITCookie; RETURN_FAILED(CPig::Create(pBehaviorType, bstrCommandLine, &dwGITCookie)); // Get an apartment-safe pointer to the pig object RETURN_FAILED(GetInterfaceFromGlobal(dwGITCookie, IID_IPig, (void**)ppPig)); assert(*ppPig); // Indicate success return S_OK; }
HRESULT CPigShip::CreateCommandWrapper(Command cmd, IAGCCommand** ppCommand) { // Initialize the [out] parameter CLEAROUT(ppCommand, (IAGCCommand*)NULL); // Create a new AGC.Command object IAGCCommandPrivatePtr spCmd; RETURN_FAILED(spCmd.CreateInstance(CLSID_AGCCommand)); // Get the command target and id ImodelIGC* pModel = GetIGC()->GetCommandTarget(cmd); const CommandID idCmd = GetIGC()->GetCommandID(cmd); // Get the strings for the command target and id const char* pszTarget = pModel ? GetModelName(pModel) : NULL; const char* pszVerb = (0 <= idCmd && idCmd < c_cidMax) ? c_cdAllCommands[idCmd].szVerb : ""; // Initialize the new object spCmd->Init(pszTarget, pszVerb); // Query for the IAGCCommand interface _SVERIFYE(spCmd->QueryInterface(IID_IAGCCommand, (void**)ppCommand)); // Indicate success return S_OK; }
HRESULT CPigEngine::GetInvokeCommands(CPigBehaviorScriptType* pType, CPigEngine::XBehaviorMap& mapCommands) { // Get the collection of invoke commands for the new object ITCStringsPtr spInvokeCommands; _SVERIFYE(pType->get_InvokeCommands(&spInvokeCommands)); assert(NULL != spInvokeCommands); // Iterate through each one and add it to a local map, ignoring duplicates long cInvokeCommands = 0; _SVERIFYE(spInvokeCommands->get_Count(&cInvokeCommands)); for (_variant_t i(0L); V_I4(&i) < cInvokeCommands; ++V_I4(&i)) { CComBSTR bstrCommand; _SVERIFYE(spInvokeCommands->get_Item(&i, &bstrCommand)); USES_CONVERSION; tstring strCommand(OLE2CT(bstrCommand)); XBehaviorMapIt it = mapCommands.find(strCommand); if (mapCommands.end() == it) mapCommands.insert(std::make_pair(strCommand, pType)); } return S_OK; }
void CPigEngine::ScriptDirMonitor(HANDLE hevtExit) { assert(m_hDirChange && INVALID_HANDLE_VALUE != m_hDirChange); // Enter this thread into the MTA _SVERIFYE(CoInitializeEx(NULL, COINIT_MULTITHREADED)); // Declare an enum and an array of objects on which to wait enum {e_DirChange = WAIT_OBJECT_0, e_Exit, e_Msg}; HANDLE hObjs[] = {m_hDirChange, hevtExit}; const int cObjs = sizeofArray(hObjs); // Process change notification until exit UINT idTimer = 0; DWORD dwWait = MsgWaitForMultipleObjects(cObjs, hObjs, false, INFINITE, QS_ALLINPUT); while (e_Exit != dwWait) { if (e_DirChange == dwWait) { // Reset the timer if (idTimer) KillTimer(NULL, idTimer); idTimer = SetTimer(NULL, 0, 2000, NULL); // Continue waiting for change notifications if (!FindNextChangeNotification(m_hDirChange)) { #ifdef _DEBUG DWORD dwLastError = ::GetLastError(); debugf("\nCPigEngine::ScriptDirMonitor(): " "FindNextChangeNotification Failed : " "GetLastError() = 0x%08X, m_hDirChange = 0x%08X\n", dwLastError, m_hDirChange); #endif // _DEBUG Sleep(1000); } } else // (e_Msg == dwWait) { MSG msg; while (PeekMessage(&msg, NULL, 0, 0, PM_REMOVE)) { if (WM_TIMER == msg.message) { assert(msg.wParam == idTimer); // Kill the timer KillTimer(NULL, idTimer); idTimer = 0; // Process the files in the directory ProcessScriptDirChanges(); } else if (WM_QUIT == msg.message) { dwWait = e_Exit; break; } } } // Continue waiting dwWait = MsgWaitForMultipleObjects(cObjs, hObjs, false, INFINITE, QS_ALLINPUT); } // Remove this thread from the MTA CoUninitialize(); // Clear the thread pointer InterlockedExchange((long*)&m_pth, 0); }