Skip to content

Commit

Permalink
WIP: Update TU and code
Browse files Browse the repository at this point in the history
  • Loading branch information
Lecrapouille committed Dec 16, 2023
1 parent 242f85b commit d186791
Show file tree
Hide file tree
Showing 28 changed files with 530 additions and 253 deletions.
12 changes: 11 additions & 1 deletion include/TimedPetriNetEditor/PetriNet.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -191,6 +191,16 @@ class Place : public Node
return std::string("P" + std::to_string(id_));
}

//--------------------------------------------------------------------------
//! \brief Increment the number of token constrained by the type of net.
//--------------------------------------------------------------------------
size_t increment(size_t const count = 1u);

//--------------------------------------------------------------------------
//! \brief Decrement the number of token constrained by the type of net.
//--------------------------------------------------------------------------
size_t decrement(size_t const count = 1u);

//--------------------------------------------------------------------------
//! \brief For debug purpose only.
//--------------------------------------------------------------------------
Expand Down Expand Up @@ -534,7 +544,7 @@ class Net
//! timed graph even, etc.
//! \return false if the net cannot be changed (i.e. to graph event).
//--------------------------------------------------------------------------
bool convertTo(TypeOfNet const type, std::vector<Arc*>& erroneous_arcs);
bool convertTo(TypeOfNet const type, std::string& error, std::vector<Arc*>& erroneous_arcs);

//--------------------------------------------------------------------------
//! \brief Load the Petri net from a JSON file. The current net is cleared
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@
#ifndef SPARSE_MATRIX_HPP
# define SPARSE_MATRIX_HPP

# include "Net/TropicalAlgebra.hpp"
# include "TimedPetriNetEditor/TropicalAlgebra.hpp"

