KoMo2  1.0.0
A modern ARM emulator GUI.
CompileLoadModel.cpp
Go to the documentation of this file.
1 
10 #include <gtkmm/filechooserdialog.h>
11 #include <sys/wait.h>
12 #include <unistd.h>
13 #include <iostream>
14 #include <regex>
15 #include <string>
16 #include "../views/MainWindowView.h"
17 #include "KoMo2Model.h"
18 
25  KoMo2Model* const parent)
26  : Model(parent), view(view) {
27  // Set the onClick events for the browse and compile and load buttons to
28  // be wired to CompileLoadModel member functions.
29  setButtonListener(view->getBrowseButton(), this,
31 
34 
35  // Set's the views model & updates the compile load models inner state.
36  view->setModel(this);
37  setInnerState(CompileLoadInnerState::NO_FILE);
38 }
39 
46  // If the length is zero, invalid path
47  if (not getAbsolutePathToSelectedFile().length()) {
48  // should not be reachable
49  return;
50  }
51 
52  // The code within this if block is executed by the child process.
53  if (not fork()) {
54  // Compile the .s program to .kmd
56  (getParent()->getAbsolutePathToProjectRoot() + "/bin/aasm").c_str(),
59  _exit(0);
60  }
61 
62  // parent process
63  else {
64  int status = 0;
65  wait(&status); // Wait for the child to return
66 
67  // If child process failed
68  if (status) {
69  return;
70  }
71 
72  // Perform the load
74 
75  // If load function failed
78  std::cout << "Error loading file into KoMo2." << std::endl;
79  return;
80  }
81 
82  getParent()->changeJimulatorState(JimulatorState::LOADED);
83  }
84 }
85 
91  // Creates a new file browser dialogue box
92  Gtk::FileChooserDialog dialog("File explorer", Gtk::FILE_CHOOSER_ACTION_OPEN);
93 
94  // Gets the parent of the dialogue box
95  dialog.set_transient_for(*getParent()->getMainWindow());
96 
97  // Add response buttons the the dialog:
98  dialog.add_button("_Cancel", Gtk::RESPONSE_CANCEL);
99  dialog.add_button("_Open", Gtk::RESPONSE_OK);
100 
101  // Creates a filter for what type of files can be selected
102  auto assemblyFilter = Gtk::FileFilter::create();
103  assemblyFilter->set_name("ARM assembly files");
104  assemblyFilter->add_pattern("*.s");
105  dialog.add_filter(assemblyFilter);
106 
107  // Show the dialog and wait for a user response, then handle the result
108  handleResultFromFileBrowser(dialog.run(), &dialog);
109 }
110 
120  const int result,
121  const Gtk::FileChooserDialog* const dialog) {
122  switch (result) {
123  // A file was selected - update inner state and overall state
124  case (Gtk::RESPONSE_OK): {
125  setAbsolutePathToSelectedFile(dialog->get_filename());
126  setInnerState(CompileLoadInnerState::FILE_SELECTED);
127  getParent()->changeJimulatorState(JimulatorState::UNLOADED);
128  return;
129  }
130  // Dialog was cancelled - update inner state but not overall state
131  case (Gtk::RESPONSE_CANCEL): {
133  setInnerState(CompileLoadInnerState::NO_FILE);
134  return;
135  }
136  default: {
137  // Some unexpected behaviour - update inner state but not overall state
139  setInnerState(CompileLoadInnerState::NO_FILE);
140  return;
141  }
142  }
143 }
144 
153  const std::string absolutePath) const {
154  return absolutePath.substr(0, absolutePath.size() - 1).append("kmd");
155 }
156 
162  // Sets the default button state for compileLoadButton
163  if (getInnerState() == CompileLoadInnerState::NO_FILE) {
165  } else {
167  }
168 
169  // Sets the state of the browseButton
170  switch (newState) {
171  // some unloaded state
172  case JimulatorState::UNLOADED:
174  break;
175 
176  // loaded, not yet run state
177  case JimulatorState::LOADED:
180  break;
181 
182  // Currently running
183  case JimulatorState::RUNNING:
186  break;
187 
188  // Has been running; is paused
189  case JimulatorState::PAUSED:
191  break;
192  // Error state
193  default:
194  // TODO: Handle some error state gracefully
195  break;
196  }
197 }
198 
204 const bool CompileLoadModel::handleKeyPress(const GdkEventKey* const e) {
205  // If ctrl is not pressed, return false
206  if ((e->state & (GDK_SHIFT_MASK | GDK_CONTROL_MASK | GDK_MOD1_MASK)) !=
207  GDK_CONTROL_MASK) {
208  return false;
209  }
210 
211  switch (e->keyval) {
212  // Ctrl + (lower- & upper-case l)
213  case GDK_KEY_L:
214  case GDK_KEY_l:
215  if (getJimulatorState() != JimulatorState::RUNNING) {
216  onBrowseClick();
217  }
218  return true;
219  // Ctrl + (lower- & upper-case r)
220  case GDK_KEY_R:
221  case GDK_KEY_r:
222  if (getJimulatorState() != JimulatorState::RUNNING &&
223  getInnerState() != CompileLoadInnerState::NO_FILE) {
225  }
226  return true;
227  default:
228  return false;
229  }
230 
231  return false;
232 }
233 
234 // ! Getters and setters!
235 
242  // This regex matches any length of characters up to a `/` character. The
243  // regex_replace replaces them with "". So if we have `/user/demo/someFile.s`
244  // it will resolve to simply become `someFile.s`
245  std::string filename =
246  regex_replace(getAbsolutePathToSelectedFile(), std::regex("(.*\\/)"), "");
247 
248  // Sets the label text to the filename
249  view->setSelectedFileLabelText("File: " + filename);
250 
251  innerState = val;
252 
253  switch (val) {
254  case CompileLoadInnerState::FILE_SELECTED:
256  getParent()->getMainWindow()->set_title(" KoMo2 - " + filename);
257  break;
258  case CompileLoadInnerState::NO_FILE:
260  getParent()->getMainWindow()->set_title(" KoMo2");
261  break;
262  default:
263  // Error state
264  break;
265  }
266 }
273 }
280 }
286  return innerState;
287 }
const std::string getAbsolutePathToSelectedFile() const
Gets the absolutePathToSelectedFile member variable.
void setButtonState(Gtk::Button *const button, const bool state, Gtk::Image *const img=nullptr, const std::string newTooltip="", const std::string newLabelText="") const
Sets the state of a button to some boolean - the assumption is that if a button is not meant to be se...
Definition: Model.cpp:37
void resetJimulator()
Reset the emulators running.
Definition: kcmd.cpp:363
void onCompileLoadClick() const
Compiles a .s file into a .kmd file: Forks a child process, executes aasm on the child, and then load it into Jimulator, if a valid file path is given.
CompileLoadInnerState
An enum indicating the state of the specific compile and load section of the GUI - specifically...
void compileJimulator(std::string pathToBin, const char *const pathToS, const char *const pathToKMD)
Runs pathToS through the associated compiler binary, and outputs a .kmd file at pathToKMD.
Definition: kcmd.cpp:283
KoMo2Model *const getParent() const
Returns the parent pointer.
Definition: Model.cpp:67
void setInnerState(const CompileLoadInnerState newState)
Handles changing the inner state of this model (whether a file is selected or not) ...
JimulatorState getJimulatorState() const
Return the jimulatorState member object.
Definition: Model.cpp:75
CompileLoadModel(CompileLoadView *const view, KoMo2Model *const parent)
Construct a new CompileLoadModel::CompileLoadModel object.
const CompileLoadInnerState getInnerState() const
Get the Inner State object.
void setModel(CompileLoadModel *const val)
Set the model pointer.
JimulatorState
Describe the 5 states of Jimulator.
Definition: Model.h:19
void setButtonListener(Gtk::Button *const button, const T1 b, const T2 c)
Connect any button to any member function of.
Definition: Model.h:52
MainWindowView *const getMainWindow() const
Gets the mainWindow member variable.
Definition: KoMo2Model.cpp:136
virtual void changeJimulatorState(const JimulatorState newState) override
Handles a change in JimulatorState for this model.
A file containing the definition of the KoMo2Model class.
The superclass for all other Model classes. Uses a pure virtual function, so is abastract. Keeps KoMo2Model as a friend so it alone can call setJimulatorState. This class provides basic data that are needed by all other.
Definition: Model.h:35
const std::string makeKmdPath(const std::string absolutePath) const
Takes an ARM assembly file, removes it&#39;s current s extension, and appends kmd. For example...
const bool loadJimulator(const char *const pathToKMD)
Clears the existing source object and loads the file at pathToKMD into Jimulator. ...
Definition: kcmd.cpp:326
CompileLoadInnerState innerState
Stores the state of the compile and load section of the GUI.
The logical model of the entire application. All other models should be member variables of this mode...
Definition: KoMo2Model.h:34
void onBrowseClick()
Opens a file selection dialog upon the BrowseButtonView being clicked.
std::string absolutePathToSelectedFile
State - stores the value of the absolute file path to a .s file, as chosen by the file browser compon...
CompileLoadView *const view
A pointer to the view that this model represents.
Gtk::Button *const getCompileAndLoadButton()
Gets the compileAndLoadButton member variable.
Gtk::Button *const getBrowseButton()
Gets the browseButton member variable.
void setAbsolutePathToSelectedFile(const std::string val)
Sets the absolutePathToSelectedFile member variable.
virtual const bool handleKeyPress(const GdkEventKey *const e) override
Handles a key press event for this model.
virtual void changeJimulatorState(const JimulatorState newState) override
Changes the Jimulator state and calls each child models own changeJimulatorState function.
Definition: KoMo2Model.cpp:97
void setSelectedFileLabelText(const std::string val)
Sets the text displayed by the selectedFileLabel member variable.
This class represents the visual aspects that make up the compile & load section of the KoMo2 GUI...
void handleResultFromFileBrowser(const int result, const Gtk::FileChooserDialog *const dialog)
Handles the result of the file browser dialog box being closed.