Есть ли в Lua способ запустить все функции указанной таблицы?
test = { }

test.a = 123
test.b = true

function test.func0( )
end

function test.func1( )
end

function test.qab( )
end
Нужно сделать так, чтобы все функции test.func0( ), test.func1( ), test.qab( ) были запущены. При этом заранее не известно количество функций.

ScopteRectuS:
Предполагаю, что делается через какой-то цикл перебором всех элементов таблицы, если элемент является функцией, то запустить.
Правильно предполагаете, но мануалы же никому неинтересны, проже же вопрос задать.
test   = { }
test.a = 123
test.b = true
function test.func0()
	print(0)
end
function test.func1()
	print(1)
end
function test.qab()
	print(2)
end

for k, v in pairs(test) do
	if type(v) == 'function' then
		print(k, ':')
		v()
	end
end
`
ОЖИДАНИЕ РЕКЛАМЫ...

Показан только небольшой набор комментариев вокруг указанного. Перейти к актуальным.
24
ScopteRectuS, идея в том чтобы просто их разделить. Heroes - примерно так как сейчас, с ключами по равкодам героев, а в значениях таблицы с инфой по героям, включая перечисление их способностей. А в Abilities - ключи это равкоды способностей, а значения - таблицы способностей.
Сейчас у тебя в Ability складывается два типа данных - по равкоду героя его список способностей, а по каким-то другим ключам таблицы с данными конкретных способностей.
Естественно, я исхожу из предположения что триггеры срабатывания способностей переделаны на получение таблицы способности по равкоду, вместо отдельных триггеров на каждую способность.
Конструкция "if GetSpellAbilityId( ) ~= Ability[ HERO_DEATH_KNIGHT ][ Q ] then return end" ужасна - это вызов функции и два обращения к таблице/массиву в глобальной переменной. И хуже всего - эта конструкция вызывается каждый раз когда срабатывает триггер, а срабатывает он на все способности. Когда способностей будет сто и все на разных триггерах - аналогичная конструкция будет вызываться уже сто раз при каждом касте любой способности.
21
prog, понятно. Спасибо за предложение. Постараюсь это реализовать.
30
ScopteRectuS, можно же просто опорную таблицу сделать.
if IDS[GetSpellAbilityId()] ~= nil then IDS[GetSpellAbilityId()]() end
24
ScopteRectuS, таблица Heroes тебе еще пригодится если у героев появятся механики, требующие что-то делать, например, при входе героя на карту или при смерти, индивидуально для разных героев. Эти действия можно будет занести в таблицу Heroes аналогично тому как можно занести действия способностей. Или, например, если для героев нужно будет хранить какие-то дополнительные данные по равкоду героя.

if IDS[GetSpellAbilityId()] ~= nil then IDS[GetSpellAbilityId()]() end
Срочно кешировать в локалку результат вызова GetSpellAbilityId()! Вызов функций намного-намного-намного дороже обращений к переменным.
21
prog, сделал так:
сама способность:
do
    Ability.DeathCoil = { }
    Ability.DeathCoil.id = FourCC( "A00I" ) -- < обязательная переменная для работы системы.
    
    function Ability.DeathCoil.onSpellCast( )
    end 

    function Ability.DeathCoil.onSpellEffect( )
    end 

    function Ability.DeathCoil.onInit( )
        -- preload...
    end

end
вызов функций:
function InitAllAbilities( )
    for key, value in pairs( Ability ) do

        if type( value ) == "table" then

            if value.onInit and type( value.onInit ) == "function" then value.onInit( ) end
        end
        
    end

    local trigger = CreateTrigger( )

    TriggerRegisterAnyUnitEventBJ( trigger, EVENT_PLAYER_UNIT_SPELL_EFFECT  )

    TriggerAddAction( trigger, 
        function( )
            local abilityId = GetSpellAbilityId( )
            
            for key, value in pairs( Ability ) do

                if type( value ) == "table" then

                    if value.id and value.id == abilityId then
                        if value.onSpellEffect  and type( value.onSpellEffect  ) == "function" then value.onSpellEffect ( ) end
                    end

                end

            end
        end
    )
end
Норм или нет?
24
ScopteRectuS, Не норм, конечно, потому что лишний цикл.
способность
AbilityIndex = {} -- Переменная для хранения способностей по равкоду
Ability = {} -- Переменная для хранения способностей по имени
do

    Ability.DeathCoil = { }
    AbilityIndex[FourCC( "A00I" )] = AbilityIndex.DeathCoil
    
    function Ability.DeathCoil.onSpellCast( )
    end 

    function Ability.DeathCoil.onSpellEffect( )
    end 

    function Ability.DeathCoil.onInit( )
        -- preload...
    end

end
вызов функций
function InitAllAbilities( )
    for key, value in pairs( Ability ) do
        if type( value ) == "table" then
            -- Если у способности нужно что-то инициализировать (прелоад, создание объектов), 
            -- то нужно в таблице способности создать функцию "onInit".
			local onInit  = value.onInit
            if  onInit  and type( onInit  ) == "function" then onInit( ) end
        end
    end
    local trigger = CreateTrigger( )
    TriggerRegisterAnyUnitEventBJ( trigger, EVENT_PLAYER_UNIT_SPELL_EFFECT  )
    TriggerAddAction( trigger, 
        function( )
            local abilityId = GetSpellAbilityId( )
			local spelldata = AbilityIndex[abilityId]
            if spelldata and type( spelldata ) == "table" then
				local onSpellEffect  = spelldata.onSpellEffect 
                if  onSpellEffect   and type( onSpellEffect    ) == "function" then onSpellEffect ( ) end
           end
		end
    )
end
Как-то так.
21
prog, prog, неужели обращение к ячейке таблицы настолько тяжелый процесс, что лучше сохранять её значение в локалку?
24
ScopteRectuS, в зависимости от кол-ва обращений, конечно. onInit в локалку я завернул больше за компанию, а вот в случае с глобальной таблицей AbilityIndex - да, смысл есть.
21
prog, понятно. А цикл разве так плох? Если на карте максимум штук 50 способностей будет?
24
ScopteRectuS, не то чтобы прям плох, но зачем елозить циклом, если прямое обращение реализовать ничего не стоит.
Показан только небольшой набор комментариев вокруг указанного. Перейти к актуальным.
Чтобы оставить комментарий, пожалуйста, войдите на сайт.