gusucode.com > appdesigner工具箱matlab源码程序 > appdesigner/+appdesigner/+internal/+codegeneration/+model/CodeData.m
classdef CodeData < handle... & appdesigner.internal.model.AbstractAppDesignerModel %CodeData code model data from the client % Copyright 2015-2016 The MathWorks, Inc. properties % the class name of the App GeneratedClassName; % an array of callbacks of type % 'appdesigner.internal.codegeneration.model.AppCallback' Callbacks; % the startup function object that can be modified of type % 'appdesigner.internal.codegeneration.model.AppCallback' ConfigurableStartupFcn; % the editable section created by the user... properties and % functions. It is an object of type 'appdesigner.internal.codegeneration.model.CodeSection' EditableSection; % an property to access the generated code GeneratedCode end properties % properties maintained for forward and backward compatibility % the startup function object of type % 'appdesigner.internal.codegeneration.model.AppCallback' % introduced in R2016a to hold the startup function for Apps % this is replaced by ConfigurableStartupFcn in R2016b StartupFcn; end properties(Transient, Hidden) % If an app has been saved to a file we will keep a copy of the % file's code for comparison in App Designer compatibility between % versions AppFileCode; end methods %------------------------------------------------------------------ function obj = CodeData(appModel, proxyView) % constructor import appdesigner.internal.codegeneration.model.AppCallback; import appdesigner.internal.codegeneration.model.CodeSection; % create an empty array for the callback and code data obj.Callbacks = AppCallback.empty; % create the startup function callback obj.ConfigurableStartupFcn = AppCallback; obj.EditableSection = CodeSection('EditableSection', ''); if (nargin > 0) assignToAppModel(obj, appModel, proxyView); end end %------------------------------------------------------------------ function assignToAppModel(obj, appModel, proxyView) import appdesigner.internal.codegeneration.getAppFileCode; % assign this object to the App Model handle appModel.CodeData = obj; % check if the CodeData is loaded From a file if(~isempty(appModel.FullFileName)) obj.AppFileCode = getAppFileCode(appModel.FullFileName); end % instantiate a controller for this dataC obj.createController(proxyView); end %------------------------------------------------------------------ function set.GeneratedClassName(obj, name) % set the generated class name for the App obj.GeneratedClassName = name; end %------------------------------------------------------------------ function sendGoToLineColumnEventToClient(obj, line, column, scrollToView) % send gotoLineColumn peerEvent to CodeModel on client side % TODO: this function needs to be refactored/moved. It is % necessary for code realted functionality but is not related % to code data obj.Controller.ProxyView.sendEventToClient('goToLineColumn', ... {'Line', line, 'Column', column, 'ScrollToView', scrollToView}); end %------------------------------------------------------------------ function data = getCodeDataForLoad(obj) % returns a struct to be sent to the client after % deserialization import appdesigner.internal.codegeneration.model.CodeData; data = struct('GeneratedClassName', obj.GeneratedClassName, ... 'EditableSection', CodeData.convertObjectToStruct(obj.EditableSection) , ... 'Callbacks', CodeData.convertObjectToStruct(obj.Callbacks), ... 'StartupFcn', CodeData.convertObjectToStruct(obj.ConfigurableStartupFcn)); end %------------------------------------------------------------------ end methods(Access=private, Static) %------------------------------------------------------------------ function codeStruct = convertObjectToStruct(objectArray) import appdesigner.internal.codegeneration.model.CodeData; % helper method to convert MCOS objects contained in this class % into structs codeStruct = struct(); codeDataProps = properties(objectArray); versionProperties = properties(appdesigner.internal.serialization.app.AppVersion); for i = 1:length(objectArray) for j = 1:length(codeDataProps) % remove properties inherted from AppVersion for code % Data objects if (~ismember(codeDataProps{j}, versionProperties)) prop = objectArray(i).(codeDataProps{j}); if(isobject(prop)) codeStruct(i).(codeDataProps{j}) = CodeData.convertObjectToStruct(prop); else codeStruct(i).(codeDataProps{j}) = prop; end end end end end %------------------------------------------------------------------ end methods(Access = public) %------------------------------------------------------------------ function controller = createController(obj, proxyView) % Creates the controller for this Model controller = appdesigner.internal.codegeneration.controller.CodeDataController(obj, proxyView); end %------------------------------------------------------------------ end methods(Static, Hidden) %------------------------------------------------------------------ function obj = loadobj(loadedObj) % handles loading the CodeData Object from a MAT file. This is % used for maintaining backward compatibilty between releases % of App Designer. loadobj is a point when unserializing App % Designer data to modify the loaded object to make it % compatibile to the current release of App Designer import appdesigner.internal.codegeneration.model.*; % update the returned obj to have the same data as loadedObj if isstruct(loadedObj) % MCOS will pass a struct into loadobj() when load() can't % create the object directly, e.g. class definition % changes. % In this case, 16a AppCallback inherits from AppVersion, % but removed in 16b (g1398205). So when loading an 16a app % into 16b, the loadedObj would be a struct obj = appdesigner.internal.codegeneration.model.CodeData(); fieldNames = fieldnames(loadedObj); for i = 1:length(fieldNames) propName = fieldNames{i}; if isprop(obj, propName) obj.(propName) = loadedObj.(propName); end end else % Otherwise class definition is compatible with the % serialized object, and MCOS load() can instantiate the % object, and loadedObj would be a regular object obj = loadedObj; end % if the loaded object is from a version earlier than the % current: % 1) copy the startupFcn data to the configurable % startupFcn % 2) convert callback.ComponentData.ComponentType from % 'matlab.ui.control.AppWindow' to 'matlab.ui.Figure' obj = CodeData.handleReleaseComaptibilty(loadedObj, obj); end %------------------------------------------------------------------ function obj = handleReleaseComaptibilty(loadedObj, obj) % handles compatibility for loading codeData % if CodeData is loaded before the Configurable Startup % function exists and there is code on the Startup Function % transfer its data to the ConfigurableStartupFcn. Otherwise, % its assumed that the user deleted the Startup function and it % is empty if (isstruct(loadedObj) || isempty(loadedObj.ConfigurableStartupFcn)) && ... ~isempty(loadedObj.StartupFcn.Code) % copy the serialized StartupFcn data to ConfigurableStatipFcn obj.ConfigurableStartupFcn = loadedObj.StartupFcn; end % From 16a, the UIFigure's callback data will store % ComponentType as 'matlab.ui.control.AppWindow', and in order % to load into 16b or later, need to change to % 'matlab.ui.Figure' % % Shared callback has multiple ComponentData, and strcmp % requires one string function convertAppWindowTypeToFigure(componentData) if strcmp(componentData.ComponentType, 'matlab.ui.control.AppWindow') componentData.ComponentType = 'matlab.ui.Figure'; end end arrayfun(@convertAppWindowTypeToFigure, [obj.Callbacks.ComponentData]); end %------------------------------------------------------------------ end methods(Hidden) %------------------------------------------------------------------ function savedObj = saveobj(obj) % handles saving the CodeData object to MAT file. This function % is used for maintaining forward compatibility in that the % saved app can be modified before serialzation to a MAT file. % update the returned obj to have the same data as obj savedObj = obj; savedObj = obj.handleSaveStartupFcnForCompatibility(savedObj); end %------------------------------------------------------------------ function savedObj = handleSaveStartupFcnForCompatibility(obj, savedObj) % save the StartupFcn for forward compatibility reasons, % earlier releases (16a) used this property for the startup % function. % this data is hard-coded to be reflective of the default % startup callback in prior releases. import appdesigner.internal.codegeneration.model.*; startupFcn = AppCallback(); startupFcn.Name = 'startupFcn'; startupFcn.Comment = getString(message('MATLAB:appdesigner:codegeneration:RunStartupFcnComment')); startupFcn.Args = {'app'}; startupFcn.ReturnArgs = []; startupFcn.Type = 'AppStartupFunction'; startupFcn.ComponentData = CallbackComponentData.empty; startupFcn.CallbackId = []; if (~isempty(obj.ConfigurableStartupFcn)) startupFcn.Code = obj.ConfigurableStartupFcn.Code; else startupFcn.Code = []; end savedObj.StartupFcn = startupFcn; end %------------------------------------------------------------------ end end