XGM Forum
Сайт - Статьи - Проекты - Ресурсы - Блоги

Форуме в режиме ТОЛЬКО ЧТЕНИЕ. Вы можете задать вопросы в Q/A на сайте, либо создать свой проект или ресурс.
Вернуться   XGM Forum > Warcraft> Академия: форум для вопросов> Jass
Ник
Пароль
Войти через VK в один клик
Сайт использует только имя.

Ответ
 
Sunn
To feel joy, not be blue
offline
Опыт: 4,975
Активность:
Прошу откоментить данные строки из vJass мануала, которые касаются удалению более ненужных структур:

..а также использование тригера тоже не очень хорошо скажется быстродействии алгоритма, что говорит против использования onDestroy method...

Тоесть использовать method onDestroy не есть хорошо? Если так, то какая альтернатива?

новый вопрос - новая тема. © swdn

Отредактировано ShadoW DaemoN, 01.01.2009 в 12:11.
Старый 30.12.2008, 20:44
ShadoW DaemoN

offline
Опыт: 37,078
Активность:
Xenosapien, вообще методы структур вызываются не совсем обычным способом - не через прямой вызов метода вроде call StructA__DoSomething(), а через дополнительную функцию, которая запускает триггер. Чтобы было понятней, приведу код:
Код:
struct omg
  static integer counter = 0
  integer a
  
  static method statix takes nothing returns nothing
    set omg.counter = omg.counter + 1
    call BJDebugMsg(I2S(omg.counter))
  endmethod
  
  method onDestroy takes nothing returns nothing
    set .a = 0
    set this = 0
  endmethod
endstruct

library pi

  function OMG_TEH_FUNC takes integer i returns nothing
    local omg z = omg.create()
    set z.a = i
    call BJDebugMsg(I2S(z.a))
    call TimerStart(CreateTimer(), 1., false, function omg.statix)
    call z.destroy()
  endfunction

endlibrary

Вот как пример выглядит в редакторе. А вот как этот же код будет выглядеть в файле war3map.j:
Код:
globals
  //JASSHelper struct globals:
  constant integer si__omg=1
  integer si__omg_F=0
  integer si__omg_I=0
  integer array si__omg_V
  // члены структуры
  integer s__omg_size= 0
  integer array s__omg_a
  // триггер для запуска методов
  trigger st__omg_destroy
  trigger st__omg_statix
  trigger st__omg_onDestroy
  // переменная для передачи индекса структуры
  integer f__arg_this
endglobals

//Generated method caller for omg.statix
function sc__omg_statix takes nothing returns nothing
    call TriggerEvaluate(st__omg_statix)
endfunction

//Generated method caller for omg.onDestroy
function sc__omg_onDestroy takes integer this returns nothing
    set f__arg_this=this
    call TriggerEvaluate(st__omg_onDestroy)
endfunction

//Generated allocator of omg
function s__omg__allocate takes nothing returns integer
 local integer this=si__omg_F
    if (this!=0) then
        set si__omg_F=si__omg_V[this]
    else
        set si__omg_I=si__omg_I+1
        set this=si__omg_I
    endif
    if (this>8190) then
        return 0
    endif
    set si__omg_V[this]=-1
 return this
endfunction

//Generated destructor of omg
function sc__omg_destroy takes integer this returns nothing
    if this==null then
        return
    elseif (si__omg_V[this]!=-1) then
        return
    endif
    set f__arg_this=this
    // >> вызов метода onDestroy
    call TriggerEvaluate(st__omg_onDestroy)
    set si__omg_V[this]=si__omg_F
    set si__omg_F=this
endfunction

//library p:
function OMG_TEH_FUNC takes integer i returns nothing
  local integer z = s__omg__allocate()
  set s__omg_a[z]=i
  call BJDebugMsg(I2S(s__omg_a[z]))
  call TimerStart(CreateTimer(), 1., false, function sc__omg_statix)
  call sc__omg_destroy(z)
endfunction
//library p ends

// . . .

function main takes nothing returns nothing
  // . . .
  call ExecuteFunc("jasshelper__initstructs3086125")
  call InitGlobals()
endfunction

// . . .

//Struct method generated initializers/callers:
function sa__omg_statix takes nothing returns boolean
  call BJDebugMsg(I2S(s__omg_size))
  set s__omg_size=s__omg_size + 1
  return true
endfunction

function sa__omg_onDestroy takes nothing returns boolean
  local integer this=f__arg_this
  set s__omg_a[this]=0x00
  return true
endfunction

function jasshelper__initstructs3086125 takes nothing returns nothing
    set st__omg_statix=CreateTrigger()
    call TriggerAddCondition(st__omg_statix,Condition( function sa__omg_statix))
    set st__omg_onDestroy=CreateTrigger()
    call TriggerAddCondition(st__omg_onDestroy,Condition( function sa__omg_onDestroy))
