VPTissue Reference Manual
SimSession.cpp
Go to the documentation of this file.
1 /*
2  * Copyright 2011-2016 Universiteit Antwerpen
3  *
4  * Licensed under the EUPL, Version 1.1 or as soon they will be approved by
5  * the European Commission - subsequent versions of the EUPL (the "Licence");
6  * You may not use this work except in compliance with the Licence.
7  * You may obtain a copy of the Licence at: http://ec.europa.eu/idabc/eupl5
8  *
9  * Unless required by applicable law or agreed to in writing, software
10  * distributed under the Licence is distributed on an "AS IS" basis,
11  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12  * See the Licence for the specific language governing
13  * permissions and limitations under the Licence.
14  */
20 #include "session/SimSession.h"
21 
23 #include "exporters/CsvExporter.h"
24 #include "exporters/Hdf5Exporter.h"
25 #include "exporters/PlyExporter.h"
27 #include "exporters/XmlExporter.h"
29 #include "session/SimWorker.h"
30 #include "viewer/RootViewerNode.h"
31 #include "util/misc/Exception.h"
32 #include "util/misc/log_debug.h"
34 
35 #include <QThread>
36 #include <QCoreApplication>
37 
38 namespace SimPT_Shell {
39 namespace Session {
40 
41 using namespace std;
42 using namespace chrono;
43 using namespace boost::property_tree;
44 using namespace SimPT_Sim::ClockMan;
45 using namespace SimPT_Sim::Util;
46 using namespace SimPT_Sim;
47 using namespace SimPT_Sim::Event;
48 using namespace SimShell::Gui;
49 using namespace SimShell::Session;
50 using namespace SimShell::Ws;
51 using namespace SimShell::Ws::Event;
52 
53 SimSession::SimSession(const shared_ptr<MergedPreferences>& prefs, const ptree& sim_pt)
54  : m_sim(make_shared<Sim>()),
55  m_preferences(prefs),
56  m_sim_thread(new QThread(this)),
57  m_running(false),
58  m_steps_limit(-1),
59  m_parameter_buffer({ false, ptree() })
60 {
61  m_sim->Initialize(sim_pt); // may throw
62 }
63 
64 SimSession::SimSession(const shared_ptr<MergedPreferences>& prefs, const SimState& sim_state)
65  : m_sim(make_shared<Sim>()),
66  m_preferences(prefs),
67  m_sim_thread(new QThread(this)),
68  m_running(false),
69  m_steps_limit(0),
70  m_parameter_buffer({ false, ptree() })
71 {
72  m_sim->Initialize(sim_state); // may throw
73 }
74 
75 SimSession::~SimSession()
76 {
77  // To process a (potential) pending ExecuteViewUnit
78  // event in the eventloop after a StopSimulation
79  QCoreApplication::processEvents(QEventLoop::ExcludeUserInputEvents);
80  // Signaling closing of project..
81  m_sim->Notify({ m_sim, m_sim->GetSimStep(), SimEvent::Type::Done });
82 }
83 
84 shared_ptr<SimSession::RootViewerType> SimSession::CreateRootViewer(
86 {
87  return make_shared<Viewer::RootViewerNode<Sim>>(
88  m_preferences->GetChild("viewers"), m_sim, parent);
89 }
90 
91 shared_ptr<SimPT_Sim::Sim> SimSession::GetSim()
92 {
93  return m_sim;
94 }
95 
96 SimSession::ExportersType SimSession::GetExporters()
97 {
98  return {
99  {"BMP", {"bmp",
100  [&](const string& file) {
101  auto pref = make_shared<BitmapGraphicsPreferences>();
102  pref->Update({m_preferences->GetChild("viewers.bitmap_graphics")});
103  pref->m_format = BitmapGraphicsPreferences::Bmp;
104  BitmapGraphicsExporter::Export(m_sim, file, true, pref);
105  }}},
107  [&](const string& file) {
108  CsvExporter::Export(m_sim, file);
109  }}},
110  {"HDF5", {Hdf5Exporter::GetFileExtension(),
111  [&](const string& file) {
112  Hdf5Exporter::Export(m_sim, file);
113  }}},
114  {"JPEG", {"jpg",
115  [&](const string& file) {
116  auto pref = make_shared<BitmapGraphicsPreferences>();
117  pref->Update({m_preferences->GetChild("viewers.bitmap_graphics")});
118  pref->m_format = BitmapGraphicsPreferences::Jpeg;
119  BitmapGraphicsExporter::Export(m_sim, file, true, pref);
120  }}},
122  [&](const string& file) {
123  PlyExporter::Export(m_sim, file);
124  }}},
125  {"PDF", {"pdf",
126  [&](const string& file) {
127  auto pref = make_shared<VectorGraphicsPreferences>();
128  pref->Update({m_preferences->GetChild("viewers.vector_graphics")});
129  pref->m_format = VectorGraphicsPreferences::Pdf;
130  VectorGraphicsExporter::Export(m_sim, file, true, pref);
131  }}},
132  {"PNG", {"png",
133  [&](const string& file) {
134  auto pref = make_shared<BitmapGraphicsPreferences>();
135  pref->Update({m_preferences->GetChild("viewers.bitmap_graphics")});
136  pref->m_format = BitmapGraphicsPreferences::Png;
137  BitmapGraphicsExporter::Export(m_sim, file, true, pref);
138  }}},
140  [&](const string& file) {
141  XmlExporter::Export(m_sim, file);
142  }}},
143  {"XML.GZ", {XmlGzExporter::GetFileExtension(),
144  [&](const string& file) {
145  XmlGzExporter::Export(m_sim, file);
146  }}}
147  };
148 }
149 
150 const ptree& SimSession::GetParameters() const
151 {
152  return m_sim->GetParameters();
153 }
154 
155 string SimSession::GetStatusMessage() const
156 {
157  return m_sim->GetStatusMessage();
158 }
159 
160 SimSession::Timings SimSession::GetTimings() const
161 {
162  auto timings = m_sim->GetTimings();
163  timings.Merge(m_timings);
164  return timings.GetRecords();
165 }
166 
167 void SimSession::ForceExport()
168 {
169  lock_guard<mutex> parameters_guard(m_viewers_mutex);
170 
172  SimEvent e(m_sim, m_sim->GetSimStep(), SimEvent::Type::Forced);
173  m_sim->Notify(e);
174 }
175 
176 void SimSession::ExecuteViewUnit(QString worker_message)
177 {
178  if (worker_message != "") {
179  throw Exception(worker_message.toStdString());
180  }
181  {
182  lock_guard<mutex> viewers_guard(m_viewers_mutex);
183  m_sim->Notify(SimEvent(m_sim, m_sim->GetSimStep(), SimEvent::Type::Stepped));
184  }
185  emit InfoMessage(GetStatusMessage(), InfoMessageReason::Stepped);
186  --m_steps_limit;
187 
188  if (m_running) {
189  if ((m_steps_limit == 0) || m_sim->IsAtTermination()) {
190  StopSimulation();
191  } else {
192  { // Check if parameters were changed.
193  lock_guard<mutex> parameters_guard(m_parameters_mutex);
194  if (m_parameter_buffer.updated) {
195  m_sim->Reinitialize(m_parameter_buffer.pt);
196  // Notify viewers (preferences can't be changed during notification).
197  {
198  lock_guard<mutex> viewers_guard(m_viewers_mutex);
199  m_sim->Notify(SimEvent(m_sim, m_sim->GetSimStep(), SimEvent::Type::Forced));
200  }
201  m_parameter_buffer.updated = false;
202  }
203  }
204  emit ExecuteWorkUnit();
205  }
206  }
207 }
208 
209 void SimSession::SetParameters(const ptree& pt)
210 {
211  lock_guard<mutex> parameters_guard(m_parameters_mutex);
212 
213  m_parameter_buffer.pt = pt;
214  m_parameter_buffer.updated = true;
215 }
216 
217 void SimSession::StartSimulation(int steps)
218 {
219  assert(steps >= -1 && "Steps should be positive or -1");
220  m_steps_limit = steps;
221 
222  // Create worker instance
223  auto sim_worker = new SimWorker(m_sim);
224  sim_worker->moveToThread(m_sim_thread);
225 
226  // The signals & slots magic
227  connect(m_sim_thread, SIGNAL(started()), sim_worker, SLOT(Work()));
228  connect(this, SIGNAL(ExecuteWorkUnit()), sim_worker, SLOT(Work()));
229  connect(sim_worker, SIGNAL(Worked(QString)), this, SLOT(ExecuteViewUnit(QString)));
230  connect(m_sim_thread, SIGNAL(finished()), sim_worker, SLOT(deleteLater()));
231 
232  // Get the ball rolling
233  m_running = true;
234  if (m_parameter_buffer.updated) {
235  m_sim->Reinitialize(m_parameter_buffer.pt);
236  // Notify viewers (preferences can't be changed during notification).
237  {
238  lock_guard<mutex> viewers_guard(m_viewers_mutex);
239  m_sim->Notify(SimEvent(m_sim, m_sim->GetSimStep(), SimEvent::Type::Forced));
240  }
241  m_parameter_buffer.updated = false;
242  }
243  if (m_sim->IsAtTermination()) {
244  emit InfoMessage(GetStatusMessage(), InfoMessageReason::Terminated);
245  } else {
246  m_sim_thread->start();
247  emit InfoMessage(GetStatusMessage(), InfoMessageReason::Started);
248  }
249 }
250 
251 void SimSession::StopSimulation()
252 {
253  m_running = false;
254  m_sim_thread->quit();
255  m_sim_thread->wait();
256  m_steps_limit = -1;
257  if (m_sim->IsAtTermination()) {
258  emit InfoMessage(GetStatusMessage(), InfoMessageReason::Terminated);
259  } else {
260  emit InfoMessage(GetStatusMessage(), InfoMessageReason::Stopped);
261  }
262 }
263 
264 void SimSession::TimeStep()
265 {
266  StartSimulation(1);
267 }
268 
269 } // namespace
270 } // namespace
Interface for XmlExporter.
STL namespace.
static bool Export(std::shared_ptr< SimPT_Sim::Sim > sim, const std::string &filename, bool overwrite=true)
Export state to xml.
Definition: XmlExporter.cpp:33
Namespace for miscellaneous utilities.
Definition: PTreeFile.cpp:44
Interface for XmlGzExporter.
Simulator: mesh & parameters, model & algorithms.
Definition: Sim.h:50
An event transmitted by a simulator.
Definition: SimEvent.h:35
static bool Export(std::shared_ptr< SimPT_Sim::Sim > sim, std::string const &file_path, bool overwrite=true, std::shared_ptr< BitmapGraphicsPreferences > prefs=std::make_shared< BitmapGraphicsPreferences >())
Export snapshot of canvas in PNG format.
Namespace for SimPT shell package.
Definition: Client.cpp:50
static bool Export(std::shared_ptr< SimPT_Sim::SimInterface > sim, std::string const &file_path, bool overwrite=true)
Export mesh state to csv format.
Definition: CsvExporter.cpp:40
static std::string GetFileExtension()
File extension associated with this export format.
Namespace for graphical interface classes.
static bool Export(std::shared_ptr< SimPT_Sim::Sim > sim, const std::string &filename, bool overwrite=true)
Export state to xml.
Extremely simple Exception root class.
Definition: Exception.h:28
Namespace for the core simulator.
Namespace for session classes.
Definition: ISession.h:42
static bool Export(std::shared_ptr< SimPT_Sim::Sim > mesh, std::string const &file_path, bool overwrite=true)
Export mesh state to hdf5 format.
SimSession(const std::shared_ptr< MergedPreferences > &prefs, const ptree &sim)
Initializes with a ptree description of the simulator state.
static bool Export(std::shared_ptr< SimPT_Sim::SimInterface > sim, std::string const &file_path, bool overwrite=true, std::shared_ptr< VectorGraphicsPreferences > prefs=std::make_shared< VectorGraphicsPreferences >())
Export snapshot of canvas in PNG format.
Macro defs for debug and logging.
Utility for running simulation in a separate thread.
Definition: SimWorker.h:35
Namespace for generic workspace classes.
Definition: SimSession.h:32
Interface for RootViewerNode.
Interface for MergedPreferences.
Interfaces for simulator session.
Contains the state of the whole Simulator at a given simulation step.
Definition: SimState.h:33
static std::string GetFileExtension()
File extension associated with this export format.
Definition: PlyExporter.cpp:62
Namespace for workspace events.
Interface for PlyExporter.
Interface for Csv Exporter.
Interface for VectorGraphicsExporter.
Interface for BitmapGraphicsExporter.
Header for SimWorker.
Header file for Exception class.
Namespace event types raised by the simulator.
static std::string GetFileExtension()
File extension associated with this export format.
static std::string GetFileExtension()
File extension associated with this export format.
Definition: XmlExporter.cpp:49
static std::string GetFileExtension()
File extension associated with this export format.
Definition: CsvExporter.cpp:65
static bool Export(std::shared_ptr< SimPT_Sim::SimInterface > sim, std::string const &file_path, bool overwrite=true)
Export sim state to ply format.
Definition: PlyExporter.cpp:38
Interface for Hdf5Exporter.
Namespace for clock and timekeeping related classes.
Definition: ClockCLib.h:27