From c64d37ed02b1ca40922fba0049c0e00906816a6c Mon Sep 17 00:00:00 2001
From: tobiglaser <76131623+tobiglaser@users.noreply.github.com>
Date: Tue, 9 Aug 2022 23:05:37 +0200
Subject: [PATCH] update readme

---
 README.md | 105 ++++++++++++++++++++++++++++++++++++++++++++----------
 1 file changed, 86 insertions(+), 19 deletions(-)

diff --git a/README.md b/README.md
index f2b0160..16d6a2e 100644
--- a/README.md
+++ b/README.md
@@ -3,10 +3,12 @@
 This repo documents the transition of the third Computer Science lab exercises from Java to C++.
 The Course is about programming concepts rather than a specific language.
 
+Please note, that `const` has not been used everywhere possible in this codebase.
+To `const` and `constexpr` everything will be a good future exercise to hone programming skills.
 ## Changes
 
 ### Worksheet 4
-**PanelCommandTypes**
+#### PanelCommandTypes
   - When using Qt, no `ActionListener`s have to be used to register the click of a button. Rather a callback function `slot` is `connect`ed to an event `signal` of the button.  
   So `setController()` doesn't instanciate any Listeners, but `connect`s the appropriate `slot`s to the button `signal`s.
   - In Qt lists can be displayed either by a simplified `QListWidget`, or via a Model/View structure.  
@@ -15,7 +17,7 @@ The Course is about programming concepts rather than a specific language.
   - For the `commandTypeList` the widget was chosen.
     - Because of that the subclass `ComTypeListWidgetItem` had to be created to allow the Item to remember its `CommandType`.
 
-**PanelCommandConfig**
+#### PanelCommandConfig
   - For the Panels a `QStackedWidget`, comparable to `CardLayout` is used.
   - The constants for switching between panels were moved into an `enum`. Enums are implicid integers, while `enum class`es have their own type.
   - The config panels are passed a pointer to the `ControlUI` and remember it to later call `updateTableView()` directly.  
@@ -23,11 +25,18 @@ The Course is about programming concepts rather than a specific language.
   The panels would not have to know the `ControlUI` and would just emit a `signal` to initiate the update.
   The connection would happed in `ControlUI.setController()`, just like with the other panels.
 
-**PanelCommandTable**
+#### PanelCommandTable
   - `TableCommandModel`
-    - In Qt a change in the model is communicated by the model.  
-    It signals `dataChanged()` for each changed cell or `layoutChanged()` if row or column counts were changed.
+    - A change in the `ControlModel` are communicated by the `TableModel`.  
+    It signals `dataChanged()` for an area of changed cells or `layoutChanged()` if row or column counts were changed.
     - Because of this the method `onChange()` was added to the model to be called by the panel.
