Commit 537a8df3 authored by Locatelli's avatar Locatelli
Browse files

Implement save and restore plot synchronize with nomad gui open and

close
parent 78f94272
......@@ -68,10 +68,8 @@ void crash_handler(int32 sig) {
int main(int32 argc, char* argv[]) {
// Init cameo application
string tmp = getServerEndPoint("ploty2");
char* args = (char*) tmp.c_str();
int32 err = EXIT_SUCCESS;
application::This::init(1, &args);
application::This::init(1, &argv[2]);
{
// Get nomad server instance
nomadserver = getNomadInstance(application::This::getServer());
......
......@@ -47,6 +47,8 @@ using namespace plot;
unique_ptr<application::Instance> nomadserver; //! Instance of nomad server
unique_ptr<application::Subscriber> datachangesubscriber; //! Subcriber on data change publisher of the server
QApplication* app = nullptr;
PlotWindow* window = nullptr;
/*!
* \brief crash handler method
......@@ -55,14 +57,27 @@ unique_ptr<application::Subscriber> datachangesubscriber; //! Subcriber on data
void crash_handler(int32 sig) {
// Cancel waiting message on data change subscriber connected to nomad server
datachangesubscriber->cancel();
app->closeAllWindows();
}
/*!
* \brief window in front
* \param[in] sig the signal number which calling this method
*/
void us1_signal(int32 sig) {
DBGMSG("receive us1_signal : " << sig);
if (window != nullptr) {
window->activateWindow();
}
}
/*!
* \brief main program function
* \return error code
*/
int32 main(int32 argc, char* argv[]) {
for (int32 i = 0; i < argc; ++i) {
DBGMSG(argv[i]);
}
......@@ -72,9 +87,8 @@ int32 main(int32 argc, char* argv[]) {
return EXIT_FAILURE;
}
QApplication app(argc, argv);
app = new QApplication(argc, argv);
qRegisterMetaType<view::qt::QtUpdateContainer>();
// Create and init the Matplolib module
view::mpl::Mpl* mpl = new view::mpl::Mpl();
......@@ -115,6 +129,7 @@ int32 main(int32 argc, char* argv[]) {
// signal(SIGSEGV, crash_handler);
signal(SIGPIPE, crash_handler);
signal(SIGINT, crash_handler);
signal(SIGUSR1, us1_signal);
// Init the nomad server requester manager
manager::ServerRequesterManager::getInstance()->init(requesterdb.get());
......@@ -157,16 +172,17 @@ int32 main(int32 argc, char* argv[]) {
DBGMSG("plotMessage.datay_ids_size() = " << plotMessage.datay_ids_size());
DBGMSG("plotMessage.dataz_ids_size() = " << plotMessage.dataz_ids_size());
PlotWindow window(mpl, plotMessage);
window = new PlotWindow(mpl, plotMessage);
try {
window.create(app, datachangesubscriber.get());
window.display();
window.show();
window->create(*app, datachangesubscriber.get());
window->display();
window->show();
}
catch (Error& e) {
err = EXIT_FAILURE;
}
app.exec();
app->exec();
delete window;
}
}
else {
......@@ -194,6 +210,8 @@ int32 main(int32 argc, char* argv[]) {
exit:
DBGMSG("delete mpl");
app->quit();
delete app;
delete mpl;
// Terminate cameo application
application::This::terminate();
......
......@@ -32,11 +32,15 @@ namespace manager {
PlotManager* PlotManager::m_Instance = nullptr;
const string PlotManager::CONFIG_PATH = "/.config/illploty2/";
const string PlotManager::CONFIG_NAME = "ploty2.conf";
const string PlotManager::DATA1_SUFFIX = ".data1";
const string PlotManager::DATA2_SUFFIX = ".data2";
/*
* constructor
*/
PlotManager::PlotManager() {
m_FileCounter = 0;
}
/*
......@@ -55,17 +59,87 @@ void PlotManager::resetInstance() {
*/
void PlotManager::reset() {
unique_lock<recursive_mutex> lock(m_PlotsMutex);
// Save open plots state
ostringstream filename;
filename << getenv("HOME") << CONFIG_PATH << CONFIG_NAME;
ofstream file(filename.str().c_str());
for (auto iter = m_PlotsProcesses.begin();iter != m_PlotsProcesses.end(); ++iter) {
if (iter->second->now() == application::RUNNING) {
// Write plot key in config file
file << iter->first << endl;
// Write plot data message in two files
ostringstream filename1;
filename1 << getenv("HOME") << CONFIG_PATH << iter->first << DATA1_SUFFIX;
ofstream file1(filename1.str().c_str(), ios::binary);
string data1;
m_PropertyPlotsData[iter->first].first.SerializeToString(&data1);
file1.write(data1.c_str(), data1.size());
ostringstream filename2;
filename2 << getenv("HOME") << CONFIG_PATH << iter->first << DATA2_SUFFIX;
ofstream file2(filename2.str().c_str(), ios::binary);
string data2;
m_PropertyPlotsData[iter->first].second.SerializeToString(&data2);
file2.write(data2.c_str(), data2.size());
}
}
// Stop all plot processes
for (auto iter : m_PlotsProcesses) {
DBGMSG("plotmanager delete plot : " << iter.first);
iter.second->kill();
iter.second->stop();
}
m_PlotsProcesses.clear();
m_PropertyPlotsData.clear();
}
/*
* reset
*/
void PlotManager::restore() {
ostringstream filename;
filename << getenv("HOME") << CONFIG_PATH << CONFIG_NAME;
ifstream file(filename.str().c_str());
if (file.is_open()) {
string line;
while(file.eof() == false) {
// Get plot key
getline(file, line);
ostringstream filename1;
filename1 << getenv("HOME") << CONFIG_PATH << line << DATA1_SUFFIX;
// Get plot data messages
ifstream file1(filename1.str().c_str(), ios::binary);
if (file1.is_open() == true) {
char c;
ostringstream part1;
while (file1.get(c)) {
part1 << c;
}
file1.close();
ostringstream filename2;
filename2 << getenv("HOME") << CONFIG_PATH << line << DATA2_SUFFIX;
ifstream file2(filename2.str().c_str(),ios::binary);
if (file2.is_open() == true) {
ostringstream part2;
while (file2.get(c)) {
part2 << c;
}
file2.close();
proto::Message message;
message.ParseFromString(part1.str());
proto::PlotPropertyDataMessage plotMessage;
plotMessage.ParseFromString(part2.str());
// Display plot
displayPropertyPlot(message, plotMessage);
}
}
}
}
}
/*
* getInstance
*/
PlotManager* PlotManager::getInstance() {
PlotManager * PlotManager::getInstance() {
if (m_Instance == nullptr) {
m_Instance = new PlotManager();
}
......@@ -85,7 +159,7 @@ void PlotManager::displayPropertyPlot(const proto::Message& message, const proto
if (iter != m_PlotsProcesses.end()) {
DBGMSG("state : " << iter->second->now());
// Check if exists
switch(iter->second->now()) {
switch (iter->second->now()) {
case application::PROCESSING_ERROR:
case application::FAILURE:
case application::SUCCESS:
......@@ -116,11 +190,7 @@ void PlotManager::displayPropertyPlot(const proto::Message& message, const proto
///////////////////////////////////////////////////////////////////////////////////////
//// Start new mplplot process for displaying, pass info to process using temporary files
////
DBGMSG("plotMessage.plotkey() = " << plotMessage.plotkey());
DBGMSG("plotMessage.aspect_ratios_size() = " << plotMessage.aspect_ratios_size());
DBGMSG("plotMessage.datax_ids_size() = " << plotMessage.datax_ids_size());
DBGMSG("plotMessage.datay_ids_size() = " << plotMessage.datay_ids_size());
DBGMSG("plotMessage.dataz_ids_size() = " << plotMessage.dataz_ids_size());
DBGMSG("plotMessage.plotkey() = " << plotMessage.plotkey()); DBGMSG("plotMessage.aspect_ratios_size() = " << plotMessage.aspect_ratios_size()); DBGMSG("plotMessage.datax_ids_size() = " << plotMessage.datax_ids_size()); DBGMSG("plotMessage.datay_ids_size() = " << plotMessage.datay_ids_size()); DBGMSG("plotMessage.dataz_ids_size() = " << plotMessage.dataz_ids_size());
string part1;
message.SerializeToString(&part1);
......@@ -129,7 +199,7 @@ void PlotManager::displayPropertyPlot(const proto::Message& message, const proto
// Create temporary file 1 which contains proto::Message info
ostringstream filename1;
filename1 << "/tmp/mplplot-" << m_FileCounter << ".message1";
filename1 << "/tmp/mplplot-" << plotMessage.plotkey() << ".message1";
ofstream file1(filename1.str().c_str(), ios::binary);
if (file1.is_open() == true) {
......@@ -138,7 +208,7 @@ void PlotManager::displayPropertyPlot(const proto::Message& message, const proto
// Create temporary file 2 which contains proto::PlotPropertyDataMessage info
ostringstream filename2;
filename2 << "/tmp/mplplot-" << m_FileCounter << ".message2";
filename2 << "/tmp/mplplot-" << plotMessage.plotkey() << ".message2";
ofstream file2(filename2.str().c_str(), ios::binary);
if (file2.is_open() == true) {
......@@ -151,36 +221,27 @@ void PlotManager::displayPropertyPlot(const proto::Message& message, const proto
args.push_back(filename2.str());
shared_ptr<cameo::application::Instance> plot = application::This::getServer().start("mplplot", args);
if (!plot->exists()) {
Error("PlotManager","displayPropertyPlot", "unable to start mplplot cameo instance", *plot);
Error("PlotManager", "displayPropertyPlot", "unable to start mplplot cameo instance", *plot);
return;
}
// Check that Ploty is really running by waiting for the status update.
plot->waitFor(application::RUNNING);
m_PlotsProcesses[plotMessage.plotkey()] = plot;
m_PropertyPlotsData[plotMessage.plotkey()] = make_pair(message, plotMessage);
} else {
Error("PlotManager","displayPropertyPlot", "couldn't managed to create temporary file", filename2.str());
Error("PlotManager", "displayPropertyPlot", "couldn't managed to create temporary file", filename2.str());
}
} else {
Error("PlotManager","displayPropertyPlot", "couldn't managed to create temporary file", filename1.str());
Error("PlotManager", "displayPropertyPlot", "couldn't managed to create temporary file", filename1.str());
}
} else {
///////////////////////////////////////////////////////////////////////////////////////
//// bring to front the plot
////
//TODO show in front
// Send signal USR1 to process pid , waiting for the new version of cameo cpp api
DBGMSG("plot already opened : " << plotMessage.plotkey());
}
}
/*
* removePlot
*/
void PlotManager::removePlot(const string& key) {
unique_lock<recursive_mutex> lock(m_PlotsMutex);
// Remove plot key of the map
if (m_PlotsProcesses.find(key) != m_PlotsProcesses.end()) {
m_PlotsProcesses.erase(key);
}
}
......
......@@ -54,10 +54,14 @@ public:
void displayPropertyPlot(const proto::Message& message, const proto::PlotPropertyDataMessage& plotMessage);
/*!
* \brief remove plot in the display plots map
* \param[in] key plot key
* \brief reset instance
*/
void reset();
/*!
* \brief restore plot as the previous instance
*/
void removePlot(const std::string& key);
void restore();
private:
......@@ -66,17 +70,17 @@ private:
*/
PlotManager();
/*!
* \brief reset instance
*/
void reset();
static PlotManager* m_Instance; //! Pointer of singleton instance
std::map<std::string, std::shared_ptr<cameo::application::Instance> > m_PlotsProcesses; //! Map of open display plots
std::map<std::string, std::pair<proto::Message , proto::PlotPropertyDataMessage> > m_PropertyPlotsData; //! Map of open display plots properties
std::recursive_mutex m_PlotsMutex; //! Mutex on plots map
uint32 m_FileCounter; //! File counter for temporary files
//! Configuration cache files
static const std::string CONFIG_PATH;
static const std::string CONFIG_NAME;
static const std::string DATA1_SUFFIX;
static const std::string DATA2_SUFFIX;
};
}
......
......@@ -74,6 +74,14 @@ void RequestDealerManager::loop(application::Responder* responder) {
dataMessage.ParseFromString(secondPart);
PlotManager::getInstance()->displayPropertyPlot(message, dataMessage);
}
// Close plots message
else if (message.type() == proto::Message::ClosePlots) {
PlotManager::getInstance()->reset();
}
// Restore plots message
else if (message.type() == proto::Message::RestorePlots) {
PlotManager::getInstance()->restore();
}
else {
Error("RequestDealerManager", "loop", "Receive bad plot type request");
}
......
......@@ -82,32 +82,37 @@ void ServerSubscriberManager::init(application::Subscriber* subscriber) {
*/
int32 ServerSubscriberManager::loop() {
string data1, data2;
m_Subscriber->receiveTwoBinaryParts(data1, data2);
notification::Message messageType;
messageType.ParseFromString(data1);
// Check for property changes
if (messageType.type() == notification::Message::PropertyChanged) {
notification::PropertyChanged messagePropertyChanged;
messagePropertyChanged.ParseFromString(data2);
if (messagePropertyChanged.databaseid() == 0) {
unique_lock<mutex> lock(m_UpdatersMutex);
int32 id = messagePropertyChanged.propertyid();
vector<int32>::iterator it;
// std::map<plot::Plot*, std::vector<int32> > localmap;
// {
// localmap = m_Updaters;
// }
// Look on all ids
for (auto iter : m_Updaters) {
it = find(iter.second.begin(), iter.second.end(), id);
if (it != iter.second.end()) {
// DBGMSG("--> " << messagePropertyChanged.databaseid() << " " << messagePropertyChanged.propertyid() << " : " << iter.first);
return id;
try {
m_Subscriber->receiveTwoBinaryParts(data1, data2);
notification::Message messageType;
messageType.ParseFromString(data1);
// Check for property changes
if (messageType.type() == notification::Message::PropertyChanged) {
notification::PropertyChanged messagePropertyChanged;
messagePropertyChanged.ParseFromString(data2);
if (messagePropertyChanged.databaseid() == 0) {
unique_lock<mutex> lock(m_UpdatersMutex);
int32 id = messagePropertyChanged.propertyid();
vector<int32>::iterator it;
// std::map<plot::Plot*, std::vector<int32> > localmap;
// {
// localmap = m_Updaters;
// }
// Look on all ids
for (auto iter : m_Updaters) {
it = find(iter.second.begin(), iter.second.end(), id);
if (it != iter.second.end()) {
// DBGMSG("--> " << messagePropertyChanged.databaseid() << " " << messagePropertyChanged.propertyid() << " : " << iter.first);
return id;
}
}
}
}
}
catch(...) {
}
return -1;
}
......
......@@ -18,6 +18,7 @@
#include "plot/EmptyPlot.h"
#include "view/mpl/Mpl.h"
#include "PlotWindow.h"
#include "Trace.h"
......@@ -50,6 +51,9 @@ void EmptyPlot::display() throw (Error) {
string title = getTitle();
try {
m_Mpl->title(title);
if (m_PlotWindow != nullptr) {
m_PlotWindow->setWindowTitle("Nomad plot");
}
} catch (Error &e) {
Warning("EmptyPlot", "display", "Failed to set window title", title);
}
......
......@@ -131,6 +131,20 @@ void PlotWindow::display() throw (Error) {
}
}
/*
* activateWindow
*/
void PlotWindow::activateWindow() {
///////////////////////////////////////////////////////////////////////////////////////
//// Show plot windows
////
try {
m_QtWindow->activateWindow();
} catch (...) {
Error("PlotWindow", "activateWindow", "Failed to activate window");
}
}
/*
* show
*/
......
......@@ -78,6 +78,12 @@ public:
*/
void display() throw (Error);
/*!
* \brief Active window on the top on screen
* \throws Error
*/
void activateWindow();
/*!
* \brief Show plot
* \throws Error
......
......@@ -106,9 +106,8 @@ void PropertyEmptyPlot::subscribeUpdate() {
* updatePlot
*/
void PropertyEmptyPlot::update(int32 id) {
plot::PlotType ptype = m_DataCont->getPlotType();
if (ptype != plot::PLOT_1D) {
if (ptype != plot::EMPTY_PLOT) {
if (m_EndOfPlot == false) {
unsubscribeUpdate();
m_EndOfPlot = true;
......
......@@ -87,12 +87,6 @@ QtColorMapWidget::QtColorMapWidget(QWidget *parent, plot::PlotWindow* plotWindow
setLayout(layout);
hide();
connect(m_ColorMapComboBox, SIGNAL(currentIndexChanged(int)), this, SLOT(setColorMap(int)));
connect(m_MinLevelRangeSlider, SIGNAL(valueChanged(int)), this, SLOT(setMinLevel(int)));
connect(m_MaxLevelRangeSlider, SIGNAL(valueChanged(int)), this, SLOT(setMaxLevel(int)));
}
/*
......@@ -108,6 +102,9 @@ QtColorMapWidget::~QtColorMapWidget() {
* activate
*/
void QtColorMapWidget::activate() {
connect(m_ColorMapComboBox, SIGNAL(currentIndexChanged(int)), this, SLOT(setColorMap(int)));
connect(m_MinLevelRangeSlider, SIGNAL(valueChanged(int)), this, SLOT(setMinLevel(int)));
connect(m_MaxLevelRangeSlider, SIGNAL(valueChanged(int)), this, SLOT(setMaxLevel(int)));
show();
}
......@@ -115,6 +112,9 @@ void QtColorMapWidget::activate() {
* desactivate
*/
void QtColorMapWidget::desactivate() {
disconnect(m_ColorMapComboBox, SIGNAL(currentIndexChanged(int)), 0, 0);
disconnect(m_MinLevelRangeSlider, SIGNAL(valueChanged(int)), 0, 0);
disconnect(m_MaxLevelRangeSlider, SIGNAL(valueChanged(int)), 0, 0);
hide();
}
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment