How can I find all object of a certain handle class?
27 vues (au cours des 30 derniers jours)
Afficher commentaires plus anciens
I need to find all current object memory instances of a certain handle class "MyClass".
I cannot use "findobj" because I do not have a "seed" handle.
using "whos" is also problematic because: (a) different variables can in fact point to the exact same object; (b) objects may exist without any variable poitnitng to them (for example objects that are pointed to from a "UserData" of a figure); (c) handles to soem objects may be held in persitence variables of a static method of the class.
is there a generic way to find all the objects of MyClass despites these listed difficulties?
Réponse acceptée
Guillaume
le 5 Août 2019
I don't think there's any way to track down instances after the fact.
You could however track the creation and deletion of all instances of any handle class, without changing the class code, with meta.class and the events InstanceCreated and InstanceDestroyed. The whole thing is badly documented but the 2nd argument of the event is of type ClassInstance whose one of the property is the object created/destroyed.
Unfortunately, for the Destroyed case, the handle is no longer valid by the time you get it (since the object has been destroyed), so overall, I'm not sure it's that useful. Still, you could keep a reference count of object creation and destruction to know how many are in memory.
7 commentaires
Guillaume
le 7 Août 2019
Yes, this is something that is cleanly implemented with events and listener.
You could have the command carried out by each object individually (they receive the command when the event is triggered) or report back to the controller which carry the command on each. I'm allowing both methods here.
First, the event arguments:
classdef (ConstructOnLoad) HasCommandEventArgs < event.EventData
properties (SetAccess = private)
Command; %The actual command to carry out. Handle to a function with one input: the class instance that the command applies to
CommandArgs; %Arguments to send to the controller when reporting back.
end
methods
function this = HasCommandEventArgs(command, args)
this.Command = command;
this.CommandArgs = args;
end
end
end
Then, the controller:
classdef MasterController < handle
events
HasCommand;
end
methods (Access = ?MyClass)
function this = MasterController()
end
%Function called by each instance once the event has been raised.
%Each instance reports back and the master controller can do whatever it wants sinc it gets the instance and the command arguments
function CheckIn(this, instance, commandargs)
fprintf('\nInstance %s reported back with command args: %s\n\n', instance.Name, commandargs);
end
end
methods (Access = public)
function SendCommand(this)
%basic command here, just ask the instances to disp themselves, and command arg is just a UUID
%you could tell the objects to save themselves, or pass a filename as argument and they'll report back with that filename for the controller to save them
uid = java.util.UUID.randomUUID;
notify(this, 'HasCommand', HasCommandEventArgs(@disp, uid));
end
end
end
And finally, the class to track:
classdef MyClass < handle
properties (SetAccess = private)
Name;
end
properties (Access = private)
controllerlistener;
end
methods (Static)
%Singleton controller for the whole class.
function controller = getController()
persistent mc;
if isempty(mc)
mc = MasterController;
end
controller = mc;
end
end
methods
%When the object is created, it listens for the controller HasCommand event
%Note that when the instance is destroyed, so is the listener
function this = MyClass(name)
this.Name = name;
controller = this.getController();
this.controllerlistener = event.listener(controller, 'HasCommand', @this.DoCommand);
end
end
methods (Access = private)
function DoCommand(this, source, eventargs)
command = eventargs.Command;
command(this);
source.CheckIn(this, eventargs.CommandArgs);
end
end
end
And simple usage example:
>> mc = MyClass.getController;
>> a = MyClass('A');
>> b = MyClass('B');
>> mc.SendCommand
MyClass with properties:
Name: 'B'
Instance B reported back with command args: 4284ae7d-d68a-4fdd-8294-4a8b63a11a12
MyClass with properties:
Name: 'A'
Instance A reported back with command args: 4284ae7d-d68a-4fdd-8294-4a8b63a11a12
Plus de réponses (0)
Voir également
Catégories
En savoir plus sur Graphics Object Programming dans Help Center et File Exchange
Community Treasure Hunt
Find the treasures in MATLAB Central and discover how the community can help you!
Start Hunting!