Are Observers a Thread?

I have created a custom class for “automatic” buttons, based on a MacOSLib-implemented NSImageView class.
The “automation” works in several ways: I have included different images for disabled, normal and switched-on state. When the user clicks on the image, it changes according to its settings and invokes a custom event that is passed to the parent property (the window it sits on). In order to change the image, I invalidate it once it was changed.

This worked all fine, until I recently changed the communication structure of my classes to an ObserverInterface (before there were many different properties calling methods of other properties …). When the parent window, which is the observer, receives the information that some class property was changed, it sets a computed property accordingly. The latter one is computed because it automatically switches the images to the right one when the property value changes. Under some circumstances now, I get a threadaccessingUI exception when invalidate is called.

Problem is: There are no threads around this class. So I wonder if the observer interface is handled internally via threads. Should I set up a UIsafe thread which gives an invalidate?

And, while we’re at it: When the debug app crashes, the debugger shows me the order of method calls that lead to it. This is really nice, but much too often I click too eagerly on the crash message box which stops the debug and returns to the editor. Are those messages saved somewhere so I still can retrieve them?

Where are you getting the ObserverInterface? If it’s just a class interface, there are no threads involved other than those you create yourself.

What do you mean by getting the interface where? I inserted it as class interface to several classes the usual way – clicking on the class and “insert interface”. The only thread I have installed in this app is on another window and not related to the buttons.

I think what Eric meant is “where is the interface defined”
But that really doesn’t matter as interfaces have no code to them so it’s not the interface

But there has to be something associated with the observations & notifications that is a thread - somewhere
I just grabbed MacOSLib and I don’t see anything i there that relates to this interface

I wonder if the error was correct. I swear there is no thread, but on the crash the debugger showed me several blank properties for the window which, on the other hand, existed …?!?!?

Maybe this has to do with me mingling Xojo Windows with MacOSLib’s NSWindow property. Like written elsewhere, I can work around the window.visble bug by addressing NSWindow.isvisible and NSWIndow.orderout instead of closing or hiding it. I’ll have an eager eye on that and, if everything else fails, shove the invalidate into a UIsafe thread. Currently the image changed is delayed or sometimes only working when I cross the button’s position with the mouse arrow which is not what’s intended.

I looked into the LR and “observer” is not found. Neither is “observerinterface”.

If I insert a class into a project and click on “Interfaces” “Choose”, I find no observer.

If I right click on the class I have no “insert interface” option but only “Implement interface” which provides the same list as before, and no observer.

What is the observer doing ? From what you write it seems to be sort of a property watcher, but finding nothing about it makes me curious. Is it a feature of MacOSLib ?

Michel,
check out the Design Patterns folder in the examples. There you’ll find the observer example.

I would describe it (please correct me if I’m wrong) as a brillant substitute for event messaging throughout different classes. You get one instance of whatever class as the emitter – the subject – that can register other instances of different classes as receiver (observers).
Via the NotifyObserver method that comes with the example you send out a notification to each observer which those can handle differently via their own Update method.

Sure but there’s nothing in there that would inherently lead to an observer using a thread not a subject using a thread

Could it be the NSImageView? It sounds like the suspect execution starts in the mouse events, which in NSImageView are originally triggered by OS calls to Shared methods (which call instance methods, which raise a mouse event, which uses Observer Interface, which calls Invalidate and causes a ThreadUI exc.) I don’t know if this is possible but maybe those OS callbacks are somehow being done from another thread?

Thank you.

That’s an excellent hint. Yes, the debug report in debugger started with a mousedown event. I did not pay much attention to it because – before inserting the observer – I never had problems and my code in the buttons uses no separate threads. But somewhere the UI call must be done from a thread, it seems. I’ll reinsert the invalidate and check if I can provoke a crash, tracing it down to the originator this time. And see if I get a clue from looking at the debugger :wink:

I couldn’t provoke a crash yet but dug into my code. I would not be suspicious about NSImageView anymore. But I have found that inside my send routine (it’s an app communicating with telephones via TCPsocket or Serial. I put the send method in a thread so that the app does not hang while the socket is not ready to send) in case of an error I raise an event. This triggers a method that notifies the observers. Can it be the event is carried out on that thread and then finally tries to manipulate the UI?

Anything that is initiated from a threads “RUN” event is “in side a thread” regardless of where it physically exists as it runs in the threads context

So - yes - sounds like that might be it

Thanks, Norman! Seems you corrected me on another misunderstood concept today.
I guess to safely return a value from a thread I’ll use the task class again and call the UIsafe method when I need to raise an event?

No idea about what UISafe method you’re using but a thread subclass could easily be crafted to do such a thing
It would create a timer in code, set it to a very short period
You respond to the timers Action event using AddHandler which is FOR SURE on the main thread so UI safe

And just to twist your brain a little, you can define the method that the timer uses in the Thread subclass! That keeps all your code together in one place. Code runs in the thread that called it, regardless of where it is defined. Timers are serviced by the event loop, so they always run in the main thread and therefore anything they call runs in the main thread.

And you could have MANY actions that the timer can execute using a delegate defined in the class that you set up based on some criteria through the course of running your thread and then when the timer action event is raised you invoke the delegate and get a different action based on whatever delegate was set up - yeehaw !

all kinds of options and eventually it all spins off into a very generic Task class :stuck_out_tongue:

Now, if Tim’s post was intended to twist my brain, consider what your post did to it, Norman! :smiley:
I made it to crash and, as it seems, I should move the send and flush into a thread safe method – if my interpretation of this log is right the thread problems occurred because I write and flush from inside the thread which then transfers to the data available event of the TCPsocket subclass which triggers parsing of the received data and then, via observer notification, transfers the thread to updating my window properties. Oh boy!