fix setting element properties in legacy lua api

This commit is contained in:
jacob1 2018-05-13 16:16:14 -04:00
parent 9f6f43cf90
commit 36a545124e
5 changed files with 142 additions and 337 deletions

View File

@ -20,6 +20,50 @@
#include "simulation/Simulation.h"
std::map<ByteString, StructProperty> legacyPropNames;
std::map<ByteString, StructProperty> legacyTransitionNames;
void initLegacyProps()
{
std::vector<StructProperty> properties = Element::GetProperties();
for (auto prop : properties)
{
if (prop.Name == "MenuVisible")
legacyPropNames.insert(std::pair<ByteString, StructProperty>("menu", prop));
else if (prop.Name == "PhotonReflectWavelengths")
continue;
else if (prop.Name == "Temperature")
legacyPropNames.insert(std::pair<ByteString, StructProperty>("heat", prop));
else if (prop.Name == "HeatConduct")
legacyPropNames.insert(std::pair<ByteString, StructProperty>("hconduct", prop));
// Put all transition stuff into separate map
else if (prop.Name == "LowPressure")
legacyTransitionNames.insert(std::pair<ByteString, StructProperty>("presLowValue", prop));
else if (prop.Name == "LowPressureTransition")
legacyTransitionNames.insert(std::pair<ByteString, StructProperty>("presLowType", prop));
else if (prop.Name == "HighPressure")
legacyTransitionNames.insert(std::pair<ByteString, StructProperty>("presHighValue", prop));
else if (prop.Name == "HighressureTransition")
legacyTransitionNames.insert(std::pair<ByteString, StructProperty>("presHighType", prop));
else if (prop.Name == "LowTemperature")
legacyTransitionNames.insert(std::pair<ByteString, StructProperty>("tempLowValue", prop));
else if (prop.Name == "LowTemperatureTransition")
legacyTransitionNames.insert(std::pair<ByteString, StructProperty>("tempLowType", prop));
else if (prop.Name == "HighTemperature")
legacyTransitionNames.insert(std::pair<ByteString, StructProperty>("tempHighValue", prop));
else if (prop.Name == "HighTemperatureTransition")
legacyTransitionNames.insert(std::pair<ByteString, StructProperty>("tempHighType", prop));
else
{
ByteString temp = ByteString(prop.Name);
std::transform(temp.begin(), temp.end(), temp.begin(), ::tolower);
legacyPropNames.insert(std::pair<ByteString, StructProperty>(temp, prop));
}
}
}
#ifndef FFI
int luacon_partread(lua_State* l)
{
@ -105,340 +149,99 @@ int luacon_partswrite(lua_State* l)
}
#endif
int luacon_transition_getproperty(const char * key, int * format)
{
int offset;
if (!strcmp(key, "presHighValue")) {
offset = offsetof(Element, HighPressure);
*format = 1;
} else if (!strcmp(key, "presHighType")) {
offset = offsetof(Element, HighPressureTransition);
*format = 0;
} else if (!strcmp(key, "presLowValue")) {
offset = offsetof(Element, LowPressure);
*format = 1;
} else if (!strcmp(key, "presLowType")) {
offset = offsetof(Element, LowPressureTransition);
*format = 0;
} else if (!strcmp(key, "tempHighValue")) {
offset = offsetof(Element, HighTemperature);
*format = 1;
} else if (!strcmp(key, "tempHighType")) {
offset = offsetof(Element, HighTemperatureTransition);
*format = 0;
} else if (!strcmp(key, "tempLowValue")) {
offset = offsetof(Element, LowTemperature);
*format = 1;
} else if (!strcmp(key, "tempLowType")) {
offset = offsetof(Element, LowTemperatureTransition);
*format = 0;
} else {
offset = -1;
}
return offset;
}
int luacon_transitionread(lua_State* l)
{
int format, offset;
int tempinteger;
float tempfloat;
int i;
const char * key = luaL_optstring(l, 2, "");
offset = luacon_transition_getproperty(key, &format);
ByteString key = luaL_optstring(l, 2, "");
if (legacyTransitionNames.find(key) == legacyTransitionNames.end())
return luaL_error(l, "Invalid property");
StructProperty prop = legacyTransitionNames[key];
//Get Raw Index value for element
lua_pushstring(l, "value");
lua_rawget(l, 1);
i = lua_tointeger(l, lua_gettop(l));
int i = lua_tointeger (l, lua_gettop(l));
lua_pop(l, 1);
if (i < 0 || i >= PT_NUM)
{
return luaL_error(l, "Invalid index");
}
intptr_t propertyAddress = (intptr_t)(((unsigned char*)&luacon_sim->elements[i]) + prop.Offset);
LuaScriptInterface::LuaGetProperty(l, prop, propertyAddress);
if (i < 0 || i >= PT_NUM || offset==-1)
{
return luaL_error(l, "Invalid property");
}
switch(format)
{
case 0:
tempinteger = *((int*)(((unsigned char*)&luacon_sim->elements[i])+offset));
lua_pushnumber(l, tempinteger);
break;
case 1:
tempfloat = *((float*)(((unsigned char*)&luacon_sim->elements[i])+offset));
lua_pushnumber(l, tempfloat);
break;
}
return 1;
}
int luacon_transitionwrite(lua_State* l)
{
int format, offset;
int i;
const char * key = luaL_optstring(l, 2, "");
offset = luacon_transition_getproperty(key, &format);
//Get Raw Index value for element
lua_pushstring(l, "value");
lua_rawget(l, 1);
i = lua_tointeger(l, lua_gettop(l));
lua_pop(l, 1);
if (i < 0 || i >= PT_NUM || offset==-1)
{
ByteString key = luaL_optstring(l, 2, "");
if (legacyTransitionNames.find(key) == legacyTransitionNames.end())
return luaL_error(l, "Invalid property");
}
switch(format)
{
case 0:
*((int*)(((unsigned char*)&luacon_sim->elements[i])+offset)) = luaL_optinteger(l, 3, 0);
break;
case 1:
*((float*)(((unsigned char*)&luacon_sim->elements[i])+offset)) = luaL_optnumber(l, 3, 0);
break;
}
return 0;
}
int luacon_element_getproperty(const char * key, int * format, unsigned int * modified_stuff)
{
int offset;
if (!strcmp(key, "name")) {
offset = offsetof(Element, Name);
*format = 2;
if(modified_stuff)
*modified_stuff |= LUACON_EL_MODIFIED_MENUS;
}
else if (!strcmp(key, "color")) {
offset = offsetof(Element, Colour);
*format = 0;
if (modified_stuff)
*modified_stuff |= LUACON_EL_MODIFIED_GRAPHICS | LUACON_EL_MODIFIED_MENUS;
}
else if (!strcmp(key, "colour")) {
offset = offsetof(Element, Colour);
*format = 0;
if (modified_stuff)
*modified_stuff |= LUACON_EL_MODIFIED_GRAPHICS;
}
else if (!strcmp(key, "advection")) {
offset = offsetof(Element, Advection);
*format = 1;
}
else if (!strcmp(key, "airdrag")) {
offset = offsetof(Element, AirDrag);
*format = 1;
}
else if (!strcmp(key, "airloss")) {
offset = offsetof(Element, AirLoss);
*format = 1;
}
else if (!strcmp(key, "loss")) {
offset = offsetof(Element, Loss);
*format = 1;
}
else if (!strcmp(key, "collision")) {
offset = offsetof(Element, Collision);
*format = 1;
}
else if (!strcmp(key, "gravity")) {
offset = offsetof(Element, Gravity);
*format = 1;
}
else if (!strcmp(key, "diffusion")) {
offset = offsetof(Element, Diffusion);
*format = 1;
}
else if (!strcmp(key, "hotair")) {
offset = offsetof(Element, HotAir);
*format = 1;
}
else if (!strcmp(key, "falldown")) {
offset = offsetof(Element, Falldown);
*format = 0;
}
else if (!strcmp(key, "flammable")) {
offset = offsetof(Element, Flammable);
*format = 0;
}
else if (!strcmp(key, "explosive")) {
offset = offsetof(Element, Explosive);
*format = 0;
}
else if (!strcmp(key, "meltable")) {
offset = offsetof(Element, Meltable);
*format = 0;
}
else if (!strcmp(key, "hardness")) {
offset = offsetof(Element, Hardness);
*format = 0;
}
// Not sure if this should be enabled
// Also, needs a new format type for unsigned ints
/*else if (!strcmp(key, "photonreflectwavelengths")) {
offset = offsetof(Element, PhotonReflectWavelengths);
*format = ;
}*/
else if (!strcmp(key, "menu")) {
offset = offsetof(Element, MenuVisible);
*format = 0;
if (modified_stuff)
*modified_stuff |= LUACON_EL_MODIFIED_MENUS;
}
else if (!strcmp(key, "enabled")) {
offset = offsetof(Element, Enabled);
*format = 0;
}
else if (!strcmp(key, "weight")) {
offset = offsetof(Element, Weight);
*format = 0;
if (modified_stuff)
*modified_stuff |= LUACON_EL_MODIFIED_CANMOVE;
}
else if (!strcmp(key, "menusection")) {
offset = offsetof(Element, MenuSection);
*format = 0;
if (modified_stuff)
*modified_stuff |= LUACON_EL_MODIFIED_MENUS;
}
else if (!strcmp(key, "heat")) {
offset = offsetof(Element, Temperature);
*format = 1;
}
else if (!strcmp(key, "hconduct")) {
offset = offsetof(Element, HeatConduct);
*format = 3;
}
else if (!strcmp(key, "state")) {
offset = 0;
*format = -1;
}
else if (!strcmp(key, "properties")) {
offset = offsetof(Element, Properties);
*format = 0;
if (modified_stuff)
*modified_stuff |= LUACON_EL_MODIFIED_GRAPHICS | LUACON_EL_MODIFIED_CANMOVE;
}
else if (!strcmp(key, "description")) {
offset = offsetof(Element, Description);
*format = 2;
if(modified_stuff)
*modified_stuff |= LUACON_EL_MODIFIED_MENUS;
}
else {
return -1;
}
return offset;
}
int luacon_elementread(lua_State* l)
{
int format, offset;
char * tempstring;
int tempinteger;
float tempfloat;
int i;
const char * key = luaL_optstring(l, 2, "");
offset = luacon_element_getproperty(key, &format, NULL);
StructProperty prop = legacyTransitionNames[key];
//Get Raw Index value for element
lua_pushstring(l, "id");
lua_rawget(l, 1);
i = lua_tointeger (l, lua_gettop(l));
int i = lua_tointeger (l, lua_gettop(l));
lua_pop(l, 1);
if (i < 0 || i >= PT_NUM)
{
return luaL_error(l, "Invalid index");
}
if (i < 0 || i >= PT_NUM || offset==-1)
{
intptr_t propertyAddress = (intptr_t)(((unsigned char*)&luacon_sim->elements[i]) + prop.Offset);
LuaScriptInterface::LuaSetProperty(l, prop, propertyAddress, 3);
return 0;
}
int luacon_elementread(lua_State* l)
{
ByteString key = luaL_optstring(l, 2, "");
if (legacyPropNames.find(key) == legacyPropNames.end())
return luaL_error(l, "Invalid property");
}
switch(format)
StructProperty prop = legacyPropNames[key];
//Get Raw Index value for element
lua_pushstring(l, "id");
lua_rawget(l, 1);
int i = lua_tointeger (l, lua_gettop(l));
lua_pop(l, 1);
if (i < 0 || i >= PT_NUM)
{
case 0:
tempinteger = *((int*)(((unsigned char*)&luacon_sim->elements[i])+offset));
lua_pushnumber(l, tempinteger);
break;
case 1:
tempfloat = *((float*)(((unsigned char*)&luacon_sim->elements[i])+offset));
lua_pushnumber(l, tempfloat);
break;
case 2:
tempstring = *((char**)(((unsigned char*)&luacon_sim->elements[i])+offset));
lua_pushstring(l, tempstring);
break;
case 3:
tempinteger = *((unsigned char*)(((unsigned char*)&luacon_sim->elements[i])+offset));
lua_pushnumber(l, tempinteger);
break;
default:
lua_pushnumber(l, 0);
return luaL_error(l, "Invalid index");
}
intptr_t propertyAddress = (intptr_t)(((unsigned char*)&luacon_sim->elements[i]) + prop.Offset);
LuaScriptInterface::LuaGetProperty(l, prop, propertyAddress);
return 1;
}
int luacon_elementwrite(lua_State* l)
{
int format, offset;
char * tempstring;
int i;
unsigned int modified_stuff = 0;
const char * key = luaL_optstring(l, 2, "");
offset = luacon_element_getproperty(key, &format, &modified_stuff);
ByteString key = luaL_optstring(l, 2, "");
if (legacyPropNames.find(key) == legacyPropNames.end())
return luaL_error(l, "Invalid property");
StructProperty prop = legacyPropNames[key];
//Get Raw Index value for element
lua_pushstring(l, "id");
lua_rawget(l, 1);
i = lua_tointeger (l, lua_gettop(l));
int i = lua_tointeger (l, lua_gettop(l));
lua_pop(l, 1);
if (i < 0 || i >= PT_NUM)
{
return luaL_error(l, "Invalid index");
}
intptr_t propertyAddress = (intptr_t)(((unsigned char*)&luacon_sim->elements[i]) + prop.Offset);
LuaScriptInterface::LuaSetProperty(l, prop, propertyAddress, 3);
luacon_model->BuildMenus();
luacon_sim->init_can_move();
memset(luacon_ren->graphicscache, 0, sizeof(gcache_item)*PT_NUM);
if (i < 0 || i >= PT_NUM || offset==-1)
{
return luaL_error(l, "Invalid property");
}
switch(format)
{
case 0:
*((int*)(((unsigned char*)&luacon_sim->elements[i])+offset)) = luaL_optinteger(l, 3, 0);
break;
case 1:
*((float*)(((unsigned char*)&luacon_sim->elements[i])+offset)) = luaL_optnumber(l, 3, 0);
break;
case 2:
tempstring = mystrdup((char*)luaL_optstring(l, 3, ""));
if (!strcmp(key, "name"))
{
//Convert to upper case
for (size_t j = 0; j < strlen(tempstring); j++)
tempstring[j] = toupper(tempstring[j]);
if(luacon_sim->GetParticleType(tempstring) != -1)
{
free(tempstring);
return luaL_error(l, "Name in use");
}
}
*((char**)(((unsigned char*)&luacon_sim->elements[i])+offset)) = tempstring;
//Need some way of cleaning up previous values
break;
case 3:
*((unsigned char*)(((unsigned char*)&luacon_sim->elements[i])+offset)) = luaL_optinteger(l, 3, 0);
break;
}
if (modified_stuff)
{
if (modified_stuff & LUACON_EL_MODIFIED_MENUS)
luacon_model->BuildMenus();
if (modified_stuff & LUACON_EL_MODIFIED_CANMOVE)
luacon_sim->init_can_move();
if (modified_stuff & LUACON_EL_MODIFIED_GRAPHICS)
memset(luacon_ren->graphicscache, 0, sizeof(gcache_item)*PT_NUM);
}
return 0;
}

