Skip to content

Commit

Permalink
* Split the lua persistance/unpersistance from mission.c.
Browse files Browse the repository at this point in the history
  • Loading branch information
bobbens committed Aug 12, 2010
1 parent 8e1945d commit 0aa34c0
Show file tree
Hide file tree
Showing 4 changed files with 362 additions and 318 deletions.
2 changes: 2 additions & 0 deletions src/Makefile.am
Expand Up @@ -86,6 +86,7 @@ naev_SOURCES = \
npc.c \
ntime.c \
nxml.c \
nxml_lua.c \
opengl.c \
opengl_ext.c \
opengl_matrix.c \
Expand Down Expand Up @@ -199,6 +200,7 @@ naev_SOURCES = \
nstd.h \
ntime.h \
nxml.h \
nxml_lua.h \
opengl.h \
opengl_ext.h \
opengl_matrix.h \
Expand Down
321 changes: 3 additions & 318 deletions src/mission.c
Expand Up @@ -27,6 +27,7 @@
#include "hook.h"
#include "ndata.h"
#include "nxml.h"
#include "nxml_lua.h"
#include "faction.h"
#include "player.h"
#include "base64.h"
Expand Down Expand Up @@ -78,11 +79,6 @@ static int mission_location( const char* loc );
/* Loading. */
static int mission_parse( MissionData* temp, const xmlNodePtr parent );
static int missions_parseActive( xmlNodePtr parent );
/* Persistance. */
static int mission_persistDataNode( lua_State *L, xmlTextWriterPtr writer, int intable );
static int mission_persistData( lua_State *L, xmlTextWriterPtr writer );
static int mission_unpersistDataNode( lua_State *L, xmlNodePtr parent );
static int mission_unpersistData( lua_State *L, xmlNodePtr parent );
/* externed */
int missions_saveActive( xmlTextWriterPtr writer );
int missions_loadActive( xmlNodePtr parent );
Expand Down Expand Up @@ -895,317 +891,6 @@ void missions_cleanup (void)
}



/**
* @brief Persists Lua data.
*
* @param writer XML Writer to use to persist stuff.
* @param type Type of the data to save.
* @param name Name of the data to save.
* @param value Value of the data to save.
* @return 0 on success.
*/
static int mission_saveData( xmlTextWriterPtr writer,
const char *type, const char *name, const char *value,
int keynum )
{
xmlw_startElem(writer,"data");

xmlw_attr(writer,"type","%s",type);
xmlw_attr(writer,"name","%s",name);
if (keynum)
xmlw_attr(writer,"keynum","1");
xmlw_str(writer,"%s",value);

xmlw_endElem(writer); /* "data" */

return 0;
}


/**
* @brief Persists the node on the top of the stack and pops it.
*
* @param L Lua state with node to persist on top of the stack.
* @param writer XML Writer to use.
* @param Are we parsing a node in a table? Avoids checking for extra __save.
* @return 0 on success.
*/
static int mission_persistDataNode( lua_State *L, xmlTextWriterPtr writer, int intable )
{
int ret, b;
LuaPlanet *p;
LuaSystem *s;
LuaFaction *f;
LuaShip *sh;
char buf[PATH_MAX];
const char *name, *str;
int keynum;

/* Default values. */
ret = 0;

/* key, value */
/* Handle different types of keys. */
switch (lua_type(L, -2)) {
case LUA_TSTRING:
/* Can just tostring directly. */
name = lua_tostring(L,-2);
/* Isn't a number key. */
keynum = 0;
break;
case LUA_TNUMBER:
/* Can't tostring directly. */
lua_pushvalue(L,-2);
name = lua_tostring(L,-1);
lua_pop(L,1);
/* Is a number key. */
keynum = 1;
break;

/* We only handle string or number keys, so ignore the rest. */
default:
lua_pop(L,1);
/* key */
return 0;
}
/* key, value */

/* Now handle the value. */
switch (lua_type(L, -1)) {
/* Recursive for tables. */
case LUA_TTABLE:
/* Check if should save -- only if not in table.. */
if (!intable) {
lua_getfield(L, -1, "__save");
b = lua_toboolean(L,-1);
lua_pop(L,1);
if (!b) /* No need to save. */
break;
}
/* Start the table. */
xmlw_startElem(writer,"data");
xmlw_attr(writer,"type","table");
xmlw_attr(writer,"name","%s",name);
if (keynum)
xmlw_attr(writer,"keynum","1");
lua_pushnil(L); /* key, value, nil */
/* key, value, nil */
while (lua_next(L, -2) != 0) {
/* key, value, key, value */
ret = mission_persistDataNode( L, writer, 1 );
/* key, value, key */
}
/* key, value */
xmlw_endElem(writer); /* "table" */
break;

/* Normal number. */
case LUA_TNUMBER:
mission_saveData( writer, "number",
name, lua_tostring(L,-1), keynum );
/* key, value */
break;

/* Boolean is either 1 or 0. */
case LUA_TBOOLEAN:
/* lua_tostring doesn't work on booleans. */
if (lua_toboolean(L,-1)) buf[0] = '1';
else buf[0] = '0';
buf[1] = '\0';
mission_saveData( writer, "bool",
name, buf, keynum );
/* key, value */
break;

/* String is saved normally. */
case LUA_TSTRING:
mission_saveData( writer, "string",
name, lua_tostring(L,-1), keynum );
/* key, value */
break;

/* User data must be handled here. */
case LUA_TUSERDATA:
if (lua_isplanet(L,-1)) {
p = lua_toplanet(L,-1);
mission_saveData( writer, "planet",
name, p->p->name, keynum );
/* key, value */
break;
}
else if (lua_issystem(L,-1)) {
s = lua_tosystem(L,-1);
mission_saveData( writer, "system",
name, s->s->name, keynum );
/* key, value */
break;
}
else if (lua_isfaction(L,-1)) {
f = lua_tofaction(L,-1);
str = faction_name( f->f );
if (str == NULL)
break;
mission_saveData( writer, "faction",
name, str, keynum );
/* key, value */
break;
}
else if (lua_isship(L,-1)) {
sh = lua_toship(L,-1);
str = sh->ship->name;
if (str == NULL)
break;
mission_saveData( writer, "ship",
name, str, keynum );
/* key, value */
break;
}

/* Rest gets ignored, like functions, etc... */
default:
/* key, value */
break;
}
lua_pop(L,1);
/* key */

return ret;
}


