
local CACHES = {}
local CACHE_CALLBACKS = {}
caches = {}

function caches.new(name, cache_depth, cleanup_callback)
	local cache = Cache:new(cache_depth)
	CACHES[cache] = name or "unnamed"
	CACHE_CALLBACKS[cache] = cleanup_callback
	return cache
end

Cache = class("Cache")

function Cache:new(cache_depth)
	local c = instance(self)
	c.data = {}
	c.depth = cache_depth
	return c
end

function Cache:get(...)
	if select("#", ...) == self.depth then
		--assert(select("#", ...) == self.depth, "depth incorrect", "num:", select("#", ...), "expected:", self.depth, "vars:", ...)
		local holder = self.data
		local num = self.depth
		for i=1, num do
			local var = select(i, ...)
			if i >= num then
				return holder[var]
			else
				if not holder[var] then
					holder[var] = {}
				end
				holder = holder[var]
			end
		end
	else
		print_error("cannot get cache, incorrect depth", "num:", select("#", ...), "expected:", self.depth, "vars:", ...)
		return nil
	end
end

function Cache:set(val, ...)
	if select("#", ...) == self.depth then
		--assert(select("#", ...) == self.depth, "depth incorrect", "num:", select("#", ...), "expected:", self.depth, "vars:", ...)
		local holder = self.data
		local var
		local num = self.depth
		for i=1, num do
			var = select(i, ...)
			if i >= num then
				break
			end
			if not holder[var] then
				holder[var] = {}
			end
			holder = holder[var]
		end
		assert(var, "no var!", ...)
		holder[var] = val
	else
		print_error("cannot assign cache, incorrect depth", "num:", select("#", ...), "expected:", self.depth, "vars:", ...)
	end
end

function Cache:getRoot()
	return self.data
end

function Cache:isEmpty()
	return next(self.data) == nil
end

function Cache:clear()
	table.clear(self.data)
	assert(next(self.data) == nil)
end