lua-users home
lua-l archive

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


> From: Tim Conkling [mailto:tconkling@brown.edu]
> Sent: Wednesday, October 22, 2003 5:50 PM
> To: lua-l
> Subject: transparent manipulation of C data
> 
> In my game, each sprite is associated with a script that can modify
its
> member variables on a per-frame basis. Right now I'm simply exposing
> some accessor and mutator functions (like get/setSpeed and
> get/setAnimation) to the Lua environment that the scripts run in, and
> the scripts call those functions directly to manipulate the sprites.
> 
> This isn't so bad, but it's kind of ugly:
> 
> setSpeed(-getSpeed())
> setAnimation("walk right")
> 
> It would be nice if users could instead do:
> 
> self.speed = self.speed * 2;
> self.animation = "walk right"
> 
> So I was thinking of doing something like this:
> 
> mt = {}
> 
> mt.__newIndex(t, k, v)
> 	if(k == "speed") then
> 		setSpeed(v);
> 	elseif(k == "animation") then
> 		setAnimation(v);
> 	else
> 		rawset(t, k, v)
> 	end
> end
> 
> mt.__index(t, k)
> 	if(k == "speed") then
> 		return getSpeed();
> 	elseif(k == "animation") then
> 		return getAnimation();
> 	endif
> 
> 	return rawget(t, k)
> end
> 
> I'm worried, however, that I'll be slowing things down unnecessarily
by
> adopting this strategy. For sprites, there will probably be about 15
or
> 20 different variables that can modified, which is a lot of
> if-elseif-elseif... checks. Is there a better way to do what I'm
trying
> to do? Also, are there any pitfalls to watch out for with this method?

If you are worried about speed, don't use conditional statements to find
what the accessor is, use a table. Delphi (and Borland C++ Builder) use
a scheme similar to the following:

-- object type field accessors:
fields = {
  <field name> = { get = <get fn>, set = <set fn> }
  ...
}

Lua table lookups are very fast. You could also add validation fns to
the get and set list, etc. I'll leave you to work out the implementation
details.

Just a note in case you get stuck: new index will only fire the first
time set is called so you need to attach the metamethods to a proxy
table (which remains empty) and all the values go in a seperate values
table.

Nick