Вверх ↑
Ответов: 1841
Рейтинг: 369
#1: 2014-12-09 04:48:08 ЛС | профиль | цитата
С сегодняшнего дня, начинаю полную переработку механизма взаимодействия среды и кодогенератора.
На данный момент, я убрал из реализации 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
Тут у нас объявлены все прототипы функций обратного вызова и структуры, для взаимодействия со средой.
Я тут чутка поправил форматирование кода
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 файл, будет немного изменён под наши нужды
А значит, в теории, мы сможем перенести все пакеты.
карма: 1
0
файлы: 1rtcg_win_fork.7z [4.9KB] [307]