124 lines
6.5 KiB
Matlab
124 lines
6.5 KiB
Matlab
classdef asynchManage < handle
|
||
% Менеджер асинхронных операций для работы с моделью Simulink
|
||
% Решает проблемы блокировки модели при одновременном доступе из GUI
|
||
% Использует таймеры для отложенного выполнения операций с моделью
|
||
|
||
properties (Access = private)
|
||
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 = ''; % Если не передали - работаем без GUI
|
||
else
|
||
obj.maskBlockPath = maskBlockPath;
|
||
end
|
||
end
|
||
|
||
function saveAndUpdateModel(obj)
|
||
% Асинхронное сохранение и обновление модели
|
||
% Использует таймер чтобы избежать конфликтов доступа к модели
|
||
obj.timerSave = timer(...
|
||
'StartDelay', 0.01, ... % Короткая задержка чтобы освободить модель
|
||
'ExecutionMode', 'singleShot', ... % Однократное выполнение
|
||
'TimerFcn', @(~,~) obj.saveCallback()); % Колбэк сохранения
|
||
start(obj.timerSave);
|
||
end
|
||
|
||
function updateGUIfromConfig(obj)
|
||
% Асинхронное обновление GUI из конфигурации
|
||
% Используется когда нужно перезагрузить маску с новыми параметрами
|
||
obj.timerConfigUpdate = timer(...
|
||
'StartDelay', 0.01, ... % Задержка для стабилизации модели
|
||
'ExecutionMode', 'singleShot', ...
|
||
'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, ... % Большая задержка для полного сохранения
|
||
'ExecutionMode', 'singleShot', ...
|
||
'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); % Открываем маску снова
|
||
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); % Функция настройки/компиляции
|
||
catch ME
|
||
warning('progr:Nneg', 'Ошибка при обновлении модели: %s', ME.message);
|
||
end
|
||
|
||
% Переоткрываем маску с обновленными параметрами
|
||
if ~isempty(obj.maskBlockPath)
|
||
try
|
||
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 |