On Nov 4, 2006, at 10:22 AM, Norman Palardy wrote:

It probably needs to yield to RB which I why I'd do a plugin


Given that I just have read the nug digest version, where the same problem is discussed, I will repost what I had said previously and a general solution to the problem:

If you are being called by a callback the natural instinct is to respond immediately. And if it requires updating of a GUI, refreshing windows, or a lengthy calculation, then it will interfere with REALbasic's runtime. Basically, you are blocking the event loop if you are going to issue a lot of stuff, while in the callback. So you do not want to do this.

1: You want to return as quickly as possible from the callback
2: You should tell your RB code that you were called
3: You will deal with the callback after the callback was issued

An RB thread is not the solution, nor will DoEvents. DoEvents will force the main event loop (the RB runtime) to cycle once. In both cases you will be back into the callback, but meanwhile you told the RB runtime to cycle, while that runtime does not know anything with respect to the callback.

Here is code that is based on the above 3 rules.

Class CallEvent

properties:
next as CallEvent
myInstance as MyClass
signature as Integer

method:
CreateEvent(instance as MyClass)
  dim theEvent, currentEvent As CallEvent

  theEvent = me
  theEvent.signature = 1000
  theEvent.myInstance = instance

  if EventModule.gEvent <> nil then
    currentEvent = EventModule.gEvent
    while currentEvent.nextEvent <> nil
      currentEvent = currentEvent.nextEvent
    Wend
    currentEvent.nextEvent = theEvent
  else
    EventModule.gEvent = theEvent
  end if


Module EventModule

properties:
gEvent As CallEvent


Class EventTimer as Timer
Action: // The Action event of the timer
        SwallowEvent
        
Method:

SwallowEvent()
  if EventModule.gEvent <> nil then
    dim instance as MyClass

    while EventModule.gEvent <> nil
      dim curEvent As CallEvent = EventModule.gEvent
      EventModule.gEvent = EventModule.gEvent.nextEvent
      if curEvent.signature = 1000 then
        instance = curEvent.myInstance
        instance.myInstanceMethod// method of your class
      end if
      curEvent = nil
    Wend

  end if

Without going into details here, you call this

        dim postEvent as new CallEvent
        postEvent.CreateEvent()
        
in the callback. You have created an instance of a CallEvent which will be handled in the main event. It is sufficient to only create this instance and you will permanently leave the dylib's callback, as it should. The timer will "sense" that there is an instance of Callback and will issue the swallowing of the CallEvent. Since the timer runs in the main event loop, the RBRuntime will handle your code appropriately, and the dylib "runtime" is satisfied as well.

Hope this will clarify the general issue of returning from a callback immediately, the posting of an event and the handling of the event in the RB runtime.....


Alfred
_______________________________________________
Unsubscribe or switch delivery mode:
<http://www.realsoftware.com/support/listmanager/>

Search the archives of this list here:
<http://support.realsoftware.com/listarchives/lists.html>

Reply via email to