Класическая задача, мне нужно построить обработчик, таковой, что обращаясь к нему, заложив параметры, можно было бы выбирать по индексу метод обработки. Можно построить дерево if-elseif-elseif-elseif-end но такое решение, возможно, не самое элегантное, хотел создать массив code, чтобы напрямую запускать функцию из массива, но это запрещено по причине указанный в комментариях в посте, там же можно найти обходное решение следуя которому, я написал этого монстра.
code vJass
library TestLib initializer TestINI

struct ExampleStruct
	static constant integer MARC_1 = 0
	static constant integer MARC_2 = 1
	static constant integer MARC_3 = 2
	static constant integer MARC_4 = 3
	static constant integer MARC_5 = 4
	//ets...
	//
	private static trigger array ACTIONTRIGGERS
	//
	private static integer GLOB_LOC_ADRESS
	private static string  GLOB_LOC_OUTPUT
	//
	private static method GetAction1 takes nothing returns boolean
		set GLOB_LOC_OUTPUT = I2S(GLOB_LOC_ADRESS+1)
		return true
	endmethod
	
	private static method GetAction2 takes nothing returns boolean
		set GLOB_LOC_OUTPUT = I2S(GLOB_LOC_ADRESS+2)
		return true
	endmethod
	
	private static method GetAction3 takes nothing returns boolean
		set GLOB_LOC_OUTPUT = I2S(GLOB_LOC_ADRESS+3)
		return true
	endmethod
	
	private static method GetAction4 takes nothing returns boolean
		set GLOB_LOC_OUTPUT = I2S(GLOB_LOC_ADRESS+4)
		return true
	endmethod
	
	private static method GetAction5 takes nothing returns boolean
		set GLOB_LOC_OUTPUT = I2S(GLOB_LOC_ADRESS+5)
		return true
	endmethod
	//etc...	

	static method GetOutput takes integer method, integer adress returns string
		set GLOB_LOC_ADRESS = adress
		if(TriggerEvaluate(ACTIONTRIGGERS[method]))then
			return GLOB_LOC_OUTPUT
		else
			return ""
		endif
	endmethod
	
	static method STRUCTINI takes nothing returns nothing
		set ACTIONTRIGGERS[MARC_1] = CreateTrigger()
		call TriggerAddCondition(ACTIONTRIGGERS[MARC_1],function s__ExampleStruct_GetAction1)
		//
		set ACTIONTRIGGERS[MARC_2] = CreateTrigger()
		call TriggerAddCondition(ACTIONTRIGGERS[MARC_2],function s__ExampleStruct_GetAction2)
		//
		set ACTIONTRIGGERS[MARC_3] = CreateTrigger()
		call TriggerAddCondition(ACTIONTRIGGERS[MARC_3],function s__ExampleStruct_GetAction3)
		//
		set ACTIONTRIGGERS[MARC_4] = CreateTrigger()
		call TriggerAddCondition(ACTIONTRIGGERS[MARC_4],function s__ExampleStruct_GetAction4)
		//
		set ACTIONTRIGGERS[MARC_5] = CreateTrigger()
		call TriggerAddCondition(ACTIONTRIGGERS[MARC_5],function s__ExampleStruct_GetAction5)
		//etc...
	endmethod

endstruct

function TestStructFunc takes nothing returns nothing
	call BJDebugMsg(ExampleStruct.GetOutput(ExampleStruct.MARC_1,12))
	call BJDebugMsg(ExampleStruct.GetOutput(ExampleStruct.MARC_2,12))
	call BJDebugMsg(ExampleStruct.GetOutput(ExampleStruct.MARC_3,12))
	call BJDebugMsg(ExampleStruct.GetOutput(ExampleStruct.MARC_4,12))
	call BJDebugMsg(ExampleStruct.GetOutput(ExampleStruct.MARC_5,12))
endfunction

function TestINI takes nothing returns nothing
	call ExampleStruct.STRUCTINI()
	call TimerStart(CreateTimer(), 1, false, function TestStructFunc)
endfunction 

endlibrary
Мне кажется, что подобное решение нормальному человеку и показывать нельзя. Но может кто-то подскажет как сделать лучше
Переписано на
code vJass
library TestLib initializer TestINI

struct ExampleStruct
	static constant integer MARC_1 = 0
	static constant integer MARC_2 = 1
	static constant integer MARC_3 = 2
	static constant integer MARC_4 = 3
	static constant integer MARC_5 = 4
	//ets...
	//
	private static boolexpr array CodeAr
	//
	private static integer GLOB_LOC_ADRESS
	private static string  GLOB_LOC_OUTPUT
	//
	private static method GetAction1 takes nothing returns boolean
		set GLOB_LOC_OUTPUT = I2S(GLOB_LOC_ADRESS+1)
		return true
	endmethod
	
	private static method GetAction2 takes nothing returns boolean
		set GLOB_LOC_OUTPUT = I2S(GLOB_LOC_ADRESS+2)
		return true
	endmethod
	
	private static method GetAction3 takes nothing returns boolean
		set GLOB_LOC_OUTPUT = I2S(GLOB_LOC_ADRESS+3)
		return true
	endmethod
	
	private static method GetAction4 takes nothing returns boolean
		set GLOB_LOC_OUTPUT = I2S(GLOB_LOC_ADRESS+4)
		return true
	endmethod
	
	private static method GetAction5 takes nothing returns boolean
		set GLOB_LOC_OUTPUT = I2S(GLOB_LOC_ADRESS+5)
		return true
	endmethod
	//etc...	

	static method GetOutput takes integer method, integer adress returns string
		set GLOB_LOC_ADRESS = adress
		call ForceEnumPlayersCounted(bj_FORCE_PLAYER[0], CodeAr[method],1)
		return GLOB_LOC_OUTPUT
	endmethod
	
	static method STRUCTINI takes nothing returns nothing
		//
		set CodeAr[MARC_1] = Condition(function s__ExampleStruct_GetAction1)
		set CodeAr[MARC_2] = Condition(function s__ExampleStruct_GetAction2)
		set CodeAr[MARC_3] = Condition(function s__ExampleStruct_GetAction3)
		set CodeAr[MARC_4] = Condition(function s__ExampleStruct_GetAction4)
		set CodeAr[MARC_5] = Condition(function s__ExampleStruct_GetAction5)
		//etc...
	endmethod

