Работаю в рамках vjass. Хотел бы понять, можно ли в структуре или вне структуры дополнить тип данных unit методами, Например, я хочу подвинуть юнита, обычно мы пишем
call SetUnitPosition(unit, X, Y)
А я бы хотел некую структуру, чтобы можно было писать
call unit.SetUnitPosition(X, Y)
В этом такая проблема , что если создать супер структуру UNIT
struct UNIT
unit un
endstruct
То по сути это будет int и следующий код будет ошибкой
local unit loc_un = GetSomeUnit()
local UNIT loc_UN = UNIT.create(loc_un)
set un = loc_UN
вообще можно переопределить оператор [] и тогда можно ссылаться на что-то, но можно ли создать некий "немой" оператор , что бы при обращении к структуре UNIT возвращался именно тип unit, что записан у него в переменную? Или можно как-то реализовать дополнение типу unit? было бы конечно идеально, если бы unit был бы наследуемым, но struct UNIT extends unit не работает
Принятый ответ
Ну да, оказалось все намного сложнее, первый мой пример - ошибка. Если не вызывать thistype.allocate() то переменным не будет выделяться память, однако все можно решить через хэш-таблицу и переопределение свойств класса через оператор.
Если есть желание обозвать свойства класса также как и нативки - это можно, но через костыль в виде дополнительного приватного имени, ибо jusshelper багует и пытается обозвать вызванную функцию внутри класса именем метода, даже без обращение через this.~ . прошерстил весь хайв, решения без костыля не нашел.
Также как и не нашел способа возвращать handle unit'а при стандартном обращении , аля "немой" оператор. Решение через оператор unit , самое оптимальное
Решение
//
// ==== Макрос для публичного свойства ====
//! textmacro OperatorProprety takes NAME, DTYPE, dtype, CHILDKEY
method operator $NAME$ takes nothing returns $dtype$
return Load$DTYPE$(this.hash, this, $CHILDKEY$)
endmethod
method operator $NAME$= takes $dtype$ value returns nothing
call Save$DTYPE$(this.hash, this, $CHILDKEY$, value)
endmethod
//! endtextmacro
//
// ==== Макрос для приватного свойства ====
//! textmacro PrivateOperatorProprety takes NAME, DTYPE, dtype, CHILDKEY
private method operator $NAME$ takes nothing returns $dtype$
return Load$DTYPE$(this.hash, this, $CHILDKEY$)
endmethod
private method operator $NAME$= takes $dtype$ value returns nothing
call Save$DTYPE$(this.hash, this, $CHILDKEY$, value)
endmethod
//! endtextmacro
//
// ==== Макрос для свойства только для чтения ====
//! textmacro ReadonlyOperatorProprety takes NAME, DTYPE, dtype, CHILDKEY
method operator $NAME$ takes nothing returns $dtype$
return Lib_Load$DTYPE$(thistype.hash, this, $CHILDKEY$)
endmethod
private method operator $NAME$= takes $dtype$ value returns nothing
call Lib_Save$DTYPE$(thistype.hash, this, $CHILDKEY$, value)
endmethod
//! endtextmacro
//
//
// ==== Переименование нативных функций ====
private function Lib_SetUnitPosition takes unit whichUnit, real newX, real newY returns nothing
call SetUnitPosition(whichUnit,newX,newY)
endfunction
//
// ==== перемеиннование Save/Load Hashtable value
//! textmacro RenameHashtableFunc takes DTYPE, dtype
private function Lib_Save$DTYPE$ takes hashtable table, integer parentKey, integer childKey, $dtype$ value returns nothing
call Save$DTYPE$(table,parentKey,childKey,value)
endfunction
private function Lib_Load$DTYPE$ takes hashtable table, integer parentKey, integer childKey returns $dtype$
return Load$DTYPE$(table,parentKey,childKey)
endfunction
//! endtextmacro
//! runtextmacro RenameHashtableFunc("Integer", "integer")
//! runtextmacro RenameHashtableFunc("Real", "real")
//! runtextmacro RenameHashtableFunc("Boolean", "boolean")
//! runtextmacro RenameHashtableFunc("UnitHandle", "unit")
// =========================================
//
private struct UNIT
private static hashtable hash
//! novjass
//private unit unit // Получение хэндла юнита
//! endnovjass
//! runtextmacro ReadonlyOperatorProprety("isin", "Boolean", "boolean", "0")
//! runtextmacro ReadonlyOperatorProprety("unit", "UnitHandle", "unit", "1")
//
//
method SetUnitPosition takes real newX,real newY returns nothing
call Lib_SetUnitPosition(this.unit, newX, newY)
endmethod
//
// Макросы для загрузки и сохранения
//! textmacro SaveLoadHashtableMethod takes DTYPE, dtype
method Load$DTYPE$ takes integer childKey returns $dtype$
return Lib_Load$DTYPE$(thistype.hash, this, childKey)
endmethod
method Save$DTYPE$ takes integer childKey, $dtype$ value returns nothing
call Lib_Save$DTYPE$(thistype.hash,this, childKey, value)
endmethod
//! endtextmacro
// ==== Загрузка/Сохранение целочисленного принадлежащего юниту ================
//! runtextmacro SaveLoadHashtableMethod("Integer", "integer")
// ==== Загрузка/Сохранение логического принадлежащего юниту ===================
//! runtextmacro SaveLoadHashtableMethod("Boolean", "boolean")
// ==== Загрузка/Сохранение числа с плавающей точкой принадлежащего юниту =======
//! runtextmacro SaveLoadHashtableMethod("Real", "real")
//
// ==== Констуркор ========================================
static method create takes unit un returns thistype
local thistype this = GetHandleId(un)
set this.unit = un
set this.isin = true
return this
endmethod
//
// ==== Деструктор ========================================
method flush takes nothing returns nothing
call FlushChildHashtable(thistype.hash, this)
endmethod
//
// ==== Инициализация =====================================
private static method onInit takes nothing returns nothing
set hash = InitHashtable()
endmethod
endstruct
//
//
`
ОЖИДАНИЕ РЕКЛАМЫ...
0
Koladik
3 месяца назад
0
пока адекватным решением для меня является следующее
Если в этом примере определение оператора unit можно заменить "немым" оператором, это будет решение
2
Hate
3 месяца назад
2
а зачем впринципе?
0
nazarpunk
3 месяца назад
0
Забей на структуры, в 99% случаев можно и без них обойтись.
0
Koladik
3 месяца назад
0
Hate:
Я делал другой класс, который обрабатывает одномерные массивы юнитов group_alpha[номер юнита] , я хотел сделать методы для этой структуры , которые бы сохраняли в хэш-таблицу параметры юнита group_alpha[номер юнита].saveinteger(childid, integer) , и при присваивании присваивались через хэштаблицу также и все параметры group_alpha[номер юнита_1] = group_alpha[номер юнита_2]. Со вторым проблем нету, а вот с первым незадача.
nazarpunk:
У меня несколько библиотек, которые выполняют все это без структур, да. И я понимаю, что можно. Структура мне нужна , что бы 10 раз не переписывать одни и те же вещи. Аля проверка умер ли юнит из массива, если умер то на его место поставить последнего юнита из массива и разные методы дополнительные, которые работали бы через наследование.
0
Koladik
3 месяца назад
0
Ну да, оказалось все намного сложнее, первый мой пример - ошибка. Если не вызывать thistype.allocate() то переменным не будет выделяться память, однако все можно решить через хэш-таблицу и переопределение свойств класса через оператор.
Если есть желание обозвать свойства класса также как и нативки - это можно, но через костыль в виде дополнительного приватного имени, ибо jusshelper багует и пытается обозвать вызванную функцию внутри класса именем метода, даже без обращение через this.~ . прошерстил весь хайв, решения без костыля не нашел.
Также как и не нашел способа возвращать handle unit'а при стандартном обращении , аля "немой" оператор. Решение через оператор unit , самое оптимальное
Решение
Принятый ответ
0
Vlod
3 месяца назад
0
Koladik:
Обращение к полям юнита через индексы приведет к тому что с ростом проекта код станет сложно читать, `unit.target_y` против `unit.LoadReal(2)`
0
ScorpioT1000
3 месяца назад
0
Мастера превратить код в нечитаемую кашу.
Привяжи айди инстанса структуры к unit custom value и расширяй сколько потребуется
0
Koladik
3 месяца назад
0
ScorpioT1000:
не не, тут прикол именно в том, что бы сделать код читаемым, например, вы создали такую структуру, как я описал в последнем сообщении, затем вы наследнуете ее, например так
Что позволяет, просто очень просто обращаться к отдельным свойствам класса через хэш-таблицу
0
Vlod
2 месяца назад
0
Это можно сделать проще через функцию
А то что указано в решении, и зачем то сделано через шаблоны - это именно обращение к полям по индексу
Чтобы оставить комментарий, пожалуйста, войдите на сайт.