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

Universal Plugin System using standard IO #553

Open
circular17 opened this issue Sep 7, 2023 · 12 comments
Open

Universal Plugin System using standard IO #553

circular17 opened this issue Sep 7, 2023 · 12 comments

Comments

@circular17
Copy link
Collaborator

The goal of the Universal Plugin System is to enhance LazPaint's capabilities by enabling third-party plugin integrations. The primary mechanism for interaction is via Standard I/O, with LazPaint acting as a server to facilitate communication with plugin providers.

Plugin Providers: These are intermediary programs that

  • List the available plugins (along with meta-data like author and version).
  • Provide information about the plugin provider.
  • Execute a specific plugin's functionalities.

Communication Protocol:

  • The plugin provider communicates using Standard I/O, sending commands via standard output and receiving responses via standard input from LazPaint.
  • A set of commands allow the plugin to identify the specific action it needs to perform (e.g., list plugins or run a specific plugin).

Basic Flow for Common Plugins:

  • Store the current layer as a temporary file.
  • The plugin modifies this temporary file.
  • Replace the current layer in LazPaint with the modified content.

Error Handling:

  • In case of errors, plugins should send details to standard error, then terminate. LazPaint will display the error details.
  • LazPaint should have a mechanism to forcibly interrupt and terminate a misbehaving plugin.

To consider:

  • Plugin Provider Manifest: A standardized manifest file (JSON format) should describe the plugin's meta-data. This would provide LazPaint with a uniform way to read and display plugin details. Though at runtime, LazPaint can get this information by calling the plugin provider.
  • Plugin SDK: Offer tools, templates, and documentation for developing plugins seamlessly.
  • Community & Showcase: Provide a platform for developers to showcase, discuss, and collaborate on plugins.
  • Sample Plugins: Offer sample plugins as a guide for potential developers.
  • Tutorials & Workshops: Host online workshops or tutorials for hands-on guidance to budding plugin developers.
@circular17
Copy link
Collaborator Author

This issue #557 was about adding a plugin directly inside LazPaint in Pascal. The core of the plugin is nice and tidy but this required to modify many files to have the integration in the interface. Maybe this could be adapted so that it becomes more general and involve less files to add one window. The interface could be also generated programmatically, and all the relevant code put in one single file and class.

@lainz
Copy link
Member

lainz commented Sep 24, 2023

Instead of standard IO why don't use a client / server approach?
Like with JSON format.
Say I can send a bitmap data in base64, or and endpoint to send binary data when needed.
So for example with this we can use the browser as the UI, and javascript to display and run the code.

@lainz
Copy link
Member

lainz commented Sep 24, 2023

With that we can use HTML5Canvas to draw, any javascript library, like 3D libraries and so on, in the end we transmit the final bitmap / final layer..

@lainz
Copy link
Member

lainz commented Oct 1, 2023

Another way without an API on the side of LazPaint, is using standard IO, make a server tp serve the webpage and an API say with python or deno, the api then sends the data using standard IO, but I'm not sure if possible

@circular17
Copy link
Collaborator Author

circular17 commented Oct 2, 2023

It makes sense. Basically, this would be a plugin provider that in facts set up a bridge between LazPaint and an API. During this lapse of time, plugins can interact via the API. The plugin provider could as well open the adequate webpage or launch the adequate script specific to the plugin. From LazPaint point of view, this would be like a regular plugin provider.

The pros:

  • no need for API development inside LazPaint
  • if the plugin provider open the specific plugin, the external plugin is actually integrated as a menu in LazPaint
  • this would as well not require to ask the firewall authorization on application startup, though this problem could be mitigated by adding a check menu to enable the API in the scripts menu

The cons:

  • there is no guarantee that the API is up-to-date with the application
  • it could be simpler to access a webpage directly and it would ask LazPaint if it is ready to accept the plugin

@lainz
Copy link
Member

lainz commented Oct 6, 2023

I prefer Lazpaint has the API inside.
In fact a simple API with 2 endpoints will do:
Get Layer and Put Layer.

Get Layer: you give an index, say 0, and it returns layer count, blend mode, opacity and bitmap or vectors content.

Put Layer: with the power to send a bitmap or a vector. Set blend mode, opacity and layer position. Say I have 4 layers. I can add the new one in the middle, so I send layer 2. A parameter that says I want to replace or add a new layer.

And if you want add plurals: Get Layer(s) and Put Layer(s). For more than a single layer at a time. Get Layers returns all layers in an array. Put Layers updates all given layers in an array.

If it fails or there are missing properties it must return a proper error message.

What do you think?

@lainz
Copy link
Member

lainz commented Oct 6, 2023

A way to launch the plugin is with python. When it launched from the menu it closes it connection with lazpaint and opens a web server. It launches the webpage. Lazpaint can provide the IP of the API with IO. So no hardcoded port is needed.

@lainz
Copy link
Member

lainz commented Oct 6, 2023

About installing new plug in.
Lazpaint is installed in program files. Should be good if another path is used for plugins.

Program files is by default not writable.

@circular17
Copy link
Collaborator Author

Hi Lainz,

Thank you for the detailed insights and thoughts on the integration with the API.

About the idea of have 2 end points for exchanging layer data, while it keeps things simple, it would limit what the plugin can do. This is all fine for a raster plugin, but I would like them to be able to do anything that is possible with LazPaint.

Having said that, the concept of having few endpoints isn't necessarily counterproductive. A single endpoint handling a call to a script function with parameters provided as JSON can indeed simplify implementation and also be quite flexible. Otherwise it would make sense to have one endpoint for each script function, still the parameters provided as JSON.

For the launching method with Python, your idea sounds feasible. Though when thinking this through, in particular keeping the synchronization with the plugin, it is not so simple and probably a similar effort as making a server API within LazPaint.

I am considering sockets, that could be used just like IO to communicate between LazPaint and a plugin and provide a status so that if the plugin is interrupted, LazPaint could give back access to the user interface.

You highlight a practical issue that the default Program Files directory in most operating systems is not writable without elevated permissions. Therefore, plugins should ideally be installed or stored in a different path/directory, which doesn't require special permissions for write operations, like for example a folder inside My Documents. So it would make sense to check for such folder to find scripts. The directory could be configured within LazPaint.

@lainz
Copy link
Member

lainz commented Oct 7, 2023

Thanks for considering usefull my ideas.

Yes a single endpoint with parameters will do.

@lainz
Copy link
Member

lainz commented Oct 8, 2023

Here is the API demo:
https://github.com/bgrabitmap/demoapi

It changes the sides of a bgrashape from a website.

@circular17
Copy link
Collaborator Author

Thank you so much for sharing this demo. That's a great base to make the http API. Clicking on the numeric field on the webpage updates the LCL application. That is wonderful. And it works seamlessly on MacOS. I will create a thread for this development.

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

No branches or pull requests

2 participants