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

Plugin system for nengo_gui #809

Open
wants to merge 7 commits into
base: master
Choose a base branch
from
Open

Plugin system for nengo_gui #809

wants to merge 7 commits into from

Conversation

jgosmann
Copy link
Collaborator

This adds a plugin system to nengo_gui to allow other Python packages to provide additional functionality. One of the main motivations is to allow to exclude the SPA system from core Nengo while keeping support for the special plots in the GUI.

Frontend refactoring required before merge

This is based on @tbekolay frontend refactoring which of course is far from completed, but I want to get this out here to receive feedback and be able to confidently continue development on the next generation SPA module. Also, I'm not sure how far @tbekolay refactoring will go, but before we make the plugin system part of the official API, we should ensure that we have well structured frontend JavaScript. After officially integrating the plugin system refactoring of the frontend may get more complicated because we might need to keep backwards compatibility for plugins.

In that refactoring the following points seem of special importance:

  • Clear namespacing to have a evident structure where things in the front-end live and can be accessed by plugins, but also to have best-practices how plugins declare and name their namespaces.
  • In NetGraphItem the menu entries are figured out through a bunch of if-statements. It would be better to use polymorphy. This will change how plugins can define additional menu items.
  • Firefox gives me this warning: "mutating the [[Prototype]] of an object will cause your code to run very slowly; instead create the object with the correct initial [[Prototype]] value using Object.create" We should probably fix that warning.

How does it work?

See nengo/nengo_gui_plugin_template for a minimal example of a plugin.

Plugins use the "entry points" feature of setuptools. A Python package can define entry points in the setup.py and another package can discover these with pkg_resources. So a nengo_gui plugin defines such entry points. There are two types of entry points:

  • nengo_gui.plugins provide classes deriving from nengo_gui.plugin.Plugin that can provide additional resources (which may be dynamic) accessible via HTTP. In the template it just provides the required JavaScript file.
  • nengo_gui.components provides additional components/graph.

Overall the required boilerplate should be reduced a bit more I think, but to do so we need the refactoring of the frontend first.

Feedback

What I want to know is basically: Does this fulfill our requirements? Anything people can think of that should be possible, but is not with this system? Can I base my work for the new SPA module on this (taking into account that some changes will be necessary as the frontend gets refactored)? The SPA module would probably also be a good test bed to see where features are missing or things are not working as intended.

tbekolay and others added 7 commits July 14, 2016 08:48
Using the <em> tag caused an issue with newer versions of
jqueryfiletree because they look at the direct parent of the
element that got a click event; since that element was the <em>
tag, the parent was <a>, but jqueryfiletree expected that to be
the <li> element, and therefore could not determine if the <li>
corresponded to a file or directory.

Fixed this by removing the <em> tag from the built-in examples
directory entry in the file tree, and instead use a CSS rule to
make that link italicized (but not any descendants).
Previously, all of the JavaScript and CSS files that we wanted to
use in Nengo GUI had to be part of the source tree, and included
manually in a <script> or <link> tag in `page.html`. While this was
a good way to start out, as we grow it limits us to only using
pure JavaScript and CSS, and requires a cumbersome process to
upgrade our JS/CSS dependencies.

Now, we use npm to download specific versions of our frontend
dependencies, and webpack to bundle all of our dependencies and
our own frontend code together into a single bundle, which
greatly simplifies `page.html`.

Specifically, the frontend workflow now requires developers
to do the following actions once:

1. Install node.js, which should come with `npm`.
2. Run `npm install`.

Developers will now have all of the necessary dependencies
in the node_modules folder, which is now in .gitignore.

If developers are modifying or debugging frontend components,
then they should run the command:

   npm run build

which will package all of the frontend files into a non-minified
JS file (which includes all of the CSS), and produce a source map,
so that when debugging JavaScript files, the browser will show you
the original source file rather than the gigantic bundle.

If developers change any frotend files in a particular commit,
they should regenerate the "production" version of the bundle
that includes all of the frontend files. To do this, run:

   npm run release

which will package all the frontend files in a minimified and
optimized JS file. No source map will be produced. This keeps
the size of commits small while still enabling all commits to
be tested by CI.

For the time being, I have limited the changes required to get
npm + webpack working to the minimum number of files, which is
mainly nengo.js, which "imports" all of the other files.

Other changes:

- In netgraph.js, we no longer have a <link> tag to get a handle
  to; fortunately, it's possible to get the string version of the
  CSS through webpack, so now we use `require` to get the CSS.
- `data_to_csv.js` had to be modified to export the data_to_csv
  function because it's used in another file, and in tests.
- Moved the styles in `main.css` to `nengo.css`, as that's the
  entrypoint that we use anyhow.
Can load external plugins and serve files from them.
@jgosmann
Copy link
Collaborator Author

Things I forgot about so far:

  • backends
  • additional examples

It should be possible to implement both easily with entry points (especially backends).

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

Successfully merging this pull request may close these issues.

2 participants