Skip to content

Commit

Permalink
update Readme
Browse files Browse the repository at this point in the history
  • Loading branch information
jacquetc committed Mar 2, 2024
1 parent 83b8683 commit 1bb39ec
Showing 1 changed file with 46 additions and 26 deletions.
72 changes: 46 additions & 26 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@ It's important to note that this conceptual representation needs to be tailored
- **Persistence**: Manages internal data persistence. It includes a 'repository' wrapper for SQLite database interactions, with each entity having its repository in the `RepositoryProvider` class.
- **Contracts**: A common library for most other components, housing all interfaces from `persistence`, `gateway`, and `infrastructure`. This design minimizes tight coupling and circular dependencies.
- **DTO Libraries**: Each functionality has its DTO library, facilitating communication with the `application` layer. DTOs are used for both input and output in interactions with the outer layers, such as interactors.
- **CQRS Libraries** (Command Query Responsibility Segregation): The `application` layer is designed to support CQRS, with commands and queries being handled separately. This separation is achieved by using the `CommandHandler` and `QueryHandler` classes. Other classes, such as `CommandValidator` and `QueryValidator`, are used to validate commands and queries, respectively. They are stored away in a separate library called `cqrs`.
- **Gateway**: Optional library for handling remote connections and services. It can be manually added by the developer and is used similarly to repositories in use cases.
- **Infrastructure**: Optional. Handles actions like file management, local settings, and system queries. It's injected into use cases similar to repositories and gateways.
- **Interactor**: Acts as an internal API to invoke use cases, streamlining the interaction between the user interface and application logic.
Expand Down Expand Up @@ -76,6 +77,51 @@ sudo cmake --install .

Qleany is building and examples are running well if you use Qt Creator or Visual Studio Code with the CMake Tools extension.

## Using Qleany

To use Qleany, follow these steps:

1. Write a `qleany.yaml` file for your project. You can use the `examples/simple/qleany.yaml` file as a reference.
2. Run the Qleany GUI interface and select the `qleany.yaml` file.
3. List and select the files you want to generate.
4. To avoid overwriting your current files: Preview the files, it will generate them in a "qleany_preview" folder.
5. If you are sure, generate the files directly. Qleany will generate them in the right place, but will never delete other files.
7. Create CMakelists.txt files to include the generated libraries in your project. You can use the `examples/simple/src/core/CMakeLists.txt` and `examples/simple/src/gui/CMakeLists.txt` files as a reference.
6. For custom commands and queries, you still have to fill the blanks in the generated files. You will find "Q_UNIMPLEMENTED();" in the generated files.


### For QWidgets GUI

7. Create an UI project, not at the root of the project, but in a dedicated sub-folder, like with did with `examples/simple/src/gui/desktop_application`.
8. You can now start to implement your GUI and use cases. A GUI made with QWidgets will only use the interactors and models in presenter. Refer to the example for guidance at `examples/simple/src/gui/desktop_application/main.cpp`

### For QML GUI

*Note*: For now, the QML file generation is tailor-made to be used after a project is created using Qt Design Studio, but only subltle changes are needed to use it with a project created manually. You can use the `examples/simple/src/gui/qml_application` as a reference of what is running fine, this project uses Qt Design Studio's generated CMakeLists.txt. At the minimum, you only have to include the generated `realqmlmodules.cmake` file in your project's CMakeLists.txt file and mofify your main.cpp to register the other libraries.

7. Create a QML project using Qt Design Studio, not at the root of the project, but in a dedicated sub-folder, like with did with `examples/simple/src/gui/qml_application`.
8. You can now start to implement your GUI and use cases. A GUI made with QML will use **not** the interactors and models directly from the interactor and presenter libraries. Wrappers around them all are generated in the QML `real_imports` folder in the QML folder to be made available from QML. Also, QML mocks are generated in `mock_imports`, to be filled by the developer. Refer to the example for guidance at `examples/simple/src/gui/qml_application/src/main.cpp` and `examples/simple/src/gui/qml_application/CMakelists.txt`

### For both QWidgets and QML GUI

You can use both QWidgets and QML GUIs in the same project. You can use the `examples/simple/` as a reference. The QML and QWidgets GUIs are in their own sub-folders, and the main.cpp file is in the root of the project. The CMakeLists.txt file is in the root of the project and includes the QML and QWidgets GUIs.

