www.gusucode.com > mbcview 工具箱matlab源码程序 > mbcview/+cageview/+optimoutput/MessageService.m
classdef MessageService < mbcmodelview.MessageService %cageview.optimoutput.MessageService class % cageview.optimoutput.MessageService extends mbcgui.multiview.AbstractMessageService. % % cageview.optimoutput.MessageService properties: % CurrentRun - Property is of type 'MATLAB array' (read only) % CurrentSolution - Property is of type 'MATLAB array' (read only) % FocusPoint - Property is of type 'MATLAB array' (read only) % CurrentSliceDirection - Property is of type 'string' (read only) % % cageview.optimoutput.MessageService methods: % getDataName - Get a name for the data being displayed % getFocusPoint - Get the currently focussed point. % getFocusRun - Get the currently focussed run. % getFocusSolution - Get the currently focussed solution. % getOptimOutput - Get the optimisation output object % hasData - Check whether the MessageService contains viewable data % hasFocusIndex - Check whether there is a focussed set of free values. % reset - Reset the message service to default values. % sendEvent - Send the appropriate events for a change's root cause % setCurrentIndex - Set the currently viewed run, solution and focus point % setCurrentRun - Set the currently viewed run. % setCurrentSlice - Set the current slice direction. % setCurrentSolution - Set the currently viewed solution. % setFocusPoint - Set the currently focussed point. % setOptimOutput - Set a new optimization object % Copyright 2005-2016 The MathWorks, Inc. and Ford Global Technologies, Inc. properties (Access=protected, AbortSet) %DESTRUCTIONLISTENER Property is of type 'handle' DestructionListener = []; end properties (SetAccess=protected, AbortSet) %CURRENTRUN Property is of type 'MATLAB array' (read only) CurrentRun = 1; %CURRENTSOLUTION Property is of type 'MATLAB array' (read only) CurrentSolution = 1; %FOCUSPOINT Property is of type 'MATLAB array' (read only) FocusPoint = 1; %CURRENTSLICEDIRECTION Property is of type 'string' (read only) CurrentSliceDirection = 'solution'; %OPTIMOUTPUTPOINTER Property is of type 'MATLAB array' OptimOutputPointer = []; end properties(Dependent,SetAccess=private) %Title Title end properties (Dependent,SetAccess=private) %ProjectPointer pointer to CAGE project ProjectPointer end events (NotifyAccess=private) ObjectChanged CurrentIndexChanged RunIndexChanged SolutionIndexChanged FocusPointChanged CurrentFocusChanged RunFocusChanged SolutionFocusChanged FocusOrFocusPointChanged SliceDirectionChanged ObjectPropertyChanged SelectedSolutionChanged WeightsChanged FeasibleToleranceChanged AcceptableChanged PreserveChanged end % events methods % constructor block function obj = MessageService(OptimOutput) %MessageService Create an instance of an MessageService object % H = MessageService(OPTIMOUT) constructs a new % MessageService object. % h = cageview.optimoutput.MessageService; obj.OptimOutputPointer = xregpointer([]); if nargin obj.OptimOutputPointer.info = OptimOutput; % Attach a listener to free the pointer when this object is destroyed obj.DestructionListener = event.listener(obj, 'ObjectBeingDestroyed', @(h,evt) iFree(h,evt,h.OptimOutputPointer)); end % create actions for output node obj.Actions = cageview.optimoutput.Actions(obj); end % MessageService end % constructor block methods % public methods function s = get.Title(obj) if obj.hasData s = name(obj.Node); else s = ''; end end function p = get.ProjectPointer(obj) %ProjectPointer pointer to CAGE project if ~isnull(obj.Pointer) p = obj.Pointer.root; else p = xregpointer; end end function OK = leaveNode(obj) %leaveNode get ready to leave node OK = leaveNode@mbcmodelview.MessageService(obj); if OK obj.OptimOutputPointer = xregpointer; end end function initialize(obj,pNode) %initialize initialize MessageService with new cgoptimoutnode obj.Pointer = pNode; obj.OptimOutputPointer = getdata(info(obj.Pointer)); reset(obj,info(obj.OptimOutputPointer)); end %---------------------------------------- function nm = getDataName(obj) %GETDATANAME Get a name for the data being displayed % NM = GETDATANAME(OBJ) returns a string that is the name of the data % that is being encapsulated by the message service. By default this % returns the string '<Unknown>'. if obj.hasData nm = getname(obj.getOptimOutput); else nm = '<Unknown>'; end end % getDataName %---------------------------------------- function FocusPointIdx = getFocusPoint(obj) %GETFOCUSPOINT Get the currently focussed point. % FOCUSPOINTIDX = GETFOCUSPOINT(OBJ) returns the current focus point. FocusPointIdx = obj.FocusPoint; end % getFocusPoint %---------------------------------------- function Idx = getFocusRun(obj) %GETFOCUSRUN Get the currently focussed run. % IDX = GETFOCUSRUN(OBJ) returns a scalar index indicating which run is % currently focussed. If there is currently no selection of runs then % the index will be zero. % Focus is defined as the last selection index if ~isempty(obj.CurrentRun) && ~strcmpi(obj.CurrentSliceDirection, 'weightedsolution') if strcmpi(obj.CurrentSliceDirection, 'selectedsolution') % Check that selected solution is initialised out = getOptimOutput(obj); if hasSelectedSolution(out) % The focus is valid Idx = obj.CurrentRun(end); else Idx = 0; end else Idx = obj.CurrentRun(end); end else Idx = 0; end end % getFocusRun %---------------------------------------- function Idx = getFocusSolution(obj) %GETFOCUSSOLUTION Get the currently focussed solution. % IDX = GETFOCUSSOLUTION(OBJ) returns a scalar index indicating which % solution is currently focussed. If there is currently no selection of % solutions then the index will be zero. % Focus is defined as the last selection index if ~isempty(obj.CurrentSolution) if strcmpi(obj.CurrentSliceDirection, 'selectedsolution') % Check that selected solution is initialised out = getOptimOutput(obj); if hasSelectedSolution(out) % The focus is valid Idx = obj.CurrentSolution(end); else Idx = 0; end else Idx = obj.CurrentSolution(end); end else Idx = 0; end end % getFocusSolution %---------------------------------------- function OptimOut = getOptimOutput(obj) %GETOPTIMOUTPUT Get the optimisation output object % OPTIM = GETOPTIMOUTPUT(OBJ) returns the optimization output object that % is currently being viewed. OptimOut = obj.OptimOutputPointer.info; end % getOptimOutput %---------------------------------------- function ret = hasData(obj) %HASDATA Check whether the MessageService contains viewable data % RET = HASDATA(OBJ) returns true if the MessageService object contains % a data object that can provide any viewing data. if ~isnull(obj.Pointer) ret = ~isempty(obj.getOptimOutput); else ret = false; end end % hasData %---------------------------------------- function val = hasFocusIndex(obj) %HASFOCUSINDEX Check whether there is a focussed set of free values. % VAL = HASFOCUSINDEX(OBJ) returns true if there is a set of focussed % free values, i.e. there is a both a valid focus run and a valid focus % solution. val = obj.hasData ... && ~isempty(obj.CurrentRun) ... && ~isempty(obj.CurrentSolution) ... && ~isempty(obj.FocusPoint) ... && ~strcmpi(obj.CurrentSliceDirection, 'weightedsolution'); if val && strcmpi(obj.CurrentSliceDirection, 'selectedsolution') out = getOptimOutput(obj); val = val && hasSelectedSolution(out); end end % hasFocusIndex %---------------------------------------- function ev = pSelectedSolutionCheck(obj) %PSELECTEDSOLUTIONCHECK Update solution selection. % EV = PSELECTEDSOLUTIONCHECK(OBJ) sets the current solution to be the % selection solution for the focussed runs. A cell array of events that % need to be sent is returned. ev = {}; if strcmpi(obj.CurrentSliceDirection, 'selectedsolution') ... && obj.hasData ... && hasSelectedSolution(obj.getOptimOutput) % The solution index is locked to a particular value for each run OldFocus = obj.getFocusSolution; obj.CurrentSolution = getSelectedSolutionNumber(obj.getOptimOutput, obj.getFocusRun); ev = [ev {'SolutionIndexChanged'}]; if obj.getFocusSolution~=OldFocus ev = [ev, {'SolutionFocusChanged'}]; end end end % pSelectedSolutionCheck %---------------------------------------- function reset(obj, OptimOut) %RESET Reset the message service to default values. % RESET(OBJ, OPTIMOUT) resets the message service indices to their % default values and sets the specified output object. obj.CurrentRun = 1; obj.CurrentSolution = 1; obj.FocusPoint = 1; obj.setOptimOutput(OptimOut, 'ObjectChanged'); if ~isempty(OptimOut) % Check whether slice setting is appropriate nSol = getNumSolutions(OptimOut); nRuns = getNumSolutions(OptimOut); if nSol>1 && strcmpi(obj.CurrentSliceDirection, 'solution') % Switch to pareto automatically obj.setCurrentSlice('pareto'); elseif nSol==1 && any(strcmpi(obj.CurrentSliceDirection, {'pareto','selectedsolution'})) % Switch to solution automatically obj.setCurrentSlice('solution'); elseif nRuns>1 && strcmpi(obj.CurrentSliceDirection, 'weightedsolution') % only 1 run so switch from weightedsolution to solution slice obj.setCurrentSlice('solution'); end end end % reset %---------------------------------------- function sendEvent(obj, Event) %SENDEVENT Send the appropriate events for a change's root cause % SENDEVENT(OBJ, EVENT) sends the event specified by EVENT. Valid % settings for EVENT are: % % 'ObjectChanged' : Send when the object changes. % 'CurrentIndexChanged' : Sent when either the current run or solution % is changed. % 'SolutionIndexChanged' : Sent when the current solution is changed. % 'RunIndexChanged' : Sent when the current run is changed. % 'CurrentFocusChanged' : Sent when either the current run or solution % focus is changed. % 'SolutionFocusChanged' : Sent when the current solution focus is changed. % 'RunFocusChanged' : Sent when the current run focus is changed. % 'FocusPointChanged' : Sent when the focus point is changed. % 'FocusOrFocusPointChanged': Sent when either the current focus or % focus point is changed. % 'SliceDirectionChanged' : Sent when the preferred slice direction is % changed. % 'SelectedSolutionChanged': Sent when the set of selected solution is % changed. % 'WeightsChanged' : Sent when the weights for the weighted view % are changed. % 'FeasibleToleranceChanged': Sent when the tolerance that is used for % deciding feasibility is changed. % 'AcceptableChanged' : Sent when the set of acceptable flags is % changed. % 'ObjectPropertyChanged' : Sent when any property of the object is % altered. % 'PreserveChanged' : Sent when the node's 'Preserved' flag is % changed. if ~iscell(Event) ev = {Event}; else ev = Event; end % Check whether the ObjectChanged event should be added ObjectPropEvents = { ... 'SelectedSolutionChanged', ... 'WeightsChanged', ... 'FeasibleToleranceChanged', ... 'AcceptableChanged'}; if ~isempty(intersect(ObjectPropEvents, ev)) ... && ~ismember('ObjectPropertyChanged', ev) ev = [ev, {'ObjectPropertyChanged'}]; end for n = 1:length(ev) obj.notify(ev{n}); end end % sendEvent %---------------------------------------- function setCurrentIndex(obj, RunIdx, SolIdx, FocusPoint) %SETCURRENTINDEX Set the currently viewed run, solution and focus point % SETCURRENTINDEX(OBJ, RUNIDX, SOLIDX, FOCUSPOINT) sets the current run, % current solution and focus point. This method fires the following % events % % Quantity changed Event % -------------------------------+-------------------------- % Run index : "RunIndexChanged" % Solution index : "SolutionIndexChanged" % Run or solution index : "CurrentIndexChanged" % Focus run : "FocusRunChanged" % Focus solution : "FocusSolutionChanged" % Focus point : "FocusPointChanged" % Focus run, solution : "CurrentFocusChanged" % Focus run, solution, point : "FocusOrFocusPointChanged" OldRunFocus = obj.getFocusRun; OldSolFocus = obj.getFocusSolution; OldRun = obj.CurrentRun; OldSol = obj.CurrentSolution; OldFocusPoint = obj.FocusPoint; % Set new indices obj.CurrentRun = RunIdx; if ~strcmp(obj.CurrentSliceDirection, 'selectedsolution') obj.CurrentSolution = SolIdx; else obj.CurrentSolution = getSelectedSolutionNumber(obj.getOptimOutput, RunIdx); end obj.FocusPoint = FocusPoint; % Set up any index changed events ev = {}; RunIC = ~isequal(obj.CurrentRun, OldRun); SolIC = ~isequal(obj.CurrentSolution, OldSol); if RunIC || SolIC ev = [ev, {'CurrentIndexChanged'}]; end if RunIC ev = [ev, {'RunIndexChanged'}]; end if SolIC ev = [ev, {'SolutionIndexChanged'}]; end % Set up any focus changed events RunFC = obj.getFocusRun~=OldRunFocus; SolFC = obj.getFocusSolution~=OldSolFocus; if RunFC ev = [ev, {'RunFocusChanged'}]; end if SolFC ev = [ev, {'SolutionFocusChanged'}]; end if RunFC || SolFC ev = [ev, {'CurrentFocusChanged'}]; end % Set up any focus point changed events PointFC = obj.FocusPoint~=OldFocusPoint; if PointFC ev = [ev, {'FocusPointChanged'}]; end % Set up an event to capture either the focus or focus point changing if RunFC || SolFC || PointFC ev = [ev, {'FocusOrFocusPointChanged'}]; end % Send the events obj.sendEvent(ev); end % setCurrentIndex %---------------------------------------- function setCurrentRun(obj, RunIdx) %SETCURRENTRUN Set the currently viewed run. % SETCURRENTRUN(OBJ, RUNIDX) sets the current run index to RUNIDX and % fires the "CurrentIndexChanged" and "RunIndexChanged" events. If the % current slice is set to 'selectedsolution', the solution is also set to % the appropriate value. % There is no concept of a run to select when looking at weighted solution if ~strcmp(obj.CurrentSliceDirection, 'weightedsolution') OldFocus = obj.getFocusRun; OldRun = obj.CurrentRun; obj.CurrentRun = RunIdx; ev = {}; if ~isequal(obj.CurrentRun, OldRun) ev = {'CurrentIndexChanged', 'RunIndexChanged'}; end if obj.getFocusRun~=OldFocus ev = [ev, {'CurrentFocusChanged', 'RunFocusChanged', ... 'FocusOrFocusPointChanged'}]; end % Check whether solution chould change too ev = [ev, obj.pSelectedSolutionCheck]; obj.sendEvent(ev); end end % setCurrentRun %---------------------------------------- function setCurrentSlice(obj, Value) %SETCURRENTSLICE Set the current slice direction. % SETCURRENTSLICE(OBJ, SLICEDIR) sets the current slice direction. % SLICEDIR must be one of 'solution' or 'pareto'. obj.CurrentSliceDirection = Value; ev ={'SliceDirectionChanged'}; ev = [ev, obj.pSelectedSolutionCheck]; obj.sendEvent(ev); end % setCurrentSlice %---------------------------------------- function setCurrentSolution(obj, SolIdx) %SETCURRENTSOLUTION Set the currently viewed solution. % SETCURRENTSOLUTION(OBJ, SOLIDX) sets the current solution index to % SOLIDX and fires the "CurrentIndexChanged" and "SolutionIndexChanged" % events. if ~strcmp(obj.CurrentSliceDirection, 'selectedsolution') OldFocus = obj.getFocusSolution; OldSolution = obj.CurrentSolution; obj.CurrentSolution = SolIdx; ev = {}; if ~isequal(obj.CurrentSolution, OldSolution) ev = {'CurrentIndexChanged', 'SolutionIndexChanged'}; end if obj.getFocusSolution~=OldFocus ev = [ev, {'CurrentFocusChanged', 'SolutionFocusChanged', ... 'FocusOrFocusPointChanged'}]; end obj.sendEvent(ev); end end % setCurrentSolution %---------------------------------------- function setFocusPoint(obj, FocusPointIdx) %SETFOCUSPOINT Set the currently focussed point. % SETFOCUSPOINT(OBJ, FOCUSPOINTIDX) sets the current focus point index to % FOCUSPOINTIDX and fires the "FocusOrFocusPointChanged" and % "FocusPointChanged" events. % Only set the focus point if it is in the range [1, Nmax], where Nmax is % the maximum length of all the optimization quantities out = obj.getOptimOutput; data = getSolution(out, 1, 'OutputFormat', 'cell', ... 'OutputContents', {'FixedVars', 'FreeVars', 'Objectives', 'Constraints'}); Nmax = max(cellfun('length', data)); if FocusPointIdx >= 1 && FocusPointIdx <= Nmax OldFocus = obj.FocusPoint; obj.FocusPoint = FocusPointIdx; % Only fire event if the focus point has actually changed if obj.FocusPoint~=OldFocus ev = {'FocusPointChanged', 'FocusOrFocusPointChanged'}; obj.sendEvent(ev); end end end % setFocusPoint %---------------------------------------- function setOptimOutput(obj, OptimOut, Event) %SETOPTIMOUTPUT Set a new optimization object % SETOPTIMOUTPUT(OBJ, OPTIM, EVENT) sets an updated optimization output % object to be viewed. The optional argument EVENT specifies which set of % events should be sent to notify views of the changes. See the SENDEVENT % method for the valid EVENT settings. % % Additional events may be added to the list automatically if the new % object causes run or solution selection or slice direction changes in % the message service. OldHasAFocus = obj.hasFocusIndex; obj.OptimOutputPointer.info = OptimOut; ev = {}; % Check whether selected solution should change evSol = obj.pSelectedSolutionCheck; % Add appropriate additional focus events HasAFocus = obj.hasFocusIndex; if OldHasAFocus~=HasAFocus %The focus run and solution have both altered from 0 to a valid value ev = [ev, {'CurrentFocusChanged', 'FocusOrFocusPointChanged'}]; else % Just add in the selection solution event if there is one. ev = [ev, evSol]; end if nargin>2 obj.sendEvent(Event); end if ~isempty(ev) obj.sendEvent(ev); end end % setOptimOutput end % public methods end % classdef function iFree(~, ~, p) freeptr(p); end % iFree