Есть ли в 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
`
ОЖИДАНИЕ РЕКЛАМЫ...

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

if IDS[GetSpellAbilityId()] ~= nil then IDS[GetSpellAbilityId()]() end
Срочно кешировать в локалку результат вызова GetSpellAbilityId()! Вызов функций намного-намного-намного дороже обращений к переменным.
0
21
5 лет назад
Отредактирован scopterectus
0
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
Норм или нет?
1
24
5 лет назад
1
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
Как-то так.
0
21
5 лет назад
0
prog, prog, неужели обращение к ячейке таблицы настолько тяжелый процесс, что лучше сохранять её значение в локалку?
1
24
5 лет назад
1
ScopteRectuS, в зависимости от кол-ва обращений, конечно. onInit в локалку я завернул больше за компанию, а вот в случае с глобальной таблицей AbilityIndex - да, смысл есть.
0
21
5 лет назад
0
prog, понятно. А цикл разве так плох? Если на карте максимум штук 50 способностей будет?
1
24
5 лет назад
1
ScopteRectuS, не то чтобы прям плох, но зачем елозить циклом, если прямое обращение реализовать ничего не стоит.
Показан только небольшой набор комментариев вокруг указанного. Перейти к актуальным.
Чтобы оставить комментарий, пожалуйста, войдите на сайт.