Clear Filters
Clear Filters

Why cannot handle class events run indefinitely?

4 views (last 30 days)
Suppose there are two objects A and B instantiated from some handle classes.
There is an event in A that B listens to, and an event in B that A listens to.
When the event in A is triggered, B trigger its own event, which in turn triggers the event in A, as demonstrated in the figure.
Theoretically, once the event in A is triggered the program should run indefinitely. However in practice the program terminates when the event in A has been triggered twice. Why?
Take following code snippets for example.
The class definition
classdef myClass < handle
properties
Name
end
events
theEvent
end
methods
function obj = myClass(c)
obj.Name = c;
end
function showName(obj)
disp(['This is obj ', obj.Name])
notify(obj, 'theEvent')
end
end
end
The main file to run
A = myClass('A');
B = myClass('B');
addlistener(A, 'theEvent', @(varargin)B.showName());
addlistener(B, 'theEvent', @(varargin)A.showName());
disp('Program started')
showName(A)
disp('Program terminated')

Answers (1)

Sandeep
Sandeep on 29 Mar 2023
Hi Yuxiao Zhai,
The reason why the program terminates after the event in A has been triggered twice is because the events are triggering each other in a loop, which leads to a recursive call of the showName() method in both objects A and B. Each time the showName() method is called, it triggers the event in the other object, which in turn triggers the event in the original object, and so on.
Since there is no exit condition for this loop, it continues indefinitely until the program reaches the maximum recursion depth, which is set by default to 500 in MATLAB. Once this limit is reached, MATLAB throws an error message and terminates the program.
To prevent this infinite loop, you can add a condition in the showName() method to stop the recursion after a certain number of iterations. For example, you can define a counter variable in each object and increment it each time the method is called. Then you can add a condition to check if the counter has reached a maximum value, and if so, stop the recursion by not triggering the event.
classdef myClass < handle
properties
Name
Counter
MaxCounter
end
events
theEvent
end
methods
function obj = myClass(c, maxCounter)
obj.Name = c; obj.Counter = 0;
obj.MaxCounter = maxCounter;
end
function showName(obj)
obj.Counter = obj.Counter + 1;
if obj.Counter <= obj.MaxCounter
disp(['This is obj ', obj.Name])
notify(obj, 'theEvent')
end
end
end
end
The constructor takes an additional argument maxCounter, which sets the maximum number of times the showName() method can be called. The method checks if the counter is less than or equal to this maximum value before triggering the event. This ensures that the recursion stops after a certain number of iterations, and the program does not terminate due to a maximum recursion depth error.
  2 Comments
Yuxiao Zhai
Yuxiao Zhai on 29 Mar 2023
Hi Sandeep,
Thank you for your answer. I tried your code in MATLAB R2022b and ran the following script
A = myClass('A', 10);
B = myClass('B', 10);
addlistener(A, 'theEvent', @(varargin)B.showName());
addlistener(B, 'theEvent', @(varargin)A.showName());
disp('Program started')
showName(A)
disp('Program terminated')
However, the program still terminated when the object A had printed its name twice rather than 10 times.
men8th
men8th on 10 May 2024
I haven't looked too hard at your code, but when you create you listener, there is an option to permit or prohibit recursion. Have a look at this documentation page: https://uk.mathworks.com/help/matlab/ref/event.listener-class.html

Sign in to comment.

Categories

Find more on Toolbox Distribution in Help Center and File Exchange

Products


Release

R2022a

Community Treasure Hunt

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

Start Hunting!