Skip to content

Commit

Permalink
renamed Interactor to Controller
Browse files Browse the repository at this point in the history
  • Loading branch information
jacquetc committed Sep 29, 2024
1 parent 6bcd1ee commit 99d0c57
Show file tree
Hide file tree
Showing 250 changed files with 1,901 additions and 1,901 deletions.
28 changes: 14 additions & 14 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@
+ [Global Settings](#global-settings)
+ [Entities Definition](#entities-definition)
+ [Repositories Configuration](#repositories-configuration)
+ [Interactor Settings](#interactor-settings)
+ [Controller Settings](#controller-settings)
+ [Application Layer Configuration](#application-layer-configuration)
+ [DTOs (Data Transfer Objects) Configuration](#dtos--data-transfer-objects--configuration)
+ [Contracts Configuration](#contracts-configuration)
Expand Down Expand Up @@ -92,23 +92,23 @@ Libraries and their respective functionalities are organized as follows:

- **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.
- **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 controllers.

- **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.
- **Controller**: Acts as an internal API to invoke use cases, streamlining the interaction between the user interface and application logic.

- **Presenter**: Maintains Qt models and representations of unique entities (referred to as `Singles`), enhancing their integration and usage within the GUI.

- **UI**: The structure allows the simultaneous use of different fronts, each in its own binary. QML and QWidgets UIs can coexist without any conflict. Same for a CLI, an API ... All these fronts will use the same models and interactors. You can have a single main.cpp file for all fronts, or one for each front. It's up to you. Qleany will only generate one for each front.
- **UI**: The structure allows the simultaneous use of different fronts, each in its own binary. QML and QWidgets UIs can coexist without any conflict. Same for a CLI, an API ... All these fronts will use the same models and controllers. You can have a single main.cpp file for all fronts, or one for each front. It's up to you. Qleany will only generate one for each front.

Another related point:

- **Registration**: Each component (`persistence`, `gateway`, `infrastructure`, `interactor`) initializes its classes in a corresponding *name*_registration.cpp file, typically called together in the main.cpp.
- **Registration**: Each component (`persistence`, `gateway`, `infrastructure`, `controller`) initializes its classes in a corresponding *name*_registration.cpp file, typically called together in the main.cpp.

Project dependencies:
![Alt text](docs/qleany_project_dep.drawio.png)
Expand Down Expand Up @@ -179,7 +179,7 @@ If you already have a QtWidgets GUI, you can craete a blank GUI in a sub-folder
Note: You can use the `examples/simple/src/gui/desktop_application` or `examples/front_ends` as references of what is running fine.

11. Your QtWidgets must be, not at the root of the project, but in a dedicated sub-folder, like with did with `examples/simple/src/gui/desktop_application`.
12. You can now start to implement your GUI and use cases. A GUI made with QWidgets will only use `interactor` for commands/queries and Q_SIGNALS. Also, it will use models from `presenter`. Refer to the example for guidance at `examples/front_ends/src/gui/qt_widgets_application/main.cpp`
12. You can now start to implement your GUI and use cases. A GUI made with QWidgets will only use `controller` for commands/queries and Q_SIGNALS. Also, it will use models from `presenter`. Refer to the example for guidance at `examples/front_ends/src/gui/qt_widgets_application/main.cpp`

### For QtQuick GUI

Expand All @@ -192,7 +192,7 @@ If you already have a QtQuick GUI, you can craete a blank GUI in a sub-folder ne
11. Your QML GUI must be, not at the root of the project, but in a dedicated sub-folder, like with did with `examples/simple/src/gui/qml_application`.
12. You can now start to implement your GUI and use cases.

A GUI made with QML will **not** use `interactor` and `presenter`. Wrappers around models, Q_SIGNALS, commands and queries 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/front_ends/src/gui/qt_quick_application/main.cpp` and `examples/front_ends/src/gui/qt_quick__application/CMakelists.txt`
A GUI made with QML will **not** use `controller` and `presenter`. Wrappers around models, Q_SIGNALS, commands and queries 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/front_ends/src/gui/qt_quick_application/main.cpp` and `examples/front_ends/src/gui/qt_quick__application/CMakelists.txt`

### For KF6 Kirigami GUI

Expand Down Expand Up @@ -232,13 +232,13 @@ Read "Front end Configuration" section below for more details.

### Other Fronts

You can also create a CLI, an API, a gRPC server, or other fronts. You can use the same models and interactors for all fronts. You can have a single main.cpp file for all fronts, or one for each front. It's up to you.
You can also create a CLI, an API, a gRPC server, or other fronts. You can use the same models and controllers for all fronts. You can have a single main.cpp file for all fronts, or one for each front. It's up to you.

### 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 wanted to add a `gateway`, I would create a `gateway` folder in the `src/core/contracts` folder, and add the interfaces for all the public classes offered by the gateway. Then, I would create a `gateway` folder in the `src/core` folder, and add the implementation of the gateway classes. When needed, use cases (handler) in `application` would have a `gateway` parameter using the interface, like what is already done with the repositories, and the `gateway` classes would be instanciated and injected into `interactor` from inside the `main.cpp` file.
So, if I wanted to add a `gateway`, I would create a `gateway` folder in the `src/core/contracts` folder, and add the interfaces for all the public classes offered by the gateway. Then, I would create a `gateway` folder in the `src/core` folder, and add the implementation of the gateway classes. When needed, use cases (handler) in `application` would have a `gateway` parameter using the interface, like what is already done with the repositories, and the `gateway` classes would be instanciated and injected into `controller` from inside the `main.cpp` file.

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

Expand Down Expand Up @@ -364,14 +364,14 @@ repositories:
base_folder_path: path/to/base/folder
```
### Interactor Settings
### Controller Settings
Configures interactor-specific settings.
Configures controller-specific settings.
```yaml
interactor:
folder_path: path/to/interactor/folder
create_undo_redo_interactor: true/false
controller:
folder_path: path/to/controller/folder
create_undo_redo_controller: true/false
```
### Application Layer Configuration
Expand Down
Binary file modified docs/qleany_project_dep.drawio.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file modified docs/qleany_project_structure.drawio.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
2 changes: 1 addition & 1 deletion examples/front_ends/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -127,7 +127,7 @@ add_subdirectory(src/core/application)

# handles the interaction between the system's inner layers (use cases, DTOs)
# and the external world
add_subdirectory(src/core/interactor/)
add_subdirectory(src/core/controller/)

# handles the Qt models
add_subdirectory(src/gui/presenter)
Expand Down
6 changes: 3 additions & 3 deletions examples/front_ends/qleany.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -68,9 +68,9 @@ repositories:
repository_folder_path: src/core/persistence/repository/
base_folder_path: src/core/persistence/

interactor:
folder_path: src/core/interactor/
create_undo_redo_interactor: true
controller:
folder_path: src/core/controller/
create_undo_redo_controller: true

application:
common_cmake_folder_path: src/core/application
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ find_package(
find_package(QCoro6 REQUIRED COMPONENTS Core)
# find_package(qleany CONFIG REQUIRED)

set(LIBRARY_NAME front-ends-example-interactor)
set(LIBRARY_NAME front-ends-example-controller)

option(BUILD_SHARED_LIBS "Build libraries as shared libraries" ON)

Expand All @@ -19,21 +19,21 @@ else()
set(LIB_TYPE STATIC)
endif()

include(interactors.cmake)
include(controllers.cmake)

set(SRCS
front_ends_example_interactor_export.h
front_ends_example_controller_export.h
event_dispatcher.h
event_dispatcher.cpp
interactor_registration.h
controller_registration.h
error_signals.h
progress_signals.h
interactor_registration.cpp)
controller_registration.cpp)

qt_add_library(${LIBRARY_NAME} ${LIB_TYPE} ${SRCS} ${INTERACTOR_LIST})
qt_add_library(${LIBRARY_NAME} ${LIB_TYPE} ${SRCS} ${CONTROLLER_LIST})

include(GenerateExportHeader)
generate_export_header(${LIBRARY_NAME} BASE_NAME front_ends_example_interactor)
generate_export_header(${LIBRARY_NAME} BASE_NAME front_ends_example_controller)

target_include_directories(${LIBRARY_NAME} PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}
${CMAKE_CURRENT_BINARY_DIR})
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
// This file was generated automatically by Qleany's generator, edit at your own risk!
// If you do, be careful to not overwrite it when you run the generator again.

#include "brand_interactor.h"
#include "brand_controller.h"

#include "brand/commands/create_brand_command.h"
#include "brand/commands/create_brand_command_handler.h"
Expand All @@ -15,16 +15,16 @@
#include "qleany/tools/undo_redo/query_command.h"
#include <QCoroSignal>

using namespace FrontEnds::Interactor;
using namespace FrontEnds::Interactor::Brand;
using namespace FrontEnds::Controller;
using namespace FrontEnds::Controller::Brand;
using namespace FrontEnds::Application::Features::Brand::Commands;
using namespace FrontEnds::Application::Features::Brand::Queries;
using namespace Qleany::Tools::UndoRedo;
using namespace Qleany::Contracts::Repository;

QPointer<BrandInteractor> BrandInteractor::s_instance = nullptr;
QPointer<BrandController> BrandController::s_instance = nullptr;

BrandInteractor::BrandInteractor(InterfaceRepositoryProvider *repositoryProvider,
BrandController::BrandController(InterfaceRepositoryProvider *repositoryProvider,
ThreadedUndoRedoSystem *undo_redo_system,
QSharedPointer<EventDispatcher> eventDispatcher)
: QObject{nullptr}
Expand All @@ -38,12 +38,12 @@ BrandInteractor::BrandInteractor(InterfaceRepositoryProvider *repositoryProvider
s_instance = this;
}

BrandInteractor *BrandInteractor::instance()
BrandController *BrandController::instance()
{
return s_instance.data();
}

QCoro::Task<BrandDTO> BrandInteractor::get(int id) const
QCoro::Task<BrandDTO> BrandController::get(int id) const
{
auto queryCommand = new QueryCommand("get"_L1);

Expand Down Expand Up @@ -73,7 +73,7 @@ QCoro::Task<BrandDTO> BrandInteractor::get(int id) const
co_return optional_result.value();
}

QCoro::Task<QList<BrandDTO>> BrandInteractor::getAll() const
QCoro::Task<QList<BrandDTO>> BrandController::getAll() const
{
auto queryCommand = new QueryCommand("getAll"_L1);

Expand Down Expand Up @@ -101,7 +101,7 @@ QCoro::Task<QList<BrandDTO>> BrandInteractor::getAll() const
co_return optional_result.value();
}

QCoro::Task<BrandDTO> BrandInteractor::create(const CreateBrandDTO &dto)
QCoro::Task<BrandDTO> BrandController::create(const CreateBrandDTO &dto)
{
CreateBrandCommand query;

Expand All @@ -128,7 +128,7 @@ QCoro::Task<BrandDTO> BrandInteractor::create(const CreateBrandDTO &dto)
});

// Create specialized UndoRedoCommand
auto command = new AlterCommand<CreateBrandCommandHandler, CreateBrandCommand>(BrandInteractor::tr("Create brand"), handler, query);
auto command = new AlterCommand<CreateBrandCommandHandler, CreateBrandCommand>(BrandController::tr("Create brand"), handler, query);

// push command
m_undo_redo_system->push(command, "brand"_L1);
Expand All @@ -143,7 +143,7 @@ QCoro::Task<BrandDTO> BrandInteractor::create(const CreateBrandDTO &dto)
co_return optional_result.value();
}

QCoro::Task<BrandDTO> BrandInteractor::update(const UpdateBrandDTO &dto)
QCoro::Task<BrandDTO> BrandController::update(const UpdateBrandDTO &dto)
{
UpdateBrandCommand query;

Expand All @@ -160,7 +160,7 @@ QCoro::Task<BrandDTO> BrandInteractor::update(const UpdateBrandDTO &dto)
QObject::connect(handler, &UpdateBrandCommandHandler::brandDetailsUpdated, m_eventDispatcher->brand(), &BrandSignals::allRelationsInvalidated);

// Create specialized UndoRedoCommand
auto command = new AlterCommand<UpdateBrandCommandHandler, UpdateBrandCommand>(BrandInteractor::tr("Update brand"), handler, query);
auto command = new AlterCommand<UpdateBrandCommandHandler, UpdateBrandCommand>(BrandController::tr("Update brand"), handler, query);

// push command
m_undo_redo_system->push(command, "brand"_L1);
Expand All @@ -175,7 +175,7 @@ QCoro::Task<BrandDTO> BrandInteractor::update(const UpdateBrandDTO &dto)
co_return optional_result.value();
}

QCoro::Task<bool> BrandInteractor::remove(int id)
QCoro::Task<bool> BrandController::remove(int id)
{
RemoveBrandCommand query;

Expand All @@ -189,7 +189,7 @@ QCoro::Task<bool> BrandInteractor::remove(int id)
// no need to connect to removed signal, because it will be emitted by the repository itself

// Create specialized UndoRedoCommand
auto command = new AlterCommand<RemoveBrandCommandHandler, RemoveBrandCommand>(BrandInteractor::tr("Remove brand"), handler, query);
auto command = new AlterCommand<RemoveBrandCommandHandler, RemoveBrandCommand>(BrandController::tr("Remove brand"), handler, query);

// push command
m_undo_redo_system->push(command, "brand"_L1);
Expand All @@ -204,12 +204,12 @@ QCoro::Task<bool> BrandInteractor::remove(int id)
co_return true;
}

CreateBrandDTO BrandInteractor::getCreateDTO()
CreateBrandDTO BrandController::getCreateDTO()
{
return CreateBrandDTO();
}

UpdateBrandDTO BrandInteractor::getUpdateDTO()
UpdateBrandDTO BrandController::getUpdateDTO()
{
return UpdateBrandDTO();
}
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
#include "brand/create_brand_dto.h"
#include "brand/update_brand_dto.h"
#include "event_dispatcher.h"
#include "front_ends_example_interactor_export.h"
#include "front_ends_example_controller_export.h"
#include <qleany/contracts/repository/interface_repository_provider.h>

#include <QCoroTask>
Expand All @@ -19,18 +19,18 @@ using namespace Qleany::Contracts::Repository;
using namespace Qleany::Tools::UndoRedo;
using namespace FrontEnds::Contracts::DTO::Brand;

namespace FrontEnds::Interactor::Brand
namespace FrontEnds::Controller::Brand
{

class FRONT_ENDS_EXAMPLE_INTERACTOR_EXPORT BrandInteractor : public QObject
class FRONT_ENDS_EXAMPLE_CONTROLLER_EXPORT BrandController : public QObject
{
Q_OBJECT
public:
explicit BrandInteractor(InterfaceRepositoryProvider *repositoryProvider,
explicit BrandController(InterfaceRepositoryProvider *repositoryProvider,
ThreadedUndoRedoSystem *undo_redo_system,
QSharedPointer<EventDispatcher> eventDispatcher);

static BrandInteractor *instance();
static BrandController *instance();

Q_INVOKABLE QCoro::Task<BrandDTO> get(int id) const;

Expand All @@ -49,13 +49,13 @@ public Q_SLOTS:
QCoro::Task<bool> remove(int id);

private:
static QPointer<BrandInteractor> s_instance;
static QPointer<BrandController> s_instance;
InterfaceRepositoryProvider *m_repositoryProvider;
ThreadedUndoRedoSystem *m_undo_redo_system;
QSharedPointer<EventDispatcher> m_eventDispatcher;
BrandInteractor() = delete;
BrandInteractor(const BrandInteractor &) = delete;
BrandInteractor &operator=(const BrandInteractor &) = delete;
BrandController() = delete;
BrandController(const BrandController &) = delete;
BrandController &operator=(const BrandController &) = delete;
};

} // namespace FrontEnds::Interactor::Brand
} // namespace FrontEnds::Controller::Brand
Original file line number Diff line number Diff line change
Expand Up @@ -2,18 +2,18 @@
// If you do, be careful to not overwrite it when you run the generator again.
#pragma once

#include "front_ends_example_interactor_export.h"
#include "front_ends_example_controller_export.h"

#include "brand/brand_dto.h"

#include <QObject>

namespace FrontEnds::Interactor
namespace FrontEnds::Controller
{

using namespace FrontEnds::Contracts::DTO::Brand;

class FRONT_ENDS_EXAMPLE_INTERACTOR_EXPORT BrandSignals : public QObject
class FRONT_ENDS_EXAMPLE_CONTROLLER_EXPORT BrandSignals : public QObject
{
Q_OBJECT
public:
Expand All @@ -31,4 +31,4 @@ class FRONT_ENDS_EXAMPLE_INTERACTOR_EXPORT BrandSignals : public QObject
void getReplied(BrandDTO dto);
void getAllReplied(QList<BrandDTO> dtoList);
};
} // namespace FrontEnds::Interactor
} // namespace FrontEnds::Controller
Loading

0 comments on commit 99d0c57

Please sign in to comment.