[Release] Context, Please! Lua-Context with M2 Examples

12/26/2018 04:22 rollback#1
I thought some of you may be interested in this.
With the following code you can add contexts to your lua application:

Code:
context = {}

--[[
	context.enter(<context(s)>, <context sensitive function>)
	last context wins
]]
context.enter = function(...)
	local env = getfenv(2)
	
	for i = 1, table.getn(arg) - 1 do
		if arg[i] then
			local temp = env
			env = {}
			setmetatable(env, {__index = function(tbl, k) return arg[i][k] or temp[k] end, __newindex = temp})
		else
			return false
		end
	end
	
	local contextSensitiveFunction = arg[table.getn(arg)]
	setfenv(contextSensitiveFunction, env)
	return contextSensitiveFunction()
end
A context is defined as a table of variables. The context can be either static or the result of a function.
Examples:
Code:
context.EXAMPLE1 = {
	["print"] = function(arg) print("EXAMPLE1", arg) end
}
context.EXAMPLE2 = {
	["print"] = function(arg) print("EXAMPLE2", arg) end
}
context.EXAMPLE3 = {
	["SOME_CONTEXT_VARIABLE"] = 10000
}
context.NON_STATIC = function(prefix)
	return {
		["print"] = function(arg) print(prefix, arg) end
	}
end
You can then enter the context like this:
Code:
context.enter(context.EXAMPLE1, function()
	print("Hello world")-- EXAMPLE1	Hello world
	
	context.enter(context.EXAMPLE2, function()
		print("Hello world")-- EXAMPLE2	Hello world
	end)
	
	print("Hello world")-- EXAMPLE1	Hello world
end)
The last context argument wins (right after local variables):
Code:
context.enter(context.EXAMPLE1, context.EXAMPLE2, function()
	print("Hello world")-- EXAMPLE2 Hello world
	
	context.enter(context.EXAMPLE1, function()
		print("Hello world")-- EXAMPLE1 Hello world
	end)
	
	print("Hello world")-- EXAMPLE2 Hello world
end)
The context.enter function returns whatever the context sensitive function returns. The result can then be used outside the context:
Code:
context.enter(context.EXAMPLE1, function()
	print(SOME_CONTEXT_VARIABLE)-- EXAMPLE1	nil
	
	context.enter(context.EXAMPLE3, function()
		print(SOME_CONTEXT_VARIABLE)-- EXAMPLE1	10000
	end)
	
	local test = context.enter(context.EXAMPLE3, function()
		return SOME_CONTEXT_VARIABLE
	end)
	
	print(test)
end)
Since a context is a simple table of variables it can also be created by a function:
Code:
context.enter(context.NON_STATIC("test"), function()
	print("Hello world")-- test	Hello World
end)
If one of the given contexts is nil or false the context.enter function returns false and will not execute the given function.

A basic example how you may use it for metin2:
Context functions:
Code:
context.PLAYER = function()
	if --[[ check if a player is selected ]] then
		return {}
	else
		return nil
	end
end

context.DUNGEON = function(dungeonMapIdx)
	if not dungeonMapIdx then
		dungeonMapIdx = context.enter(context.PLAYER(), function() return pc.get_map_index() end)
	end
	
	if dungeonMapIdx and d.select(dungeonMapIdx) then
		return {
			["dungeon_timer"] = function(name, seconds)
				server_timer(name, seconds, dungeonMapIdx)
			end,
			["dungeon_loop_timer"] = function(name, interval)
				server_loop_timer(name, interval, dungeonMapIdx)
			end,
			["clear_dungeon_timer"] = function(name)
				clear_server_timer(name, dungeonMapIdx)
			end
		}
	else
		return nil
	end
end
Using the context(s):
Code:
when kill with npc.get_race() == 1093 begin
	context.enter(context.DUNGEON(), function()
		dungeon_timer("some_timer_name", 60)
	end)
end

when some_timer_name.server_timer begin
	context.enter(context.DUNGEON(get_server_timer_arg()), function()
		-- do something with the dungeon context
	end)
end
12/27/2018 19:08 nybu#2
nice dude! now do the same for a game that is deadn't :)
01/05/2019 23:49 Poccix#3
Quote:
Originally Posted by nybu View Post
nice dude! now do the same for a game that is deadn't :)
Sie können Deutsch - Sprechen sie Deutsch! Scheiß 2012er Fameboy... :D

Release tatsächlich usefull. thx. (nur nicht für mich quark.)