### Gateway and Infrastructure

The gateway and infrastructure are not generated by Qleany. You have to create them manually. You can use the `examples/simple/src/core/contracts` and `examples/simple/src/core/persistence` as a reference. The `contracts` folder contains the interfaces for the gateway and infrastructure, similar to what is done with the repositories of `persistence`.

So, if I wnated to add a `gateway`, I would create a `gateway` folder in the `src/core/contracts` folder, and add the interfaces for the gateway. Then, I would create a `gateway` folder in the `src/core` folder, and add the implementation of the gateway. Each use case (handler) in `application` would have a `gateway` parameter using the interface, like what is already one with the repositories, and the `gateway` would be instanciated and injected into `interactor` in the `main.cpp` file.

Finally, do not forget a `gateway_registration.cpp` file in the `src/core/gateway` folder to register the gateway classes.

In a Gateway, we would find connections to remote services like REST APIs and remote datbases, and in Infrastructure, we would find connections to local services, like file management, local settings, and system queries. A "loadFile" method in a `FileLoader` class would be an example of an infrastructure service. Same for a `Settings` class or "exportToPdf" method in a `PdfExporter` class.

The names Gateway and Infrastructure are not mandatory, you can use other names, like Remote and Local, or whatever you want.

### Custom Commands and Queries

You can add custom commands and queries for each feature in the `application.features` of the `qleany.yaml`. You can use the `examples/simple/qleany.yaml` and `examples/simple/src/core/application` as references. Search for the Q_UNIMPLEMENTED(); macro in the generated files to find the places to fill with your custom code. Be careful ot not overwrite your custom code when you regenerate the files.

## Installing the Qleany GUI Interface

Qleany tooling can be installed using `pip install qleany`. Alternatively, for an easier installation, you can install it using `pipx run qleany` if you have pipx installed.
Expand Down Expand Up @@ -302,29 +348,3 @@ qml:
folder_path: path/to/qml/folder
```

## Using Qleany

To use Qleany, follow these steps:

1. Write a `qleany.yaml` file for your project. You can use the `examples/simple/qleany.yaml` file as a reference.
2. Run the Qleany GUI interface and select the `qleany.yaml` file.
3. List and select the files you want to generate.
4. To avoid overwriting your current files: Preview the files, it will generate them in a "qleany_preview" folder.
5. If you are sure, generate the files directly. Qleany will generate them in the right place, but will never delete other files.
7. Create CMakelists.txt files to include the generated libraries in your project. You can use the `examples/simple/src/core/CMakeLists.txt` and `examples/simple/src/gui/CMakeLists.txt` files as a reference.
6. For custom commands and queries, you still have to fill the blanks in the generated files. You will find "Q_UNIMPLEMENTED();" in the generated files.


### For QWidgets GUI

7. Create an UI project, not at the root of the project, but in a dedicated sub-folder, like with did with `examples/simple/src/gui/desktop_application`.
8. You can now start to implement your GUI and use cases. A GUI made with QWidgets will only use the interactors and models in presenter. Refer to the example for guidance at `examples/simple/src/gui/desktop_application/main.cpp`

### For QML GUI

*Note*: For now, the file generation is tailor-made to be used after a project is created using Qt Design Studio, but only subltle changes are needed to use it with a project created manually. You can use the `examples/simple/src/gui/qml_application` as a reference of what is running fine, this project uses Qt Design Studio's generated CMakeLists.txt. At the minimum, you only have to include the generated `realqmlmodules.cmake` file in your project's CMakeLists.txt file and mofify your main.cpp to register the other libraries.

7. Create a QML project using Qt Design Studio, not at the root of the project, but in a dedicated sub-folder, like with did with `examples/simple/src/gui/qml_application`.
8. You can now start to implement your GUI and use cases. A GUI made with QML will use **not** the interactors and models directly from the interactor and presenter libraries. Wrappers around them all are generated in the QML `real_imports` folder in the QML folder to be made available from QML. Also, QML mocks are generated in `mock_imports`, to be filled by the developer. Refer to the example for guidance at `examples/simple/src/gui/qml_application/src/main.cpp` and `examples/simple/src/gui/qml_application/CMakelists.txt`

0 comments on commit 1bb39ec

Please sign in to comment.