From 5b762fb645d5d2f39b0bceadd10a26dfb1368560 Mon Sep 17 00:00:00 2001 From: Cristian-Adrian Frasineanu Date: Sun, 20 Nov 2016 13:08:49 +0200 Subject: [PATCH] Controller class, improved helpers and view renderer. Delegated the interpolation decision to the controller from view. --- app/Bootstrap.cpp | 7 +--- app/Console.cpp | 40 +++++++++++--------- app/Console.h | 20 +++++----- app/Controller.cpp | 80 +++++++++++++++++++++++++++++++++++++++ app/Controller.h | 36 ++++++++++++++++++ app/Helpers.cpp | 32 +++++++++++++--- app/Helpers.h | 7 +++- app/View.cpp | 17 ++++++--- app/View.h | 14 +++---- app/app.vcxproj | 2 + app/app.vcxproj.filters | 6 +++ database/categories.store | 0 database/questions.store | 0 database/users.store | 0 views/login.view | 8 +++- 15 files changed, 216 insertions(+), 53 deletions(-) create mode 100644 app/Controller.cpp create mode 100644 app/Controller.h create mode 100644 database/categories.store create mode 100644 database/questions.store create mode 100644 database/users.store diff --git a/app/Bootstrap.cpp b/app/Bootstrap.cpp index e363ac0..67d88f5 100644 --- a/app/Bootstrap.cpp +++ b/app/Bootstrap.cpp @@ -1,5 +1,3 @@ -#include - #include "Console.h" using namespace std; @@ -10,7 +8,6 @@ void main() { View::loadViewsOptions(); Console console; - do { try @@ -24,9 +21,7 @@ void main() } catch (const invalid_argument &e) { - cout << endl - << e.what() - << endl; + cout << e.what(); sleepAndClearBuffer(console.getDelay()); console.reloadView(); diff --git a/app/Console.cpp b/app/Console.cpp index ac8c9ac..6ed44b1 100644 --- a/app/Console.cpp +++ b/app/Console.cpp @@ -15,7 +15,7 @@ Console::Console() map availableOptions = View::getViewsOptions().find(Console::initialView)->second; - this->currentView = View(Console::initialView, availableOptions, false); + this->currentView = View(Console::initialView, availableOptions); this->delay = 2000; this->loadActions(); @@ -23,7 +23,7 @@ Console::Console() if (find(this->loadedViews.begin(), this->loadedViews.end(), this->currentView.getViewName()) != this->loadedViews.end()) { - this->renderView(this->currentView); + this->renderView(); } else { @@ -41,7 +41,7 @@ Console::Console(char *mode) string viewName = "debug.view"; map availableOptions = View::getViewsOptions().find(Console::initialView)->second; - this->currentView = View(viewName, availableOptions, true); + this->currentView = View(viewName, availableOptions); this->delay = 2000; this->loadActions(); @@ -49,7 +49,7 @@ Console::Console(char *mode) if (find(this->loadedViews.begin(), this->loadedViews.end(), this->currentView.getViewName()) != this->loadedViews.end()) { - this->renderView(this->currentView); + this->renderView(); } else { @@ -100,7 +100,7 @@ void Console::loadViews(const fs::path &viewsFolder) while (it != endit) { if (fs::is_regular_file(*it) - && it->path().extension() == ".view") + && it->path().extension().string() == View::getViewExtension()) { this->loadedViews.push_back(it->path().filename()); } @@ -110,25 +110,34 @@ void Console::loadViews(const fs::path &viewsFolder) void Console::loadActions() { - vector actions = { 'q', 'b', 'n' }; + vector actions = { 'q', 'b', 'n', 'c' }; this->actions = actions; } -void Console::renderView(View &view) +void Console::renderView() { string content; string path = Console::viewsFolder; - path.append("\\").append(view.getViewName()); + path.append("\\").append(this->currentView.getViewName()); + stringstream buffer; ifstream viewFile(path, ios::out); if (viewFile.is_open()) { buffer << viewFile.rdbuf(); + this->currentView.setRawFormat(buffer.str()); - cout << buffer.str() - << endl; + if (Controller::hasInput(buffer.str())) + { + this->theController = Controller(this->currentView.getViewName(), buffer.str(), View::getViewExtension()); + } + else + { + cout << buffer.str() + << endl; + } buffer.clear(); @@ -144,13 +153,10 @@ void Console::renderNextView() // Cache the current view this->previousViews.push_back(this->currentView); - this->currentView = View(nextView, nextOptions, false); + this->currentView = View(nextView, nextOptions); - //TODO: detemine if the view has interpolation enabled in order to replace the template strings or to splice the view in certain places (prepareView) clearScreen(); - this->renderView(this->currentView); - - //Show it directly for now... + this->renderView(); } void Console::renderPreviousView() @@ -159,7 +165,7 @@ void Console::renderPreviousView() { clearScreen(); this->currentView = this->previousViews.back(); - this->renderView(this->currentView); + this->renderView(); this->previousViews.pop_back(); } } @@ -167,7 +173,7 @@ void Console::renderPreviousView() void Console::reloadView() { clearScreen(); - this->renderView(this->currentView); + this->renderView(); } bool Console::takeActionIfAny() diff --git a/app/Console.h b/app/Console.h index 1c325fa..cae0a34 100644 --- a/app/Console.h +++ b/app/Console.h @@ -5,8 +5,9 @@ #include #include -#include "Helpers.h" #include "View.h" +#include "Helpers.h" +#include "Controller.h" using namespace std; namespace fs = std::experimental::filesystem::v1; @@ -15,12 +16,13 @@ class Console { private: static string initialView; static string viewsFolder; - + char *mode; char lastInput; unsigned delay; bool exit; View currentView; + Controller theController; vector previousViews; vector loadedViews; @@ -33,20 +35,20 @@ class Console { Console(char *); vector &getActions(); - - void showPrompt(); char getLastInput(); + void setLastInput(char); + bool takeActionIfAny(); + bool shouldExit(); + void breakTheLoop(); + + void showPrompt(); unsigned getDelay(); - void renderView(View &); + void renderView(); void renderNextView(); void renderPreviousView(); void reloadView(); - bool takeActionIfAny(); - bool shouldExit(); - void breakTheLoop(); - ~Console(); }; \ No newline at end of file diff --git a/app/Controller.cpp b/app/Controller.cpp new file mode 100644 index 0000000..b0f5289 --- /dev/null +++ b/app/Controller.cpp @@ -0,0 +1,80 @@ +#include "Controller.h" + +//---Controller--- +//---------------- +string Controller::viewInputFormat = "@input-"; +string Controller::viewOutputFormat = "@output-"; + +void Controller::prepareView() +{ + cout << this->viewChunk.c_str() + << endl; +} + +void Controller::prepareViewInput() +{ + // Prompt the user for input +} + +string &Controller::getViewInputFormat() +{ + return Controller::viewInputFormat; +} + +string & Controller::getViewOutputFormat() +{ + return Controller::viewOutputFormat; +} + +Controller::Controller() +{ + this->controllerName = new char[strlen("NO_CONTROLLER") + 1]; + strcpy(this->controllerName, "NO_CONTROLLER"); + this->viewChunk = ""; + this->controllerAttributions = {}; +} + +Controller::Controller(char *viewName, string &viewChunk, string &ViewExtension) +{ + string controllerName = viewName; + controllerName.erase(controllerName.find(ViewExtension), ViewExtension.size()).append("Controller"); + + this->controllerName = new char[strlen(controllerName.c_str()) + 1]; + strcpy(this->controllerName, controllerName.c_str()); + this->viewChunk = viewChunk; + this->controllerAttributions = controllerAttributions; + + this->prepareView(); +} + +vector& Controller::getControllerAttributions() +{ + return this->controllerAttributions; +} + +char *Controller::getControllerName() +{ + return this->controllerName; +} + +void Controller::operator=(const Controller &controller) +{ + if (controller.controllerName != NULL) + { + delete[] this->controllerName; + this->controllerName = new char[strlen(controller.controllerName) + 1]; + strcpy(this->controllerName, controller.controllerName); + } + this->viewChunk = controller.viewChunk; + this->controllerAttributions = controller.controllerAttributions; +} + +bool Controller::hasInput(string &raw) +{ + return raw.find(Controller::getViewInputFormat()) != string::npos; +} + +Controller::~Controller() +{ + delete[] this->controllerName; +} diff --git a/app/Controller.h b/app/Controller.h new file mode 100644 index 0000000..08b58f8 --- /dev/null +++ b/app/Controller.h @@ -0,0 +1,36 @@ +#include +#include +#include +#include + +#include "Helpers.h" + +using namespace std; + +class Controller { +private: + static string viewInputFormat; + static string viewOutputFormat; + + char *controllerName; + vector controllerAttributions; + string viewChunk; + + void prepareView(); + void prepareViewInput(); + // TODO: interpolate the view strings for output with the according variables received from the model. +public: + static string &getViewInputFormat(); + static string &getViewOutputFormat(); + static bool hasInput(string &); + + Controller(); + Controller(char *, string &, string &); + + vector &getControllerAttributions(); + char *getControllerName(); + + void operator=(const Controller &); + + ~Controller(); +}; \ No newline at end of file diff --git a/app/Helpers.cpp b/app/Helpers.cpp index a2f52ea..d8a286f 100644 --- a/app/Helpers.cpp +++ b/app/Helpers.cpp @@ -1,9 +1,3 @@ -#include -#include -#include -#include -#include - #include "Helpers.h" bool isInCharStringMap(const map &haystack, char needle) @@ -42,3 +36,29 @@ void clearScreen() { system("cls"); } + +void log(char *data, char *identifier, char *situation) +{ + cout << "---///////////---" << endl; + cout << identifier << " is currently " << data << " when " << situation << endl; + cout << "---///////////---" << endl; +} + +void log(string &data, char *identifier, char *situation) +{ + cout << "---///////////---" << endl; + cout << identifier << " is currently " << data.c_str() << " when " << situation << endl; + cout << "---///////////---" << endl; +} + +void log(vector &data, char *identifier, char *situation) +{ + cout << "---///////////---" << endl; + cout << identifier << " is currently "; + for (vector::iterator it = data.begin(); it != data.end(); it++) + { + cout << (*it).c_str() << " "; + } + cout << " when " << situation << endl; + cout << "---///////////---" << endl; +} \ No newline at end of file diff --git a/app/Helpers.h b/app/Helpers.h index 2b27905..e09d011 100644 --- a/app/Helpers.h +++ b/app/Helpers.h @@ -1,6 +1,8 @@ #include #include #include +#include +#include using namespace std; @@ -9,4 +11,7 @@ bool isInCharVector(const vector &, char); bool isInIntVector(const vector &, int); bool isInStringVector(const vector &, string); void sleepAndClearBuffer(unsigned delay); -void clearScreen(); \ No newline at end of file +void clearScreen(); +void log(char *, char *, char *); +void log(string &, char *, char *); +void log(vector &, char *, char *); \ No newline at end of file diff --git a/app/View.cpp b/app/View.cpp index 793d53a..8a9b44d 100644 --- a/app/View.cpp +++ b/app/View.cpp @@ -5,27 +5,25 @@ // A view has attached to it a range of available actions or certain verbs that are used by the console to do some action. // It's basically a dictionary holding the options mapping. map> View::ViewsOptions = { { "",{ { '\0', "" } } } }; +string View::ViewExtenstion = ".view"; View::View() { this->viewName = new char[strlen("NO_VIEW") + 1]; strcpy(this->viewName, "NO_VIEW"); - this->hasInterpolation = false; } -View::View(string &viewName, map &availableOptions, bool hasInterpolation) +View::View(string &viewName, map &availableOptions) { this->viewName = new char[strlen(viewName.c_str()) + 1]; strcpy(this->viewName, viewName.c_str()); this->availableOptions = availableOptions; - this->hasInterpolation = hasInterpolation; } View::View(const View &view) { this->viewName = new char[strlen(view.viewName) + 1]; strcpy(this->viewName, view.viewName); - this->hasInterpolation = view.hasInterpolation; this->availableOptions = view.availableOptions; } @@ -39,6 +37,11 @@ char *View::getViewName() return this->viewName; } +void View::setRawFormat(string &rawFormat) +{ + this->rawFormat = rawFormat; +} + void View::loadViewsOptions() { string homeView = "home.view", @@ -69,6 +72,11 @@ map> &View::getViewsOptions() return View::ViewsOptions; } +string View::getViewExtension() +{ + return View::ViewExtenstion; +} + // Prevent multiple assignments of views, i.e. a view can transition only once and cannot split into multiple views. void View::operator=(const View &view) { @@ -76,7 +84,6 @@ void View::operator=(const View &view) this->viewName = new char[strlen(view.viewName) + 1]; strcpy(this->viewName, view.viewName); - this->hasInterpolation = view.hasInterpolation; this->availableOptions = view.availableOptions; } diff --git a/app/View.h b/app/View.h index f7d9575..ec30810 100644 --- a/app/View.h +++ b/app/View.h @@ -1,8 +1,3 @@ -#include -#include -#include -#include -#include #include #include "Helpers.h" @@ -12,23 +7,28 @@ using namespace std; class View { private: static map> ViewsOptions; + static string ViewExtenstion; char *viewName; - bool hasInterpolation; + string rawFormat; map availableOptions; public: static void loadViewsOptions(); static map> &getViewsOptions(); + static string getViewExtension(); View(); - View(string &, map &, bool); + View(string &, map &); View(const View &); map &getAvailableOptions(); char *getViewName(); + void setRawFormat(string &); + void operator=(const View &); + ~View(); }; \ No newline at end of file diff --git a/app/app.vcxproj b/app/app.vcxproj index 6ff7d0b..8f2d5b0 100644 --- a/app/app.vcxproj +++ b/app/app.vcxproj @@ -145,12 +145,14 @@ + + diff --git a/app/app.vcxproj.filters b/app/app.vcxproj.filters index 0a71083..ceea3d5 100644 --- a/app/app.vcxproj.filters +++ b/app/app.vcxproj.filters @@ -30,6 +30,9 @@ Source Files + + Source Files + @@ -44,5 +47,8 @@ Header Files + + Header Files + \ No newline at end of file diff --git a/database/categories.store b/database/categories.store new file mode 100644 index 0000000..e69de29 diff --git a/database/questions.store b/database/questions.store new file mode 100644 index 0000000..e69de29 diff --git a/database/users.store b/database/users.store new file mode 100644 index 0000000..e69de29 diff --git a/views/login.view b/views/login.view index 5e39b56..7628f30 100644 --- a/views/login.view +++ b/views/login.view @@ -4,9 +4,13 @@ _\ \ || (_| | (__|