Search in the Machipedia (in all posts)
NINJA-IDE 3.0-alpha, cleaning up the architecture.
Ninja is an IDE growing faster in the pythonic world. We are releasing the Alpha version of Ninja IDE 3, codenamed “lawgiver”, the road we took from 2.3 to this version is an interesting one, as it poses an interesting exercise in phasing from a chaotic architecture to one designed based on the usual needs detected by the developers.
Many of the new features were ending up in roadblocks when we required to do a given action with a given object and found out that:
Whatever abstraction we wanted to modify was not represented by a proper object
Functionality of that object was not handled by it but by some GUI portion handling the functionality.
Obtaining the required modules often ended in circular import resolution.
Arranging functionality as objects or helpers:
Designing objects is easy, at least for software such as an editor, you start by enumerating the identifiable parts of your software, in our case some of the most notable are:
- Main IDE
- Edit buffer
- Editable file
We have more, but they correspond to items very particular to our UI and we discovered them after making the base re-write.
The next exercise is to list the many functionalities you have, which parts are involved and therefore deduct where should that be coded.
An example: Saving a file, it was implemented as a whole big part of the editor buffer, which handled everything about a file. Files are now handled by an NFile object that knows everything about the file it represents and it is linked by all parts that interact with a file, this way a buffer can now read/write a file or do whatever it wants and also the file can change locations without affecting the buffer.
Having finished this the last exercise we made was in communication, we started by deciding how all parts should communicate. The hardest part of designing inter object communication is to avoid falling in the classic error of “lets make an architecture such that any object can be replaced and it works as a framework…” the use of “lets make a framework” is a good indicator that you are over designing, thinking on all the possible different uses any line of code can have, just stick to what you know you require.
After a few rounds of design, we end up with this:
- A central IDE object, where all other parts can register (this object is a singleton and registration can happen before or after instantiation) and that triggers initialisation on all registered objets, only when the rest of the ide is able to do it.
- Component classes: for many of the basic UI and Backend parts we have defined classes such as toolbars, central objects, file managers and such, that can be replaced/extended by plugins if necessary.
- Everything is, sort of, a plugin: every component we created works in a relatively easy way to hot plug (an entry point method for initialisation and a single registration using a human readable name, ie: “left_toolbar”.
- Standarized methods to add actions.
- Extremely tied to Qt: We don't believe in “extremely generic” stuff, so instead, we use as many Qt components as possible for the things that the library has already solved in a more efficient way than we could possible by re-implementing (ie: filesystem watching)
So, we are releasing an alpha version, which was, in most part, developed using the pre-alpha version which in time was made using the previous versions, so from ninja, with ninja for ninjas. Give it a try and let us know what you find is missing from the previous version and, if you like, which changes you find better.
For this version we are not providing packaged binaries, but you can download the code from:
- Source Code: https://github.com/ninja-ide/ninja-ide
- NINJA-IDE website: http://ninja-ide.org/
- Website Source Code: https://github.com/ninja-ide/ninja-ide-web
- Issue Tracker: https://github.com/ninja-ide/ninja-ide/issues
- Features for 3.0: https://github.com/ninja-ide/ninja-ide/wiki/Features-3.0