5 ms·
Hello HN, Two years back or so I was trying to build a new user interface for the ZynAddSubFX synth and getting the level of customization I wanted while being
by fundamental 8y ago
Hello HN,
Two years back or so I was trying to build a new user interface for the ZynAddSubFX synth and getting the level of customization I wanted while being able to embed the interface cleanly into plugin hosts was difficult. I could have gone the route of producing a series of raster based assets and providing fixed locations for everything, but since I had different devices with rather different resolutions I wanted something to be more flexible than that. After starting with Qt prototypes I borrowed the ideas of Qt's QML and applied them to a ruby based widget system (I would have gone with com
mon-lisp + CLOS, but that's not the best route to entice contributors), a nanovg/OpenGL rendering system, and a open sound control based messaging layer between the GUI and backend. Initially there was a GLPK based layout system, though that was unfortunately scrapped due to the runtime cost.
The end result is MRuby-Zest and it's a system that's reasonably efficient, embeddable, and in my opinion fast to iterate upon designs. The last note is mostly due to the fact that the system can hotload code updating existing widgets in a live GUI. That hotloading combined with the fact that widget code is all ruby (rather than building off an existing C/C++ toolkit) has made working with the framework pretty fun for myself. Overall the project is still pretty young and somewhat tied to the Zyn GUI (named Zyn-Fusion), but I thought some of the design choices and trade-offs might be interesting to the broader HN community.
Outside of the technical choices this work is some of the first open source work that I've seriously tried to get community funding for. After working on the software for a few (~3) months fulltime I was able to put binaries up for sale and I've managed to get ~200 sales for my efforts.
- pjmlp 8y agoNice overview, it looks quite good. Have you thought about bringing in Crystal when it gets more mature? Congratulations on the sale and good luck with the project.
- fundamental 8y agoI've seen Crystal a few times in the past, though I haven't used it for a project so far. Looking at their website and issue tracker it looks like it would be rather difficult to be able to hotload code if Crystal was used compared to MRuby (based upon the notes that a Crystal REPL isn't a primary feature as a compiled language). Additionally I can't find too many details (though I'm sure they're there) about the runtime requirements imposed by Crystal applications. One of the nice things about the MRuby implementation is that it makes it easier to combine all parts of your program (C extensions and ruby compiled to VM instructions) into a single binary with minimal external dependencies.
- jcelerier 8y ago> After starting with Qt prototypes I borrowed the ideas of Qt's QML and applied them to a ruby based widget system Did you reimplement property binding ? That's the #1 feature of QML imho and I couldn't find an example in your source.
- fundamental 8y agoYep, that was one of the things that I got working early on. It's used a fair bit in the codebase, though it's not necessarily all that apparent if you don't know where to look. As mentioned at https://github.com/mruby-zest/mruby-qml-spawn/blob/master/mrblib/database.rb#L61 https://github.com/mruby-zest/mruby-qml-spawn/blob/master/mr... the properties form a dependency graph, so the property bindings should stay up-to-date when you change dependent properties. This is one of the features of the overall framework which may be a bit under-tested at the moment. I've fixed a number of bugs in the system, though you certainly can get into odd edge cases when updating bindings during widget creation or destruction.
- jcelerier 8y ago> Yep, that was one of the things that I got working early on. It's used a fair bit in the codebase, though it's not necessarily all that apparent if you don't know where to look. hmmm... but what I don't see is stuff like `onColorChanged: doStuff(color)`. Basically, the event system ?
- fundamental 8y agoThat's in there as well, though certainly not as refined as it is in Qt's QML. https://github.com/mruby-zest/mruby-zest/blob/master/qml/Valuator.qml#L18-L20 https://github.com/mruby-zest/mruby-zest/blob/master/qml/Val... shows one example of having a callback when a property is changed ( defined at https://github.com/mruby-zest/mruby-zest/blob/master/qml/Widget.qml#L15 https://github.com/mruby-zest/mruby-zest/blob/master/qml/Wid... ). Elsewhere in the codebase you'll see whenEvent style callbacks https://github.com/mruby-zest/mruby-zest/blob/master/qml/Valuator.qml#L11 https://github.com/mruby-zest/mruby-zest/blob/master/qml/Val... Most of the events, however, are handled through more traditional methods as that ended up being more comfortable when scaling to a larger program.
- deleted 8y ago[deleted]