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

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,103 +1,124 @@
classdef asynchManage < handle
% Менеджер асинхронных операций для работы с моделью Simulink
% Решает проблемы блокировки модели при одновременном доступе из GUI
% Использует таймеры для отложенного выполнения операций с моделью
properties (Access = private)
modelName % Имя модели
maskBlockPath % Полный путь к блоку с маской
timerSave
timerUpdate
timerConfigUpdate
modelName % Имя модели Simulink для управления
maskBlockPath % Полный путь к блоку с маской (если нужен доступ к GUI)
timerSave % Таймер для операции сохранения модели
timerUpdate % Таймер для операции обновления модели
timerConfigUpdate % Таймер для обновления конфигурации
end
methods
function obj = asynchManage(modelName, maskBlockPath)
% Конструктор принимает имя модели и путь к блоку с маской
% Конструктор - создает менеджер для асинхронных операций
% modelName - имя модели Simulink для управления
% maskBlockPath - путь к блоку с маской (опционально, для GUI)
obj.modelName = modelName;
if nargin < 2
obj.maskBlockPath = ''; % если не передали, оставляем пустым
obj.maskBlockPath = ''; % Если не передали - работаем без GUI
else
obj.maskBlockPath = maskBlockPath;
end
end
function saveAndUpdateModel(obj)
% Асинхронное сохранение и обновление модели
% Использует таймер чтобы избежать конфликтов доступа к модели
obj.timerSave = timer(...
'StartDelay', 0.01, ...
'ExecutionMode', 'singleShot', ...
'TimerFcn', @(~,~) obj.saveCallback());
'StartDelay', 0.01, ... % Короткая задержка чтобы освободить модель
'ExecutionMode', 'singleShot', ... % Однократное выполнение
'TimerFcn', @(~,~) obj.saveCallback()); % Колбэк сохранения
start(obj.timerSave);
end
function updateGUIfromConfig(obj)
% Асинхронное обновление GUI из конфигурации
% Используется когда нужно перезагрузить маску с новыми параметрами
obj.timerConfigUpdate = timer(...
'StartDelay', 0.01, ...
'StartDelay', 0.01, ... % Задержка для стабилизации модели
'ExecutionMode', 'singleShot', ...
'TimerFcn', @(~,~) obj.GUIconfigCallback());
'TimerFcn', @(~,~) obj.GUIconfigCallback()); % Колбэк обновления GUI
start(obj.timerConfigUpdate);
end
end
methods (Access = private)
function saveCallback(obj)
% Колбэк для сохранения модели - вызывается через таймер
try
% Закрываем маску чтобы разблокировать модель для сохранения
mcuMask.close(obj.maskBlockPath);
% Сохраняем модель (это могло бы вызвать конфликт без таймера)
save_system(obj.modelName);
catch ME
warning('progr:Nneg', 'Ошибка при сохранении модели: %s', ME.message);
end
% Очищаем таймер сохранения
stop(obj.timerSave);
delete(obj.timerSave);
obj.timerSave = [];
% Запускаем таймер для обновления модели после сохранения
obj.timerUpdate = timer(...
'StartDelay', 0.05, ...
'StartDelay', 0.05, ... % Большая задержка для полного сохранения
'ExecutionMode', 'singleShot', ...
'TimerFcn', @(~,~) obj.updateCallback());
'TimerFcn', @(~,~) obj.updateCallback()); % Колбэк обновления
start(obj.timerUpdate);
end
function updateCallback(obj)
% Колбэк для обновления модели - вызывается после сохранения
try
% Команда обновления модели (перекомпиляция и т.д.)
set_param(obj.modelName, 'SimulationCommand', 'update');
% Повторное сохранение после обновления
save_system(obj.modelName);
catch ME
warning('progr:Nneg', 'Ошибка при обновлении модели: %s', ME.message);
end
% Открываем маску, если задан путь к блоку
% Переоткрываем маску если был указан путь к блоку
if ~isempty(obj.maskBlockPath)
try
mcuMask.open(obj.maskBlockPath, 1);
mcuMask.open(obj.maskBlockPath, 1); % Открываем маску снова
catch ME
warning('progr:Nneg', 'Не удалось открыть маску: %s', ME.message);
end
end
% Очищаем таймер обновления
stop(obj.timerUpdate);
delete(obj.timerUpdate);
obj.timerUpdate = [];
end
function GUIconfigCallback(obj)
% Колбэк для обновления GUI из конфигурации
try
% Закрываем маску и выполняем настройку (mexing)
mcuMask.close(obj.maskBlockPath);
mexing(0);
mexing(0); % Функция настройки/компиляции
catch ME
warning('progr:Nneg', 'Ошибка при обновлении модели: %s', ME.message);
end
% Открываем маску, если задан путь к блоку
% Переоткрываем маску с обновленными параметрами
if ~isempty(obj.maskBlockPath)
try
mcuMask.open(obj.maskBlockPath, 1);
mcuMask.open(obj.maskBlockPath, 1); % Открываем обновленную маску
catch ME
warning('progr:Nneg', 'Не удалось открыть маску: %s', ME.message);
end
end
% Очищаем таймер обновления конфигурации
stop(obj.timerConfigUpdate);
delete(obj.timerConfigUpdate);
obj.timerConfigUpdate = [];
end
end
end
end