Может кто знает принцип взаимодействия наследованных структур, ибо столкнулся с такой проблемой:
struct Tracker
    static method create takes real x, real y, string rpath, integer p returns Tracker
        ...
        set trk.tr = CreateTrackable(rpath,x,y,0)
        
        set trk.t_track = CreateTrigger()
        call TriggerRegisterTrackableTrackEvent(trk.t_track,trk.tr)
        call TriggerAddAction(trk.t_track,function Tracker.defaultTrack)
        call DisableTrigger(trk.t_track)
        
        call SaveInteger(hash,H2I(trk.tr),1,trk)
		...
    endmethod

    stub method OnTrack takes nothing returns nothing
        echo("track1")
    endmethod

    static method defaultTrack takes nothing returns nothing
        Tracker(LoadInteger(hash,H2I(GetTriggeringTrackable()),1)).OnTrack()
    endmethod
endstruct

struct Button extends Tracker
    stub method OnTrack takes nothing returns nothing
        echo("track2")
    endmethod
endstruct
хочу переопределить OnTrack но получается что приведение типа в статическом методе defaultTrack указывает четко имя структуры(не знаю как иначе сделать), метод которой будет вызван, т.е. по дефолту при наведение на трекебл выведется "track1", если же я в defaultTrack сделаю приведение типа Button то выведется "track2", но Tracker не должен знать о своих детях, потому вопрос в том, можно ли с помощью структур реализовать наследование экшенов или как привести тип к актуальному, а не конкретному?
Возможно я что-то упускаю.

Принятый ответ

да вот только thistype возвращает структуру из которой он вызван, а не структуру инстанса идентификатора, т.е. getTrack будет всегда возвращать тип Tracker. Вопрос в том, как по идентификатору определить конкретный тип структуры и к нему привести.
Этот код тестировал? Он должен работать.

Структуры в vJass - массивы. Объект структуры - integer.
У каждой структуры есть массив, куда записывается тип каждого объекта структуры. Пусть у Trackle айди 1, а у Button 2. При создании объекта структуры будет сделано следующее: set массив_куда_записывается_тип[объект_структуры] = айди_структуры. При создании объекта Button и в массив типа структуры Button, и в массив структуры Trackle будет записано 2.

Перезаписываемые методы - массив триггеров, у которых в качестве условия записано тело метода.
Вызов такого метода - call TriggerEvaluate(массив_триггеров[массив_куда_записывается_тип[объект_структуры]]).
В нашем случае это будет выглядеть call TriggerEvaluate(массив_триггеров_OnTrack[массив_куда_записывается_тип[getTrack(h)]]).

