How to make a class object respond to a long stream of event listener callbacks only at the end of the stream of events

2 views (last 30 days)
I have an object Obj of a handle class MyClass that listens for "Change" event notifications from other objects.
Obj runs an "update" function when these other objects notify a "Change" event.
Though, when multiple such “Change” events co-occur (namely, appearing in a fast sequence right after the other), then I would like the object to run the "update" function only after the last event (otherwise it is unnecessarily slow).
What would be the recommended way?
  2 Comments
Walter Roberson
Walter Roberson on 13 Aug 2019
At the time that a particular event is received, how can the code know that it is the last in the series or not?
Matt J
Matt J on 13 Aug 2019
royk's comment moved here:
I guess that's my question!
I can imagine the last event can be identified by either:
(1) no additional events within a set time frame;
(2) Matlab becomes "not-busy" within a set time frame.
But in any of these options, my problem is that I cannot simply put a "pause" command in the callback function since this will prevent also the continued execution of the calling objects and thereby will delay the upcoming event notifications.

Sign in to comment.

Accepted Answer

Guillaume
Guillaume on 13 Aug 2019
I guess this follows from your previous question.
As there's no matlab not busy kind of notification, I think the only way you could implement this is with a timer. Whenever you receive an update, start or restart a single shot timer and queue whatever needs queing. So it would be something like this:
classdef MasterController < handle
properties (Access = private)
updatetimer;
updatequeue = {};
end
%events, etc.
methods
%constructor
function this = MasterController()
%if MasterController is guaranteed to be a singleton, the timer could be constructed in the property declaration
%if not, it has to be constructed in the constructor to avoid all instances sharing the same timer
this.updatetimer = timer('BusyMode', 'queue', 'ExecutionMode', 'singleshot', 'StartDelay', 1, 'TimerFcn', @this.ExecuteQueue);
%StartDelay specifies how many seconds to wait before executing the queue. If an event occurs within that time, the timer will be reset
end
%the update callback
function CheckIn(this, updatedata)
%stop timer if running
if strcmp(this.updatetimer.Running, 'on')
stop(this.updatetimer);
end
this.updatequeue = {this.updatequeue, updatedata};
%and start timer
start(this.updatetimer);
end
end
methods (Access = private)
function ExecuteQueue(this, ~, ~)
%with matlab being single threaded, we shouldn't have to worry about having items added to the queue while we read the queue
%nonetheless, we can make a copy of the queue, clear it and work on the copy
queue = this.updatequeue;
this.updatequeue = {};
for queueditem = queue
%do something with queueditem{1}
end
end
end
end

More Answers (1)

royk
royk on 13 Aug 2019
looks great - much thanks!!

Categories

Find more on Programming in Help Center and File Exchange

Community Treasure Hunt

Find the treasures in MATLAB Central and discover how the community can help you!

Start Hunting!