Алгоритмический Модуль является компонентой программного комплекса "Universal Spectrometer". Он отвечает за логику проводимого эксперимента.
В реализации данного модуля отсутствует функционал представления данных - этим занимается Управляющая Программа. Так же, разработка модуля не обременяет программиста реализацией функций взаимодействия с КАМАК. Эти функции вынесены в отдельную, заменяемую в зависимости от установленного драйвера КАМАК, компоненту под названием Интерфейсный Модуль. В Алгоритмическом Модуле достаточно лишь использовать названия функций.
Таким образом, реализуя Алгоритмический Модуль, вы можете сконцентрироваться исключительно на схеме проведения эксперимента.
Реализация Алгоритмического Модуля заключается в реализации методов абстрактного класса CAbstractExperiment. Помимо этого рекомендуется разработать и включить в модуль диалоговое окно установки начальных параметров, которое по идеологии вызывается функцией CAbstractExperiment::expSetupParameters.
Итогом разработки модуля является DLL (Dynamic Link Library), реализованная с поддержкой MFC в динамических библиотеках.
Так же, в целях распределенности выполнения задач, рекомендуется реализовывать функцию исполнения эксперимента CAbstractExperiment::expStartExperiment через работу с нитями процесса.
Не забудьте, что все функции необходимо объявить с методом вызова "__stdcall", а так же каждую функцию следует указать в *.def-файле в разделе EXPORTS.
class CAbstractExperiment {
public:
virtual void expInitExperiment(CWnd *Owner) = 0;
virtual char expChannelCount() = 0;
virtual char *expExperimentName() = 0;
virtual char *expExperimentDescription() = 0;
virtual void expSetupParameters(CWnd *Owner) = 0;
virtual void *expGetChannelInfo(char ChannelNum) = 0;
virtual void *expGetTimeChannelInfo() = 0;
virtual double expGetChannelData(char ChannelNum) = 0;
virtual double expGetChannelDataFromStack(char ChannelNum, int ElementNum) = 0;
virtual int expGetParamBufferSize() = 0;
virtual int expGetStackSize() = 0;
virtual void *expGetParamBuffer() = 0;
virtual void expSetParamBuffer(void *Buffer) = 0;
virtual bool expGetStackState() = 0;
virtual void expSetStackState(bool StackState) = 0;
virtual void expStartExperiment(char StartResume) = 0;
virtual void expPauseExperiment() = 0;
virtual void expBreakExperiment() = 0;
virtual int expGetExpState() = 0;
virtual bool expLoadCAMAC(CString Filename) = 0;
};
Прототип:
void expInitExperiment(CWnd *Owner);
В функции определяется число каналов данных, и заполняются их инициализирующие значения. Канал данных представляет собой следующую структуру:
struct ChannelInfo{
char *Name;
char *ShortName;
BOOL IsMain;
CDoublePoint Limits;
};
где Name -- название канала (будет отражено на графике и в файле данных)
ShortName -- короткое название канала (для отображения на панели данных)
IsMain -- планируется ли этот график отображать на оси абсцисс
Limits.p_begin -- нижний базовый предел диапазона значений канала
Limits.p_end -- верхний базовый предел диапазона значений канала
Так же обратите внимание, что функция получает в качестве параметра указатель на родительское окно (окно управляющей программы). Это может вам понадобиться в случае создания и вызова собственного окна начальных параметров.
Прототип:
char expChannelCount();
Функция возвращает общее количество каналов данных, контролируемых данным модулем.
Прототип:
char* expExperimentName();
Функция возвращает строку с названием эксперимента.
Прототип:
char* expExperimentDescription();
Функция возвращает строку с кратким описанием сути данного эксперимента.
Прототип:
void expSetupParameters(CWnd *Owner);
Функция предназначена для установки начальных параметров эксперимента. Для этого рекомендуется реализовать собственное диалоговое окно и вызывать его из данной функции.
Не забудьте, что DLL и Управляющая Программа имеют разные источники ресурсов, следовательно перед вызовом своего окна в DLL следует изменить источник ресурсов. Обратная смена происходит автоматически по окончанию работы функции. Выглядит это примерно так:
AFX_MANAGE_STATE(AfxGetStaticModuleState( ))
CParamDialog ParDlg(MAKEINTRESOURCE(IDD_SETUP_PARAM_DLG), Owner);
ParDlg.DoModal();
Прототип:
void* expGetChannelInfo(char ChannelNum);
Функция возвращает указатель на структуру ChannelInfo для запрошенного номера канала.
Прототип:
void* expGetTimeChannelInfo();
Функция предназначена для расчета времени проведения эксперимента. Возвращает указатель на структуру TimeChannelInfo, которая выглядит следующим образом:
struct TimeChannelInfo{
CDoublePoint Limits;
double Move;
double ScanCount;
};
где Limits -- границы основного спектрального диапазона,
Move -- шаг, через который производится очередное измерение
ScanCount -- число проходов по спектральному диапазону
Прототип:
double expGetChannelData(char ChannelNum);
Возвращает последнее значение, положенное в стек по каналу ChannelNum.
Прототип:
double expGetChannelDataFromStack(char ChannelNum, int ElementNum);
Функция возвращает значение элемента стека под номером ElementNum по каналу ChannelNum. Не забываем, что нумерация элементов стека, как и нумерация каналов, идет с нуля.
Прототип:
int expGetParamBufferSize();
Функция возвращает размер структуры, содержащей параметры эксперимента.
Прототип:
int expGetStackSize();
Функция возвращает текущий размер стека.
Прототип:
void* expGetParamBuffer();
Функция возвращает указатель на начало структуры параметров эксперимента. Размер структуры определяется функцией GetParamBufferSize(). Функция предназначена для того, чтобы Управляющая Программа имела возможность сохранить параметры в конфигурационный файл.
Прототип:
void expSetParamBuffer(void *Buffer);
Функция, которая позволяет Управляющей Программе установить параметры эксперимента, подгруженные из конфигурационного файла.
В качестве параметра передает указатель на структуру, определяемую вами, как структуру по хранению параметров эксперимента.
Прототип:
bool expGetStackState();
Функция возвращает состояние стека. Состояний может быть два: true -- в стеке появились новые данные, false -- в стеке нет новых данных.
Прототип:
void expSetStackState(bool StackState);
Функция предназначена для управления переменной состояния стека из Управляющей Программы. Постоянно анализируя значение переменной, Управляющая Программа ожидает момента, когда в стек поступит новая информация. Как только это происходит, она их отображает и сохраняет в файл, а затем при помощи вызова этой функции возвращает значение стековой переменной в исходное состояние.
По идеологии, новые данные вам следует ложить в стек только при условии, что в стеке нет новых данных, то есть что все имеющиеся в стеке данные уже известны Управляющей Программе.
Прототип:
void expStartExperiment(char StartResume);
Функция, выполняющаяся по команде "Начать эксперимент" в интерфейсе Управляющей Программы. Параметр StartResume определяет смысл команды. Если он равен нулю, значит, начинается новый эксперимент, а в противном случае эксперимент был приостановлен и данный вызов функции означает отмену паузы.
Перед началом нового эксперимента не забудьте обнулить стек, и реинициализировать все необходимые переменные.
Прототип:
void expPauseExperiment();
Вызов данной функции означает желание пользователя сделать паузу в проведении эксперимента.
Прототип:
void expBreakExperiment();
Функция, прерывающая выполнение эксперимента. Не забудьте при этом перевести переменную состояния эксперимента в значение 0.
Прототип:
int expGetExpState();
Функция возвращает текущее состояние эксперимента. Функция регулярно вызывается Управляющей Программой, поэтому рекомендуется флаговую переменную выставлять своевременно.
Различается 3 варианта состояний:
0 -- Эксперимент не запущен
1 -- Эксперимент выполняется
2 -- Эксперимент закончил очередной проход по спектру и выходит на стартовую позицию для нового прохода.
Несмотря на то, что состояние 2 может быть минимальным по времени, оно должно присутствовать, чтобы Управляющая Программа смогла отсечь в стеке разные спектры. В случае быстрой смены состояния 2 на 1 рекомендуется воспользоваться принудительной заглушкой Sleep(100);
По окончанию проведения эксперимента так же не забудьте перевести переменную состояния эксперимента в ноль.
Прототип:
bool expLoadCAMAC(CString Filename);
Функция подгружает реализацию методов Интерфейсного Модуля из DLL с именем Filename.
Функция возвращает true в случае, если все методы Интерфейсного Модуля были подгружены успешно, в противном случае возвращает false и Управляющая Программа выдает соответствующее сообщение об ошибке.
|