Все изменения накопившиеся с релиза

This commit is contained in:
2025-11-14 21:56:39 +03:00
parent ac2fe4d653
commit 9b8b5ec533
17 changed files with 1008 additions and 699 deletions

View File

@@ -1,12 +1,20 @@
classdef mainConfig
% Класс для экспорта и импорта конфигурации маски Simulink в JSON
% Позволяет сохранять и загружать настройки блока между сессиями
methods(Static)
function config = export()
% Экспортирует текущую конфигурацию маски в JSON файл
% Сохраняет параметры обёртки, портов и приложения
blockPath = gcb;
mask = Simulink.Mask.get(blockPath);
% Списки параметров для экспорта по категориям
wrapParamToExport = {'wrapperPath', 'enableDebug', 'mcuClk', ...
'threadCycles', 'enableThreading', 'enableDeinit'};
'threadCycles', 'enableThreading', 'enableDeinit', ...
'periphPath'};
portParamToExport = {'inNumb', ...
'in_port_1_name', 'in_port_1_width', ...
'in_port_2_name', 'in_port_2_width', ...
@@ -21,29 +29,32 @@ classdef mainConfig
'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' для форматирования
% Кодируем структуру в JSON с форматированием
jsonStr = jsonencode(config, 'PrettyPrint', true);
% Диалог сохранения файла
[file, path] = uiputfile('*.json', 'Сохранить конфигурацию как', 'WrapperConfig.json');
@@ -54,8 +65,6 @@ classdef mainConfig
filepath = fullfile(path, file);
% Сохраняем в файл
fid = fopen(filepath, 'w');
if fid == -1
@@ -66,8 +75,10 @@ classdef mainConfig
fclose(fid);
end
function import()
% Импортирует конфигурацию маски из JSON файла
% Восстанавливает параметры обёртки, портов и приложения
% Получаем путь к текущему блоку
blockPath = gcb;
mask = Simulink.Mask.get(blockPath);
@@ -103,18 +114,21 @@ classdef mainConfig
end
mcuMask.disp(0, 'Конфигурация успешно импортирована.');
% Обновляем периферию после импорта
mcuMask.periphUpdate();
end
end
methods(Static, Access=private)
function def = exportParamToConfig(mask, paramName)
% mask объект Simulink.Mask.get(blockPath)
% paramName имя параметра (как в mask.Parameters.Name)
% Экспортирует один параметр маски в структуру для JSON
% mask - объект маски Simulink
% paramName - имя параметра для экспорта
% Возвращает структуру с описанием параметра
param = mask.getParameter(paramName);
if isempty(param)
mcuMask.disp(0, 'Параметр "%s" не найден в маске.', paramName);
@@ -124,53 +138,50 @@ classdef mainConfig
def = struct();
% Prompt
% Сохраняем подпись параметра
def.Prompt = param.Prompt;
% Тип параметра
% Сохраняем тип параметра
def.Type = param.Type;
% Значение по умолчанию
% Сохраняем значение в зависимости от типа
val = param.Value;
switch lower(param.Type)
case 'checkbox'
% Для чекбоксов преобразуем 'on'/'off' в true/false
def.Default = strcmp(val, 'on');
case {'edit', 'spinbox'}
% Для числовых полей пробуем преобразовать в число
num = str2double(val);
if ~isnan(num)
def.Default = num;
else
def.Default = val;
def.Default = val; % Оставляем строкой если не число
end
case 'customtable'
def.Default = customtable.parse(param.Name); % или можно попытаться распарсить значение позже
% Для таблиц парсим содержимое в cell-массив
def.Default = customtable.parse(param.Name);
case 'text'
def.Default = ''; % или можно попытаться распарсить значение позже
% Для текстовых полей сохраняем пустую строку
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
% Получаем параметр
% Применяет параметр из конфигурации к маске
% mask - объект маски Simulink
% paramName - имя параметра для применения
% def - структура с данными параметра
% Получаем параметр из маски
param = mask.getParameter(paramName);
if isempty(param)
mcuMask.disp(0, 'Параметр "%s" не найден в маске.', paramName);
@@ -182,9 +193,10 @@ classdef mainConfig
return;
end
% Устанавливаем значение в зависимости от типа параметра
switch lower(def.Type)
case 'checkbox'
% Логическое значение true/false
% Устанавливаем состояние чекбокса
if islogical(def.Default)
param.Value = mainConfig.ternary(def.Default, 'on', 'off');
else
@@ -192,7 +204,7 @@ classdef mainConfig
end
case {'edit', 'spinbox'}
% Строка или число
% Устанавливаем значение для текстового поля
if isnumeric(def.Default)
param.Value = num2str(def.Default);
elseif ischar(def.Default) || isstring(def.Default)
@@ -202,7 +214,7 @@ classdef mainConfig
end
case 'customtable'
% Массив строк
% Загружаем данные в таблицу
if iscell(def.Default)
customtable.collect(paramName, def.Default);
else
@@ -210,7 +222,7 @@ classdef mainConfig
end
case 'text'
% Просто текстовая строка
% Устанавливаем текстовое значение
if ischar(def.Default) || isstring(def.Default)
param.Value = char(def.Default);
else
@@ -218,7 +230,7 @@ classdef mainConfig
end
case 'popup'
% popup установить значение, если оно есть в списке
% Устанавливаем значение выпадающего списка
if ischar(def.Default) && isfield(def, 'Def') && any(strcmp(def.Default, def.Def))
param.Value = def.Default;
else
@@ -226,7 +238,7 @@ classdef mainConfig
end
otherwise
% По умолчанию просто устанавливаем строковое значение
% Универсальная установка значения
if ischar(def.Default) || isstring(def.Default)
param.Value = char(def.Default);
elseif isnumeric(def.Default)
@@ -236,16 +248,16 @@ classdef mainConfig
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
@@ -260,8 +272,9 @@ classdef mainConfig
% end
end
function result = ternary(cond, a, b)
% Вспомогательная функция - тернарный оператор
% cond - условие, a - значение если true, b - значение если false
if cond
result = a;
else