Flexible flag system

#1

If you have many flags for something that are checked all over the place you can make a flexible flag system instead of needing to declare them ahead of time. This takes advantage of functions being first-class in Lua, able to be returned as values. If the function is assigned to a local variable in different objects, they will not share flag tables as their individual references to the function are unique.

function flag()
	local F = {
		flags = {}
	}
	function F.set(name, value)
		assert(type(value) == "boolean", "Flag value must be true or false!")
		assert(type(name) == "string" or type(name) == "userdata", "Flag name must be a string or a hash!")
		name = (type(name) == "string" and hash(name) or name) -- convert the name to a hash if it is a string
		if value then
			table_add_new(F.flags, name)
		else
			table_remove_existing(F.flags, name)
		end
	end
	function F.get(name)
		assert(type(name) == "string" or type(name) == "userdata", "Flag name must be a string or a hash!")
		name = (type(name) == "string" and hash(name) or name) -- convert the name to a hash if it is a string
		if table_value_exists(F.flags, name) then
			return true
		else
			return false
		end
	end
	return F
end

function table_value_exists(t, value)
	local exists = false
	for _, v in ipairs(t) do
		if v == value then
			exists = true
		end
	end
	return exists
end

function table_add_new(t, value)
	if not table_value_exists(t, value) then
		table.insert(t, value)
	end
end

function table_remove_existing(t, value)
	for i, v in ipairs(t) do
		if v == value then
			table.remove(t, i)
		end
	end
end


-- how to use
local flag = flag()
flag.set("my_flag", true)
pprint(flag.get("my_flag")) --> true

flag.set("another_flag", true)
pprint(flag.flags) -- > { hash: [my_flag], hash: [another_flag] }
5 Likes