Skip to content

Commit

Permalink
Errors bag (avoid memory leak from controller).
Browse files Browse the repository at this point in the history
Renamed methods for passing user input.
  • Loading branch information
cristianfrasineanu committed Nov 24, 2016
1 parent 93aa3c6 commit bc5a113
Show file tree
Hide file tree
Showing 16 changed files with 124 additions and 87 deletions.
5 changes: 1 addition & 4 deletions app/Bootstrap.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -14,10 +14,7 @@ void main()
{
console.showPrompt();
console.setLastInput(_getch());
if (console.takeActionIfAny() == false)
{
console.renderNextView();
}
console.takeActionOrNext();
}
catch (const invalid_argument &e)
{
Expand Down
51 changes: 20 additions & 31 deletions app/Console.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -17,12 +17,13 @@ Console::Console()
map<char, string> availableOptions = View::getViewsOptions().find(Console::initialView)->second;
this->previousViews = {};

this->currentView = View(Console::initialView, availableOptions);
this->delay = 2000;
this->loadActions();
this->loadViews(Console::viewsFolder);

if (find(this->loadedViews.begin(), this->loadedViews.end(), this->currentView.getViewName()) != this->loadedViews.end())
this->currentView = View(Console::initialView, availableOptions);

if (isInVector(this->loadedViews, Console::initialView))
{
this->handleView();
}
Expand All @@ -44,12 +45,13 @@ Console::Console(char *mode)
map<char, string> availableOptions = View::getViewsOptions().find(Console::initialView)->second;
this->previousViews = {};

this->currentView = View(viewName, availableOptions);
this->delay = 2000;
this->loadActions();
this->loadViews(Console::viewsFolder);

if (find(this->loadedViews.begin(), this->loadedViews.end(), this->currentView.getViewName()) != this->loadedViews.end())
this->currentView = View(viewName, availableOptions);

if (isInVector(this->loadedViews, viewName))
{
this->handleView();
}
Expand All @@ -72,11 +74,6 @@ void Console::setLastInput(char input)
}
}

vector<char> &Console::getActions()
{
return this->actions;
}

void Console::showPrompt()
{
cout << endl
Expand All @@ -88,11 +85,6 @@ char Console::getLastInput()
return this->lastInput;
}

string & Console::getViewsFolder()
{
return Console::viewsFolder;
}

