Все изменения накопившиеся с релиза
This commit is contained in:
@@ -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
|
||||
Reference in New Issue
Block a user