/**
* @brief Persists all the mission Lua data.
*
* Does not save anything in tables nor functions of any type.
*
* @param L Lua state to save.
* @param writer XML Writer to use.
* @return 0 on success.
*/
static int mission_persistData( lua_State *L, xmlTextWriterPtr writer )
{
int ret = 0;

lua_pushstring(L,"_G");
lua_pushnil(L);
/* str, nil */
while (lua_next(L, LUA_GLOBALSINDEX) != 0) {
/* str, key, value */
ret |= mission_persistDataNode( L, writer, 0 );
/* str, key */
}
/* str */
lua_pop(L,1);

return ret;
}


/**
* @brief Unpersists Lua data.
*
* @param L State to unperisist data into.
* @param parent Node containing all the Lua persisted data.
* @return 0 on success.
*/
static int mission_unpersistDataNode( lua_State *L, xmlNodePtr parent )
{
LuaPlanet p;
LuaSystem s;
LuaFaction f;
LuaShip sh;
xmlNodePtr node;
char *name, *type, *buf, *num;
int keynum;

node = parent->xmlChildrenNode;
do {
if (xml_isNode(node,"data")) {
/* Get general info. */
xmlr_attr(node,"name",name);
xmlr_attr(node,"type",type);
/* Check to see if key is a number. */
xmlr_attr(node,"keynum",num);
if (num != NULL) {
keynum = 1;
lua_pushnumber(L, atof(name));
free(num);
}
else
lua_pushstring(L, name);

/* handle data types */
/* Recursive tables. */
if (strcmp(type,"table")==0) {
xmlr_attr(node,"name",buf);
/* Create new table. */
lua_newtable(L);
/* Save data. */
mission_unpersistDataNode(L,node);
/* Set table. */
free(buf);
}
else if (strcmp(type,"number")==0)
lua_pushnumber(L,xml_getFloat(node));
else if (strcmp(type,"bool")==0)
lua_pushboolean(L,xml_getInt(node));
else if (strcmp(type,"string")==0)
lua_pushstring(L,xml_get(node));
else if (strcmp(type,"planet")==0) {
p.p = planet_get(xml_get(node));
lua_pushplanet(L,p);
}
else if (strcmp(type,"system")==0) {
s.s = system_get(xml_get(node));
lua_pushsystem(L,s);
}
else if (strcmp(type,"faction")==0) {
f.f = faction_get(xml_get(node));
lua_pushfaction(L,f);
}
else if (strcmp(type,"ship")==0) {
sh.ship = ship_get(xml_get(node));
lua_pushship(L,sh);
}
else {
WARN("Unknown lua data type!");
lua_pop(L,1);
return -1;
}

/* Set field. */
lua_settable(L, -3);

/* cleanup */
free(type);
free(name);
}
} while (xml_nextNode(node));

return 0;
}


/**
* @brief Unpersists Lua data.
*
* @param L State to unperisist data into.
* @param parent Node containing all the Lua persisted data.
* @return 0 on success.
*/
static int mission_unpersistData( lua_State *L, xmlNodePtr parent )
{
int ret;

lua_pushvalue(L,LUA_GLOBALSINDEX);
ret = mission_unpersistDataNode(L,parent);
lua_pop(L,1);

return ret;
}


/**
* @brief Saves the player's active missions.
*
Expand Down Expand Up @@ -1273,7 +958,7 @@ int missions_saveActive( xmlTextWriterPtr writer )
xmlw_startElem(writer,"lua");

/* prepare the data */
mission_persistData(player_missions[i].L, writer);
nxml_persistLua( player_missions[i].L, writer );

xmlw_endElem(writer); /* "lua" */

Expand Down Expand Up @@ -1437,7 +1122,7 @@ static int missions_parseActive( xmlNodePtr parent )

if (xml_isNode(cur,"lua"))
/* start the unpersist routine */
mission_unpersistData(misn->L, cur);
nxml_unpersistLua( misn->L, cur );

} while (xml_nextNode(cur));

Expand Down

0 comments on commit 0aa34c0

Please sign in to comment.