lua-users home
lua-l archive

[Date Prev][Date Next][Thread Prev][Thread Next] [Date Index] [Thread Index]


Hi

May be your IndexHandler can return a closure function.
See below

Jean-Claude Morlier

function new(_obj)
	if(type(_obj)=="table") then
		local newInstance={};
		for i,field in _obj do
			if(type(field)=="table") then
				newInstance[i]=new(field);
			else
				newInstance[i]=field;
			end
		end
		return newInstance;
	else
		return _obj;
	end
end

MethodDispatcherPool={
	_pool={},
	_index=nil,
};

function MethodDispatcherPool:AddObj(obj)
	local key=getn(self._pool)+1;
	self._pool[key]=obj;
end

function MethodDispatcherPool.IndexHandler(table,index)
	 return function (...)
						 for i, val in %table._pool do
								_func=val[%index];
								if(type(_func)=="function")then
									 arg[1]=val;
									 call(_func,arg);
								end
						 end
					end
end

function MethodDispatcherPool:new()
	local mmp=new(MethodDispatcherPool);
	local tag=newtag()
	settagmethod(tag,"index",MethodDispatcherPool.IndexHandler);
	settag(mmp,tag);
	return mmp;
end


--==============Exemple d'utilisation
Test1={
	OnUpdate=function(self,string)
		print(self.name.." param="..string);
	end,
	name="I'm Test 1"
}

Test2={
	OnUpdate=function(self,string)
		print(self.name.." param="..string);
	end,
	name="I'm Test 2"
}

Test3={
	OnUpdate=function(self,string)
		print(self.name.." param="..string);
	end,
	name="I'm Test 3"
}

Test0={
	OnUpdateNotExist=function(self,string)
		print(self.name.." param="..string);
	end,
	name="I'm Test 0"
}

mdp=MethodDispatcherPool:new()
mdp:AddObj(Test1);
mdp:AddObj(Test2);
mdp:AddObj(Test3);
mdp:AddObj(Test0)
mdp:OnUpdate("I'm the param");

--==========Sortie

--I'm Test 1 param=I'm the param
--I'm Test 2 param=I'm the param
--I'm Test 3 param=I'm the param



Alberto Demichelis wrote:

Hi all,
	I'm trying to implement a "container"(table) that allow me to insert several tables into it and transparently call a function in all inserted tables (like the following sample).
If you look at my current implementation I use the "index" tag method to obtain the function name ,I store it in the container,
I return the container table, I handle the "function" tag method and I use the previously stored index to call all functions in
the tables.
What I think is not really elegant (and also a bit dangerous) is storing the index into the table without being sure that
a call is going to be done on it. Somebody can see any better solution?

thanks for your time
Alberto

-------------------------------
Alberto Demichelis
alberto@crytek.de
www.crytek.com


--==============SAMPLE
Test1={
	OnUpdate=function(self,string)
		print(self.name.." param="..string);
	end,
	name="I'm Test 1"
}

Test2={
	OnUpdate=function(self,string)
		print(self.name.." param="..string);
	end,
	name="I'm Test 2"
}

Test3={
	OnUpdate=function(self,string)
		print(self.name.." param="..string);
	end,
	name="I'm Test 3"
}


mdp=MethodDispatcherPool:new()
mdp:AddObj(Test1);
mdp:AddObj(Test2);
mdp:AddObj(Test3);
mdp:OnUpdate("I'm the param");

--==========OUTPUT

--I'm Test 1 param=I'm the param
--I'm Test 2 param=I'm the param
--I'm Test 3 param=I'm the param

--==========CURRENT IMPLEMENTATION

function new(_obj)
	if(type(_obj)=="table") then
		local newInstance={};
		for i,field in _obj do
			if(type(field)=="table") then
				newInstance[i]=new(field);
			else
				newInstance[i]=field;
			end
		end
		return newInstance;
	else
		return _obj;
	end
end

MethodDispatcherPool={
	_pool={},
	_index=nil,
};

function MethodDispatcherPool:AddObj(obj)
	local key=getn(self._pool)+1;
	self._pool[key]=obj;
end

function MethodDispatcherPool.IndexHandler(table,index)
	table._index=index;
	return table;
end

function MethodDispatcherPool.CallHandler(table,...)
	local _func;
	if(type(table)=="table" and table._index)then
		local idx=table._index;
		for i,val in table._pool do
			_func=val[idx];
			if(type(_func)=="function")then
				arg[1]=val;
				call(_func,arg);
			end
		end
	else
		error("call expression in not a function");
	end
	table._index=nil;
end

function MethodDispatcherPool:new()
	local mmp=new(MethodDispatcherPool);
	local tag=newtag()
	settagmethod(tag,"index",MethodDispatcherPool.IndexHandler);
	settagmethod(tag,"function",MethodDispatcherPool.CallHandler);
	settag(mmp,tag);
	return mmp;
end