endfunction
Старый 01.01.2009, 12:28
J
expert
offline
Опыт: 48,447
Активность:
свдн не прально выразился, не все методы структур вызываются через триггер, только перегрузки
я бы не рекомендовал использовать он дестрой, да и вообще любые перегрузки методов создания удаление и прочее, просто создай свой метод в котором удаляеш структуру или созадеш, без перегрезуки, тогда никакого триггера не будет

J добавил:
перегрузки методов создания и удаление сделаны через триггер чтобы были доступны из любой части кода, естестено если будеш делать обычными методами, то прийдется использоватся только ниже, но это не большой минус, все уже привычное...

Отредактировано J, 01.01.2009 в 14:04.
Старый 01.01.2009, 14:06
Sunn
To feel joy, not be blue
offline
Опыт: 4,975
Активность:
A что делает
Код:
native TriggerEvaluate (trigger whichTrigger) returns boolean
?
Функция возвращает булево а это нигде не используется%]
Тоесть, function sc__omg_destroy сообщает варику, что освободилось место для еще одного представителя структуры, а собственно обнуление ее переменных совершает sa__omg_onDestroy?

Xenosapien добавил:
Цитата:
Сообщение от J
я бы не рекомендовал использовать он дестрой, да и вообще любые перегрузки методов создания удаление и прочее, просто создай свой метод в котором удаляеш структуру или созадеш, без перегрезуки, тогда никакого триггера не будет

Ну свой конструктор это насколько я понял что-то типа этого:
Код:
static method new takes unit new_uc, unit new_us returns polar
        local polar pol = polar.create()
            ...
            ...
            ...
            return pol
        endmethod

Хотя нет, я всеравно использую дефолтный метод create()...
Вобще, структура с ее методами это некая оболочка которая упрощает использование глобальных массивов, коими являются все не-статик переменные структуры. Соответственно, вЖасс имеет свои методы работы с этими массивами.... это я к тому что "просто создай свой метод" означает изменить то как вар обрабатывает структуры? Ведь когда я пишу какойто метод, я не могу указать как именно вар должен его обрабатывать, я лишь говорю ему что он должен делать.
Старый 01.01.2009, 15:07
ShadoW DaemoN

offline
Опыт: 37,078
Активность:
Цитата:
Сообщение от Jon
не все методы структур вызываются через триггер, только перегрузки

Все, абсолютно: и перегрузки, и статические, и обычные. Проверь сам.

Честно говоря, использование самописных перегруженных методов create и onDestroy не кажется мне полной фигней. Эти методы вызываются в единичных экземплярах, в отличие от часто используемых методов. К примеру, у нас есть структура pos (некий аналог location), и в ней методы Set (устанавливает координаты для точки) и Get (получает координаты точки). И есть спелл, в периодической части которого производится вызов этих методов. Вызов этих методов идет через доп. функцию, которая, в свою очередь, забивает в глобалки переданные для метода параметры (если таковые имеются) и запускает триггер. Это, конечно, не может не отразиться на быстродействии.

Xenosapien, TriggerEvaluate проверяет условие (condition) триггера, и возвращает true, если условие истинно, и false, если ложно.

sc__omg_destroy - функция, которая удаляет запись о данной структуре (по алгоритму freeslot).
sa__omg_onDestroy - функция, содержащая действия, которые необходимо выполнить при удалении записи о структуре.

Отредактировано ShadoW DaemoN, 01.01.2009 в 15:29.
Старый 01.01.2009, 15:21
J
expert
offline
Опыт: 48,447
Активность:
Цитата:
Сообщение от ShadoW DaemoN
Все, абсолютно: и перегрузки, и статические, и обычные
дезинформация, советую самому проверить... никаково прогрыша в производительности при использовании не перегруженых методов структур - нет, будь они статичные или обычные

J добавил:
Цитата:
Сообщение от Xenosapien
Ведь когда я пишу какойто метод, я не могу указать как именно вар должен его обрабатывать, я лишь говорю ему что он должен делать.
всмысле? метод это просто обычная функция, только параметром передается еще индекс экземпляра структуры, ничего особеного в обработке нет
Цитата:
Сообщение от Xenosapien
Хотя нет, я всеравно использую дефолтный метод create()...
нет нет, все праельно кокраз, метод create() помещается в самый верх кода, и доступен отовсюда и нет необходимости в создании триггера, это не перегрузочный метод, а просто функция выделения индекса, все правельно тобиш, и с удалением также...

Отредактировано J, 01.01.2009 в 16:30.
Старый 01.01.2009, 15:42
ShadoW DaemoN

offline
Опыт: 37,078
Активность:
Jon, между прочим, я не сообщаю информацию, которую сам не проверял. Или мне запостить сюда код и компиляцию джассхелпера в качестве доказательства, что все самописные методы вызываются через триггеры, если ты не веришь? Хмм, хотя можешь посмотреть вышеуказанный код, там есть статический метод в структуре.

