274 lines
11 KiB
Matlab
274 lines
11 KiB
Matlab
classdef mainConfig
|
||
|
||
methods(Static)
|
||
|
||
function config = export()
|
||
blockPath = gcb;
|
||
mask = Simulink.Mask.get(blockPath);
|
||
wrapParamToExport = {'wrapperPath', 'enableDebug', 'mcuClk', ...
|
||
'threadCycles', 'enableThreading', 'enableDeinit'};
|
||
portParamToExport = {'inNumb', ...
|
||
'in_port_1_name', 'in_port_1_width', ...
|
||
'in_port_2_name', 'in_port_2_width', ...
|
||
'in_port_3_name', 'in_port_3_width', ...
|
||
'in_port_4_name', 'in_port_4_width', ...
|
||
'in_port_5_name', 'in_port_5_width', ...
|
||
'outNumb', ...
|
||
'out_port_1_name', 'out_port_1_width', ...
|
||
'out_port_2_name', 'out_port_2_width', ...
|
||
'out_port_3_name', 'out_port_3_width', ...
|
||
'out_port_4_name', 'out_port_4_width', ...
|
||
'out_port_5_name', 'out_port_5_width',};
|
||
appParamToExport = {'appWrapperPath', 'srcTable', 'incTable', 'userDefs'};
|
||
|
||
config = struct();
|
||
for i = 1:numel(wrapParamToExport)
|
||
paramName = wrapParamToExport{i};
|
||
def = mainConfig.exportParamToConfig(mask, paramName);
|
||
config.(paramName) = def;
|
||
end
|
||
|
||
for i = 1:numel(portParamToExport)
|
||
paramName = portParamToExport{i};
|
||
def = mainConfig.exportParamToConfig(mask, paramName);
|
||
config.(paramName) = def;
|
||
end
|
||
|
||
for i = 1:numel(appParamToExport)
|
||
paramName = appParamToExport{i};
|
||
def = mainConfig.exportParamToConfig(mask, paramName);
|
||
config.(paramName) = def;
|
||
end
|
||
|
||
|
||
|
||
jsonStr = jsonencode(config, 'PrettyPrint', true); % 'PrettyPrint' для форматирования
|
||
|
||
|
||
% Диалог сохранения файла
|
||
[file, path] = uiputfile('*.json', 'Сохранить конфигурацию как', 'WrapperConfig.json');
|
||
if isequal(file, 0) || isequal(path, 0)
|
||
disp('Сохранение отменено пользователем.');
|
||
return;
|
||
end
|
||
|
||
filepath = fullfile(path, file);
|
||
|
||
|
||
|
||
% Сохраняем в файл
|
||
fid = fopen(filepath, 'w');
|
||
if fid == -1
|
||
mcuMask.disp(0, 'Не удалось открыть файл для записи: %s', filename);
|
||
end
|
||
|
||
fwrite(fid, jsonStr, 'char');
|
||
fclose(fid);
|
||
end
|
||
|
||
|
||
function import()
|
||
% Получаем путь к текущему блоку
|
||
blockPath = gcb;
|
||
mask = Simulink.Mask.get(blockPath);
|
||
|
||
% Выбор JSON-файла через диалоговое окно
|
||
[file, path] = uigetfile('*.json', 'Выберите файл конфигурации');
|
||
if isequal(file, 0)
|
||
mcuMask.disp(0, 'Импорт отменён пользователем.');
|
||
return;
|
||
end
|
||
|
||
fullpath = fullfile(path, file);
|
||
|
||
% Чтение и декодирование JSON
|
||
try
|
||
jsonStr = fileread(fullpath);
|
||
config = jsondecode(jsonStr);
|
||
catch err
|
||
mcuMask.disp(0, 'Ошибка при чтении или разборе JSON: %s', err.message);
|
||
end
|
||
|
||
% Применение параметров из конфигурации
|
||
paramNames = fieldnames(config);
|
||
for i = 1:numel(paramNames)
|
||
paramName = paramNames{i};
|
||
def = config.(paramName);
|
||
|
||
try
|
||
mainConfig.applyDefToMask(mask, paramName, def);
|
||
catch err
|
||
mcuMask.disp(0, 'Ошибка при применении параметра "%s": %s', paramName, err.message);
|
||
end
|
||
end
|
||
|
||
mcuMask.disp(0, 'Конфигурация успешно импортирована.');
|
||
end
|
||
|
||
end
|
||
|
||
|
||
methods(Static, Access=private)
|
||
|
||
|
||
function def = exportParamToConfig(mask, paramName)
|
||
% mask — объект Simulink.Mask.get(blockPath)
|
||
% paramName — имя параметра (как в mask.Parameters.Name)
|
||
|
||
param = mask.getParameter(paramName);
|
||
if isempty(param)
|
||
mcuMask.disp(0, 'Параметр "%s" не найден в маске.', paramName);
|
||
def = [];
|
||
return;
|
||
end
|
||
|
||
def = struct();
|
||
|
||
% Prompt
|
||
def.Prompt = param.Prompt;
|
||
|
||
% Тип параметра
|
||
def.Type = param.Type;
|
||
|
||
% Значение по умолчанию
|
||
val = param.Value;
|
||
switch lower(param.Type)
|
||
case 'checkbox'
|
||
def.Default = strcmp(val, 'on');
|
||
case {'edit', 'spinbox'}
|
||
num = str2double(val);
|
||
if ~isnan(num)
|
||
def.Default = num;
|
||
else
|
||
def.Default = val;
|
||
end
|
||
case 'customtable'
|
||
def.Default = customtable.parse(param.Name); % или можно попытаться распарсить значение позже
|
||
case 'text'
|
||
def.Default = ''; % или можно попытаться распарсить значение позже
|
||
otherwise
|
||
def.Default = val;
|
||
end
|
||
|
||
% Alias, если есть
|
||
if ~isempty(param.Alias)
|
||
def.Def = param.Alias;
|
||
end
|
||
|
||
% % Row (new/current)
|
||
% try
|
||
% rowSetting = param.DialogControl.Row;
|
||
% def.NewRow = strcmp(rowSetting, 'new');
|
||
% catch
|
||
% def.NewRow = false;
|
||
% end
|
||
end
|
||
|
||
|
||
function applyDefToMask(mask, paramName, def)
|
||
% mask — объект Simulink.Mask.get(blockPath)
|
||
% paramName — имя параметра маски
|
||
% def — структура, полученная из extractDefFromMask
|
||
|
||
% Получаем параметр
|
||
param = mask.getParameter(paramName);
|
||
if isempty(param)
|
||
mcuMask.disp(0, 'Параметр "%s" не найден в маске.', paramName);
|
||
return;
|
||
end
|
||
|
||
if isempty(def)
|
||
mcuMask.disp(0, 'Параметр "%s" не найден в конфиге.', paramName);
|
||
return;
|
||
end
|
||
|
||
switch lower(def.Type)
|
||
case 'checkbox'
|
||
% Логическое значение true/false
|
||
if islogical(def.Default)
|
||
param.Value = mainConfig.ternary(def.Default, 'on', 'off');
|
||
else
|
||
mcuMask.disp(0, 'Ожидалось логическое значение для checkbox "%s".', paramName);
|
||
end
|
||
|
||
case {'edit', 'spinbox'}
|
||
% Строка или число
|
||
if isnumeric(def.Default)
|
||
param.Value = num2str(def.Default);
|
||
elseif ischar(def.Default) || isstring(def.Default)
|
||
param.Value = char(def.Default);
|
||
else
|
||
mcuMask.disp(0, 'Некорректный формат значения для edit "%s".', paramName);
|
||
end
|
||
|
||
case 'customtable'
|
||
% Массив строк
|
||
if iscell(def.Default)
|
||
customtable.collect(paramName, def.Default);
|
||
else
|
||
mcuMask.disp(0, 'customtable "%s" требует cell-массив строк.', paramName);
|
||
end
|
||
|
||
case 'text'
|
||
% Просто текстовая строка
|
||
if ischar(def.Default) || isstring(def.Default)
|
||
param.Value = char(def.Default);
|
||
else
|
||
mcuMask.disp(0, 'text-параметр "%s" должен быть строкой.', paramName);
|
||
end
|
||
|
||
case 'popup'
|
||
% popup — установить значение, если оно есть в списке
|
||
if ischar(def.Default) && isfield(def, 'Def') && any(strcmp(def.Default, def.Def))
|
||
param.Value = def.Default;
|
||
else
|
||
mcuMask.disp(0, 'popup-параметр "%s" имеет неверное значение или список.', paramName);
|
||
end
|
||
|
||
otherwise
|
||
% По умолчанию просто устанавливаем строковое значение
|
||
if ischar(def.Default) || isstring(def.Default)
|
||
param.Value = char(def.Default);
|
||
elseif isnumeric(def.Default)
|
||
param.Value = num2str(def.Default);
|
||
else
|
||
mcuMask.disp(0, 'Неизвестный формат значения параметра "%s".', paramName);
|
||
end
|
||
end
|
||
|
||
% Применение Prompt, если нужно
|
||
if isfield(def, 'Prompt')
|
||
param.Prompt = def.Prompt;
|
||
end
|
||
|
||
% Применение Alias, если есть
|
||
if isfield(def, 'Def') && ischar(def.Def)
|
||
param.Alias = def.Def;
|
||
end
|
||
|
||
% % Установка Row, если поддерживается
|
||
% if isfield(def, 'NewRow')
|
||
% try
|
||
% if def.NewRow
|
||
% param.DialogControl.Row = 'new';
|
||
% else
|
||
% param.DialogControl.Row = 'current';
|
||
% end
|
||
% catch
|
||
% % Некоторым типам параметров Row может быть неприменим
|
||
% end
|
||
% end
|
||
end
|
||
|
||
|
||
function result = ternary(cond, a, b)
|
||
if cond
|
||
result = a;
|
||
else
|
||
result = b;
|
||
end
|
||
end
|
||
|
||
end
|
||
|
||
end |