Если вдруг кто не знал, в vJass размер массива JASS захрадкоден, поэтому увеличение размера массива в 4 раза в версии 1.29 WarCraft 3 никак не повлияло на vJass. Сотрудник Blizzard попытался это исправить, однако найти походящую IDE для пересборки vJass оказалось не так-то просто, поэтому он не стал ничего менять,…
И на самом деле можно указать размер в 8191, последний индекс будет работать, а указание размера не выльется в создание доп. массивов для структуры.
Тут я немного ошибся, доп. массивы будут созданы и все присвоения/получения будут делаться через функцию, но сами массивы не будут использованы.
код
globals
constant integer A_size= 8191
//JASSHelper struct globals:
constant integer si__A=1
integer si__A_F=0
integer si__A_I=0
integer array si__A_V
integer array si__A_2V
integer array s__A_2a
integer array s__A_a
endglobals
function sg__A_get_a takes integer i returns integer
return s__A_a[i]
endfunction
function sg__A_set_a takes integer i,integer v returns nothing
set s__A_a[i]=v
endfunction
//Generated allocator of A
function s__A__allocate takes nothing returns integer
local integer this=si__A_F
if (this!=0) then
set si__A_F=si__A_V[this]
else
set si__A_I=si__A_I+1
set this=si__A_I
endif
if (this>8191) then
call DisplayTimedTextToPlayer(GetLocalPlayer(),0,0,1000.,"Unable to allocate id for an object of type: A")
return 0
endif
set si__A_V[this]=-1
return this
endfunction
//Generated destructor of A
function s__A_deallocate takes integer this returns nothing
local integer used
if this==null then
call DisplayTimedTextToPlayer(GetLocalPlayer(),0,0,1000.,"Attempt to destroy a null struct of type: A")
return
else
set used=si__A_V[this]
if (used!=-1) then
call DisplayTimedTextToPlayer(GetLocalPlayer(),0,0,1000.,"Double free of type: A")
return
endif
endif
set si__A_V[this]=si__A_F
set si__A_F=this
endfunction
Отчего была зажата рабочая ячейка - неясно. Если указать размер 16382, то будут созданы 2 доп. массива, но использоваться будет только один. Если указать 16383, то будут использоваться все, хотя места хватает, ведь 16383 = 8192 * 2 - 1.
fenathesnake, так кол-во индексов для структуры можно указать после имени структуры. И на самом деле можно указать размер в 8191, последний индекс будет работать, а указание размера не выльется в создание доп. массивов для структуры. Не знаю, почему по умолчанию размер 8190.
ScorpioT1000, для структур все-равно лимит в 8190 инстансов.
Если в полях структуры используются массивы, то все становится печально.
Пример кода, который не сможет создать 500 объектов MyStruct с правильно инициализированными полями (место под StringArray тупо закончится)
library Test initializer Init
type StringArray extends string array[20]
struct MyStruct
StringArray sarray
method init takes nothing returns nothing
call sarray.create()
endmethod
endstruct
function Init takes nothing returns nothing
local integer i = 0
local MyStruct s
loop
exitwhen i == 500
set s = MyStruct.create()
call s.init()
set i = i + 1
endloop
endfunction
endlibrary
PT153, нет, он делает бинари поиск при указании массивов или структур выше 8190 элементов, причем сам решает количество переменных:
globals
// processed: unit array a[100000]
//JASSHelper struct globals:
unit array s__a
unit array s__2a
unit array s__3a
unit array s__4a
unit array s__5a
unit array s__6a
unit array s__7a
unit array s__8a
unit array s__9a
unit array s__10a
unit array s__11a
unit array s__12a
unit array s__13a
endglobals
function sg__a_get takes integer i returns unit
if(i<8191) then
return s__a[i]
elseif(i<57337) then
if(i<16382) then
return s__2a[i-8191]
elseif(i<32764) then
if(i<24573) then
return s__3a[i-16382]
else
return s__4a[i-24573]
endif
elseif(i<40955) then
return s__5a[i-32764]
elseif(i<49146) then
return s__6a[i-40955]
else
return s__7a[i-49146]
endif
elseif(i<65528) then
return s__8a[i-57337]
elseif(i<81910) then
if(i<73719) then
return s__9a[i-65528]
else
return s__10a[i-73719]
endif
elseif(i<90101) then
return s__11a[i-81910]
elseif(i<98292) then
return s__12a[i-90101]
else
return s__13a[i-98292]
endif
endfunction
function sg__a_set takes integer i,unit v returns nothing
if(i<8191) then
set s__a[i]=v
elseif(i<57337) then
if(i<16382) then
set s__2a[i-8191]=v
elseif(i<32764) then
if(i<24573) then
set s__3a[i-16382]=v
else
set s__4a[i-24573]=v
endif
elseif(i<40955) then
set s__5a[i-32764]=v
elseif(i<49146) then
set s__6a[i-40955]=v
else
set s__7a[i-49146]=v
endif
elseif(i<65528) then
set s__8a[i-57337]=v
elseif(i<81910) then
if(i<73719) then
set s__9a[i-65528]=v
else
set s__10a[i-73719]=v
endif
elseif(i<90101) then
set s__11a[i-81910]=v
elseif(i<98292) then
set s__12a[i-90101]=v
else
set s__13a[i-98292]=v
endif
endfunction
function main takes nothing returns nothing
endfunction
//Struct method generated initializers/callers:
//Functions for BigArrays:
ScorpioT1000, бинарного поиска там нет, аллокация происходит за константное время. Там больше проблема в том, что эти 8к общие для класса и всех его наследников. И наличие массивов в атрибутах тоже уменьшает кол-во возможных объектов.
Комментарии проекта За огненной стеной
Комментарий от сотрудника Blizzard по поводу vJass
Ред. PT153
Ред. fenathesnake
Ред. PT153
Пример кода, который не сможет создать 500 объектов MyStruct с правильно инициализированными полями (место под StringArray тупо закончится)
Ред. ScorpioT1000