View File

@ -27,6 +27,7 @@ int luacon_keyevent(int key, Uint16 character, int modifier, int event);
int luacon_eval(const char *command);
String luacon_geterror();
void luacon_close();
void initLegacyProps();
int luacon_partsread(lua_State* l);
int luacon_partswrite(lua_State* l);
int luacon_partread(lua_State* l);
@ -35,8 +36,6 @@ int luacon_elementread(lua_State* l);
int luacon_elementwrite(lua_State* l);
int luacon_transitionread(lua_State* l);
int luacon_transitionwrite(lua_State* l);
int luacon_transition_getproperty(const char * key, int * format);
int luacon_element_getproperty(const char * key, int * format, unsigned int * modified_stuff);
//int process_command_lua(pixel *vid_buf, char *console, char *console_error);
//Interface

View File

@ -359,6 +359,7 @@ tpt.partsdata = nil");
lua_setfield(l, -2, "__newindex");
lua_setmetatable(l, -2);
initLegacyProps();
}
void LuaScriptInterface::Init()

View File

@ -122,8 +122,6 @@ class LuaScriptInterface: public CommandInterface
//Elements
void initElementsAPI();
static void LuaGetProperty(lua_State* l, StructProperty property, intptr_t propertyAddress);
static void LuaSetProperty(lua_State* l, StructProperty property, intptr_t propertyAddress, int stackPos);
static int elements_allocate(lua_State * l);
static int elements_element(lua_State * l);
static int elements_property(lua_State * l);
@ -173,6 +171,9 @@ public:
int tpt_index(lua_State *l);
int tpt_newIndex(lua_State *l);
static void LuaGetProperty(lua_State* l, StructProperty property, intptr_t propertyAddress);
static void LuaSetProperty(lua_State* l, StructProperty property, intptr_t propertyAddress, int stackPos);
ui::Window * Window;
lua_State *l;
LuaScriptInterface(GameController * c, GameModel * m);

