Matlab classes: inconsistent state and 'PostSet' property listener

88 views Asked by At

I've got a problem of an inconsistent class state in combination with a PostSet Listener.

classdef myClass < handle 
    properties (SetObservable,GetAccess = public, SetAccess = public )
        propA;
        propB;
    end

    methods
        function myClass = myClass()
            myClass.propA = zeros(2);
            myClass.propB = zeros(2);
            addlistener(myClass,{'propA','propB'},'PostSet',@myClass.propChange);
        end
    end

   methods 

        function setSize(myClass,  size)
            myClass.propA = zeros(size);
            myClass.propB = zeros(size);
        end

        function propChange(obj,eventData, metaProp)
            disp(obj.propA - obj.propB)
        end
    end        
end

The main function is:

m = myClass();
m.setSize([1,2])

The listener functions on propA and propB needs both properties to be the same size. Unfortunately, setSize creates a short moment of inconsistency.

Ways to solve this:

  • Is there a way to set propA and propB simultaneously so that the PostSet is executed later?
  • I can use a consistency flag as another property. But how to delay the listener execution?
  • I can define my own notifications, but everything's working nicely with the predefined function.
1

There are 1 answers

0
Vladimir On

Two options can be considered

  1. Save all listener handles in some private property. And then change Enabled property of the listener when it will be necessary to switch off notifications. Disadvantage of this solution is that the listener handle will be lost if the listener is added from outside of the class.
  2. As another variant avoid using of PostSet events and define simple event. In this case PropA and PropB will be defined as public dependent properties with set and get methods.
classdef myClass < handle

    properties(Access=private)
        mPropA;
        mPropB;
    end

    properties(Dependent)
        PropA;
        PropB;
    end

    methods
        function this = myClass()
            this.mPropA = zeros(2);
            this.mPropB = zeros(2);
            addlistener(this, 'ChangedPropA', @this.propChange);
            addlistener(this, 'ChangedPropB', @this.propChange);
        end
        function setSize(this, sz)
            this.mPropA = zeros(sz);
            this.mPropB = zeros(sz);
            notify(this, 'ChangedPropA');
            notify(this, 'ChangedPropB');
        end
        function val = get.PropA(this)
            val = this.mPropA;
        end
        function set.PropA(this,val)
            this.mPropA = val;
            notify(this, 'ChangedPropA');
        end
        function val = get.PropB(this)
            val = this.mPropB;
        end
        function set.PropB(this,val)
            this.mPropB = val;
            notify(this, 'ChangedPropB');
        end
    end

    methods(Access=private)
        function propChange(this, src, evt)
            disp(src.PropA - src.PropB);
        end
    end

    events
        ChangedPropA;
        ChangedPropB;
    end
end