diff --git a/xvaga/agasys.cpp b/xvaga/agasys.cpp index f6f22fe7d..ca43668e7 100755 --- a/xvaga/agasys.cpp +++ b/xvaga/agasys.cpp @@ -1,526 +1,526 @@ -#include "wxinc.h" -#include "incstr.h" - -#include "agasys.h" -#include "xvt.h" - -/////////////////////////////////////////////////////////// -// Unzip support -/////////////////////////////////////////////////////////// - -#include -#include -#include -#include - -static unsigned int aga_getziplist(const char* zipfile, wxArrayString& aFiles) -{ - wxFFileInputStream fin(zipfile); - wxZipInputStream zip(fin); - for (wxZipEntry* z = zip.GetNextEntry(); z; z = zip.GetNextEntry()) - { - const wxString str = z->GetInternalName(); - aFiles.Add(str); - } - - return aFiles.GetCount(); -} - -static int aga_find_slash(const wxString& path, int from) -{ - for (int i = from; path[i]; i++) - if (wxIsPathSeparator(path[i])) - return i; - - return -1; -} - -static void aga_create_dir(wxString strPath) -{ - if (!wxEndsWithPathSeparator(strPath)) - strPath += wxFILE_SEP_PATH; - - for (int i = aga_find_slash(strPath, 0); i > 0; i = aga_find_slash(strPath, i+1)) - { - const wxString strDir = strPath.Mid(0,i); - if (!::wxDirExists(strDir)) - { - if (!::wxMkdir(strDir)) - { - wxString strMsg = "Impossibile creare la cartella "; - strMsg << strDir << " !!"; - wxMessageBox(strMsg, "Attenzione!", wxICON_ERROR); - } - } - } -} - -bool aga_unzip(const char* zipfile, const char* destdir) -{ - wxArrayString aFiles; - const unsigned int files = aga_getziplist(zipfile, aFiles); - - wxProgressDialog pi("Unzip", "", files, NULL, wxPD_AUTO_HIDE | wxPD_APP_MODAL | wxPD_CAN_ABORT); - pi.SetSize(480, 120); - pi.Center(); - - for (unsigned int f = 0; f < files; f++) - { - const wxString& strFileName = aFiles[f]; - if (!pi.Update(f, strFileName)) - break; - - if (wxEndsWithPathSeparator(strFileName) || strFileName.Find('.') < 0) // Is dir name - { - wxString strOutDir = destdir; - if (!wxEndsWithPathSeparator(strOutDir)) - strOutDir += wxFILE_SEP_PATH; - strOutDir += strFileName; - aga_create_dir(strOutDir); - } - else - { - wxFFileInputStream file(zipfile); - wxZipInputStream fin(file); +#include "wxinc.h" +#include "incstr.h" + +#include "agasys.h" +#include "xvt.h" + +/////////////////////////////////////////////////////////// +// Unzip support +/////////////////////////////////////////////////////////// + +#include +#include +#include +#include + +static unsigned int aga_getziplist(const char* zipfile, wxArrayString& aFiles) +{ + wxFFileInputStream fin(zipfile); + wxZipInputStream zip(fin); + for (wxZipEntry* z = zip.GetNextEntry(); z; z = zip.GetNextEntry()) + { + const wxString str = z->GetInternalName(); + aFiles.Add(str); + } + + return aFiles.GetCount(); +} + +static int aga_find_slash(const wxString& path, int from) +{ + for (int i = from; path[i]; i++) + if (wxIsPathSeparator(path[i])) + return i; + + return -1; +} + +static void aga_create_dir(wxString strPath) +{ + if (!wxEndsWithPathSeparator(strPath)) + strPath += wxFILE_SEP_PATH; + + for (int i = aga_find_slash(strPath, 0); i > 0; i = aga_find_slash(strPath, i+1)) + { + const wxString strDir = strPath.Mid(0,i); + if (!::wxDirExists(strDir)) + { + if (!::wxMkdir(strDir)) + { + wxString strMsg = "Impossibile creare la cartella "; + strMsg << strDir << " !!"; + wxMessageBox(strMsg, "Attenzione!", wxICON_ERROR); + } + } + } +} + +bool aga_unzip(const char* zipfile, const char* destdir) +{ + wxArrayString aFiles; + const unsigned int files = aga_getziplist(zipfile, aFiles); + + wxProgressDialog pi("Unzip", "", files, NULL, wxPD_AUTO_HIDE | wxPD_APP_MODAL | wxPD_CAN_ABORT); + pi.SetSize(480, 120); + pi.Center(); + + for (unsigned int f = 0; f < files; f++) + { + const wxString& strFileName = aFiles[f]; + if (!pi.Update(f, strFileName)) + break; + + if (wxEndsWithPathSeparator(strFileName) || strFileName.Find('.') < 0) // Is dir name + { + wxString strOutDir = destdir; + if (!wxEndsWithPathSeparator(strOutDir)) + strOutDir += wxFILE_SEP_PATH; + strOutDir += strFileName; + aga_create_dir(strOutDir); + } + else + { + wxFFileInputStream file(zipfile); + wxZipInputStream fin(file); wxZipEntry* entry = NULL; do entry = fin.GetNextEntry(); while (entry && entry->GetInternalName() != strFileName); if (entry == NULL || !fin.OpenEntry(*entry)) continue; - - wxString strOutFile = destdir; - if (!wxEndsWithPathSeparator(strOutFile) && !wxIsPathSeparator(strFileName[0])) - strOutFile += wxFILE_SEP_PATH; - strOutFile += strFileName; - - wxString strPath; - ::wxSplitPath(strOutFile, &strPath, NULL, NULL); - aga_create_dir(strPath); - - wxFileOutputStream fout(strOutFile); - fout.Write(fin); - } - } - return files > 0; -} - -/////////////////////////////////////////////////////////// -// Zip support -/////////////////////////////////////////////////////////// - -static void AddFileToZip(const wxString& strPrefix, const wxString& strFile, - wxZipOutputStream& zip) -{ - if (!wxFileExists(strFile)) - return; - - wxString strPath, strName, strExt; - wxSplitPath(strFile, &strPath, &strName, &strExt); - - wxString strRelName; - strRelName = strPath.Mid(strPrefix.Length()); - if (!strRelName.IsEmpty()) - strRelName += '/'; - strRelName += strName; - strRelName += '.'; - strRelName += strExt; - - zip.PutNextEntry(strRelName); - wxFileInputStream fin(strFile); - zip.Write(fin); // Scrivo file compresso -} - -static bool AddFilesToZip(const wxString& strBase, wxArrayString& aFiles, const char* zipfile) -{ - wxFFileOutputStream out(zipfile); - wxZipOutputStream zip(out); - - const size_t nFiles = aFiles.GetCount(); - wxProgressDialog pi("Zip", "", nFiles, NULL, wxPD_AUTO_HIDE | wxPD_APP_MODAL | wxPD_CAN_ABORT); - pi.SetSize(480, 120); - pi.Center(); - - for (size_t i = 0; i < nFiles; i++) - { - const wxString& str = aFiles[i]; - if (!pi.Update(i, str)) - break; - AddFileToZip(strBase, str, zip); - } - return true; -} - -bool aga_zip(const char* srcfiles, const char* zipfile) -{ - wxString strBase, strMask, strExt; - wxSplitPath(srcfiles, &strBase, &strMask, &strExt); - strMask += '.'; - strMask += strExt; - - wxArrayString aFiles; - wxDir::GetAllFiles(strBase, &aFiles, strMask); - - return AddFilesToZip(strBase, aFiles, zipfile); -} - -bool aga_zip_filelist(const char* filelist, const char* zipfile) -{ - wxArrayString aFiles; - ifstream fin(filelist); - while (!fin.eof()) - { - char name[_MAX_PATH]; - fin.getline(name, sizeof(name)); - if (*name) - aFiles.Add(name); - else - break; - } - return AddFilesToZip("", aFiles, zipfile); -} - -/////////////////////////////////////////////////////////// -// DDE -/////////////////////////////////////////////////////////// - -#ifdef __WXMSW__ - #include - #define wxAgaClient wxDDEClient - #define wxAgaConnection wxDDEConnection -#else - // Forse inutile: forse gia' fatto da wxWidgets - #include - #define wxAgaClient wxTCPClient - #define wxAgaConnection wxTCPConnection -#endif - -static wxAgaClient* _net_client = NULL; -static unsigned long _net_conns = 0; - -unsigned long aga_dde_connect(const char* host, const char* service, const char* topic) -{ - if (_net_client == NULL) - { - _net_client = new wxAgaClient; - _net_conns = 0; - } - - wxConnectionBase* conn = _net_client->MakeConnection(host, service, topic); - if (conn != NULL) - _net_conns++; - - return (unsigned long)conn; -} - -bool aga_dde_execute(unsigned long connection, const char* msg) -{ - bool ok = false; - if (connection != 0) - { - wxAgaConnection* conn = (wxAgaConnection*)connection; - ok = conn->Execute((char*)msg, -1); - } - return ok; -} - -bool aga_dde_terminate(unsigned long connection) -{ - bool ok = false; - if (connection != 0 && _net_client != NULL) - { - wxAgaConnection* conn = (wxAgaConnection*)connection; - ok = conn->Disconnect(); - if (ok && _net_conns > 0) - { - _net_conns--; - if (_net_conns == 0) - { - delete _net_client; - _net_client = NULL; - } - } - } - return ok; -} - -/////////////////////////////////////////////////////////// -// TProgressIndicator -/////////////////////////////////////////////////////////// - -class TProgressIndicator : public wxDialog -{ - enum { MAX_GAUGES = 16 }; - wxGauge* m_pGauge[MAX_GAUGES]; - wxStaticText* m_pPassed; - wxStaticText* m_pResidual; - wxStaticText* m_pEstimated; - wxStopWatch m_chrono; - long m_nNextUpdate; - -protected: - DECLARE_EVENT_TABLE(); - - void Init(wxString msg, int nGauges, bool bCancellable); - wxString msec2str(long ms) const; - long Elapsed() const { return m_chrono.Time(); } - -public: - void SetRange(int nRange, int nGauge = 0); - bool SetProgress(int nPos, int nGauge = 0); - void SetMessage(wxString msg); - - TProgressIndicator(wxString msg, bool bCancellable, int nGauges); - TProgressIndicator(size_t nRange, wxString msg, bool bCancellable); - virtual ~TProgressIndicator(); -}; - -BEGIN_EVENT_TABLE(TProgressIndicator, wxDialog) -// EVT_MENU(wxID_CANCEL, TProgressIndicator::OnCancel) -END_EVENT_TABLE() - -wxString TProgressIndicator::msec2str(long ms) const -{ - int s = ms/1000; - const int h = s / 3600; - s -= h*3600; - const int m = s / 60; - s -= m*60; - return wxString::Format(wxT("%02d:%02d:%02d"), h, m, s); -} - -void TProgressIndicator::SetRange(int nRange, int nGauge) -{ - wxASSERT(nRange >= 0 && nGauge >= 0 && nGauge < MAX_GAUGES); - m_pGauge[nGauge]->SetRange(nRange); -} - -bool TProgressIndicator::SetProgress(int nPos, int nGauge) -{ - if (!IsShown()) - return false; - - wxASSERT(nPos >= 0 && nGauge >= 0 && nGauge < MAX_GAUGES); - m_pGauge[nGauge]->SetValue(nPos); - - const long elap = Elapsed(); - if (elap > m_nNextUpdate) - { - m_nNextUpdate = elap+CLOCKS_PER_SEC; - m_pPassed->SetLabel(msec2str(elap)); - - wxLongLong_t nTotValue = 0, nTotRange = 0; - for (int i = 0; i < MAX_GAUGES && m_pGauge[i]; i++) - { - const int nValue = m_pGauge[i]->GetValue(); - const int nRange = m_pGauge[i]->GetRange(); - if (nValue < nRange) // Escludi dal calcolo i processi già terminati - { - nTotValue += nValue; - nTotRange += nRange; - } - } - if (nTotValue > 0) - { - const long est = long(elap * nTotRange / nTotValue); - m_pEstimated->SetLabel(msec2str(est)); - m_pResidual->SetLabel(msec2str(est-elap)); - } - - wxYield(); - } - - return true; -} - -void TProgressIndicator::SetMessage(wxString msg) -{ SetLabel(msg); } - -void TProgressIndicator::Init(wxString msg, int nGauges, bool bCancellable) -{ - const int nGap = 4; - wxBoxSizer* pTopSizer = new wxBoxSizer(wxVERTICAL); - SetSizer(pTopSizer); - - memset(m_pGauge, 0, sizeof(m_pGauge)); - for (int i = 0; i < nGauges; i++) - { - m_pGauge[i] = new wxGauge(this, 1001+i, 100, wxDefaultPosition, wxSize(400, -1)); - pTopSizer->Add(m_pGauge[i], 0, wxALL, nGap); - } - - wxGridSizer* pTimersSizer = new wxGridSizer(1, 3, nGap, nGap); - pTopSizer->Add(pTimersSizer, 0, wxEXPAND); - - wxStaticBoxSizer* pPassed = new wxStaticBoxSizer(wxVERTICAL, this, _("Elapsed Time")); - pTimersSizer->Add(pPassed, 0, wxEXPAND); - m_pPassed = new wxStaticText(this, 1101, wxT("00:00:00")); - pPassed->Add(m_pPassed, 0, wxALL|wxALIGN_CENTER, 0); - - wxStaticBoxSizer* pResidual = new wxStaticBoxSizer(wxVERTICAL, this, _("Residual Time")); - pTimersSizer->Add(pResidual, 0, wxEXPAND); - m_pResidual = new wxStaticText(this, 1102, wxT("00:00:00")); - pResidual->Add(m_pResidual, 0, wxALL|wxALIGN_CENTER, 0); - - wxStaticBoxSizer* pEstimated = new wxStaticBoxSizer(wxVERTICAL, this, _("Estimated Time")); - pTimersSizer->Add(pEstimated, 0, wxEXPAND); - m_pEstimated = new wxStaticText(this, 1103, wxT("00:00:00")); - pEstimated->Add(m_pEstimated, 0, wxALL|wxALIGN_CENTER, 0); - - wxButton* pCancel = NULL; - if (bCancellable) - { - pCancel = new wxButton(this, wxID_CANCEL, _("Cancel")); - pTopSizer->Add(pCancel, 0, wxALL|wxALIGN_CENTER_HORIZONTAL, nGap); - } - - pTopSizer->SetSizeHints(this); - - SetMessage(msg); - - Show(); - Enable(); - Update(); - - m_nNextUpdate = 0; - m_chrono.Start(); -} - -TProgressIndicator::TProgressIndicator(size_t nRange, wxString msg, bool bCancellable) - : wxDialog(NULL, wxID_ANY, msg) -{ - Init(msg, 1, bCancellable); - SetRange(nRange, 0); -} - -TProgressIndicator::TProgressIndicator(wxString msg, bool bCancellable, int nGauges) - : wxDialog(NULL, wxID_ANY, msg) -{ - Init(msg, nGauges, bCancellable); -} - -TProgressIndicator::~TProgressIndicator() -{ } - -/////////////////////////////////////////////////////////// -// Multiprocess -/////////////////////////////////////////////////////////// - -class TWorker : public wxThread -{ - XVT_MULTITHREAD_CALLBACK m_pFunc; - void* m_pCaller; - void* m_pData; - int m_nFirst, m_nLast, m_nTotal; - TProgressIndicator* m_pi; - int m_nGauge; - -protected: - virtual ExitCode Entry(); - -public: - TWorker(XVT_MULTITHREAD_CALLBACK func, void* pCaller, void* pData, - int nFirst, int nLast, int nTotal, TProgressIndicator* pi, int nGauge); -}; - -wxThread::ExitCode TWorker::Entry() -{ - ExitCode ec = 0; - if (m_pi != NULL) - { - m_pi->SetRange(m_nLast-m_nFirst, m_nGauge); - for (int i = m_nFirst; i < m_nLast && ec == 0; i++) - { - ec = (ExitCode)m_pFunc(m_pCaller, m_pData, i, m_nTotal); - if (!m_pi->SetProgress(i-m_nFirst+1, m_nGauge)) - ec = ExitCode(-1); - } - } - else - { - for (int i = m_nFirst; i < m_nLast && ec == 0; i++) - ec = (ExitCode)m_pFunc(m_pCaller, m_pData, i, m_nTotal); - } - return ec; -} - -TWorker::TWorker(XVT_MULTITHREAD_CALLBACK func, void* pCaller, void* pData, - int nFirst, int nLast, int nTotal, TProgressIndicator* pi, int nGauge) - : wxThread(wxTHREAD_JOINABLE), m_pFunc(func), m_pCaller(pCaller), m_pData(pData), - m_nFirst(nFirst), m_nLast(nLast), m_nTotal(nTotal), m_pi(pi), m_nGauge(nGauge) - -{ -// SetPriority(WXTHREAD_MIN_PRIORITY); - Create(); -} - -BOOLEAN xvt_sys_multithread(XVT_MULTITHREAD_CALLBACK pFunc, void* pCaller, void* pData, - int tot, const char* msg) -{ - const int MAX_WORKERS = 16; - - // Bilanciamento automatico - int nWorkers = wxThread::GetCPUCount(); - if (nWorkers <= 0) - nWorkers = 1; - if (nWorkers > tot) - nWorkers = tot; - if (nWorkers > MAX_WORKERS) - nWorkers = MAX_WORKERS; - - int ret = 0; - if (nWorkers > 1) - { - TProgressIndicator* pi = NULL; - if (msg && *msg) - pi = new TProgressIndicator(msg, tot > nWorkers, nWorkers); - - TWorker* worker[MAX_WORKERS]; memset(worker, 0, sizeof(worker)); - - int nFirst, nLast = 0, w; - for (w = 0; w < nWorkers; w++) - { - nFirst = nLast; - nLast = tot*(w+1)/nWorkers; - worker[w] = new TWorker(pFunc, pCaller, pData, nFirst, nLast, tot, pi, w); - } - - for (w = 0; w < nWorkers; w++) - worker[w]->Run(); - - if (pi != NULL) - pi->Refresh(); - - for (w = 0; w < nWorkers; w++) - { - const wxThread::ExitCode r = worker[w]->Wait(); - if (ret == 0 && r != 0) - ret = int(r); - delete worker[w]; - worker[w] = NULL; - } - - if (pi != NULL) - delete pi; - } - else - { - if (msg && *msg) - { - TProgressIndicator pi(size_t(tot), msg, tot > nWorkers); - for (int i = 0; i < tot && ret == 0; i++) - { - ret = pFunc(pCaller, pData, i, tot); - if (!pi.SetProgress(i+1)) - ret = -1; - } - } - else - { - for (int i = 0; i < tot && ret == 0; i++) - ret = pFunc(pCaller, pData, i, tot); - } - } - - return ret; -} + + wxString strOutFile = destdir; + if (!wxEndsWithPathSeparator(strOutFile) && !wxIsPathSeparator(strFileName[0])) + strOutFile += wxFILE_SEP_PATH; + strOutFile += strFileName; + + wxString strPath; + ::wxSplitPath(strOutFile, &strPath, NULL, NULL); + aga_create_dir(strPath); + + wxFileOutputStream fout(strOutFile); + fout.Write(fin); + } + } + return files > 0; +} + +/////////////////////////////////////////////////////////// +// Zip support +/////////////////////////////////////////////////////////// + +static void AddFileToZip(const wxString& strPrefix, const wxString& strFile, + wxZipOutputStream& zip) +{ + if (!wxFileExists(strFile)) + return; + + wxString strPath, strName, strExt; + wxSplitPath(strFile, &strPath, &strName, &strExt); + + wxString strRelName; + strRelName = strPath.Mid(strPrefix.Length()); + if (!strRelName.IsEmpty()) + strRelName += '/'; + strRelName += strName; + strRelName += '.'; + strRelName += strExt; + + zip.PutNextEntry(strRelName); + wxFileInputStream fin(strFile); + zip.Write(fin); // Scrivo file compresso +} + +static bool AddFilesToZip(const wxString& strBase, wxArrayString& aFiles, const char* zipfile) +{ + wxFFileOutputStream out(zipfile); + wxZipOutputStream zip(out); + + const size_t nFiles = aFiles.GetCount(); + wxProgressDialog pi("Zip", "", nFiles, NULL, wxPD_AUTO_HIDE | wxPD_APP_MODAL | wxPD_CAN_ABORT); + pi.SetSize(480, 120); + pi.Center(); + + for (size_t i = 0; i < nFiles; i++) + { + const wxString& str = aFiles[i]; + if (!pi.Update(i, str)) + break; + AddFileToZip(strBase, str, zip); + } + return true; +} + +bool aga_zip(const char* srcfiles, const char* zipfile) +{ + wxString strBase, strMask, strExt; + wxSplitPath(srcfiles, &strBase, &strMask, &strExt); + strMask += '.'; + strMask += strExt; + + wxArrayString aFiles; + wxDir::GetAllFiles(strBase, &aFiles, strMask); + + return AddFilesToZip(strBase, aFiles, zipfile); +} + +bool aga_zip_filelist(const char* filelist, const char* zipfile) +{ + wxArrayString aFiles; + ifstream fin(filelist); + while (!fin.eof()) + { + char name[_MAX_PATH]; + fin.getline(name, sizeof(name)); + if (*name) + aFiles.Add(name); + else + break; + } + return AddFilesToZip("", aFiles, zipfile); +} + +/////////////////////////////////////////////////////////// +// DDE +/////////////////////////////////////////////////////////// + +#ifdef __WXMSW__ + #include + #define wxAgaClient wxDDEClient + #define wxAgaConnection wxDDEConnection +#else + // Forse inutile: forse gia' fatto da wxWidgets + #include + #define wxAgaClient wxTCPClient + #define wxAgaConnection wxTCPConnection +#endif + +static wxAgaClient* _net_client = NULL; +static unsigned long _net_conns = 0; + +unsigned long aga_dde_connect(const char* host, const char* service, const char* topic) +{ + if (_net_client == NULL) + { + _net_client = new wxAgaClient; + _net_conns = 0; + } + + wxConnectionBase* conn = _net_client->MakeConnection(host, service, topic); + if (conn != NULL) + _net_conns++; + + return (unsigned long)conn; +} + +bool aga_dde_execute(unsigned long connection, const char* msg) +{ + bool ok = false; + if (connection != 0) + { + wxAgaConnection* conn = (wxAgaConnection*)connection; + ok = conn->Execute((char*)msg, -1); + } + return ok; +} + +bool aga_dde_terminate(unsigned long connection) +{ + bool ok = false; + if (connection != 0 && _net_client != NULL) + { + wxAgaConnection* conn = (wxAgaConnection*)connection; + ok = conn->Disconnect(); + if (ok && _net_conns > 0) + { + _net_conns--; + if (_net_conns == 0) + { + delete _net_client; + _net_client = NULL; + } + } + } + return ok; +} + +/////////////////////////////////////////////////////////// +// TProgressIndicator +/////////////////////////////////////////////////////////// + +class TProgressIndicator : public wxDialog +{ + enum { MAX_GAUGES = 16 }; + wxGauge* m_pGauge[MAX_GAUGES]; + wxStaticText* m_pPassed; + wxStaticText* m_pResidual; + wxStaticText* m_pEstimated; + wxStopWatch m_chrono; + long m_nNextUpdate; + +protected: + DECLARE_EVENT_TABLE(); + + void Init(wxString msg, int nGauges, bool bCancellable); + wxString msec2str(long ms) const; + long Elapsed() const { return m_chrono.Time(); } + +public: + void SetRange(int nRange, int nGauge = 0); + bool SetProgress(int nPos, int nGauge = 0); + void SetMessage(wxString msg); + + TProgressIndicator(wxString msg, bool bCancellable, int nGauges); + TProgressIndicator(size_t nRange, wxString msg, bool bCancellable); + virtual ~TProgressIndicator(); +}; + +BEGIN_EVENT_TABLE(TProgressIndicator, wxDialog) +// EVT_MENU(wxID_CANCEL, TProgressIndicator::OnCancel) +END_EVENT_TABLE() + +wxString TProgressIndicator::msec2str(long ms) const +{ + int s = ms/1000; + const int h = s / 3600; + s -= h*3600; + const int m = s / 60; + s -= m*60; + return wxString::Format(wxT("%02d:%02d:%02d"), h, m, s); +} + +void TProgressIndicator::SetRange(int nRange, int nGauge) +{ + wxASSERT(nRange >= 0 && nGauge >= 0 && nGauge < MAX_GAUGES); + m_pGauge[nGauge]->SetRange(nRange); +} + +bool TProgressIndicator::SetProgress(int nPos, int nGauge) +{ + if (!IsShown()) + return false; + + wxASSERT(nPos >= 0 && nGauge >= 0 && nGauge < MAX_GAUGES); + m_pGauge[nGauge]->SetValue(nPos); + + const long elap = Elapsed(); + if (elap > m_nNextUpdate) + { + m_nNextUpdate = elap+CLOCKS_PER_SEC; + m_pPassed->SetLabel(msec2str(elap)); + + wxLongLong_t nTotValue = 0, nTotRange = 0; + for (int i = 0; i < MAX_GAUGES && m_pGauge[i]; i++) + { + const int nValue = m_pGauge[i]->GetValue(); + const int nRange = m_pGauge[i]->GetRange(); + if (nValue < nRange) // Escludi dal calcolo i processi già terminati + { + nTotValue += nValue; + nTotRange += nRange; + } + } + if (nTotValue > 0) + { + const long est = long(elap * nTotRange / nTotValue); + m_pEstimated->SetLabel(msec2str(est)); + m_pResidual->SetLabel(msec2str(est-elap)); + } + + wxYield(); + } + + return true; +} + +void TProgressIndicator::SetMessage(wxString msg) +{ SetLabel(msg); } + +void TProgressIndicator::Init(wxString msg, int nGauges, bool bCancellable) +{ + const int nGap = 4; + wxBoxSizer* pTopSizer = new wxBoxSizer(wxVERTICAL); + SetSizer(pTopSizer); + + memset(m_pGauge, 0, sizeof(m_pGauge)); + for (int i = 0; i < nGauges; i++) + { + m_pGauge[i] = new wxGauge(this, 1001+i, 100, wxDefaultPosition, wxSize(400, -1)); + pTopSizer->Add(m_pGauge[i], 0, wxALL, nGap); + } + + wxGridSizer* pTimersSizer = new wxGridSizer(1, 3, nGap, nGap); + pTopSizer->Add(pTimersSizer, 0, wxEXPAND); + + wxStaticBoxSizer* pPassed = new wxStaticBoxSizer(wxVERTICAL, this, _("Elapsed Time")); + pTimersSizer->Add(pPassed, 0, wxEXPAND); + m_pPassed = new wxStaticText(this, 1101, wxT("00:00:00")); + pPassed->Add(m_pPassed, 0, wxALL|wxALIGN_CENTER, 0); + + wxStaticBoxSizer* pResidual = new wxStaticBoxSizer(wxVERTICAL, this, _("Residual Time")); + pTimersSizer->Add(pResidual, 0, wxEXPAND); + m_pResidual = new wxStaticText(this, 1102, wxT("00:00:00")); + pResidual->Add(m_pResidual, 0, wxALL|wxALIGN_CENTER, 0); + + wxStaticBoxSizer* pEstimated = new wxStaticBoxSizer(wxVERTICAL, this, _("Estimated Time")); + pTimersSizer->Add(pEstimated, 0, wxEXPAND); + m_pEstimated = new wxStaticText(this, 1103, wxT("00:00:00")); + pEstimated->Add(m_pEstimated, 0, wxALL|wxALIGN_CENTER, 0); + + wxButton* pCancel = NULL; + if (bCancellable) + { + pCancel = new wxButton(this, wxID_CANCEL, _("Cancel")); + pTopSizer->Add(pCancel, 0, wxALL|wxALIGN_CENTER_HORIZONTAL, nGap); + } + + pTopSizer->SetSizeHints(this); + + SetMessage(msg); + + Show(); + Enable(); + Update(); + + m_nNextUpdate = 0; + m_chrono.Start(); +} + +TProgressIndicator::TProgressIndicator(size_t nRange, wxString msg, bool bCancellable) + : wxDialog(NULL, wxID_ANY, msg) +{ + Init(msg, 1, bCancellable); + SetRange(nRange, 0); +} + +TProgressIndicator::TProgressIndicator(wxString msg, bool bCancellable, int nGauges) + : wxDialog(NULL, wxID_ANY, msg) +{ + Init(msg, nGauges, bCancellable); +} + +TProgressIndicator::~TProgressIndicator() +{ } + +/////////////////////////////////////////////////////////// +// Multiprocess +/////////////////////////////////////////////////////////// + +class TWorker : public wxThread +{ + XVT_MULTITHREAD_CALLBACK m_pFunc; + void* m_pCaller; + void* m_pData; + int m_nFirst, m_nLast, m_nTotal; + TProgressIndicator* m_pi; + int m_nGauge; + +protected: + virtual ExitCode Entry(); + +public: + TWorker(XVT_MULTITHREAD_CALLBACK func, void* pCaller, void* pData, + int nFirst, int nLast, int nTotal, TProgressIndicator* pi, int nGauge); +}; + +wxThread::ExitCode TWorker::Entry() +{ + ExitCode ec = 0; + if (m_pi != NULL) + { + m_pi->SetRange(m_nLast-m_nFirst, m_nGauge); + for (int i = m_nFirst; i < m_nLast && ec == 0; i++) + { + ec = (ExitCode)m_pFunc(m_pCaller, m_pData, i, m_nTotal); + if (!m_pi->SetProgress(i-m_nFirst+1, m_nGauge)) + ec = ExitCode(-1); + } + } + else + { + for (int i = m_nFirst; i < m_nLast && ec == 0; i++) + ec = (ExitCode)m_pFunc(m_pCaller, m_pData, i, m_nTotal); + } + return ec; +} + +TWorker::TWorker(XVT_MULTITHREAD_CALLBACK func, void* pCaller, void* pData, + int nFirst, int nLast, int nTotal, TProgressIndicator* pi, int nGauge) + : wxThread(wxTHREAD_JOINABLE), m_pFunc(func), m_pCaller(pCaller), m_pData(pData), + m_nFirst(nFirst), m_nLast(nLast), m_nTotal(nTotal), m_pi(pi), m_nGauge(nGauge) + +{ +// SetPriority(WXTHREAD_MIN_PRIORITY); + Create(); +} + +BOOLEAN xvt_sys_multithread(XVT_MULTITHREAD_CALLBACK pFunc, void* pCaller, void* pData, + int tot, const char* msg) +{ + const int MAX_WORKERS = 16; + + // Bilanciamento automatico + int nWorkers = wxThread::GetCPUCount(); + if (nWorkers <= 0) + nWorkers = 1; + if (nWorkers > tot) + nWorkers = tot; + if (nWorkers > MAX_WORKERS) + nWorkers = MAX_WORKERS; + + int ret = 0; + if (nWorkers > 1) + { + TProgressIndicator* pi = NULL; + if (msg && *msg) + pi = new TProgressIndicator(msg, tot > nWorkers, nWorkers); + + TWorker* worker[MAX_WORKERS]; memset(worker, 0, sizeof(worker)); + + int nFirst, nLast = 0, w; + for (w = 0; w < nWorkers; w++) + { + nFirst = nLast; + nLast = tot*(w+1)/nWorkers; + worker[w] = new TWorker(pFunc, pCaller, pData, nFirst, nLast, tot, pi, w); + } + + for (w = 0; w < nWorkers; w++) + worker[w]->Run(); + + if (pi != NULL) + pi->Refresh(); + + for (w = 0; w < nWorkers; w++) + { + const wxThread::ExitCode r = worker[w]->Wait(); + if (ret == 0 && r != 0) + ret = int(r); + delete worker[w]; + worker[w] = NULL; + } + + if (pi != NULL) + delete pi; + } + else + { + if (msg && *msg) + { + TProgressIndicator pi(size_t(tot), msg, tot > nWorkers); + for (int i = 0; i < tot && ret == 0; i++) + { + ret = pFunc(pCaller, pData, i, tot); + if (!pi.SetProgress(i+1)) + ret = -1; + } + } + else + { + for (int i = 0; i < tot && ret == 0; i++) + ret = pFunc(pCaller, pData, i, tot); + } + } + + return ret; +} diff --git a/xvaga/xvaga.cpp b/xvaga/xvaga.cpp index 87d2e02c9..631a4112c 100755 --- a/xvaga/xvaga.cpp +++ b/xvaga/xvaga.cpp @@ -3504,6 +3504,27 @@ int xvt_sys_get_profile_string(const char* file, const char* paragraph, const ch if (file == NULL || *file == '\0') file = xvt_fsys_get_campo_ini(); + if (wxStricmp(file, "ssa.ini") == 0) + { + wxTextFile ssa; + if (ssa.Open(file)) + { + for (wxString str = ssa.GetFirstLine(); !ssa.Eof(); str = ssa.GetNextLine()) + { + str.Trim(false); + if (str.StartsWith(name)) + { + str = str.AfterFirst('='); + str.Trim(true); str.Trim(false); + wxStrncpy(value, str, maxsize-1); + return str.Len(); + } + } + } + wxStrncpy(value, defval, maxsize-1); + return wxStrlen(defval); + } + if (paragraph == NULL || *paragraph == '\0') paragraph = "Main"; @@ -3953,7 +3974,13 @@ long xvt_vobj_get_attr(WINDOW win, long data) ret = (long)(const char*)_appl_version; break; case ATTR_APPL_VERSION_YEAR: - ret = wxAtoi(_appl_version.Left(4)); + if (_appl_version.IsEmpty()) + { + const wxString str = wxVERSION_STRING; + ret = str >= wxT("wxWidgets 2.8.12") ? 2121 : 2091; + } + else + ret = wxAtoi(_appl_version.Left(4)); break; case ATTR_APPL_ALREADY_RUNNING: ret = _appl_already_running; diff --git a/xvaga/xvt_ssa.cpp b/xvaga/xvt_ssa.cpp index d879d8ac2..28346f131 100644 --- a/xvaga/xvt_ssa.cpp +++ b/xvaga/xvt_ssa.cpp @@ -1,6 +1,8 @@ #include "wxinc.h" #include "xvt.h" +#include "wx/filename.h" + #include "../ssa/h/ssadll.h" #include "../ssa/h/ssaerr.h" @@ -23,18 +25,59 @@ static const char* xvt_dongle_sa_id() return id; } +static BOOLEAN xvt_dongle_sa_is_remote() +{ + char ssaagent[128]; + const int len = xvt_sys_get_profile_string("ssa.ini", "", "SSA-PORT", "", ssaagent, sizeof(ssaagent)); + return len > 0; +} + +/////////////////////////////////////////////////////////// +// TSSA_Pinger +/////////////////////////////////////////////////////////// + +class TSSA_Pinger : public wxTimer +{ +protected: + virtual void Notify(); + +public: + TSSA_Pinger(); +}; + +static TSSA_Pinger* _ssa_timer = NULL; + +void TSSA_Pinger::Notify() +{ SSA_Ping(xvt_dongle_sa_id()); } + +TSSA_Pinger::TSSA_Pinger() +{ + const int sec = xvt_sys_get_profile_int("ssa.ini", "", "PING-DELAY", 60); + if (sec > 0) + Start(sec*1000); +} + +/////////////////////////////////////////////////////////// +// xvt_dongle_sa_... +/////////////////////////////////////////////////////////// + int xvt_dongle_sa_login(const char* module) { int err = _ssa_serial; const int nAssYear = xvt_vobj_get_attr(NULL_WIN, ATTR_APPL_VERSION_YEAR); - if (nAssYear > 2091) + if (nAssYear >= 2121) { if (_ssa_serial < 0) { err = SSA_Login(xvt_dongle_sa_id(), "Campo"); if (err == 0) + { err = _ssa_serial = SSA_NumeroSerie("Campo"); + + if (_ssa_timer == NULL && xvt_dongle_sa_is_remote()) + _ssa_timer = new TSSA_Pinger; + } } if (_ssa_serial >= 0 && module && *module) @@ -87,6 +130,11 @@ int xvt_dongle_sa_logout(const char* module) { _ssa_serial = SSA_UTENTE_NON_LOGGATO; _ssa_module.Empty(); + if (_ssa_timer) + { + delete _ssa_timer; + _ssa_timer = NULL; + } } } }