summaryrefslogtreecommitdiff
path: root/NSCmpts/ActionEngine.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'NSCmpts/ActionEngine.cpp')
-rw-r--r--NSCmpts/ActionEngine.cpp276
1 files changed, 276 insertions, 0 deletions
diff --git a/NSCmpts/ActionEngine.cpp b/NSCmpts/ActionEngine.cpp
new file mode 100644
index 0000000..59673b1
--- /dev/null
+++ b/NSCmpts/ActionEngine.cpp
@@ -0,0 +1,276 @@
+// ActionEngine.cpp: implementation of the CActionEngine class.
+//
+//////////////////////////////////////////////////////////////////////
+
+#include "stdafx.h"
+#include "ActionEngine.h"
+
+#include "NSMessages.h"
+#include <appmisc.h>
+
+//////////////////////////////////////////////////////////////////////
+// CActionEngine
+
+// Starts with only this action
+HRESULT CActionEngine::Start(CAction* pFirstAction)
+{
+ ASSERT(pFirstAction);
+ clear();
+ pFirstAction->addref();
+ push_back(pFirstAction);
+ return Start();
+}
+
+///////////////////////////////////////////////////////////////////////
+// Starts the Actual Processing
+
+HRESULT CActionEngine::Start()
+{
+ HRESULT hr = S_OK;
+ CAction* pAction = NULL;
+ UINT nDone = 0;
+
+ // Keep going while there are actions to process
+ while(size())
+ {
+ // Get current action
+ pAction = at(0);
+ ASSERT(pAction);
+
+ try
+ {
+ // Do Action
+ pAction->Do(this, m_hwndUpdates);
+
+ }
+ catch(CActionError& e)
+ {
+ if(m_hwndErrors)
+ {
+ // Send Error to Window
+ NS_ERROR_DATA nsErr;
+ nsErr.hRes = e.m_hRes;
+ nsErr.szDesc = e.m_sDesc;
+ nsErr.lParam = (LPARAM)pAction;
+
+ ::SendMessage(m_hwndErrors, NSM_ERROR, NULL, (LPARAM)&nsErr);
+ }
+
+ hr = E_FAIL;
+ }
+
+ // Update the Window
+ nDone++;
+
+ if(m_hwndUpdates)
+ {
+ // Send Update Message
+ NS_UPDATE_DATA nsUpd;
+ nsUpd.lCur = nDone;
+ nsUpd.lTot = nDone + size();
+ nsUpd.szMessage1 = NULL;
+ nsUpd.szMessage2 = NULL;
+
+ // If message returns false then cancel
+ if(!::SendMessage(m_hwndUpdates, NSM_UPDATE, NULL, (LPARAM)&nsUpd))
+ {
+ hr = E_ABORT;
+ break;
+ }
+ }
+
+ // Remove action from array and release it
+ erase(begin());
+ pAction->release();
+ }
+
+ return hr;
+}
+
+/////////////////////////////////////////////////////////////////////
+// Starts the Engine in another thread
+HANDLE CActionEngine::StartThread()
+{
+ DWORD dwThreadID = NULL;
+ return (HANDLE)CreateThread(NULL, 0, ThreadProc,
+ (LPVOID)this, 0, &dwThreadID);
+}
+
+DWORD CALLBACK CActionEngine::ThreadProc(LPVOID lpParam)
+{
+ // Need to Initialize for this thread
+ // BUG: This didn't work in Win95 (non-OSR2) because
+ // only have CoInitialize
+ // HRESULT hr = CoInitializeEx(NULL, COINIT_APARTMENTTHREADED);
+ HRESULT hr = CoInitialize(NULL);
+
+ ASSERT(lpParam);
+
+ CActionEngine* pEngine = (CActionEngine*)lpParam;
+ HRESULT hRet = pEngine->Start();
+
+ if(SUCCEEDED(hr))
+ CoUninitialize();
+
+ // Return the result of the engine
+ // as our thread exit code
+ return hRet;
+}
+
+// Sets the pointers for the update windows
+void CActionEngine::SetUpdates(HWND hwndUpdates /*= NULL*/,
+ HWND hwndErrors /*= NULL*/)
+{
+ m_hwndUpdates = hwndUpdates;
+ m_hwndErrors = hwndErrors;
+}
+
+
+///////////////////////////////////////////////////////////////
+// Array Management Stuff
+
+UINT CActionEngine::Add(CAction* pAction)
+{
+ ASSERT(pAction);
+ pAction->addref();
+ push_back(pAction);
+ return size();
+}
+
+UINT CActionEngine::Insert(CAction* pAction, UINT nIndex)
+{
+ ASSERT(pAction);
+ ASSERT(nIndex < size());
+ pAction->addref();
+ insert(begin() + nIndex, pAction);
+ return nIndex;
+}
+
+void CActionEngine::Remove(UINT nIndex)
+{
+ ASSERT(nIndex < size());
+ CAction* pAction = at(nIndex);
+ erase(begin() + nIndex);
+ pAction->release();
+}
+
+void CActionEngine::RemoveAll(CAction* pKeep /*= NULL*/)
+{
+ if(pKeep)
+ pKeep->addref();
+
+ while(size())
+ {
+ CAction* pAction = at(0);
+ pAction->release();
+ erase(begin());
+ }
+
+ if(pKeep)
+ {
+ Add(pKeep);
+ pKeep->release();
+ }
+}
+
+CAction* CActionEngine::At(UINT nIndex)
+{
+ ASSERT(nIndex < size());
+ return at(nIndex);
+}
+
+
+
+
+
+////////////////////////////////////////////////////////////////////////
+// CAction Helper Function
+////////////////////////////////////////////////////////////////////////
+
+void CAction::Update(HWND hwndUpdates, LPCTSTR szDesc)
+{
+ // Send a message with only the string valid
+ NS_UPDATE_DATA nsUpd;
+ nsUpd.lCur = -1;
+ nsUpd.lTot = -1;
+ nsUpd.szMessage1 = NULL;
+ nsUpd.szMessage2 = szDesc;
+
+ ::SendMessage(hwndUpdates, NSM_UPDATE, NULL, (LPARAM)&nsUpd);
+}
+
+void CAction::Update(HWND hwndUpdates, LPCTSTR szStatus, LPCTSTR szDesc)
+{
+ // Send a message with only the string valid
+ NS_UPDATE_DATA nsUpd;
+ nsUpd.lCur = -1;
+ nsUpd.lTot = -1;
+ nsUpd.szMessage1 = szStatus;
+ nsUpd.szMessage2 = szDesc;
+
+ ::SendMessage(hwndUpdates, NSM_UPDATE, NULL, (LPARAM)&nsUpd);
+}
+
+
+
+//////////////////////////////////////////////////////////////////////
+// CActionError Construction Helper Functions
+
+inline CActionError::CActionError(HRESULT hr, const string& sMessage,
+ const file_path& path /*= file_path()*/)
+{
+ Construct(hr, sMessage, path);
+}
+
+CActionError::CActionError(HRESULT hr, UINT nID,
+ const file_path& path /*= file_path()*/)
+{
+ string sTemp;
+ sTemp.load_string(nID);
+ Construct(hr, sTemp, path);
+}
+
+CActionError::CActionError(const string& sError, HRESULT hr, UINT nID,
+ const file_path& path /*= file_path()*/)
+{
+ string sTemp;
+ sTemp.load_string(nID);
+ Construct(sError, hr, sTemp, path);
+}
+
+inline CActionError::CActionError(const string& sError, HRESULT hr, const string& sMessage,
+ const file_path& path /*= file_path()*/)
+{
+ Construct(sError, hr, sMessage, path);
+}
+
+
+void CActionError::Construct(const string& sError, HRESULT hr, string sMessage, const file_path& path)
+{
+ // Replace with custom message before passing on
+ sMessage.replace(_T("%e"), sError);
+ Construct(hr, sMessage, path);
+}
+
+void CActionError::Construct(HRESULT hr, string sMessage, const file_path& path)
+{
+ m_hRes = hr;
+
+ // If there's a need then replace
+ if(sMessage.find(_T("%e")) != string::npos)
+ sMessage.replace(_T("%e"), FormatHR(m_hRes));
+
+ // Same here
+ if(path.valid())
+ {
+ sMessage.replace(_T("%f"), path.file());
+ sMessage.replace(_T("%F"), path);
+ }
+
+ m_sDesc = sMessage;
+}
+
+void Lower(string& s)
+{
+ s.make_lower();
+}