На данный момент, я убрал из реализации RTCG всё, кроме базовой реализации обратных вызовов среды.
Т.е. у нас имеется main.cpp с минимальным функционалом:
main.cpp
#cpp
#include <QDebug>
#include "global.h"
#include "CGTShare.h"
PCodeGenTools cgt;
DLLEXPORT int buildPrepareProc(TBuildPrepareRec *params)
{
return CG_SUCCESS;
}
DLLEXPORT int buildProcessProc(TBuildProcessRec *params) {
cgt = params->cgt;
id_sdk sdk = params->sdk;
id_element e = NULL;
int countElements = cgt->sdkGetCount(sdk);
for(int i = 0; i < countElements; ++i)
{
e = cgt->sdkGetElement(sdk, i);
qDebug() << cgt->elGetClassName(e);
}
return CG_SUCCESS;
}
DLLEXPORT int CheckVersionProc(THiAsmVersion *params)
{
//if ((params->major >= 3) && (params->minor >= 63) && (params->build >= 162))
//return CG_SUCCESS;
return CG_SUCCESS;
}
global.h - с служебными объявлениями:
global.h
#cpp
#ifndef GLOBAL_H
#define GLOBAL_H
#ifdef BUILDING_DLL
#define DLLEXPORT extern "C" __declspec(dllexport)
#else
#define DLLEXPORT extern "C"
#endif
#endif // GLOBAL_H
Тут у нас объявлены все прототипы функций обратного вызова и структуры, для взаимодействия со средой.
Я тут чутка поправил форматирование кода
CGTShare.h
#cpp
#ifndef _CGTSHARE_H_
#define _CGTSHARE_H_
#include "share.h"
#ifdef BUILDING_DLL
#ifndef HIASM_5
#define ELEMENT_FLG_IS_SELECT0x100
#define ELEMENT_FLG_IS_NOMOUSE0x2000
#define ELEMENT_FLG_IS_PARENT0x200
#define ELEMENT_FLG_IS_CORE0x400
#define ELEMENT_FLG_IS_FREEZE0x0
#define ELEMENT_FLG_IS_NODELETE0x2
#define ELEMENT_FLG_IS_MULTI0x40
#define ELEMENT_FLG_ONE_WIDGET0x1
#define ELEMENT_FLG_IS_EDIT 0x20
#define ELEMENT_FLG_IS_SYSTEM0x400
#else
#define ELEMENT_FLG_IS_SELECT0x01
#define ELEMENT_FLG_IS_NOMOUSE0x02
#define ELEMENT_FLG_IS_PARENT0x04
#define ELEMENT_FLG_IS_CORE0x08
#define ELEMENT_FLG_IS_FREEZE0x10
#define ELEMENT_FLG_IS_NODELETE0x20
#define ELEMENT_FLG_IS_MULTI0x40
#define ELEMENT_FLG_ONE_WIDGET0x80
#define ELEMENT_FLG_IS_EDIT 0x100
#define ELEMENT_FLG_IS_SYSTEM0x400
#endif
#else
#define ELEMENT_FLG_IS_SELECT0x01
#define ELEMENT_FLG_IS_NOMOUSE0x02
#define ELEMENT_FLG_IS_PARENT0x04
#define ELEMENT_FLG_IS_CORE0x08
#define ELEMENT_FLG_IS_FREEZE0x10
#define ELEMENT_FLG_IS_NODELETE0x20
#define ELEMENT_FLG_ONE_WIDGET0x80
#define ELEMENT_FLG_IS_SYSTEM0x400
#endif
#define pt_Work 1
#define pt_Event 2
#define pt_Var 3
#define pt_Data 4
#define data_null 0
#define data_int 1
#define data_str 2
#define data_data 3
#define data_combo 4
#define data_list 5
#define data_icon 6
#define data_real 7
#define data_color 8
#define data_script 9
#define data_stream 10
#define data_bitmap 11
#define data_wave 12
#define data_array 13
#define data_comboEx 14
#define data_font 15
#define data_matr 16
#define data_jpeg 17
#define data_menu 18
#define data_code 19
#define data_element 20
#define data_flags 21
// // классы элемента (elGetClassIndex)
#define CI_DPElement 1
#define CI_MultiElement 2
#define CI_EditMulti 3
#define CI_EditMultiEx 4
#define CI_InlineCode 5
#define CI_DrawElement 6
#define CI_AS_Special 7
#define CI_DPLElement 8
#define CI_UseHiDLL 9
#define CI_WinElement 10
#define CI_PointHint 11
#define CI_PointElement 12
#define CI_LineBreak 13
#define CI_LineBreakEx 14
#define CI_UserElement 15
// имена типов св-тв элемента
//extern char *DataNames[];
// индексы параметров среды
#define PARAM_CODE_PATH 0
#define PARAM_DEBUG_MODE 1
#define PARAM_DEBUG_SERVER_PORT 2
#define PARAM_DEBUG_CLIENT_PORT 3
#define PARAM_PROJECT_PATH 4
#define PARAM_HIASM_VERSION 5
#define PARAM_USER_NAME 6
#define PARAM_USER_MAIL 7
#define PARAM_PROJECT_NAME 8
#define PARAM_SDE_WIDTH 9
#define PARAM_SDE_HEIGHT 10
#define PARAM_COMPILER 11
// ошибки при работе с библиотекой кодогенератора
#define CG_SUCCESS 0
#define CG_NOT_FOUND 1 // кодогенератор не найден
#define CG_INVALID_VERSION 2 // эта версия HiAsm требует более позднюю версию кодогенератора
#define CG_ENTRY_POINT_NF 3 // точка входа в кодогенератор не найдена
#define CG_MODULE_FILE_NF 4 // файл модуля кода не найден
// ошибки при компиляции проекта
#define CG_BUILD_FAILED 10 // общая ошибка при сборке проекта
// ошибки на этапе обработки результата компиляции
#define CG_APP_NOT_FOUND 20 // результат компиляции не найден
// параметры проекта
#define CGMP_COMPRESSED 0x01 // поддерживает сжатие
#define CGMP_RUN 0x02 // поддерживает запуск из среды
#define CGMP_RUN_DEBUG 0x04 // поддерживает запуск из среды в отладочном режиме
#define CGMP_FORM_EDIT 0x08 // внешний редактор форм
typedef void* id_sdk;
typedef void* id_element;
typedef void* id_point;
typedef void* id_prop;
typedef void* id_array;
typedef void* id_data;
typedef void* id_font;
typedef void* id_proplist;
struct TCodeGenTools;
typedef TCodeGenTools *PCodeGenTools;
// CodeGen types and entry point interfaces
typedef struct{
short int major;
short int minor;
short int build;
} THiAsmVersion;
typedef struct {
// none
} TBuildPrepareRec;
typedef struct {
PCodeGenTools cgt;
id_sdk sdk;
void *result;
} TBuildProcessRec;
typedef struct {
void *result;
char *prjFilename;
char *compiler;
} TBuildMakePrjRec;
typedef struct {
char *prjFilename;
char *appFilename;
} TBuildCompliteRec;
typedef struct {
int flags;
} TBuildParams;
typedef struct {
char *FileName;
int Mode;
int ServerPort;
int ClientPort;
void *data;
} TBuildRunRec;
#define stdcall __stdcall
struct TCodeGenTools {
//!~~~~~~~~~~~~~~~~~~~~~~~~ SDK ~~~~~~~~~~~~~~~~~~~~~~~~~~
//возвращает количество элементов в схеме
stdcall int (*sdkGetCount)(id_sdk SDK);
//возвращает идент элемента по его Z-координате(индексу)
stdcall id_element (*sdkGetElement)(id_sdk SDK, int Index);
//возвращает идент элемента по имени его класса
stdcall id_element (*sdkGetElementName)(id_sdk SDK, char *Name);
//!~~~~~~~~~~~~~~~~~~~~~~~~ Element ~~~~~~~~~~~~~~~~~~~~~~~~~~
//возвращает "хитрые" особенности элемента по его иденту
stdcall int (*elGetFlag)(id_element e);
//возвращает кол-во св-в элемента
stdcall int (*elGetPropCount)(id_element e);
//возвращает целую структуру для конкретного св-ва с порядковым номером из INI
stdcall id_prop (*elGetProperty)(id_element e, int Index);
//возвращает True, если значение св-ва совпадает с заданным в INI файле, иначе False
stdcall bool (*elIsDefProp)(id_element e, int Index);
//даем элементу свое любимое(уникальное) имя
stdcall id_element (*elSetCodeName)(id_element e, char *Name);
//и получаем его обратно (если забыли)
stdcall char* (*elGetCodeName)(id_element e);
//а вот имя класса не мы давали - можем только узнать
stdcall char* (*elGetClassName)(id_element e);
//просто содержимое поля Sub из INI-файла элемента
stdcall char* (*elGetInfSub)(id_element e);
//получаем количество точек у элемента
stdcall int (*elGetPtCount)(id_element e);
//получаем идент точки по её индексу
stdcall id_point (*elGetPt)(id_element e, int i);
//получаем идент точки по её имени
stdcall id_point (*elGetPtName)(id_element e, const char *Name);
//получаем подкласс элемента(константы типа CI_ХХХ)
stdcall unsigned char (*elGetClassIndex)(id_element e);
//получаем идент внутренней схемы для контейнеров и идент родителя(id_element) для редактора контейнера
stdcall id_sdk (*elGetSDK)(id_element e);
//возвращает True, если данный элемент является ссылкой либо на него ссылаются
stdcall bool (*elLinkIs)(id_element e);
//возвращает идент главного элемента(тот, на который ссылаются другие)
stdcall id_element (*elLinkMain)(id_element e);
//возвращает позицию элемента в редакторе схем
stdcall void (*elGetPos)(id_element e, int &X, int &Y);
//возвращает размеры элемента в редакторе схем
stdcall void (*elGetSize)(id_element e, int &W, int &H);
//??
stdcall int (*elGetEID)(id_element e);
//!~~~~~~~~~~~~~~~~~~~~~~~~ Point ~~~~~~~~~~~~~~~~~~~~~~~~~~
//возвращает идент точки, с которой соеденена данная
stdcall id_point (*ptGetLinkPoint)(id_point p);
//возвращает идент точки, с которой соеденена данная без учета точек разрыва и хабов
stdcall id_point (*ptGetRLinkPoint)(id_point p);
//возвращает тип точек(константы pt_XXX)
stdcall int (*ptGetType)(id_point p);
//возвращает имя точки
stdcall char* (*ptGetName)(id_point p);
//возвращает идент элемента, которому принадлежит точка
stdcall id_element (*ptGetParent)(id_point p);
//возвращает относительный индекс точки по принадлежности к одной из 4х групп
stdcall int (*ptGetIndex)(id_point p);
//возвращает базовую часть имени динамических точек(для CI_DPElement)
stdcall char* (*pt_dpeGetName)(id_point p);
//!~~~~~~~~~~~~~~~~~~~~~~~~ Property ~~~~~~~~~~~~~~~~~~~~~~~~~~
//возвращает тип параметра
stdcall int (*propGetType)(id_prop prop);
//возвращает имя параметра
stdcall char* (*propGetName)(id_prop prop);
//возвращает значение параметра
stdcall void* (*propGetValue)(id_prop prop);
//
stdcall unsigned char (*propToByte)(id_prop prop);
//
stdcall int (*propToInteger)(id_prop prop);
//
stdcall float (*propToReal)(id_prop prop);
//
stdcall char* (*propToString)(id_prop prop);
//!~~~~~~~~~~~~~~~~~~~~~~~~ Res ~~~~~~~~~~~~~~~~~~~~~~~~~~
//добавляет имя файла в общий список временных файлов для последующего удаления
stdcall int (*resAddFile)(const char *Name);
//добавляет иконку в ресурсы и в список временных файлов
stdcall char* (*resAddIcon)(id_prop p);
//добавляет строку в ресурсы и в список временных файлов
stdcall char* (*resAddStr)(const char *p);
//добавляет поток в ресурсы и в список временных файлов
stdcall char* (*resAddStream)(id_prop p);
//добавляет звук в ресурсы и в список временных файлов
stdcall char* (*resAddWave)(id_prop p);
//добавляет картинку в ресурсы и в список временных файлов
stdcall char* (*resAddBitmap)(id_prop p);
//добавляет меню в ресурсы и в список временных файлов
stdcall char* (*resAddMenu)(id_prop p);
//!~~~~~~~~~~~~~~~~~~~~~~~~ Other ~~~~~~~~~~~~~~~~~~~~~~~~~~
//выводит строку Text в окно Отладка цветом Color
stdcall int (*_Debug)(const char *Text, int Color);
//возвращает значение параметра среды по его индексу
stdcall int (*GetParam)(short int index, void *value);
//~~~~~~~~~~~~~~~~~~~~~~~~ Arrays ~~~~~~~~~~~~~~~~~~~~~~~~~~
//возвращает кол-во элементов в массиве а
stdcall int (*arrCount)(id_array a);
//возвращает тип элементов в массиве а
stdcall int (*arrType)(id_array a);
//возвращает имя элемента с индексом Index
stdcall char* (*arrItemName)(id_array a, int Index);
//возвращает значение элемента с индексом Index
stdcall void* (*arrItemData)(id_array a, int Index);
//
stdcall id_prop (*arrGetItem)(id_array a, int Index);
//
stdcall bool (*isDebug)(id_sdk e);
//!~~~~~~~~~~~~~~~~~~~~~~~~ Data ~~~~~~~~~~~~~~~~~~~~~~~~~~
stdcall unsigned char (*dtType)(id_data d);
stdcall char* (*dtStr)(id_data d);
stdcall int (*dtInt)(id_data d);
stdcall double (*dtReal)(id_data d);
//!~~~~~~~~~~~~~~~~~~~~~~~~ Font ~~~~~~~~~~~~~~~~~~~~~~~~~~
stdcall char* (*fntName)(id_font f);
stdcall int (*fntSize)(id_font f);
stdcall unsigned char (*fntStyle)(id_font f);
stdcall int (*fntColor)(id_font f);
stdcall unsigned char (*fntCharSet)(id_font f);
//!~~~~~~~~~~~~~~~~~~~~~~~~ Element ~~~~~~~~~~~~~~~~~~~~~~~~~~
// получает пользовательские данные элемента
stdcall void* (*elGetData)(id_element e);
// устанавливает пользовательские данные элемента
stdcall void (*elSetData)(id_element e, void *data);
//!~~~~~~~~~~~~~~~~~~~~~~~~ Point ~~~~~~~~~~~~~~~~~~~~~~~~~~
// возвращает тип данных точки
stdcall int (*ptGetDataType)(id_point p);
//!~~~~~~~~~~~~~~~~~~~~~~~~ Element ~~~~~~~~~~~~~~~~~~~~~~~~~~
// возвращает родителя
stdcall id_sdk (*elGetParent)(id_element e);
// возвращает количество элементов в списке св-тв(из панели св-ва)
stdcall int (*elGetPropertyListCount)(id_element e);
// возвращает элемент списка св-тв
stdcall id_proplist (*elGetPropertyListItem)(id_element e, int i);
//!~~~~~~~~~~~~~~~~~~~~~~~~ PropertyList ~~~~~~~~~~~~~~~~~~~~~~~~~~
// возвращает имя св-ва
stdcall char* (*plGetName)(id_proplist p);
// возвращает описание св-ва
stdcall char* (*plGetInfo)(id_proplist p);
// возвращает группу св-ва
stdcall char* (*plGetGroup)(id_proplist p);
// возвращает значение св-ва
stdcall id_prop (*plGetProperty)(id_proplist p);
// возвращает родительский элемент даного св-ва
stdcall id_element (*plGetOwner)(id_proplist p);
//!~~~~~~~~~~~~~~~~~~~~~~~~ Point ~~~~~~~~~~~~~~~~~~~~~~~~~~
// Возвращает описание точки
stdcall char* (*ptGetInfo)(id_point p);
//~~~~~~~~~~~~~~~~~~~~~~~~ Property ~~~~~~~~~~~~~~~~~~~~~~~~~~
// Возвращает id элемента, прилинкованного к указанному св-ву
stdcall id_element (*propGetLinkedElement)(id_element e, const char *propName);
// Возвращает 1 если св-во помечено на перевод
stdcall int (*propIsTranslate)(id_element e, id_prop p);
stdcall id_element (*propGetLinkedElementInfo)(id_element e, id_prop prop, const char *_int);
//!~~~~~~~~~~~~~~~~~~~~~~~~ Element ~~~~~~~~~~~~~~~~~~~~~~~~~~
// Возвращает SDK полиморфного контейнера по его индексу
stdcall id_sdk (*elGetSDKByIndex)(id_element e, int index);
// Возвращает количаство сабклассов полиморфного контейнера
stdcall int (*elGetSDKCount)(id_element e);
stdcall char* (*elGetSDKName)(id_element e, int index);
//!~~~~~~~~~~~~~~~~~~~~~~~~ SDK ~~~~~~~~~~~~~~~~~~~~~~~~~~
// Возвращает элемент родитель для данного SDK
stdcall id_element (*sdkGetParent)(id_sdk SDK);
//!~~~~~~~~~~~~~~~~~~~~~~~~ Element ~~~~~~~~~~~~~~~~~~~~~~~~~~
// Возвращает интерфейсы, предоставляемые элементом
stdcall char* (*elGetInterface)(id_element e);
// Возвращает классы, от которых наследуется элемент
stdcall char* (*elGetInherit)(id_element e);
//!~~~~~~~~~~~~~~~~~~~~~~~~ Resource ~~~~~~~~~~~~~~~~~~~~~~~~~~
// Возвращает 1 если список ресурсов пуст, и 0 в противном случае
stdcall int (*resEmpty)();
// Устанавливает префикс для имен ресурсов
stdcall int (*resSetPref)(const char *pref);
//!~~~~~~~~~~~~~~~~~~~~~~~~ SDE ~~~~~~~~~~~~~~~~~~~~~~~~~~
// Добавляет информацию в панель ошибок
stdcall int (*_Error)(int line, id_element e, const char *text);
//!~~~~~~~~~~~~~~~~~~~~~~~~ Element ~~~~~~~~~~~~~~~~~~~~~~~~~~
// возвращает ID группы, к которой принадлежит элемент и 0 если группа отсутствует
stdcall int (*elGetGroup)(id_element e);
//!~~~~~~~~~~~~~~~~~~~~~~~~ Property ~~~~~~~~~~~~~~~~~~~~~~~~~~
stdcall int (*propSaveToFile)(id_prop p, const char *fileName);
#ifdef MSDK
//~~~~~~~~~~~~~~~~~~~~~~~~ Element ~~~~~~~~~~~~~~~~~~~~~~~~~~
stdcall id_prop (*elGetPropertyName)(id_element e, const char *name);
stdcall bool (*elIsDefProperty)(id_element e, id_prop p);
#endif
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// пользовательские ф-ции, не входящие в интерфейс
int ReadIntParam(int Index) {
int i = 0;
GetParam(Index, &i);
return i;
}
char *ReadStrParam(int Index, id_element e = NULL) {
char *c;
c = new char[256];
*((id_element*)c) = e;
GetParam(Index, c);
return c;
}
//------------------------- DEBUG TOOLS ----------------------
id_point getPointByType(id_element e, int type, int index) {
int c = 0;
for(int i = 0; i < elGetPtCount(e); i++) {
id_point point = elGetPt(e, i);
if(ptGetType(point) == type) {
if(c == index)
return point;
c++;
}
}
return NULL;
}
id_prop getPropByName(id_element e, const char *name) {
#ifdef MSDK
return elGetPropertyName(e, name);
#else
for(int i = 0; i < elGetPropCount(e); i++) {
id_prop p = elGetProperty(e, i);
if(strcasecmp(name, propGetName(p)) == 0)
return p;
}
return NULL;
#endif
}
bool isDefProp(id_element e, id_prop p) {
#ifdef MSDK
return elIsDefProperty(e, p);
#else
for(int i = 0; i < elGetPropCount(e); i++) {
if(elGetProperty(e, i) == p) {
if(propGetType(p) == data_array) {
if(arrCount((id_array)propGetValue(p)))
return false;
else
return true;
}
return elIsDefProp(e, i);
}
}
return false;
#endif
}
};
typedef struct {
char *elName; // имя текущего элемента
char *objName; // имя объекта
char *inst_list; // список методов и полей для вставки в редактор
char *disp_list; // список, отображаемый во всплывающей подсказке
} TSynParams;
typedef struct {
id_point point;
id_sdk sdk;
PCodeGenTools cgt;
char *hint;
} THintParams;
#endif
Всё.
На основе данного базового функционала, можно разработать свой кодогенератор иили выгрузить всю схему в файл для дальнейшей обработки
У меня же в планах, в течении неделидвух, реализовать выгрузку всей схемы в файл (для начала), который можно будет использовать для генерации кода используя свой инструмент.
К сообщению прикрепил архив с минимальным проектом на Qt, но его без усилий можно перенести на любой фреймворк, или чистый C++.
------------ Дoбавленo в 03.09:
Выделю пару дней, и попробую добавить поддержку пакета Windows в CGTShare, для полного комплекта, так сказать
------------ Дoбавленo в 04.48:
Ну что же, C++ реализация интерфейса (CGTShare) HiAsm 4, позволяет работать с любым пакетом, при условии, что make файл, будет немного изменён под наши нужды
А значит, в теории, мы сможем перенести все пакеты.