void Console::loadViews(const fs::path &viewsFolder)
{
if (!fs::exists(viewsFolder)
Expand All @@ -118,8 +110,6 @@ void Console::loadViews(const fs::path &viewsFolder)
void Console::loadActions()
{
// TODO: load actions via config file
// The confirm is basically linked to the next view.
// For instance, the login view will have then next view the dashboard.
vector<char> actions = { 'q', 'b', 'n', 'c' };

this->actions = actions;
Expand All @@ -132,24 +122,21 @@ void Console::handleView()
path.append("\\").append(this->currentView.getViewName());

stringstream buffer;
ifstream viewFile(path, ios::out);
ifstream viewFile(path, ios::in);

if (viewFile.is_open())
{
buffer << viewFile.rdbuf();
this->currentView.setRawFormat(buffer.str());

vector<string> emptyErrorBag = {};
Controller::setErrorsBag(emptyErrorBag);

// If there's any validation error catch it and reload the view.
// TODO: Fix the memory leak when catching an error.
try
{
this->theController = Controller(this->currentView.getViewName(), buffer.str(), View::getViewExtension());
}
catch (const invalid_argument &e)
{
cout << endl
<< e.what()
<< endl;
this->theController = Controller(this->currentView.getViewName(), buffer.str(), View::getViewExtension());
if (!Controller::getErrorsBag().empty()) {
string message = "\nPlease correct the following: ";
printVector(Controller::getErrorsBag(), message);

sleepAndClearBuffer(3 * this->delay);
this->reloadView();
Expand Down Expand Up @@ -195,9 +182,9 @@ void Console::reloadView()
this->handleView();
}

bool Console::takeActionIfAny()
void Console::takeActionOrNext()
{
if (isInVector(this->getActions(), this->lastInput))
if (isInVector(this->actions, this->lastInput))
{
switch (this->lastInput)
{
Expand All @@ -216,9 +203,11 @@ bool Console::takeActionIfAny()
default:
break;
}
return true;
}
return false;
else
{
this->renderNextView();
}
}

bool Console::shouldExit()
Expand Down
17 changes: 6 additions & 11 deletions app/Console.h
Original file line number Diff line number Diff line change
@@ -1,9 +1,8 @@
#include <iostream>
#include <fstream>
#pragma once

#include <sstream>
#include <stdexcept>
#include <filesystem>
#include <map>

#include "Helpers.h"
#include "View.h"
Expand All @@ -30,25 +29,21 @@ class Console {

void loadViews(const fs::path &);
void loadActions();
void renderNextView();
void handleView();
void renderPreviousView();
public:
Console();
Console(char *);

vector<char> &getActions();
char getLastInput();
string &getViewsFolder();

void setLastInput(char);
bool takeActionIfAny();
void takeActionOrNext();
bool shouldExit();
void breakTheLoop();

void showPrompt();
unsigned getDelay();

void handleView();
void renderNextView();
void renderPreviousView();
void reloadView();

~Console();
Expand Down
18 changes: 15 additions & 3 deletions app/Controller.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,8 @@
string Controller::viewInputFormat = "@input-";
string Controller::viewOutputFormat = "@output-";

vector<string> Controller::errorsBag = {};

void Controller::justShow()
{
cout << this->viewChunk
Expand Down Expand Up @@ -49,14 +51,14 @@ void Controller::prepareView()
}
}

// Show the rest
// Show the rest.
if (copyChunk.size())
{
cout << copyChunk
<< endl;
}

// Send the payload to be validated and handled by the main model
// Send the payload to the accessor model to be passed to the according repository.
if (isInVector(this->controllerAttributions, "input"))
{
this->model.confirmInput(this->userInputs);
Expand All @@ -75,6 +77,16 @@ void Controller::prepareViewInput(const string &subChunk, const string &inputAli
this->userInputs[inputAlias] = userInput;
}

void Controller::setErrorsBag(vector<string> &errorsBag)
{
Controller::errorsBag = errorsBag;
}

vector<string> Controller::getErrorsBag()
{
return Controller::errorsBag;
}

Controller::Controller()
{
this->controllerName = new char[strlen("NO_CONTROLLER") + 1];
Expand Down Expand Up @@ -119,7 +131,7 @@ void Controller::chopChunkAndGetAlias(string &chunk)
chunk.erase(0, chunk.find(inputAlias) + inputAlias.size() + 2);
}

// Don't assign multiple Controllers, stupid.
// Don't assign it multiple times, stupid.
void Controller::operator=(const Controller &controller)
{
delete[] this->controllerName;
Expand Down
6 changes: 6 additions & 0 deletions app/Controller.h
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
#pragma once

#include <fstream>

#include "Helpers.h"
Expand All @@ -9,6 +11,7 @@ class Controller {
private:
static string viewInputFormat;
static string viewOutputFormat;
static vector<string> errorsBag;

char *controllerName;
vector<string> controllerAttributions;
Expand All @@ -21,6 +24,9 @@ class Controller {
void prepareViewInput(const string &, const string &);
// TODO: take the chunk one by one for output and request output from model for each output variable
public:
static void setErrorsBag(vector<string> &);
static vector<string> getErrorsBag();

Controller();
Controller(char *, string &, string &);

Expand Down
2 changes: 1 addition & 1 deletion app/Helpers.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ void sleepAndClearBuffer(unsigned delay)
Sleep(delay);

// Clear the keyboard buffer during the sleep cycle (if there are any keys pressed),
// so whatever keys are hit are discarded
// so whatever keys are hit are discarded.
while (_kbhit())
{
_getch();
Expand Down
16 changes: 16 additions & 0 deletions app/Helpers.h
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,22 @@ inline bool isInMap(map<FirstT, SecondT> &haystack, FirstT needle)
return haystack.find(needle) != haystack.end();
}

template<typename V>
inline void printVector(vector<V> &v, string &message)
{
if (message != "")
{
cout << message
<< endl;
}

for (vector<V>::iterator it = v.begin(); it != v.end(); it++)
{
cout << (*it)
<< endl;
}
}

void toLowerCase(string &);
void sleepAndClearBuffer(unsigned delay);
void clearScreen();
24 changes: 10 additions & 14 deletions app/Model.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -8,29 +8,31 @@ string Model::parseEntityName(string inputAlias)
void Model::attachEntity(string &model)
{
toLowerCase(model);
if (model == "user")
if (model == UserRepository::getAlias())
{
this->repository = new UserRepository();
}
else if (model == "question")
/*else if (model == "question")
{
}
else if (model == "category")
{
}
}*/
}

Model::Model()
{
this->repository = NULL;
this->rawInput = {};
this->serializedInput = {};
this->truncatedInput = {};
}

void Model::sendSerializedInput()
void Model::confirmInput(const map<string, string> &payLoad)
{
this->rawInput = payLoad;

// There's interaction with only one model on the view.
string entityName = this->parseEntityName(this->rawInput.begin()->first),
inputAlias;
Expand All @@ -45,17 +47,11 @@ void Model::sendSerializedInput()
inputAlias = it->first;
inputAlias.erase(0, entityName.size() + 1);

this->serializedInput[inputAlias] = it->second;
this->truncatedInput[inputAlias] = it->second;
}

// Sanitize the input, if there are any errors, display them and reload the view.
this->repository->validateItems(this->serializedInput);
}

void Model::confirmInput(const map<string, string> &payLoad)
{
this->rawInput = payLoad;
this->sendSerializedInput();
// Validate the input, if there are any errors, display them and reload the view.
this->repository->validateItems(this->truncatedInput);
}

Model::~Model()
Expand Down
8 changes: 3 additions & 5 deletions app/Model.h
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
#pragma once

#include "Helpers.h"
#include "RepositoryInterface.h"
#include "UserRepository.h"
Expand All @@ -6,17 +8,13 @@ using namespace std;

class Model {
private:
static string userModelAlias;
static string questionModelAlias;

map<string, string> rawInput;
map<string, string> serializedInput;
map<string, string> truncatedInput;

RepositoryInterface *repository;

string parseEntityName(string);
void attachEntity(string &);
void sendSerializedInput();
public:
Model();

Expand Down
1 change: 1 addition & 0 deletions app/ModelInterface.h
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
#pragma once

#include <fstream>

#include "Helpers.h"

using namespace std;
Expand Down
3 changes: 3 additions & 0 deletions app/RepositoryInterface.h
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
#pragma once

#include "Helpers.h"

#include "ModelInterface.h"

using namespace std;
Expand All @@ -20,6 +21,8 @@ class RepositoryInterface {
map<string, string> ValidationErrors;

ModelInterface *model;

vector<string> errorsBag;
public:
virtual void validateItems(map<string, string> &) = 0;
virtual void retrieveItemForActive() = 0;
Expand Down
Loading

0 comments on commit bc5a113

Please sign in to comment.