+      - `onChange()` checks the dimensions of the table, emitting `layoutChanged()` if appropriate.
+      - `onChange()` also finds the cells that need to be updated in the View and emits `dataChanged()` for each cell
+      - Single cells are updated rather than the whole area.
+        When figuring out Qt Tables two similar `QModelIndex`es worked more reliably then two different ones.
+      - Later it was noted the same signals can also be emitted from the Panel and connected manually to the [`dataChanged()` slot](https://doc.qt.io/qt-6/qabstractitemview.html#dataChanged) of the View.
+      The control flow would then match the java version.
+      - Maybe it would be a good idea to have the `tableModel` observe the `ControlModel` via `IControlModelListener` and add a function `listChanged()` there?
     - The `data()` method does not only define the text, but also other properties of each cell.
     These should be considered when overriding the function. An empty `QVariant()` means invalid.
   - `PanelCommandTable`
@@ -37,14 +46,14 @@ The Course is about programming concepts rather than a specific language.
       With signals and slots neither the sender nor the receiver need to know each other, just the one who connects them does.
       - This would have been completely avoidable if `updateTable()` was called directly inside the panel, but well it works.
 
-**ControlUI**
+#### ControlUI
   - `updateTableView()` and `updateConfigView()` are declared as slots such that the signals of the panels can be connected to it.
   - `QActions`, needed for the `QMenubar`, are not taken ownership of by the `QMenu`s they are assigned to.
   Because of this they need to be cleaned up manually. They also get `triggered()` rather then `clicked()`.
 
 
 ### Worksheet 3
-**Background**
+#### Background
   - Many files were added so that all excercises could be solved, enough funtionality was introduced to allow some level of simulation.
   - `ComHandler` and `RoverHandler` were implemented as Singletons as they are not members of `ControlModel`.  
     They could be implemented differently. With `getInstance()` as the interface to get a reference to the `ComHandler` instance this will not break the implementation.
@@ -57,19 +66,19 @@ The Course is about programming concepts rather than a specific language.
       It is fine for a file from `src/` to include from `include/`, but not the other way around.
       "Solved" by including with manual path `#include "../src/Gear.h"` rather than relying on CMake.
 
-**CommandType**
+#### CommandType
   - Yields a `std::shared_ptr<ICommand>` rather than a `Command`.
   - `Element` was extended with a constructor that takes an existing `shared_ptr`, rather then creating a new one.
     This was done because it would be unnecessary to extract the raw `Command` out of the returned `shared_ptr` to `Command`,
     only to pass it to `Element` where it is wrapped into a `shared_ptr` again.
 
-**ControlModelRegistry**
+#### ControlModelRegistry
   - The registry holds `weak_ptr`s rather than `shared_ptr`s because it should not own the `listeners`. `Weak pointers` are locked and checked for validity when they are used.
   - Earlier `std::erase` was used to remove `listeners` from the `registry`, but this doesn't work for `weak_ptr`, so a for-loop with an `iterator` is used.
   - To notify the `listeners` a *range based for-loop* is used.  
     Here one can see how code complexity can be reduced by using modern features of Cpp.
 
-**ControlModel**
+#### ControlModel
   - The instance variable of the singleton pattern was moved to inside the `getInstance()` function reducing complexity.
   - To register the `ControlModel` to the `ComHandler` the raw pointer had to be used.
     This should be ok as the lifetime of the singleton instance should last until the program is terminated. The raw pointer was wrapped into an `optional` in `ComHandler` which might be unnecessary because it could also be `nullptr`. It is more expressive tough.
@@ -81,36 +90,36 @@ The Course is about programming concepts rather than a specific language.
     Maybe a good opportunity to write an own `iterator` for `CommandList`?
   - The `getters` return references to private data of `ControlModel`, likely `const` should be used to protect them from the harsh world outside `ControlModel`.
   - Since no `Rover` could be selected `getSelectedRoverId()` returns an `optional string`.
-**Test**
+#### Test
   - The test was expanded also show adding `Commands` from the `CommandTypes` as well as reading from and writing to a file.
   - Because `ObjectFileHandler` was created, another test was added for for that.
 
 
 ### Worksheet 2
-**Background**
+#### Background
   - `commandlib.h` was introduced as a stand in for `hsrt.mec.controldeveloper.core.com.command`. For simplicity everything is defined in one header.
   - Diverging from the class diagram the other interfaces dont inherit from `ICommand` as that would leed to weird inheritance loops where e.g. `Gear` inherits from `Command` which inherits from `ICommand`, but also from `IDirection` which also already inherits from `ICommand`. Maybe the class diagram could be simplified if `ICommand` would be replaced by the partially virtual `Command`.
-**Commands**
+#### Commands
   - `Gear`, `Pause` and `Direction` use multiple inheritance to allow the use of interfaces.
   This is fine, but it should be good practice to inherit from one base class only and only virtual classes otherwise.
-**CommandList:**
+#### CommandList:
   - `CommandList` now needs a default constructor for `Element` because `Command` is now virtual and can no longer be use for the root `Element`.
   - `CommandList` and `Element` use template functions to allow adding multiple types of `Command`s. This sort of is compile-time polymorphism.
   - There is no checking if the template got the right type though. Possibly there is a solution using `static_assert` and `std::is_...`.
   - For variable types templates should use `typename` rather than `class`.
-**Class vs Member variables**
+#### Class vs Member variables
   - To call a static function without an object it is necessary to use the namespace operator `MyClass::foo()` rather than `MyClass.foo()`.
-**Doxygen**
+#### Doxygen
   - see Trivia
 
 ### Worksheet 1
-**Element:**
+#### Element:
   - In Element every mention of Element is replaced with `std::shared_ptr<Element>`.
   - Command cmd becomes `std::shared_ptr<Command>`.
   - In the constructor `Element(Command cmd)` uses `std::make_shared<Command>(cmd)` to produce a `std::shared_ptr`.
   - The destructor `~Element()` may be configured to log destruction of removed Elements.
 
-**CommandList:**
+#### CommandList:
   - the `Element root` now is a `shared_ptr<Element>` and is initialized inline with `std::make_shared<Element>(Command("root"))`. This is necessary because a shared pointer is empty upon construction.
   - All member functions previously returning `Command`s now return `std::make_shared<Command>`.
   This is to allow for returning `nullptr` if something went wrong.
@@ -174,4 +183,62 @@ Basic settings in `Doxyfile`:
   - USE_MDFILE_AS_MAINPAGE because it would be empty otherwise (here README.md) (specify file in INPUT)
   - SOURCE_BROWSER and INLINE_SOURCES for source code in documentation
   - GENERATE_TREEVIEW for the sidebar well-known from Javadoc
-  - GENERATE_LATEX to spare generation of latex files
\ No newline at end of file
+  - GENERATE_LATEX to spare generation of latex files
+
+### Dynamic Cast
+To retrieve subclasses from a base pointer e.g. `ICommand*` we need to cast
+it to the desired class.
+For this dynamic_cast<>() can be used. It returns a pointer to the class we want or, if the object is not of that type, it returns nullptr.
+To check if an `ICommand*` is also a `Gear*` we do:
+
+    ICommand* icom = new Gear();
+    Gear* p = dynamic_cast<Gear*>(ICommand*);
+    if (p)
+      //icom was of type Gear*, we can use p.
+
+dynamic_pointer_cast can be used with the same syntax.
+It returnins a shared_ptr to the same Object, this way memory safety is kept.  
+static_cast<>() does also exist, [Kate Gregory](https://youtu.be/XkDEzfpdcSg?t=2375) calls this the
+"This is my foot and I'm pointing this gun here on purpose"-operator.
+It should only be used if we are absolutely sure of what we are getting.
+
+### Virtual Inheritance
+With multiple inheritance it is possible that a class inherits from the same base class twice.
+In our case this happens in the Commands:
+Gear -> Command -> ICommand
+Gear -> IGear -> ICommand
+In that case it would have two separate instances of the base class.
+Usually only one instance of the base class is neccessary.
+To achieve that the keyword `virtual` is used in the class declaration.
+Like this:
+
+    class IGear : public virtual ICommand
+
+Meaning IGear does not need a separate instance of ICommand.
+Especially useful for interfaces.
+More Info: [Virtual Inheritance](https://en.wikipedia.org/wiki/Virtual_inheritance?oldformat=true)
+
+### Qt
+#### German Youtube Tutorials
+[CodingProf](https://www.youtube.com/c/CodingProf/) is a professor at Hochschule Ruhr West and has many videos on programming and C++ in general, but also talks about GUIs and Qt: [Playlist with Qt](https://www.youtube.com/playlist?list=PL1urCEuoZfltITfwd7jEA51XSHme8Oq3d).
+
+#### Qt Memory and ownership
+Qt doesn't use unique or shared pointers for memory management,
+but rather manages the QObjects in an [Object Tree](https://doc.qt.io/archives/qt-6.0/objecttrees.html).
+This *mostly* takes away concerns about memory safety.
+As soon as we add a new Widget to an existing e.g. with `addWidget()` one we don't care about the deletion of the object anymore as the ownership is transfered.  
+There *of course* are exceptions:
+QAction can be represented in a QMenuBar as well as a QToolBar, 
+so none of them take ownership of the QAction.
+This is stated in the [documentation](https://doc.qt.io/qt-6/qwidget.html#addAction).  
+Here two paths can be chosen:  
+The [recommended](https://doc.qt.io/qt-6/qaction.html) one: "We recommend that actions are created as children of the window they are used in. In most cases actions will be children of the application's main window."  
+Or we create them without a parent specified and manage/delete them on our own, as was done here. If choosing that route care must be taken to not delete twice.
+
+#### QString
+QStrings can be constructed from char[]s, but not from std::string, convert them like:  
+`std::string -> QString .c_Str()`  
+`QString -> std::string .toStdString()`
+
+#### Qt Examples
+Some examples showcasing different basic functionalities are compiled [here](https://github.com/tobiglaser/qt-examples).
\ No newline at end of file
-- 
GitLab