View File

@ -51,39 +51,40 @@ Element::Element():
std::vector<StructProperty> Element::GetProperties()
{
std::vector<StructProperty> properties;
properties.push_back(StructProperty("Name", StructProperty::BString, offsetof(Element, Name)));
properties.push_back(StructProperty("Colour", StructProperty::Colour, offsetof(Element, Colour)));
properties.push_back(StructProperty("Color", StructProperty::Colour, offsetof(Element, Colour)));
properties.push_back(StructProperty("MenuVisible", StructProperty::Integer, offsetof(Element, MenuVisible)));
properties.push_back(StructProperty("MenuSection", StructProperty::Integer, offsetof(Element, MenuSection)));
properties.push_back(StructProperty("Advection", StructProperty::Float, offsetof(Element, Advection)));
properties.push_back(StructProperty("AirDrag", StructProperty::Float, offsetof(Element, AirDrag)));
properties.push_back(StructProperty("AirLoss", StructProperty::Float, offsetof(Element, AirLoss)));
properties.push_back(StructProperty("Loss", StructProperty::Float, offsetof(Element, Loss)));
properties.push_back(StructProperty("Collision", StructProperty::Float, offsetof(Element, Collision)));
properties.push_back(StructProperty("Gravity", StructProperty::Float, offsetof(Element, Gravity)));
properties.push_back(StructProperty("Diffusion", StructProperty::Float, offsetof(Element, Diffusion)));
properties.push_back(StructProperty("HotAir", StructProperty::Float, offsetof(Element, HotAir)));
properties.push_back(StructProperty("Falldown", StructProperty::Integer, offsetof(Element, Falldown)));
properties.push_back(StructProperty("Flammable", StructProperty::Integer, offsetof(Element, Flammable)));
properties.push_back(StructProperty("Explosive", StructProperty::Integer, offsetof(Element, Explosive)));
properties.push_back(StructProperty("Meltable", StructProperty::Integer, offsetof(Element, Meltable)));
properties.push_back(StructProperty("Hardness", StructProperty::Integer, offsetof(Element, Hardness)));
properties.push_back(StructProperty("PhotonReflectWavelengths", StructProperty::UInteger, offsetof(Element, PhotonReflectWavelengths)));
properties.push_back(StructProperty("Weight", StructProperty::Integer, offsetof(Element, Weight)));
properties.push_back(StructProperty("Temperature", StructProperty::Float, offsetof(Element, Temperature)));
properties.push_back(StructProperty("HeatConduct", StructProperty::UChar, offsetof(Element, HeatConduct)));
properties.push_back(StructProperty("Description", StructProperty::String, offsetof(Element, Description)));
properties.push_back(StructProperty("State", StructProperty::Removed, 0));
properties.push_back(StructProperty("Properties", StructProperty::Integer, offsetof(Element, Properties)));
properties.push_back(StructProperty("LowPressure", StructProperty::Float, offsetof(Element, LowPressure)));
properties.push_back(StructProperty("LowPressureTransition", StructProperty::Integer, offsetof(Element, LowPressureTransition)));
properties.push_back(StructProperty("HighPressure", StructProperty::Float, offsetof(Element, HighPressure)));
properties.push_back(StructProperty("HighPressureTransition", StructProperty::Integer, offsetof(Element, HighPressureTransition)));
properties.push_back(StructProperty("LowTemperature", StructProperty::Float, offsetof(Element, LowTemperature)));
properties.push_back(StructProperty("LowTemperatureTransition", StructProperty::Integer, offsetof(Element, LowTemperatureTransition)));
properties.push_back(StructProperty("HighTemperature", StructProperty::Float, offsetof(Element, HighTemperature)));
properties.push_back(StructProperty("HighTemperatureTransition", StructProperty::Integer, offsetof(Element, HighTemperatureTransition)));
properties.push_back(StructProperty("Name", StructProperty::BString, offsetof(Element, Name)));
properties.push_back(StructProperty("Colour", StructProperty::Colour, offsetof(Element, Colour)));
properties.push_back(StructProperty("Color", StructProperty::Colour, offsetof(Element, Colour)));
properties.push_back(StructProperty("MenuVisible", StructProperty::Integer, offsetof(Element, MenuVisible)));
properties.push_back(StructProperty("MenuSection", StructProperty::Integer, offsetof(Element, MenuSection)));
properties.push_back(StructProperty("Enabled", StructProperty::Integer, offsetof(Element, Enabled)));
properties.push_back(StructProperty("Advection", StructProperty::Float, offsetof(Element, Advection)));
properties.push_back(StructProperty("AirDrag", StructProperty::Float, offsetof(Element, AirDrag)));
properties.push_back(StructProperty("AirLoss", StructProperty::Float, offsetof(Element, AirLoss)));
properties.push_back(StructProperty("Loss", StructProperty::Float, offsetof(Element, Loss)));
properties.push_back(StructProperty("Collision", StructProperty::Float, offsetof(Element, Collision)));
properties.push_back(StructProperty("Gravity", StructProperty::Float, offsetof(Element, Gravity)));
properties.push_back(StructProperty("Diffusion", StructProperty::Float, offsetof(Element, Diffusion)));
properties.push_back(StructProperty("HotAir", StructProperty::Float, offsetof(Element, HotAir)));
properties.push_back(StructProperty("Falldown", StructProperty::Integer, offsetof(Element, Falldown)));
properties.push_back(StructProperty("Flammable", StructProperty::Integer, offsetof(Element, Flammable)));
properties.push_back(StructProperty("Explosive", StructProperty::Integer, offsetof(Element, Explosive)));
properties.push_back(StructProperty("Meltable", StructProperty::Integer, offsetof(Element, Meltable)));
properties.push_back(StructProperty("Hardness", StructProperty::Integer, offsetof(Element, Hardness)));
properties.push_back(StructProperty("PhotonReflectWavelengths", StructProperty::UInteger, offsetof(Element, PhotonReflectWavelengths)));
properties.push_back(StructProperty("Weight", StructProperty::Integer, offsetof(Element, Weight)));
properties.push_back(StructProperty("Temperature", StructProperty::Float, offsetof(Element, Temperature)));
properties.push_back(StructProperty("HeatConduct", StructProperty::UChar, offsetof(Element, HeatConduct)));
properties.push_back(StructProperty("Description", StructProperty::String, offsetof(Element, Description)));
properties.push_back(StructProperty("State", StructProperty::Removed, 0));
properties.push_back(StructProperty("Properties", StructProperty::Integer, offsetof(Element, Properties)));
properties.push_back(StructProperty("LowPressure", StructProperty::Float, offsetof(Element, LowPressure)));
properties.push_back(StructProperty("LowPressureTransition", StructProperty::Integer, offsetof(Element, LowPressureTransition)));
properties.push_back(StructProperty("HighPressure", StructProperty::Float, offsetof(Element, HighPressure)));
properties.push_back(StructProperty("HighPressureTransition", StructProperty::Integer, offsetof(Element, HighPressureTransition)));
properties.push_back(StructProperty("LowTemperature", StructProperty::Float, offsetof(Element, LowTemperature)));
properties.push_back(StructProperty("LowTemperatureTransition", StructProperty::Integer, offsetof(Element, LowTemperatureTransition)));
properties.push_back(StructProperty("HighTemperature", StructProperty::Float, offsetof(Element, HighTemperature)));
properties.push_back(StructProperty("HighTemperatureTransition", StructProperty::Integer, offsetof(Element, HighTemperatureTransition)));
return properties;
}