endstruct

function TestStructFunc takes nothing returns nothing
	call BJDebugMsg(ExampleStruct.GetOutput(ExampleStruct.MARC_1,12))
	call BJDebugMsg(ExampleStruct.GetOutput(ExampleStruct.MARC_2,12))
	call BJDebugMsg(ExampleStruct.GetOutput(ExampleStruct.MARC_3,12))
	call BJDebugMsg(ExampleStruct.GetOutput(ExampleStruct.MARC_4,12))
	call BJDebugMsg(ExampleStruct.GetOutput(ExampleStruct.MARC_5,12))
endfunction

function TestINI takes nothing returns nothing
	call ExampleStruct.STRUCTINI()
	call TimerStart(CreateTimer(), 1, false, function TestStructFunc)
endfunction 

endlibrary

Koladik:
обработчик, таковой, что обращаясь к нему, заложив параметры, можно было бы выбирать по индексу метод обработки
Для jass такие решения уже есть, cjass добавляет лишь сахар, который легко изымается при необходимости

Koladik:
проверить точно, насколько доступ к lua таблицам быстрее чем к хэш-таблицам на жазе невозможно
Можно нагрузить пустую карту сравниваемыми операциями, и посмотреть, какие будут нагружать сильнее
`
ОЖИДАНИЕ РЕКЛАМЫ...

Показан только небольшой набор комментариев вокруг указанного. Перейти к актуальным.
26
работает? ну и норм. что вас еще должно волновать? крашей нет? фпс в нулину не падает? так чего думаете?
вообще в луа можно хранить функции в таблицах, так что такие телодвижения свойственны только жассу
24
Оптимальный вариант - перейти на Lua. Там можно хранить функции в переменных и массивах и вызывать их оттуда, соответственно.
На жассе - только страдать и грызть костыли.
26
сама рациональность данного мероприятия только под вопросов. зачем вам такой франкенштейн, что он позволяет делать чего невозможно делать руками?
17
Так есть же фильтры, енумы и прочая гадость для этого.
Да и просто вызвать функцию в блоке if будет в разы дешевле
if(UnitAlive(u))then
	call DisplayTimedTextToPlayer(GetLocalPlayer(),0.,0.,30,GetUnitName(u)+" is Alive")
endif
11
блоке if будет в разы дешевле
Если блоков мало то да, но если вырастить их до 100 то не факт, а тут фиксированное время применения.

невозможно делать руками?
Например, нужен цикл различных обработчиков с вызовом по индексу
26
тогда нужно менять подход, все еще вы не объяснили зачем данная конструкция и какие проблемы она решает
вы попробуйте практично объяснить и экстраполировать применение данной конструкции
30
Если блоков мало то да, но если вырастить их до 100 то не факт, а тут фиксированное время применения.
Если вложенные ифы не помещаются в экран, то пора задуматься.
17
Зачем нам увеличивать кол-во ифов если мы можем разнести это всё по разным функциям
И if/then/elseif/else/endif работает по принципу - наткнулся на первый false, дропнул ветку и пошёл проверять другие elseif.
11
объяснили
Я не уверен, что конкретика тут существенна, но в моем случае по ряду входных параметров собирает путь к различным .blp файлам, одним из параметров является тип blp по int, их может быть множество, остальные вспомогательные. Соответственно меняя тип, который я ищу, существенно меняется метод сборки string, использующий вспомогательные параметры.

N1ghtSiren:
Зачем нам увеличивать кол-во ифов если мы можем разнести это всё по разным функциям
И if/then/elseif/else/endif работает по принципу - наткнулся на первый false, дропнул ветку и пошёл проверять другие elseif.
Я понимаю, но если у вас каждый if по очереди проверяет номера 1,2,3,4, а у вас на входе 100 то ему придется провести 100 проверок. Если на входе 2 то, конечно, будет очень быстро.
28
Koladik, ты можешь взять параметр для сравнения как ключ в хе-таблице, а по ключу хранить строку. Получаешь ключ, находишь строку, а эта строка есть имя функции, что нужно вызвать, через ExecuteFunc вызываешь.
Показан только небольшой набор комментариев вокруг указанного. Перейти к актуальным.
Чтобы оставить комментарий, пожалуйста, войдите на сайт.