Hello all!
I'm creating an external which should only allow one copy loaded at the same time. Is there a way to check this upon creation?
I tried going the same approach as checking if a receiver exists before attempting to send, but it doesn't seem to work.
if (gensym("class_name")->s_thing) { post("Exists!"); return false; }
Any help is greatly appreciated.
Best regards, Alex Clément
On Sun, Jun 14, 2015 at 3:36 PM, Alexandre Clément < alexandre.r.clement@gmail.com> wrote:
Hello all!
I'm creating an external which should only allow one copy loaded at the same time. Is there a way to check this upon creation?
I tried going the same approach as checking if a receiver exists before attempting to send, but it doesn't seem to work.
if (gensym("class_name")->s_thing) { post("Exists!"); return false; }
Because gensym generates the symbol if it wasn't already in the list.
What I do is have a global variable outside the class struct and check if it is not zero before instantiating a new object. Since c is guaranteed to initialize globals to zero, the first object created can set it to some other value. Maybe some more trickery will be needed if the object is deleted and recreated, possibly the code is still in memory and the global will have the non-zero value; in this case the free routine should zero the global,
Martin
Wow, never would have thought about that... Tried it out right out, worked like a charm!
Thanks a lot, Martin!
Alex
On 14 June 2015 at 21:44, Martin Peach chakekatzil@gmail.com wrote:
On Sun, Jun 14, 2015 at 3:36 PM, Alexandre Clément < alexandre.r.clement@gmail.com> wrote:
Hello all!
I'm creating an external which should only allow one copy loaded at the same time. Is there a way to check this upon creation?
I tried going the same approach as checking if a receiver exists before attempting to send, but it doesn't seem to work.
if (gensym("class_name")->s_thing) { post("Exists!"); return false; }
Because gensym generates the symbol if it wasn't already in the list.
What I do is have a global variable outside the class struct and check if it is not zero before instantiating a new object. Since c is guaranteed to initialize globals to zero, the first object created can set it to some other value. Maybe some more trickery will be needed if the object is deleted and recreated, possibly the code is still in memory and the global will have the non-zero value; in this case the free routine should zero the global,
Martin
On 2015-06-14 21:36, Alexandre Clément wrote:
I tried going the same approach as checking if a receiver exists before attempting to send, but it doesn't seem to work.
if (gensym("class_name")->s_thing) { post("Exists!"); return false; }
Any help is greatly appreciated.
as you already know a correct solution to your problem, just two remarks as way this canot work.
#1 gensym("class_name") refers to the literal "class_name" (and your class probably is not named like that). you probably have this reight anyhow, butit reads a bit weird. the following is a bitless ambiguous:
gensym(class_name) // hinting at a variable named "class_name".
or
gensym("FOO")
#2 the "s_thing" member symbols points to "listeners" of that symbol. e.g. if you create [receive foo], then gensym("foo")->s_thing will give you a handle to that receive-object (indirectly). you *can* use this to check for the existence of another instance of your object, by "binding" (using 'pd_bind()') your successfully created object to a name (e.g. "foo") in the creator (myobject_new()). however, you probably should not do that, as it is fragile: if the user has a [receive foo] anywhere in their patch, this logic will wrongly assume that there is already an instance of this object.
but anyhow: it is usually not a good idea to prevent multiple instances of objects. it breaks the functional paradigm of Pd in a fundamental way. if your code uses global variables (that cannot be used by multiple instances independently), you should fix the code so it allows for more than one instance. if your code accesses mutually exclusive ressources (e.g. a hardware device that cannot be opened concurrently), it's not a good idea either to maintain a global variable yourself to check whether the mutually exclusive access has already taken place. instead query the device whether it allows to be opened "now". also what happens if your ressource becomes available again (e.g. because the user closed the patch that contains the *other* instance of your external)? wouldn't it be nice if the remaining instance could now "take over"?
but of there are numerous exceptions to that rule :-)
fgmas IOhannes