Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 6 additions & 0 deletions include/ShellLoop.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
#include <map>
#include <regex>
#include "Circuit.hpp"
#include <csignal>

namespace nts {

Expand All @@ -17,6 +18,8 @@ class ShellLoop {
~ShellLoop();
void run();

static bool signalReceived;
static void signalHandler(int signal);
private:
protected:
Circuit &_circuit;
Expand All @@ -26,6 +29,9 @@ class ShellLoop {
void display(Circuit &circuit);
void simulate(Circuit &circuit);
void loop(Circuit &circuit);
bool getUserInput(std::string &input);
bool executeCommand(const std::string &input);
void handleException(const std::exception &e);
bool _running;

};
Expand Down
82 changes: 66 additions & 16 deletions src/ShellLoop.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -7,14 +7,29 @@

#include "ShellLoop.hpp"


bool nts::ShellLoop::signalReceived = false;

void nts::ShellLoop::signalHandler(int signal) {
if (signal == SIGINT) {
signalReceived = true;
dup2(0, 0);
}
}

nts::ShellLoop::ShellLoop(Circuit &circuit) : _circuit(circuit)
{
struct sigaction sa;

_commands.emplace("exit", &ShellLoop::exit);
_commands.emplace("simulate", &ShellLoop::simulate);
_commands.emplace("display", &ShellLoop::display);
_commands.emplace("loop", &ShellLoop::loop);
_running = true;
}
sa.sa_handler = signalHandler;
sa.sa_flags = 0;
sigemptyset(&sa.sa_mask);
sigaction(SIGINT, &sa, NULL);}

nts::ShellLoop::~ShellLoop()
{
Expand All @@ -38,7 +53,7 @@ void nts::ShellLoop::simulate(Circuit &circuit)

void nts::ShellLoop::loop(Circuit &circuit)
{
while (_running) {
while (_running && !signalReceived) {
circuit.simulate(circuit.getTick() + 1);
circuit.display();
}
Expand Down Expand Up @@ -78,25 +93,60 @@ bool nts::ShellLoop::setComponentValue(const std::string &input, Circuit &circui
return false;
}

bool nts::ShellLoop::getUserInput(std::string &input)
{
if (!std::getline(std::cin, input)) {
if (signalReceived || std::cin.eof()) {
std::cout << std::endl;
return false;
}
if (std::cin.fail()) {
std::cin.clear();
return true;
}
}
return !signalReceived;
}

bool nts::ShellLoop::executeCommand(const std::string &input)
{
if (input.empty())
return true;
if (_commands.find(input) != _commands.end()) {
(this->*_commands[input])(_circuit);
} else if (input == "exit") {
exit(_circuit);
return false;
} else if (!setComponentValue(input, _circuit)) {
std::cerr << "Invalid command: " << input << std::endl;
}
return !signalReceived;
}

void nts::ShellLoop::handleException(const std::exception &e)
{
if (!signalReceived) {
std::cerr << "Error: " << e.what() << std::endl;
}
}

void nts::ShellLoop::run()
{
std::string input;

_circuit.simulate(0);
while (_running) {
std::cout << "> ";
if (!std::getline(std::cin, input)) {
std::cout << std::endl;
break;
}
if (input.empty())
continue;
if (_commands.find(input) != _commands.end())
(this->*_commands[input])(_circuit);
else if (input == "exit")
exit(_circuit);
else if (!setComponentValue(input, _circuit)) {
std::cerr << "Invalid command: " << input << std::endl;
while (_running && !signalReceived) {
std::cout << "> " << std::flush;
try {
if (!getUserInput(input))
break;
if (!executeCommand(input))
break;
} catch (const std::exception &e) {
handleException(e);
}
if (signalReceived)
break;
}
_running = false;
}
15 changes: 10 additions & 5 deletions src/specialComponents/Input.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -21,18 +21,23 @@ nts::InputComponent::~InputComponent()

void nts::InputComponent::simulate(std::size_t tick)
{
(void)tick;
if (_pins[0].lock() == nullptr) {
if (_lastTick == tick)
return;
_lastTick = tick;

if (_pins[0].lock() == nullptr)
this->setState(nts::UNDEFINED);
}
else {
this->setState(_pins[0].lock()->compute(tick));
auto linkedComponent = _pins[0].lock();
linkedComponent->simulate(tick);
this->setState(linkedComponent->getState());
}
}

nts::Tristate nts::InputComponent::compute(std::size_t tick)
{
this->simulate(tick);
if (_lastTick != tick)
this->simulate(tick);
return this->getState();
}

Expand Down
2 changes: 1 addition & 1 deletion tests/test_elementaryComponents.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ Test(Circuit, link_input_to_output) {
circuit.addComponent("output", "Out1");
circuit.linkComponents("In1", "Out1", 1, 1);
circuit.setInputState(*dynamic_cast<nts::InputComponent*>(circuit.getComponent("In1").get()), nts::TRUE);
circuit.simulate(1);
//circuit.simulate(1);
nts::Tristate state = circuit.compute("Out1");
cr_assert_eq(state, nts::TRUE, "Output should be TRUE when input is TRUE");
}
Expand Down
Loading