Dave Addey wrote:
> Hi James,
>
> Well, I've got the Factory approach pretty much working. My only
> problem comes from the newly-created subclass instances. So, I have (on
> a class HIDDeviceMouseFactory, which implements interface HIDDeviceFactory):
>
> Function CreateInstance() as HIDDevice
> return new HIDDeviceMouse()
> End Function
>
> This is registered with a list of factories known to the plugin, as you
> described. The CreateInstance function is then called from my plugin
> via something like...
>
> REALobject(*CreateInstanceFuncPtr)(REALobject instance) = NULL;
>
> CreateInstanceFuncPtr = (REALobject(*)(REALobject
> instance))REALInterfaceRoutine(me->RegisteredDeviceFactories[i],
> "HIDDeviceFactory", "CreateInstance");
>
> REALobject UserCreatedDevice = NULL;
>
> // Call the function
> if(CreateInstanceFuncPtr) {
> UserCreatedDevice =
> CreateInstanceFuncPtr(me->RegisteredDeviceFactories[i]);
> if (UserCreatedDevice) {
> REALLockObject(UserCreatedDevice);
> return UserCreatedDevice;
> }
> }
>
> This correctly calls the factory?s CreateInstance function in RB, and I
> do get a non-NULL UserCreatedDevice back in the plugin (sometimes).
>
> What (I think) I'm finding, however, is that the new HIDDeviceMouse is
> created in the RB code in the factory, but it is destroyed before I get
> chance to lock it when it is returned to the plugin. The object needs
> to go ?back in? to the plugin before it is returned from GetNextDevice
> as a HIDDevice. Is there some way I can ensure it is not destroyed, so
> that I can lock it?
You don't need to lock the object that is returned by the Factory create
function. The object has a ref count of 1 when it is created. The factory
function does not own that reference, it is merely passing it along to whomever
called the factory function. Imagine the function was a getter; you would lock
the reference _inside_ the getter, not in the calling function. Same deal here.
However, it should not be coming back as NULL. This implies that there is
something else going on. Are you calling your the CreateInstanceFuncPtr from
some other C callback function?
It could be that you are trying to call the CreateInstanceFuncPtr from a thread
other than the main application thread. REALbasic won't like this, as its
runtime code (which allocates objects, calls constructors, etc.) is not
thread-safe (in the pre-emptive multithreading sense.)
If you have registered some sort of notification function with the OS inside
your plugin, you cannot call directly into REALbasic from that notification
function. You'll need to take a slightly different approach. I might recommend
that you create your own subclass of REALbasic's Thread class in your plugin,
and implement its Run event in your plugin. Call it a HIDUpdateThread (with a
super of Thread). When you receive a call into your notification function, you
will have to post that notification message in a queue somewhere. You could
have a global list of pending messages in a std::list or std::vector somewhere.
In the HIDUpdateThread Run event, you should check your global notification
queue. If you find a notification, you can then pass that message onto
REALbasic, or call the factories to create a new HID Device or something like
that. It's safe to do all that inside your Thread subclass, because that thread
actually runs inside the main OS thread created by the REALbasic runtime. As a
result, you won't have any issues with REALbasic's runtime not being threadsafe.
The only slight downside to creating a Thread subclass is that your plugin
needs to register it in order to instantiate it, so you'll end up with a
HIDUpdateThread class in the class library. You'll just have to document that
people are not meant to touch it :-) It would be nice if we could create an
instance of Thread, and attach a function in an existing class to be the body
of the Run event. If only REALbasic had delegates....
--
Kind regards,
James Milne
_______________________________________________
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>