local w={}w.__index=w function w.new(O)local T={_rocs=O;_hooks={onAdded={},onRemoved={};onUpdated={};onParentUpdated={}};_lookup={},_selectors={}}return setmetatable(T,w)end function w._trigger(O,w,...)for w,O in O._hooks[w]do O(...)end end function w.fetch(w)if w._ready then local O={}for w in pairs(w._lookup)do table.insert(O,w)end return O else return w:instances()end end function w.setup(w)if w._ready then return end w._ready=true w:_listen()for w,O in pairs(w._selectors)do O:setup()end for O,T in pairs(w:instances())do w._lookup[T]=true end return w end function w.destroy(w)if not w._ready then return end w._ready=nil for O,T in pairs(w._hooks)do w._hooks[O]={}end for w,O in pairs(w._selectors)do O:destroy()end w._lookup={}return w end function w.onAdded(O,w)table.insert(O._hooks.onAdded,w)return O end function w.onRemoved(O,w)table.insert(O._hooks.onRemoved,w)return O end function w.onUpdated(O,w)table.insert(O._hooks.onUpdated,w)return O end function w.onParentUpdated(O,w)table.insert(O._hooks.onParentUpdated,w)return O end return w
local BaseSelector = {}
BaseSelector.__index = BaseSelector

function BaseSelector.new(rocs)
	local self = {
		_rocs = rocs,
		_hooks = {
			onAdded = {},
			onRemoved = {},
			onUpdated = {},
			onParentUpdated = {}
		},
		_lookup = {},
		_selectors = {}
	}

	return setmetatable(self, BaseSelector)
end

function BaseSelector:_trigger(lifecycle, ...)
	for _, hook in self._hooks[lifecycle] do
		hook(...)
	end
end

function BaseSelector:fetch()
	if self._ready then
		local instances = {}

		for instance in pairs(self._lookup) do
			table.insert(instances, instance)
		end

		return instances
	else
		return self:instances()
	end
end

function BaseSelector:setup()
	if self._ready then
		return
	end
	self._ready = true

	self:_listen()

	for _, selector in pairs(self._selectors) do
		selector:setup()
	end

	for _, instance in pairs(self:instances()) do
		self._lookup[instance] = true
	end

	return self
end

function BaseSelector:destroy()
	if not self._ready then
		return
	end
	self._ready = nil

	for category, _ in pairs(self._hooks) do
		self._hooks[category] = {}
	end

	for _, selector in pairs(self._selectors) do
		selector:destroy()
	end

	self._lookup = {}

	return self
end

function BaseSelector:onAdded(hook)
	table.insert(self._hooks.onAdded, hook)
	return self
end

function BaseSelector:onRemoved(hook)
	table.insert(self._hooks.onRemoved, hook)
	return self
end

function BaseSelector:onUpdated(hook)
	table.insert(self._hooks.onUpdated, hook)
	return self
end

function BaseSelector:onParentUpdated(hook)
	table.insert(self._hooks.onParentUpdated, hook)
	return self
end

return BaseSelector
