33
44 methods (Static )
55 function save(config , filepath )
6- % SAVE Write dashboard config struct to JSON file.
6+ % SAVE Write dashboard config as a MATLAB function file.
7+ % The output is a function returning a DashboardEngine.
8+ [~ , funcname ] = fileparts(filepath );
9+
10+ % Generate the script body (reuse exportScript logic)
11+ lines = {};
12+ lines{end + 1 } = sprintf(' function d = %s ()' , funcname );
13+ lines{end + 1 } = sprintf(' %%%s Recreate dashboard.' , upper(funcname ));
14+ lines{end + 1 } = sprintf(' %% d = %s () returns a DashboardEngine.' , funcname );
15+ lines{end + 1 } = ' ' ;
16+ lines{end + 1 } = sprintf(' d = DashboardEngine(''%s'' );' , strrep(config .name , ' '' ' , ' '''' ' ));
17+ if isfield(config , ' theme' )
18+ lines{end + 1 } = sprintf(' d.Theme = ''%s'' ;' , config .theme );
19+ end
20+ if isfield(config , ' liveInterval' )
21+ lines{end + 1 } = sprintf(' d.LiveInterval = %g ;' , config .liveInterval );
22+ end
23+ if isfield(config , ' infoFile' ) && ~isempty(config .infoFile )
24+ lines{end + 1 } = sprintf(' d.InfoFile = ''%s'' ;' , strrep(config .infoFile , ' '' ' , ' '''' ' ));
25+ end
26+ lines{end + 1 } = ' ' ;
27+
28+ % Write widget calls (indented, with return value)
29+ for i = 1 : numel(config .widgets )
30+ ws = config.widgets{i };
31+ pos = sprintf(' [%d %d %d %d ]' , ws .position .col , ws .position .row , ...
32+ ws .position .width , ws .position .height );
33+
34+ switch ws .type
35+ case ' fastsense'
36+ if isfield(ws , ' source' )
37+ switch ws .source .type
38+ case ' sensor'
39+ lines{end + 1 } = sprintf(' w = d.addWidget('' fastsense'' , '' Title'' , ''%s'' , ...' , ws .title );
40+ lines{end + 1 } = sprintf(' '' Position'' , %s , ...' , pos );
41+ lines{end + 1 } = sprintf(' '' Sensor'' , SensorRegistry.get(''%s'' ));' , ws .source .name );
42+ case ' file'
43+ lines{end + 1 } = sprintf(' w = d.addWidget('' fastsense'' , '' Title'' , ''%s'' , ...' , ws .title );
44+ lines{end + 1 } = sprintf(' '' Position'' , %s , ...' , pos );
45+ lines{end + 1 } = sprintf(' '' File'' , ''%s'' , '' XVar'' , ''%s'' , '' YVar'' , ''%s'' );' , ...
46+ ws .source .path , ws .source .xVar , ws .source .yVar );
47+ case ' data'
48+ lines{end + 1 } = sprintf(' w = d.addWidget('' fastsense'' , '' Title'' , ''%s'' , ...' , ws .title );
49+ lines{end + 1 } = sprintf(' '' Position'' , %s , ...' , pos );
50+ lines{end + 1 } = sprintf(' '' XData'' , %s , '' YData'' , %s );' , ...
51+ mat2str(ws .source .x ), mat2str(ws .source .y ));
52+ otherwise
53+ lines{end + 1 } = sprintf(' d.addWidget('' fastsense'' , '' Title'' , ''%s'' , '' Position'' , %s );' , ws .title , pos );
54+ end
55+ else
56+ lines{end + 1 } = sprintf(' d.addWidget('' fastsense'' , '' Title'' , ''%s'' , '' Position'' , %s );' , ws .title , pos );
57+ end
58+ case ' number'
59+ line = sprintf(' d.addWidget('' number'' , '' Title'' , ''%s'' , '' Position'' , %s ' , ws .title , pos );
60+ if isfield(ws , ' units' ) && ~isempty(ws .units )
61+ line = [line , sprintf(' , ...\n '' Units'' , ''%s'' ' , ws .units )];
62+ end
63+ lines{end + 1 } = [line , ' );' ];
64+ case ' status'
65+ line = sprintf(' d.addWidget('' status'' , '' Title'' , ''%s'' , '' Position'' , %s ' , ws .title , pos );
66+ lines{end + 1 } = [line , ' );' ];
67+ case ' text'
68+ line = sprintf(' d.addWidget('' text'' , '' Title'' , ''%s'' , '' Position'' , %s ' , ws .title , pos );
69+ if isfield(ws , ' content' ) && ~isempty(ws .content )
70+ line = [line , sprintf(' , ...\n '' Content'' , ''%s'' ' , ws .content )];
71+ end
72+ lines{end + 1 } = [line , ' );' ];
73+ case ' gauge'
74+ line = sprintf(' d.addWidget('' gauge'' , '' Title'' , ''%s'' , '' Position'' , %s ' , ws .title , pos );
75+ if isfield(ws , ' range' )
76+ line = [line , sprintf(' , ...\n '' Range'' , [%g %g ]' , ws .range(1 ), ws .range(2 ))];
77+ end
78+ if isfield(ws , ' units' ) && ~isempty(ws .units )
79+ line = [line , sprintf(' , ...\n '' Units'' , ''%s'' ' , ws .units )];
80+ end
81+ lines{end + 1 } = [line , ' );' ];
82+ case ' group'
83+ line = sprintf(' d.addWidget('' group'' , '' Label'' , ''%s'' , '' Position'' , %s ' , ws .label , pos );
84+ if isfield(ws , ' mode' ) && ~isempty(ws .mode )
85+ line = [line , sprintf(' , ...\n '' Mode'' , ''%s'' ' , ws .mode )];
86+ end
87+ lines{end + 1 } = [line , ' );' ];
88+ otherwise
89+ lines{end + 1 } = sprintf(' d.addWidget(''%s'' , '' Title'' , ''%s'' , '' Position'' , %s );' , ws .type , ws .title , pos );
90+ end
91+ lines{end + 1 } = ' ' ;
92+ end
93+
94+ lines{end + 1 } = ' end' ;
95+
96+ fid = fopen(filepath , ' w' );
97+ if fid == - 1
98+ error(' DashboardSerializer:fileError' , ' Cannot open file: %s ' , filepath );
99+ end
100+ fprintf(fid , ' %s\n ' , lines{: });
101+ fclose(fid );
102+ end
103+
104+ function saveJSON(config , filepath )
105+ % SAVEJSON Legacy: write dashboard config struct to JSON file.
7106 % Widgets may have heterogeneous fields, so encode each
8107 % widget individually and assemble the JSON array by hand.
9108 parts = cell(1 , numel(config .widgets ));
@@ -26,19 +125,33 @@ function save(config, filepath)
26125 fclose(fid );
27126 end
28127
29- function config = load(filepath )
30- % LOAD Read dashboard config from JSON file.
128+ function result = load(filepath )
129+ % LOAD Load dashboard config from file.
130+ % For .m files: uses feval to execute the function and return the engine.
131+ % For .json files: uses legacy JSON parsing.
31132 if ~exist(filepath , ' file' )
32133 error(' DashboardSerializer:fileNotFound' , ' File not found: %s ' , filepath );
33134 end
34135
136+ [fdir , funcname , ext ] = fileparts(filepath );
137+
138+ if strcmp(ext , ' .json' )
139+ result = DashboardSerializer .loadJSON(filepath );
140+ return ;
141+ end
142+
143+ % .m function file
144+ addpath(fdir );
145+ cleanupPath = onCleanup(@() rmpath(fdir ));
146+ result = feval(funcname );
147+ end
148+
149+ function config = loadJSON(filepath )
150+ % LOADJSON Legacy: read dashboard config from JSON file.
35151 fid = fopen(filepath , ' r' );
36152 jsonStr = fread(fid , ' *char' )' ;
37153 fclose(fid );
38-
39154 config = jsondecode(jsonStr );
40-
41- % Ensure widgets is a cell array
42155 if isstruct(config .widgets )
43156 wa = config .widgets ;
44157 config.widgets = cell(1 , numel(wa ));
0 commit comments