iphreeqc/phreeqcpp/ChartHandler.cpp
Darth Vader d83e815edb Squashed 'src/' changes from 9bd0be28..32fbc5ab
32fbc5ab Merge commit '050663209be623e2af35e3f93a41ac6f5ac1f18f'
05066320 Squashed 'phreeqcpp/' changes from 93ab5c9..82515f7

git-subtree-dir: src
git-subtree-split: 32fbc5ab56eb19fff92831e32cbac7f01e1cdf56
2023-05-26 04:28:17 +00:00

226 lines
4.9 KiB
C++

// ChartHandler.cpp: implementation of the ChartHandler class.
//
//////////////////////////////////////////////////////////////////////
#if defined MULTICHART
#include "Phreeqc.h"
#ifdef _DEBUG
#pragma warning(disable : 4786) // disable truncation warning (Only used by debugger)
#endif
#include "ChartHandler.h"
#include <iostream>
#if defined(PHREEQCI_GUI)
#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif
#endif
//////////////////////////////////////////////////////////////////////
// Construction/Destruction
//////////////////////////////////////////////////////////////////////
ChartHandler::ChartHandler(PHRQ_io *io)
:
PHRQ_base(io)
//
// default constructor for ChartHandler
//
{
current_chart = NULL;
current_chart_n_user = -1000;
u_g_defined = false;
timer = true;
active_charts = 0;
}
ChartHandler::~ChartHandler()
{
std::map<int, ChartObject *>::iterator it;
for (it = this->chart_map.begin(); it != chart_map.end(); it++)
{
delete it->second;
}
}
void
ChartHandler::Punch_user_graph(Phreeqc * phreeqc_ptr)
{
std::map<int, ChartObject *>::iterator it = this->chart_map.begin();
for ( ; it != chart_map.end(); it++)
{
if (it->second->Get_active())
{
#if defined(__cplusplus_cli)
while (0 != System::Threading::Interlocked::CompareExchange(it->second->usingResource, 4, 0))
{
System::Threading::Thread::Sleep(5);
}
#endif
try
{
this->current_chart = it->second;
phreeqc_ptr-> punch_user_graph();
}
catch (...)
{
#if defined(__cplusplus_cli)
int n = System::Threading::Interlocked::Exchange(it->second->usingResource, 0);
assert(n == 4);
#endif
throw;
}
#if defined(__cplusplus_cli)
System::Threading::Interlocked::Exchange(it->second->usingResource, 0);
#endif
}
}
}
bool
ChartHandler::Read(Phreeqc * phreeqc_ptr, CParser &parser)
{
int n_user;
std::string token;
// reads line, next character is after keyword
parser.check_line("ChartHandler", true, false, true, false);
std::istringstream iss(parser.line());
// keyword
iss >> token;
// number
if (!(iss >> n_user))
{
n_user = 1;
}
// makes new ChartObject if necessary
std::map<int, ChartObject *>::iterator it = this->chart_map.find(n_user);
if (it == this->chart_map.end())
{
chart_map[n_user] = new ChartObject(this->Get_io());
it = this->chart_map.find(n_user);
it->second->Set_phreeqc(phreeqc_ptr);
}
// Read/update ChartObject
#if defined(__cplusplus_cli)
while (0 != System::Threading::Interlocked::CompareExchange(it->second->usingResource, 5, 0))
{
System::Threading::Thread::Sleep(5);
}
#endif
try
{
{
it->second->Read(parser);
current_chart_n_user = n_user;
current_chart = it->second;
u_g_defined = true;
}
// if detached, set timer_end and free
if (it->second->Get_detach() && it->second->Get_form_started())
{
it->second->Set_end_timer(true);
it->second->Rate_free();
}
}
catch(...)
{
#if defined(__cplusplus_cli)
// Release lock
int n = System::Threading::Interlocked::Exchange(it->second->usingResource, 0);
assert(n == 5);
throw;
#endif
}
#if defined(__cplusplus_cli)
// Release lock
int n = System::Threading::Interlocked::Exchange(it->second->usingResource, 0);
assert(n == 5);
#endif
// if detached, wait for thread to acknowledge and then erase chart
if (it->second->Get_detach())
{
while (it->second->Get_form_started() && it->second->Get_done() != true)
{
#if defined(__cplusplus_cli)
System::Threading::Thread::Sleep(5);
#endif
}
delete it->second;
this->chart_map.erase(it);
}
return true;
}
bool
ChartHandler::End_timer()
{
size_t max_tries = 6000; // 1 h, but not used
std::map<int, ChartObject *>::iterator it = this->chart_map.begin();
if (chart_map.size() > 0)
{
screen_msg("Detaching charts...");
if (io != NULL)
{
io->error_flush();
}
}
for ( ; it != chart_map.end(); it++)
{
it->second->Rate_free();
if (it->second->Get_form_started())
{
#if defined(__cplusplus_cli)
while (0 != System::Threading::Interlocked::CompareExchange(it->second->usingResource, 6, 0))
{
System::Threading::Thread::Sleep(60);
}
#endif
it->second->Set_end_timer(true);
//it->second->Set_phreeqc(NULL);
#if defined(__cplusplus_cli)
int n = System::Threading::Interlocked::Exchange(it->second->usingResource, 0);
assert(n == 6);
#endif
while (it->second->Get_done() != true)
{
#if defined(__cplusplus_cli)
System::Threading::Thread::Sleep(60);
#endif
}
//if (i >= max_tries || i2 >= max_tries)
//{
// error_msg("\nChart did not respond.", CONTINUE);
//}
}
}
if (chart_map.size() > 0)
{
screen_msg("\rCharts detached. \n");
if (io != NULL)
{
io->error_flush();
}
}
this->timer = false;
return true;
}
bool
ChartHandler::dump(std::ostream & oss, unsigned int indent)
{
std::map<int, ChartObject *>::iterator it = this->chart_map.begin();
for ( ; it != chart_map.end(); it++)
{
it->second->dump(oss, indent);
}
return true;
}
#endif