Потому должно работать.
`
ОЖИДАНИЕ РЕКЛАМЫ...

Показан только небольшой набор комментариев вокруг указанного. Перейти к актуальным.
0
28
6 лет назад
Отредактирован PT153
0
Я не понял, что ты хочешь, но в vJass есть каст структур Нужный_тип(переменная_структуры_другого_типа).

Также по правилам ООП в переменной типа Tracker может быть как объект типа Traker, так и объект его детей.
struct MyTracker extends Tracker
    method OnTrack takes nothing return nothing
        call DisplayTextToPlayer(Player(0), 0., 0., 5. "HAHAHAH")
    endmethod
endstruct
...
function f takes nothing returns nothing
    Tracker t = MyTracker.create();
    t.OnTarck(); // выведет текст "HAHAHAH" и ничего больше не сделает.
endfunction

Вроде понял.
Ты делаешь каст integerа в Tracker, потому вызывается метод, описанный в Tracker. Если делаешь каст в Button, то сработает метод Button. Тебе нужно сделать метод defaultTrack не статичным и перезаписываемым.

Вот как я решил твою проблему.
struct Tracker
    ...
    static method getTrack takes nothing returns thistype
        return LoadInteger(hash,H2I(GetTriggeringTrackable()),1)
    endmethod

    stub method OnTrack takes nothing returns nothing
        call echo("track1")
    endmethod
endstruct

struct Button extends Tracker
    method OnTrack takes nothing returns nothing
        call echo("track2")
    endmethod
endstruct
...
function f1 takes nothing returns nothing
    local Button t = Tracker.getTrack()
    call t.OnTrack() // будет вызвано echo("track2").
endfunction

// Делает тоже самое, что и f1.
function f2 takes nothing returns nothing
    call Button(Tracker.getTrack()).OnTrack() // будет вызвано echo("track2").
endfunction
0
28
6 лет назад
0
интерфейсы юзай
хотя я бы не советовал часто юзать полиморфизм на вджасс
он реализован через триггеры и при большом количестве объектов существенно растёт нагрузка на машину
0
15
6 лет назад
Отредактирован exAres
0
PT153, вот только беда в том, что при регистрации TriggerAddAction(trk.t_track,function Tracker.defaultTrack) я должен указать именно статичную функцию, а вот с нее уже вызвать наследованную.
0
28
6 лет назад
Отредактирован PT153
0
вот только беда в том, что при регистрации TriggerAddAction(trk.t_track,function Tracker.defaultTrack) я должен указать именно статичную функцию, а вот с нее уже вызвать наследованную.
Так должно работать как нужно.
struct Tracker
    static method getTrack takes integer h returns thistype
        return LoadInteger(hash, h, 1)
    endmethod

    stub method OnTrack takes nothing returns nothing
        call echo("track1")
    endmethod

    static method defaultTrack takes nothing returns nothing
        local integer h = GetHandleId(GetTriggeringTrackable())
        call getTrack(h).OnTrack()
    endmethod
endstruct

struct Button extends Tracker
    stub method OnTrack takes nothing returns nothing
        call echo("track2")
    endmethod
endstruct
интерфейсы юзай
Ему же нужно создавать объект типа Tracker.
0
15
6 лет назад
Отредактирован exAres
0
PT153, да вот только thistype возвращает структуру из которой он вызван, а не структуру инстанса идентификатора, т.е. getTrack будет всегда возвращать тип Tracker. Вопрос в том, как по идентификатору определить конкретный тип структуры и к нему привести.
2
28
6 лет назад
Отредактирован PT153
2
да вот только thistype возвращает структуру из которой он вызван, а не структуру инстанса идентификатора, т.е. getTrack будет всегда возвращать тип Tracker. Вопрос в том, как по идентификатору определить конкретный тип структуры и к нему привести.
Этот код тестировал? Он должен работать.

Структуры в vJass - массивы. Объект структуры - integer.
У каждой структуры есть массив, куда записывается тип каждого объекта структуры. Пусть у Trackle айди 1, а у Button 2. При создании объекта структуры будет сделано следующее: set массив_куда_записывается_тип[объект_структуры] = айди_структуры. При создании объекта Button и в массив типа структуры Button, и в массив структуры Trackle будет записано 2.

Перезаписываемые методы - массив триггеров, у которых в качестве условия записано тело метода.
Вызов такого метода - call TriggerEvaluate(массив_триггеров[массив_куда_записывается_тип[объект_структуры]]).
В нашем случае это будет выглядеть call TriggerEvaluate(массив_триггеров_OnTrack[массив_куда_записывается_тип[getTrack(h)]]).

Потому должно работать.
Принятый ответ
0
15
6 лет назад
0
PT153, у меня есть привычка проверять сначала, если не уверен) так что да, тестировал, не работает, getTrack, который принадлежит Tracker, его и возвращает.
0
28
6 лет назад
Отредактирован PT153
0
у меня есть привычка проверять сначала, если не уверен) так что да, тестировал, не работает, getTrack, который принадлежит Tracker, его и возвращает.
Попробуй так.
    static method defaultTrack takes nothing returns nothing
        local thistype h = getTrack(GetHandleId(GetTriggeringTrackable()))
        call h.OnTrack()
    endmethod
Если и это не сработает, то правьте руки кинь свой код Tracker и его детей в мне в ЛС. Я уж гляну, что к чему.
0
28
6 лет назад
0
exAres, я тоже проверил
код работает
2
28
6 лет назад
Отредактирован PT153
2
Прошёл день, а кода в ЛС я не увидел, проблема решена?

Ты делаешь каст integerа в Tracker, потому вызывается метод, описанный в Tracker.
А вот это неправда, и в этом случае вызывается так, как я описал в комментарии 7.
То есть даже код из вопроса работает, как нужно.
Небольшой совет: определение метода нужно писать над кодом, в котором этот метод передаётся как code, иначе на самом деле будет передана функция, что вызывает триггер, в котором уже вызывается указанный метод.

Карта, в которой есть подтверждения моих слов.
Загруженные файлы
Показан только небольшой набор комментариев вокруг указанного. Перейти к актуальным.
Чтобы оставить комментарий, пожалуйста, войдите на сайт.