Класическая задача, мне нужно построить обработчик, таковой, что обращаясь к нему, заложив параметры, можно было бы выбирать по индексу метод обработки. Можно построить дерево 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
а в чем общий смысол этого?
вы конечно можете использовать либо текстмакросы, либо пойти путем как в первом ответе темы которой вы дали ссылку
11
Hate:
а в чем общий смысол этого?
Получить обработчик с выбором метода обработки по индексу, чтобы не городить дерево if-elseif-elseif-end, а напрямую вызывать нужную функцию.

первом ответе
Пример, который я прикрепил, решен именно с помощью решения описанного в посте. Вот мне и интересно, насколько это адекватное решение.
Я боюсь, что создав массив trigger я начну использовать слишком много памяти или еще что хуже, а решение в целом будет медленнее чем дерево if-elseif-elseif-end
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 вызываешь.
16
быстрее if-then-else на жассе ничего не придумаешь
11
быстрее if-then-else на жассе ничего не придумаешь
Был бы доступ к видоувскому таймеру можно было бы проверить несколько различных подобных реализаций, а так получается, что даже проверить точно, насколько доступ к lua таблицам быстрее чем к хэш-таблицам на жазе невозможно.
16
таблицы есть обычный C-список, луа-таблицы намного новее и, я верю, оптимизированнее
26
и так можно сказать что таблицы гораздо быстрее хештаблиц
11
и так можно сказать что таблицы гораздо быстрее хештаблиц
Сказать то и теоретически обосновать можно, но реальных подсчетов никто не провести не может. Но смысл моего сообщения не в дурацком холиваре, а в том, что решать, что быстрее очень сложно и можно только эмпирически.
11
а зачем?
Обоснованного на реальных цифрах, а не вере выбора реализации не достаточно?
30
Сказать то и теоретически обосновать можно, но реальных подсчетов никто не провести не может.
Да запросто, например на lua я могу создать больше 256 таблиц.
26
Koladik:
а зачем?
Обоснованного на реальных цифрах, а не вере выбора реализации не достаточно?
это не вера, это здравый смысл
11
больше 256 таблиц.
Это, конечно, весомая причина, спору нет. Но я не уверен, что это серьезная преграда т.к. многие таблицы можно было бы объединить но да, тут начинаются костыли
18
Koladik:
обработчик, таковой, что обращаясь к нему, заложив параметры, можно было бы выбирать по индексу метод обработки
Для jass такие решения уже есть, cjass добавляет лишь сахар, который легко изымается при необходимости

Koladik:
проверить точно, насколько доступ к lua таблицам быстрее чем к хэш-таблицам на жазе невозможно
Можно нагрузить пустую карту сравниваемыми операциями, и посмотреть, какие будут нагружать сильнее
Принятый ответ
30
Но я не уверен, что это серьезная преграда т.к. многие таблицы можно было бы объединить но да, тут начинаются костыли
Только вот зачем заниматься костылеписанием, если разрабы предоставили нормальный ЯП, в котором можно комфортно работать. Чего только стоят замыкания, которые избавляют от муторного сохранения информации на id таймера.
Чтобы оставить комментарий, пожалуйста, войдите на сайт.