Когда необходимо перебрать все экземпляры структуры, я обычно объявляю массив типа структуры. Этот массив я заполняю и очищаю по мере надобности.
library FooBar initializer onInit

globals
  Foo array foos
  integer foosQuantity = 0
endglobals

struct Foo
  real x
  real y

  static method create takes nothing returns Foo
    local Foo f = Foo.allocate()
    set foos[foosQuantity] = f
    set foosQuantity = foosQuantity + 1
    return f
  endmethod

  method bar takes nothing returns nothing
    call BJDebugMsg("Bar!")
  endmethod
endstruct

function timerCallback takes nothing returns nothing
  local integer i = 0
  loop
    exitwhen i >= foosQuantity
    call foos[i].bar()
    set i = i + 1
  endloop
endfunction

function onInit takes nothing returns nothing
  local boolean periodic = true
  call TimerStart(CreateTimer(), periodic, function timerCallback)
endfunction

endlibrary
Известно, что структуры vJass реализованы параллельными массивами.
Как можно избежать создания ещё одного многомерного массива? В любом случае количество экземляров структуры ещё более ограничено, чем размер массива.
Я не смог до конца понять какие сгенерированные переменные за что отвечают. К тому же я сомневаюсь что возможно безопасно обращаться к переменным которым только предстоит быть сгенерированными. xgm.guru/p/wc3/198980#h4
Другими словами, как добиться такого же эффекта как и в примере, но избежав объявления "собственных" глобальных переменных?
P. S.
Я уверен что это старая тема и я дурак. Пожалуйста, не смотря на это, ответьте серьезно.

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

- Я использую это:
struct linkedList
        private  static  constant  timer     period  =  CreateTimer( )
        private                    thistype  prev
        private                    thistype  next


        private stub method destroy takes nothing returns nothing

//          Здесь должен находится Ваш код.

            set  this.prev.next  =  this.next
            set  this.next.prev  =  this.prev

            if ( thistype( 0 ).next == 0 ) then
                call PauseTimer( thistype.period )
            endif

            call thistype.deallocate( this )
        endmethod


        private static method iterate takes nothing returns nothing
            local  thistype  this  =  thistype( 0 ).next

            loop
                exitwhen ( this == 0 )

//              Здесь должен находится Ваш код.

                call this.destroy( )

                set  this  =  this.next
            endloop
        endmethod


        private static method create takes nothing returns thistype
            local  thistype  this  =  thistype.allocate( )

            set  this.next         =  thistype( 0 )
            set  this.prev         =  thistype( 0 ).prev
            set  this.next.prev    =  this
            set  this.prev.next    =  this

//          Здесь должен находится Ваш код.
            
            if ( this.prev == 0 ) then
                call TimerStart( thistype.period, 0.03125, true, function thistype.iterate )
            endif

            return this
        endmethod


    endstruct
static method create takes nothing returns nothing
static method iterate takes nothing returns nothing
method destroy takes nothing returns nothing
Для работы этого двусвязного списка требуется создать 2-е переменные с именами next, prev.
0
23
6 лет назад
0
тогда делай переменную приватную и он обрашать будет только внутри библиотек... извне будет ошибка
1
21
6 лет назад
Отредактирован scopterectus
1
- Я использую это:
struct linkedList
        private  static  constant  timer     period  =  CreateTimer( )
        private                    thistype  prev
        private                    thistype  next


        private stub method destroy takes nothing returns nothing

//          Здесь должен находится Ваш код.

            set  this.prev.next  =  this.next
            set  this.next.prev  =  this.prev

            if ( thistype( 0 ).next == 0 ) then
                call PauseTimer( thistype.period )
            endif

            call thistype.deallocate( this )
        endmethod


        private static method iterate takes nothing returns nothing
            local  thistype  this  =  thistype( 0 ).next

            loop
                exitwhen ( this == 0 )

//              Здесь должен находится Ваш код.

                call this.destroy( )

                set  this  =  this.next
            endloop
        endmethod


        private static method create takes nothing returns thistype
            local  thistype  this  =  thistype.allocate( )

            set  this.next         =  thistype( 0 )
            set  this.prev         =  thistype( 0 ).prev
            set  this.next.prev    =  this
            set  this.prev.next    =  this

//          Здесь должен находится Ваш код.
            
            if ( this.prev == 0 ) then
                call TimerStart( thistype.period, 0.03125, true, function thistype.iterate )
            endif

            return this
        endmethod


    endstruct
static method create takes nothing returns nothing
static method iterate takes nothing returns nothing
method destroy takes nothing returns nothing
Для работы этого двусвязного списка требуется создать 2-е переменные с именами next, prev.
Принятый ответ
0
22
6 лет назад
Отредактирован Zahanc
0
pro100master:
тогда делай переменную приватную и он обрашать будет только внутри библиотек... извне будет ошибка
Суть в том чтобы избежать повторения кода. А именно алгоритм стэка.
Что значит следующее:
((код
thistype(0)
))
Здесь сказано что это ключевое слово, но не функция.
0
21
6 лет назад
0
Zahanc, проще говоря, thistype( 0 ) вернет 0, то есть нулевую ячейку структуры. Слово thistype используется для того, чтобы не было ошибок при компиляции. Действует примерно также, как и integer( this ).
0
22
6 лет назад
Отредактирован Zahanc
0
То есть thistype(3) вернёт мне третий экземлпяр, если он существует? В смысле индекс экземпляра, то есть 3.
0
21
6 лет назад
Отредактирован scopterectus
0
Zahanc, не третий экземпляр, а то что хранится в ячейке c индексом 3.
struct data
	real x
	real y
endstruct
Чтобы оставить комментарий, пожалуйста, войдите на сайт.