mcu_matlab/McuLib/m/mainConfig.m
2025-06-19 13:29:33 +03:00

274 lines
11 KiB
Matlab
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

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