// FIXME Add template and manage (max,+) types
//# include <cstdint>
Expand Down
File renamed without changes.
25 changes: 15 additions & 10 deletions src/Editor/DearImGui/Drawable.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -123,7 +123,7 @@ void drawArc(ImDrawList* draw_list, Arc const& arc, TypeOfNet const type, ImVec2
float x = origin.x + arc.from.x + (arc.to.x - arc.from.x) / 2.0f;
float y = origin.y + arc.from.y + (arc.to.y - arc.from.y) / 2.0f - 15.0f;
std::stringstream stream;
stream << std::fixed << std::setprecision(2) << arc.duration;
stream << std::fixed << std::setprecision(1) << arc.duration;
draw_list->AddText(ImVec2(x, y), DURATION_COLOR, stream.str().c_str());
}
}
Expand Down Expand Up @@ -193,6 +193,7 @@ void drawPlace(ImDrawList* draw_list, Place const& place, TypeOfNet const type,
}
else
{
drawToken(draw_list, p.x, p.y);
std::string tokens = std::to_string(place.tokens);
draw_list->AddText(ImVec2(p.x, p.y), CAPTION_COLOR, tokens.c_str());
}
Expand All @@ -207,18 +208,22 @@ void drawTransition(ImDrawList* draw_list, Transition const& transition, TypeOfN
// Color of the transition: green if validated else yellow if enabled
// else color is fadding value.
ImU32 color;
//if (type == TypeOfNet::PetriNet)
//{
if (transition.canFire())
{
color = FIREABLE_COLOR;
}
else if (transition.isValidated() || transition.isEnabled())
if (transition.key == "T0")
{
color = IM_COL32(255, 165, 10, 255);
}

if (transition.canFire())
{
color = FIREABLE_COLOR;
}
else if (type == TypeOfNet::GRAFCET)
{
if (transition.isValidated() || transition.isEnabled())
{
color = IM_COL32(255, 165, 0, 255);
}
//}
//else if
}
else
{
color = FILL_COLOR(alpha);
Expand Down
14 changes: 8 additions & 6 deletions src/Editor/DearImGui/KeyBindings.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -22,11 +22,13 @@
# define KEY_BINDINGS_HPP

// -----------------------------------------------------------------------------
# define KEY_BINDING_QUIT_APPLICATION ImGuiKey_Escape
# define KEY_BINDING_RUN_SIMULATION ImGuiKey_Space
# define KEY_BINDING_RUN_SIMULATION_ALT ImGuiKey_R
# define KEY_BINDING_ROTATE_CW ImGuiKey_PageUp
# define KEY_BINDING_ROTATE_CCW ImGuiKey_PageDown
# define KEY_BINDING_MOVE_PETRI_NODE ImGuiKey_Semicolon
# define KEY_QUIT_APPLICATION ImGuiKey_Escape
# define KEY_RUN_SIMULATION ImGuiKey_Space
# define KEY_RUN_SIMULATION_ALT ImGuiKey_R
# define KEY_ROTATE_CW ImGuiKey_PageUp
# define KEY_ROTATE_CCW ImGuiKey_PageDown
# define KEY_MOVE_PETRI_NODE ImGuiKey_Semicolon
# define KEY_INCREMENT_TOKENS ImGuiKey_KeypadAdd
# define KEY_DECREMENT_TOKENS ImGuiKey_KeypadSubtract

#endif
34 changes: 28 additions & 6 deletions src/Editor/PetriEditor.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -18,13 +18,14 @@
// along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>.
//=============================================================================

#include "TimedPetriNetEditor/PetriNet.hpp"
#include "TimedPetriNetEditor/Algorithms.hpp"
#include "TimedPetriNetEditor/SparseMatrix.hpp"
#include "Editor/PetriEditor.hpp"
#include "Editor/DearImGui/Drawable.hpp"
#include "Editor/DearImGui/DearUtils.hpp"
#include "Editor/DearImGui/KeyBindings.hpp"
#include "Net/SparseMatrix.hpp"
#include "Utils/Utils.hpp"
#include "TimedPetriNetEditor/Algorithms.hpp"

namespace tpne {

Expand Down Expand Up @@ -763,7 +764,8 @@ bool Editor::switchOfNet(TypeOfNet const type)
return false;

std::vector<Arc*> arcs;
if (m_net.convertTo(type, arcs))
std::string error;
if (m_net.convertTo(type, error, arcs))
return true;

m_messages.setError(m_net.error());
Expand Down Expand Up @@ -1332,16 +1334,36 @@ void Editor::PetriView::onHandleInput()

if (ImGui::IsItemHovered())
{
if (ImGui::IsKeyPressed(KEY_BINDING_MOVE_PETRI_NODE, false))
if (ImGui::IsKeyPressed(KEY_MOVE_PETRI_NODE, false))
{
handleMoveNode();
}
// Run the animation of the Petri net
else if (ImGui::IsKeyPressed(KEY_BINDING_RUN_SIMULATION) ||
ImGui::IsKeyPressed(KEY_BINDING_RUN_SIMULATION_ALT))
else if (ImGui::IsKeyPressed(KEY_RUN_SIMULATION) ||
ImGui::IsKeyPressed(KEY_RUN_SIMULATION_ALT))
{
m_editor.toogleStartSimulation();
}
// Increment the number of tokens in the place.
else if (ImGui::IsKeyPressed(KEY_INCREMENT_TOKENS))
{
Node* node = m_editor.getNode(m_mouse.position);
if ((node != nullptr) && (node->type == Node::Type::Place))
{
reinterpret_cast<Place*>(node)->increment(1u);
m_editor.m_net.modified = true;
}
}
// Decrement the number of tokens in the place.
else if (ImGui::IsKeyPressed(KEY_DECREMENT_TOKENS))
{
Node* node = m_editor.getNode(m_mouse.position);
if ((node != nullptr) && (node->type == Node::Type::Place))
{
reinterpret_cast<Place*>(node)->decrement(1u);
m_editor.m_net.modified = true;
}
}
}
}

Expand Down
3 changes: 2 additions & 1 deletion src/Net/Algorithms.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@

#include "TimedPetriNetEditor/PetriNet.hpp"
#include "TimedPetriNetEditor/Algorithms.hpp"
#include "Net/SparseMatrix.hpp"
#include "TimedPetriNetEditor/SparseMatrix.hpp"
#include "Net/Howard.h"

namespace tpne {
Expand All @@ -35,6 +35,7 @@ template<> bool SparseMatrix<double>::display_as_dense = false;
bool isEventGraph(Net const& net, std::string& error, std::vector<Arc*>& erroneous_arcs)
{
erroneous_arcs.clear();
error.clear();
if (net.isEmpty())
{
error = "Empty Petri net is not an event graph";
Expand Down
4 changes: 2 additions & 2 deletions src/Net/Exports/ExportJulia.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -18,10 +18,10 @@
// along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>.
//=============================================================================

#include "Net/Exports/Exports.hpp"
#include "TimedPetriNetEditor/PetriNet.hpp"
#include "TimedPetriNetEditor/Algorithms.hpp"
#include "Net/SparseMatrix.hpp"
#include "TimedPetriNetEditor/SparseMatrix.hpp"
#include "Net/Exports/Exports.hpp"
#include <fstream>
#include <cstring>

Expand Down
44 changes: 33 additions & 11 deletions src/Net/Imports/ImportJSON.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -54,22 +54,44 @@ std::string importFromJSON(Net& net, std::string const& filename)
return error.str();
}

std::string type = std::string(json["type"]);
if (type == "GRAFCET") {
net.clear(TypeOfNet::GRAFCET);
} else if (type == "Petri net") {
net.clear(TypeOfNet::PetriNet);
} else if (type == "Timed Petri net") {
net.clear(TypeOfNet::TimedPetriNet);
} else if (type == "Timed event graph") {
net.clear(TypeOfNet::TimedEventGraph);
} else {
if (json.contains("type"))
{
std::string type = std::string(json["type"]);
if (type == "GRAFCET") {
net.clear(TypeOfNet::GRAFCET);
} else if (type == "Petri net") {
net.clear(TypeOfNet::PetriNet);
} else if (type == "Timed Petri net") {
net.clear(TypeOfNet::TimedPetriNet);
} else if (type == "Timed event graph") {
net.clear(TypeOfNet::TimedEventGraph);
} else {
error << "Failed parsing '" << filename << "'. Reason was '"
<< "Unknown type of net: " << type << "'" << std::endl;
return error.str();
}
}
else
{
error << "Failed parsing '" << filename << "'. Reason was '"
<< "Unknown type of net: " << type << "'" << std::endl;
<< "Missing type of Net'" << std::endl;
return error.str();
}

if (!json.contains("nets"))
{
error << "Failed parsing '" << filename << "'. Reason was '"
<< "Missing JSON nets field'" << std::endl;
return error.str();
}
nlohmann::json const& jnet = json["nets"][0];

if (!jnet.contains("name"))
{
error << "Failed parsing '" << filename << "'. Reason was '"
<< "Missing JSON net name'" << std::endl;
return error.str();
}
net.name = std::string(jnet["name"]);

// Places
Expand Down
44 changes: 33 additions & 11 deletions src/Net/PetriNet.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,20 @@ Place::Place(size_t const id_, std::string const& caption_, float const x_,
tokens = std::min(Net::Settings::maxTokens, tokens_);
}

//------------------------------------------------------------------------------
size_t Place::increment(size_t const count)
{
tokens = std::min(Net::Settings::maxTokens, tokens + count);
return tokens;
}

//------------------------------------------------------------------------------
size_t Place::decrement(size_t const count)
{
tokens = std::max(tokens, count) - count;
return tokens;
}

//------------------------------------------------------------------------------
bool Transition::isEnabled() const
{
Expand Down Expand Up @@ -152,7 +166,7 @@ void Net::clear(TypeOfNet const type)
}

//------------------------------------------------------------------------------
bool Net::convertTo(TypeOfNet const type, std::vector<Arc*>& erroneous_arcs)
bool Net::convertTo(TypeOfNet const type, std::string& error, std::vector<Arc*>& erroneous_arcs)
{
if (m_type == type)
return true;
Expand All @@ -162,6 +176,13 @@ bool Net::convertTo(TypeOfNet const type, std::vector<Arc*>& erroneous_arcs)
case TypeOfNet::GRAFCET:
Net::Settings::maxTokens = 1u;
Net::Settings::firing = Net::Settings::Fire::OneByOne;
// Constrain the number of tokens.
// TBD: not constraining the number of tokens allow us to save the
// net (json format) without loosing number of tokens for other nets.
for (auto& place: m_places)
{
place.tokens = std::min(Net::Settings::maxTokens, place.tokens);
}
// FIXME
//m_sensors.clear();
//for (auto& transition: m_transitions)
Expand All @@ -179,7 +200,7 @@ bool Net::convertTo(TypeOfNet const type, std::vector<Arc*>& erroneous_arcs)
break;
case TypeOfNet::TimedEventGraph:
// Check conditions of a well formed event graph
if ((!isEmpty()) && (!isEventGraph(*this)))
if ((!isEmpty()) && (!isEventGraph(*this, error, erroneous_arcs)))
return false;
Net::Settings::maxTokens = std::numeric_limits<size_t>::max();
Net::Settings::firing = Net::Settings::Fire::OneByOne;
Expand All @@ -189,8 +210,10 @@ bool Net::convertTo(TypeOfNet const type, std::vector<Arc*>& erroneous_arcs)
break;
}

// Place this at the end because of possible return false.
// Set the new type of net at the end of this method because of possible
// previous "return false" preventing to change of type.
m_type = type;

return true;
}

Expand All @@ -209,18 +232,18 @@ std::vector<size_t> Net::tokens() const
//------------------------------------------------------------------------------
bool Net::tokens(std::vector<size_t> const& tokens_)
{
m_message.str("");
if (m_places.size() != tokens_.size())
{
m_message.str("");
m_message << "the container dimension holding tokens does not match the number of places"
m_message << "The container dimension holding tokens does not match the number of places"
<< std::endl;
return false;
}

size_t i = tokens_.size();
while (i--)
{
m_places[i].tokens = tokens_[i];
m_places[i].tokens = std::min(Net::Settings::maxTokens, tokens_[i]);
}

return true;
Expand Down Expand Up @@ -471,8 +494,7 @@ Node const* Net::findNode(std::string const& key) const
}
return nullptr;
}

if (key[0] == 'T')
else if (key[0] == 'T')
{
for (auto& t: m_transitions)
{
Expand Down Expand Up @@ -646,9 +668,9 @@ bool Net::load(std::string const& filepath)

// Get the name from path
size_t lastindex = filepath.find_last_of(".");
std::string name = filepath.substr(0, lastindex);
lastindex = name.find_last_of("/");
name = name.substr(lastindex + 1u);
std::string _name = filepath.substr(0, lastindex);
lastindex = _name.find_last_of("/");
_name = _name.substr(lastindex + 1u);

m_message.str("");
m_message << error;
Expand Down
1 change: 1 addition & 0 deletions src/Net/Simulation.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -109,6 +109,7 @@ void Simulation::stateStarting()
#endif

// Reset states of the simulator
m_net.generateArcsInArcsOut();
m_initial_tokens = m_net.tokens();
shuffle_transitions(true);
m_timed_tokens.clear();
Expand Down
Loading

0 comments on commit d186791

Please sign in to comment.