inexorgame-obsolete / deprecated-cube-engine-inexor

UNMAINTAINED: Please have a look at the vulkan-renderer
https://inexor.org
zlib License
11 stars 1 forks source link

Hookable plugin architecture for flex #369

Open Fohlen opened 7 years ago

Fohlen commented 7 years ago

It'll be very usefull to discuss a hookable plugin architecture for flex.

Hookable, what would that mean? Currently plugins can expose a router object to the flex server in an isolated scope, allowing them to bring new functionality into flex. Anyhow objects returned by those routers do not have any access to the tree(s), meaning that they must be applied manually to them. In the future it should become possible to interact with tree objects directly, so that you can e.g

Since Node.add, Node.preSet and Node.postSet are already fired, this is a good base to work with object instances. A Node.onSync event would probably be sufficient to indicate changes from the core.

Security implications Even though hookable plugins should access tree object, they should still be applied to a particular tree manually (using the plugin manager for instance). Allowing direct access to the root tree or instances node is highly discouraged.

Fohlen commented 7 years ago

@aschaeffer I've added a draft of resources for trees in this pad, https://piratenpad.de/p/inexor-resource-id

Fohlen commented 7 years ago

https://github.com/felixge/node-dirty could be used for resource handling locally, while servers should depend on redis.

aschaeffer commented 7 years ago

Interesting ideas and I like them. I would call it Inexor Tree Persistence and Tree Sharing.

Inexor Tree Persistence

A key-value store like Redis would be able to store the keys (full path of the node in the tree) and the value (the value of the node), but not the meta data (datatype, read only, sync/or/not). We could encode the meta data in other keys though.

And I would suggest that we introduce an abstraction layer for the Inexor Tree Persistence, so we can use a KVS (like redit), a database (like mariadb) or a graph database (like neo4j) to store the contents of a tree. The main difficulty would be the continuously synchronization between the storage back-end and the local in-memory-tree. Remember that the in-memory-tree contains validation and an event system.

Tree Sharing

Fohlen commented 7 years ago

For the synchronization my suggestion was to use a message queue that will behave similar to our rest API. You can request GET, SET, UPDATE types. You then actually only reference the resource id, and when necessary lazy-load the resource. In the same manner a broker could distribute changes made to the tree among subscribers by announcing the resource ID. If necessary, the subscribers can then pull the resource again.

Fohlen commented 7 years ago

ZeroMQ can do something like this already, but a simple cluster-based message queue might do it as well (using multiple backends would be the best bet we can take).

aschaeffer commented 7 years ago

I'm not sure if message queues are the best way to do the synchronization - especially if it is the same process. I'm not against using messaging in general but messaging from one plugin/component to another plugin/component seems a bit overhead.

Registry pattern

Instead I would suggest the registry pattern:

During startup of a plugin the application context is passed via an constructor argument. At a later point the plugin can call methods of the Inexor Tree or the Texture Manager by getting the component from the application context and calls the method.

Originally I thought about something like a dependency injection framework like the popular spring framework. But non of the dependency injection frameworks available for node js are that easy and/or mature as spring. Dependency injection would be great, but the main feature we need is a registry for components.

Security

The security aspect of the Inexor Tree should be solved on the level of a particular tree node for the node or recursive for the complete sub tree.

Security for the application context could be implemented as well. The application context returns other components only if the plugin has the permission.

I would suggest to open a separate issue for the security because it's a bigger task.

Fohlen commented 7 years ago

I would avoid using the global namespace any way we can. We'll be better of to use a database mapper with different backends (such as Redis, MongoDB and Node-Dirty for local environments). For the notifications, really only reliable is a Pub/Sub architecture.. However, using lazy evaluation of the objects should be sufficient for what we want to do! That way we can still provide a registry-style object that is distributed among other parties by using the @inexor-game/registry module.. Since node modules are cached statically by default, this is also a fast solution for us to export singleton instances of the registry.

Fohlen commented 7 years ago

I think we can solve this with the setDependencies based architecture. We will