Binding my PILS language to juce, I’m having a problem with component ownership, and I’d like to know how this is handled in pyJuce or similar systems.
First, here is a bit of PILS code that creates a DocumentWindow with a TabbedComponent with two TextEditor tabs - don’t bother with understanding the PILS syntax, most of it is juce calls anyway.
{ .test
| :ok
;window
j:DocumentWindow ("Testvindue", j:Colour [200 100 50], 7)
j:setBounds [100 200 300 400]
j:setResizable (1, 0)
j:setVisible 1
;
;tabs j:TabbedComponent 0;
;page1
j:TextEditor ()
j:setMultiLine 1
j:setReturnKeyStartsNewLine 1
j:setFont (j:Font ("Times New Roman", 30, 3))
j:setText "This is page 1..."
;
;page2
j:TextEditor ()
j:setMultiLine 1
j:setReturnKeyStartsNewLine 1
j:setText "... and this is page 2."
;
tabs
j:addTab("Page 1", j:Colour [100 200 250], page1, 1)
j:addTab("Page 2", j:Colour [100 200 100], page2, 1)
and:
window j:setContentComponent (tabs, 1, 0) and:
window j:when
{ j:closeButtonPressed:
| :ok
tabs j:clearTabs and:
window j:removeFromDesktop
}
}
PILS has two kinds of wrappers for juce Components: Pilsmade and Jucemade. Those created by PILS are really of a special class that extends the juce class, redirecting its public virtual methods so that the PILS programmer may implement them (this is done with the j:when operation at the end of the sample.) Every supported juce component class is subclassed in this way by the interface generator.
A PILSmade component is automatically deleted when both of the following conditions are met: PILS has no references to it, and the component is not (directly or indirectly) on the desktop.
A Jucemade component - such as a TabBarButton created by the TabbedCompponent - is never deleted by PILS.
To trace whether a PILSmade component is on the desktop, the PILSmade wrapper implements a ComponentListener and checks the component state on componentParentHierarchyChanged and componentVisibilityChanged
Well, this works some of the time - but there are problems.
First, the tabs j:clearTabs had to be inserted. window j:removeFromDesktop causes automatic deletion of the pages and the tabs (if they aren’t already deleted). Unfortunately, the pages get deleted first, causing an assertion failure when the tabs is deleted. The tabs j:clearTabs fixes this but it makes the bindings less foolproof than I wished for.
Second, if I run the test, view both tab pages and close the window, everything works. All PILSmade components get deleted, causing the component count to reach 0 which triggers a quit() and shuts down the app with no mem leak. However if I close it without having seen the 2nd page, the app doesn’t shut down, which indicates a component didn’t get deleted. (I haven’t yet found out quite what’s going on, will investigate.)
Third, I’d like the Jucemade wrappers to act as weak pointers. Unfortunately, the ComponentListener class doesn’t have a componentDeleted() method which would be the obvious way to implement weak pointers. This isn’t a problem with the PILSmade components since they are subclassed by the binding generator, so their destructors can zero the wrapper’s pointers - but it is quite possible that a PILS program can keep a reference to a component that gets deleted because the user closes a window - operations on such a dangling reference should fail but not crash, and this is best achieved by some sort of weak pointer.
I guess the makers of bindings for Python and other languages must have faced similar problems and perhaps solved them but I don’t have a cue. Or could these problems be the reason pyJUCE is still at version 0.1?
I’d appreciate very much if you could spare time to write some reflections on this.
I have tried binding PILS to many cross platforms, I got a wxWidgets binding that actually works (I use wxPILS to write the jucePILS bindings generator) but wxWidgets is a mess compared to juce, I also experimented with GTK, VCF, QT, OpenOffice UNO - but got stuck in mud. With juce, I have been making fast progress, I find it vastly easier to grasp than the other systems, but I could use some advice on dealing with component lifetime management.
If juce doesn’t have the stuff needed for foolproof scripting, perhaps we could work together in finding a solution - I’m sure juce applications can benefit from scripting.
(Perhaps PILS could be used to graft an optional reflection interface on juce, which would make it very easy to bind other languages to it. Much of the work is already done in my binding generator.)
BTW in case you wonder, here are the “terms of use” by which PILS will be published (this will happen as soon as I get it to work satisfactorily with a framework less messy than wxWidgets.)
The PILS system as such is freeware but military institutions and the weapon’s industry should expect no cooperation from my side should they decide to use it.
If you want to use PILS for commercial applications, please consult the licensing terms of the framework used by PILS. The wxWidgets framework imposes no legal restrictions on PILS code using it, but other frameworks may.
Beware that the programming system is designed for open-source projects and relies on distributing unobfuscated source code. If you change it, please do not rampage your customers’ standard PILS installations and do not expect my help if your obfuscated code causes problems.

I think I just found the solution.