Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Underlying library architecture #1

Open
Suzie97 opened this issue Aug 30, 2021 · 4 comments
Open

Underlying library architecture #1

Suzie97 opened this issue Aug 30, 2021 · 4 comments

Comments

@Suzie97
Copy link
Member

Suzie97 commented Aug 30, 2021

Right now, we are thinking of building our own library rather than using an existing one.

This is mainly so that we have a clear understanding of it works and also, to have full control over how things work so that we can adjust things according to our needs.

We need ideas right now, so feel free to share them.

@ghost ghost transferred this issue from PhotostatEditor/Photostat Aug 30, 2021
@ghost
Copy link

ghost commented Aug 30, 2021

@Suzie97 I transferred the issue to the library's repo

@AshishS-1123
Copy link
Member

I would like to share my approach for the base architecture.

AbstractOperation

Each operation will implement the class AbstractOperation. (Let's call a class implementing this class as Operation)

This class will define the following-

  • signal perform_operation - The client code will trigger this signal, following which the Operation will perform its computation. The client code will not have any direct access to the main operation methods, and can only be triggered using this signal.
  • signal operation_complete - This signal will be triggered internally by the Operation class as soon as the computation is done.
  • variable processed_state will represent the image after performing the operations. This will be useful for performing undo and redo operations. We might need to figure out a way to compress this variable to save memory.

Let's consider that the user wishes to perform the following operation in given order-

  1. Read an image from a file.
  2. Blur the image.
  3. Convert image to HSL color space.
  4. Write to a file

Internally, these will be chained together to form a chain as

Reader -----> GaussianBlur -----> ColorSpaceConverter -----> Writer

By chaining, I mean that one object will be listening to the operation_complete signal of previous class. As soon as that signal is triggered, the listening class will trigger its own perform_operation signal.

Client code will only trigger the perform_operation signal of first class. The rest will automatically happen. When the last class triggers its operation_complete signal we can get the result and do what we want with it.

Implementing AbstractOperation also obeys the single responsibility principle as each new operation only has to worry about performing the operation and not the rest of the code.

I have written code for reading and writing images. Working on creating tests as TDD approach seems to be more productive.

TODO

  • Create a pattern to create different operations and chain them together. This should also allow us to remove operations from a chain to simulate undo redo operations.
  • When we implement layers, this pattern will need to be changed from list format to tree/directed graph format.

@Suzie97
Copy link
Member Author

Suzie97 commented Sep 1, 2021

I would like to share my approach for the base architecture.

AbstractOperation

Each operation will implement the class AbstractOperation. (Let's call a class implementing this class as Operation)

This class will define the following-

  • signal perform_operation - The client code will trigger this signal, following which the Operation will perform its computation. The client code will not have any direct access to the main operation methods, and can only be triggered using this signal.
  • signal operation_complete - This signal will be triggered internally by the Operation class as soon as the computation is done.
  • variable processed_state will represent the image after performing the operations. This will be useful for performing undo and redo operations. We might need to figure out a way to compress this variable to save memory.

Let's consider that the user wishes to perform the following operation in given order-

  1. Read an image from a file.
  2. Blur the image.
  3. Convert image to HSL color space.
  4. Write to a file

Internally, these will be chained together to form a chain as

Reader -----> GaussianBlur -----> ColorSpaceConverter -----> Writer

By chaining, I mean that one object will be listening to the operation_complete signal of previous class. As soon as that signal is triggered, the listening class will trigger its own perform_operation signal.

Client code will only trigger the perform_operation signal of first class. The rest will automatically happen. When the last class triggers its operation_complete signal we can get the result and do what we want with it.

Implementing AbstractOperation also obeys the single responsibility principle as each new operation only has to worry about performing the operation and not the rest of the code.

I have written code for reading and writing images. Working on creating tests as TDD approach seems to be more productive.

TODO

  • Create a pattern to create different operations and chain them together. This should also allow us to remove operations from a chain to simulate undo redo operations.
  • When we implement layers, this pattern will need to be changed from list format to tree/directed graph format.

This is an amazing start. Great work.

I just have one question, can't we directly start implementing the tree format rather than a linear one?

@AshishS-1123
Copy link
Member

@Suzie97 We can chain as many operations to each other as we can. Its only a matter of connecting to the proper signals.

The real challenge is to prevent cycles so our program doesn't get stuck in a infinite loop.

To take care of that we need to create another class that creates and manages these classes, makes sure they obey certain rules (like no cycles).
This way the client doesn't interact with the operations directly but through the manager.

Thanks to @abdallah-moh for pointing this out. We don't need a variable to store our original image in every operation. Instead we can create a method that reverts the operation and only for reversible operations do we store the previous state.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants