Extend NumberDesc and StringDesc to lua function.

This commit is contained in:
jarod42 2005-07-10 17:34:47 +00:00
parent f39a826596
commit 4fdab910f9
3 changed files with 103 additions and 0 deletions

View file

@ -77,6 +77,8 @@ and how to use it.
<dl>
<dt>number</dt>
<dd>direct value. Or value which are not recompute during the game.</dd>
<dt>a lua function</dt>
<dd>A Lua function (which take no argument) which returns the value.</dd>
<dt>Add(NumberDesc, NumberDesc)</dt>
<dd>the sum of two numbers.<br>
Note: prefer do (5 + 9) if you can.
@ -145,6 +147,8 @@ and how to use it.
<dl>
<dt>"string"</dt>
<dd>direct value. Or value which are not recompute during the game.</dd>
<dt>a lua function</dt>
<dd>A Lua function (which take no argument) which returns the value.</dd>
<dt>Concat(StringDesc, StringDesc[, StringDesc, ...])</dt>
<dd>Concatenation of several strings.</dd>
<dt>String(NumberDesc)</dt>

View file

@ -76,6 +76,7 @@ extern int LuaCall(int narg, int clear);
#include "iolib.h"
typedef enum {
ENumber_Lua, /// a lua function.
ENumber_Dir, /// directly a number.
ENumber_Add, /// a + b.
ENumber_Sub, /// a - b.
@ -107,6 +108,7 @@ typedef enum {
} EUnit; /// All possible value for a unit.
typedef enum {
EString_Lua, /// a lua function.
EString_Dir, /// directly a string.
EString_Concat, /// a + b [+ c ...].
EString_String, /// Convert number in string.
@ -180,6 +182,7 @@ typedef struct {
struct _NumberDesc_ {
ENumber e; /// which number.
union {
unsigned int Index; /// index of the lua function.
int Val; /// Direct value.
NumberDesc* N; /// Other number.
BinOp BinOp; /// For binary operand.
@ -217,6 +220,7 @@ struct _UnitDesc_ {
struct _StringDesc_ {
EString e; /// which number.
union {
unsigned int Index; /// index of the lua function.
char *Val; /// Direct value.
struct {
StringDesc** Strings; /// Array of operands.

View file

@ -95,6 +95,9 @@ int NoRandomPlacementMultiplayer = 0; /// Disable the random placement of player
char UseHPForXp = 0; /// true if gain XP by dealing damage, false if by killing.
NumberDesc* Damage; /// Damage calculation for missile.
static int NumberCounter = 0; /// Counter for lua function.
static int StringCounter = 0; /// Counter for lua function.
/*----------------------------------------------------------------------------
-- Functions
----------------------------------------------------------------------------*/
@ -471,6 +474,83 @@ UnitDesc* CclParseUnitDesc(lua_State* l)
}
/**
** Add a Lua handler
**
** @param l lua state.
** @param tablename name of the lua table.
** @param counter Counter for the handler
**
** @return handle of the function.
*/
static int ParseLuaFunction(lua_State* l, const char* tablename, int* counter)
{
lua_pushstring(l, tablename);
lua_gettable(l, LUA_GLOBALSINDEX);
if (lua_isnil(l, -1)) {
lua_pop(l, 1);
lua_pushstring(l, tablename);
lua_newtable(l);
lua_settable(l, LUA_GLOBALSINDEX);
lua_pushstring(l, tablename);
lua_gettable(l, LUA_GLOBALSINDEX);
}
lua_pushvalue(l, -2);
lua_rawseti(l, -2, *counter);
lua_pop(l, 1);
return (*counter)++;
}
/**
** Call a Lua handler
**
** @param handler handler of the lua function to call.
**
** @return lua function result.
*/
static int CallLuaNumberFunction(unsigned int handler)
{
int narg;
int res;
narg = lua_gettop(Lua);
lua_pushstring(Lua, "_numberfunction_");
lua_gettable(Lua, LUA_GLOBALSINDEX);
lua_rawgeti(Lua, -1, handler);
LuaCall(0, 0);
if (lua_gettop(Lua) - narg != 2) {
LuaError(Lua, "Function must return one value.");
}
res = LuaToNumber(Lua, -1);
lua_pop(Lua, 2);
return res;
}
/**
** Call a Lua handler
**
** @param handler handler of the lua function to call.
**
** @return lua function result.
*/
static char* CallLuaStringFunction(unsigned int handler)
{
int narg;
char* res;
narg = lua_gettop(Lua);
lua_pushstring(Lua, "_stringfunction_");
lua_gettable(Lua, LUA_GLOBALSINDEX);
lua_rawgeti(Lua, -1, handler);
LuaCall(0, 0);
if (lua_gettop(Lua) - narg != 2) {
LuaError(Lua, "Function must return one value.");
}
res = strdup(LuaToString(Lua, -1));
lua_pop(Lua, 2);
return res;
}
/**
** Return number.
**
@ -488,6 +568,9 @@ NumberDesc* CclParseNumberDesc(lua_State* l)
if (lua_isnumber(l, -1)) {
res->e = ENumber_Dir;
res->D.Val = LuaToNumber(l, -1);
} else if (lua_isfunction(l, -1)) {
res->e = ENumber_Lua;
res->D.Index = ParseLuaFunction(l, "_numberfunction_", &NumberCounter);
} else if (lua_istable(l, -1)) {
nargs = luaL_getn(l, -1);
if (nargs != 2) {
@ -663,6 +746,9 @@ StringDesc* CclParseStringDesc(lua_State* l)
if (lua_isstring(l, -1)) {
res->e = EString_Dir;
res->D.Val = strdup(LuaToString(l, -1));
} else if (lua_isfunction(l, -1)) {
res->e = EString_Lua;
res->D.Index = ParseLuaFunction(l, "_stringfunction_", &StringCounter);
} else if (lua_istable(l, -1)) {
nargs = luaL_getn(l, -1);
if (nargs != 2) {
@ -809,6 +895,8 @@ int EvalNumber(const NumberDesc* number)
Assert(number);
switch (number->e) {
case ENumber_Lua : // a lua function.
return CallLuaNumberFunction(number->D.Index);
case ENumber_Dir : // directly a number.
return number->D.Val;
case ENumber_Add : // a + b.
@ -910,6 +998,8 @@ char* EvalString(const StringDesc* s)
Assert(s);
switch (s->e) {
case EString_Lua : // a lua function.
return CallLuaStringFunction(s->D.Index);
case EString_Dir : // directly a string.
return strdup(s->D.Val);
case EString_Concat : // a + b -> "ab"
@ -1058,6 +1148,8 @@ void FreeNumberDesc(NumberDesc* number)
return;
}
switch (number->e) {
case ENumber_Lua : // a lua function.
// FIXME: when lua table should be freed ?
case ENumber_Dir : // directly a number.
break;
case ENumber_Add : // a + b.
@ -1110,6 +1202,9 @@ void FreeStringDesc(StringDesc* s)
return;
}
switch (s->e) {
case EString_Lua : // a lua function.
// FIXME: when lua table should be freed ?
break;
case EString_Dir : // directly a string.
free(s->D.Val);
break;