Насчет проигрыша в производительности: ты наверняка знаешь, что вызов функции через триггер + TriggerEvaluate/TriggerExecute в несколько раз медленнее, чем прямой вызов (через call).
Старый 01.01.2009, 15:44
J
expert
offline
Опыт: 48,447
Активность:
Цитата:
Сообщение от ShadoW DaemoN
Jon, между прочим, я не сообщаю информацию, которую сам не проверял
проверяй лутче...
Цитата:
Сообщение от ShadoW DaemoN
Или мне запостить сюда код и компиляцию джассхелпера в качестве доказательства
запости...

P.S.
посмотрел вДжаз Мануал... там все правельно написано... с чего ты вообще взял что все методы вызываются через триггеры?
» Цитата из vJass мануала
Достаточна простая в понимание конструкция, на vJass выглядит так:
Код:
struct Position

 real x
 real y
 real z

method move takes real nx, real ny, real nz returns nothing
 set this.x=this.x+nx
 set this.y=this.y+ny
 set this.z=this.z+nz
endmethod

endstruct

function MyFunc takes nothing returns nothing

 local Position A=Position.create()

 call A.move(1, 2, 3)

 call Position.destroy(A)

endfunction
На Jass:
Код:
globals

//JASSHelper struct globals:

integer si__Position_F=0
integer si__Position_I=0
integer array si__Position_V
real array s__Position_x
real array s__Position_y
real array s__Position_z

endglobals

//Generated allocator of Position

function s__Position__allocate takes nothing returns integer
 local integer this=si__Position_F
    if (this!=0) then
        set si__Position_F=si__Position_V[this]
    else
        set si__Position_I=si__Position_I+1
        set this=si__Position_I
    endif
    if (this>8190) then
        return 0
    endif

    set si__Position_V[this]=-1
 return this
endfunction

//Generated destructor of Position

function s__Position_destroy takes integer this returns nothing
    if this==null then
        return
    elseif (si__Position_V[this]!=-1) then
        return
    endif
    set si__Position_V[this]=si__Position_F
    set si__Position_F=this
endfunction

...

function s__Position_move takes integer this, real nx, real ny, real nz returns nothing
 set s__Position_x[this]=s__Position_x[this] + nx
 set s__Position_y[this]=s__Position_y[this] + ny
 set s__Position_z[this]=s__Position_z[this] + nz
endfunction

function MyFunc takes nothing returns nothing

 local integer A=s__Position__allocate()

 call s__Position_move(A, 1 , 2 , 3)

 call s__Position_destroy(A)

endfunction
Ааа! я наверно знаю почему... ты наверно смотрел методы структур наследуемых от интерфейса - все они вызываются через триггеры, это дает одинаковую скорость выполнения при любом количестве наследуемых структур, а также независимость от начинки методов в разных структурах одного интерфейса
В случае же обычных сруктур это просто бесмыслено

Отредактировано J, 01.01.2009 в 16:24.
Старый 01.01.2009, 15:51
ShadoW DaemoN

offline
Опыт: 37,078
Активность:
Так... я вроде разобрался =)
Я тестировал структуры в действии в библиотеках (library) и областях (scope).
В первом случае все методы вызываются через запуск триггера, во втором случае - через стандартный вызов (call) - и даже onDestroy, несмотря на то, что триггер для этого метода все равно создается.
Дело в том, что описание библиотек физически находятся раньше в war3map.j, чем описание структур, поэтому приходится пользоваться функциями-посредниками.
Надеюсь, я прояснил ситуацию.

Отредактировано ShadoW DaemoN, 01.01.2009 в 18:58.
Старый 01.01.2009, 18:34
adic3x

offline
Опыт: 108,439
Активность:
Цитата:
перегрузки методов создания и удаление сделаны через триггер чтобы были доступны из любой части кода, естестено если будеш делать обычными методами, то прийдется использоватся только ниже, но это не большой минус, все уже привычное...

в данном случае несовсем, онДестрой идет через тригер для поддержки полиморфизма как я понимаю

Цитата:
дезинформация, советую самому проверить... никаково прогрыша в производительности при использовании не перегруженых методов структур - нет, будь они статичные или обычные

ага, обычные методы зовуться через калл, если векс в последней версии ничего не напортачил, а то он такой, он может... вобщем хз, всеравно я юзаю просто массивы, аллко/дестрой делаю через макросы и неимею никаких проблем
Старый 07.01.2009, 13:18
Ответ

Опции темы Поиск в этой теме
Поиск в этой теме:

Расширенный поиск

Ваши права в разделе
Вы не можете создавать темы
Вы не можете отвечать на сообщения
Вы не можете прикреплять файлы
Вы можете скачивать файлы

BB-коды Вкл.
[IMG] код Вкл.
HTML код Выкл.
Быстрый переход



Часовой пояс GMT +3, время: 10:02.