Fix transition properties not being validated

Also clean up some more of the Lua API code, again. Eww.
This commit is contained in:
Tamás Bálint Misius 2019-06-02 17:06:18 +02:00
parent 20c98e9b48
commit 8671332e60
No known key found for this signature in database
GPG Key ID: 5B472A12F6ECA9F2
7 changed files with 175 additions and 185 deletions

View File

@ -4,6 +4,7 @@
#include <vector>
#include <fstream>
#include <algorithm>
#include "Config.h"
#include "Format.h"
@ -33,6 +34,7 @@
#include "simulation/Simulation.h"
#include "simulation/ElementGraphics.h"
#include "simulation/ElementCommon.h"
#include "simulation/Air.h"
#include "ToolClasses.h"
@ -712,9 +714,6 @@ int simulation_deletesign(lua_State *l)
//// Begin Simulation API
StructProperty * LuaScriptInterface::particleProperties;
int LuaScriptInterface::particlePropertiesCount;
void LuaScriptInterface::initSimulationAPI()
{
//Methods
@ -817,14 +816,13 @@ void LuaScriptInterface::initSimulationAPI()
SETCONST(l, PMAPMASK);
//Declare FIELD_BLAH constants
std::vector<StructProperty> particlePropertiesV = Particle::GetProperties();
particlePropertiesCount = 0;
particleProperties = new StructProperty[particlePropertiesV.size()];
for(std::vector<StructProperty>::iterator iter = particlePropertiesV.begin(), end = particlePropertiesV.end(); iter != end; ++iter)
{
lua_pushinteger(l, particlePropertiesCount);
lua_setfield(l, -2, ("FIELD_" + (*iter).Name.ToUpper()).c_str());
particleProperties[particlePropertiesCount++] = *iter;
int particlePropertiesCount = 0;
for (auto &prop : Particle::GetProperties())
{
lua_pushinteger(l, particlePropertiesCount++);
lua_setfield(l, -2, ("FIELD_" + prop.Name.ToUpper()).c_str());
}
}
lua_newtable(l);
@ -1020,29 +1018,29 @@ int LuaScriptInterface::simulation_partProperty(lua_State * l)
}
}
auto &properties = Particle::GetProperties();
auto prop = properties.end();
//Get field
if (lua_type(l, 2) == LUA_TNUMBER)
{
int fieldID = lua_tointeger(l, 2);
if (fieldID < 0 || fieldID >= particlePropertiesCount)
if (fieldID < 0 || fieldID >= (int)properties.size())
{
return luaL_error(l, "Invalid field ID (%d)", fieldID);
property = particleProperties[fieldID];
}
prop = properties.begin() + fieldID;
}
else if(lua_type(l, 2) == LUA_TSTRING)
else if (lua_type(l, 2) == LUA_TSTRING)
{
ByteString fieldName = lua_tostring(l, 2);
bool foundProperty = false;
for(int i = particlePropertiesCount-1; i >= 0; i--)
prop = std::find_if(properties.begin(), properties.end(), [&fieldName](StructProperty const &p) {
return p.Name == fieldName;
});
if (prop == properties.end())
{
if (particleProperties[i].Name == fieldName)
{
property = particleProperties[i];
foundProperty = true;
break;
}
}
if (!foundProperty)
return luaL_error(l, "Unknown field (%s)", fieldName.c_str());
}
}
else
{
@ -1050,16 +1048,16 @@ int LuaScriptInterface::simulation_partProperty(lua_State * l)
}
//Calculate memory address of property
intptr_t propertyAddress = (intptr_t)(((unsigned char*)&luacon_sim->parts[particleID])+property.Offset);
intptr_t propertyAddress = (intptr_t)(((unsigned char*)&luacon_sim->parts[particleID]) + prop->Offset);
if(argCount == 3)
{
LuaSetProperty(l, property, propertyAddress, 3);
LuaSetProperty(l, *prop, propertyAddress, 3);
return 0;
}
else
{
LuaGetProperty(l, property, propertyAddress);
LuaGetProperty(l, *prop, propertyAddress);
return 1;
}
}
@ -2473,6 +2471,7 @@ void LuaScriptInterface::LuaGetProperty(lua_State* l, StructProperty property, i
{
switch (property.Type)
{
case StructProperty::TransitionType:
case StructProperty::ParticleType:
case StructProperty::Integer:
lua_pushinteger(l, *((int*)propertyAddress));
@ -2517,6 +2516,7 @@ void LuaScriptInterface::LuaSetProperty(lua_State* l, StructProperty property, i
{
switch (property.Type)
{
case StructProperty::TransitionType:
case StructProperty::ParticleType:
case StructProperty::Integer:
*((int*)propertyAddress) = luaL_checkinteger(l, stackPos);
@ -2674,79 +2674,68 @@ int LuaScriptInterface::elements_allocate(lua_State * l)
int LuaScriptInterface::elements_element(lua_State * l)
{
int args = lua_gettop(l);
int id;
luaL_checktype(l, 1, LUA_TNUMBER);
id = lua_tointeger(l, 1);
if(id < 0 || id >= PT_NUM || !luacon_sim->elements[id].Enabled)
int id = luaL_checkinteger(l, 1);
if (!luacon_sim->IsValidElement(id))
{
return luaL_error(l, "Invalid element");
}
if(args > 1)
if (lua_gettop(l) > 1)
{
luaL_checktype(l, 2, LUA_TTABLE);
std::vector<StructProperty> properties = Element::GetProperties();
//Write values from native data to a table
for(std::vector<StructProperty>::iterator iter = properties.begin(), end = properties.end(); iter != end; ++iter)
for (auto &prop : Element::GetProperties())
{
lua_getfield(l, -1, (*iter).Name.c_str());
if(lua_type(l, -1) != LUA_TNIL)
lua_getfield(l, -1, prop.Name.c_str());
if (lua_type(l, -1) != LUA_TNIL)
{
intptr_t propertyAddress = (intptr_t)(((unsigned char*)&luacon_sim->elements[id]) + (*iter).Offset);
LuaSetProperty(l, (*iter), propertyAddress, -1);
intptr_t propertyAddress = (intptr_t)(((unsigned char*)&luacon_sim->elements[id]) + prop.Offset);
LuaSetProperty(l, prop, propertyAddress, -1);
}
lua_pop(l, 1);
}
lua_getfield(l, -1, "Update");
if(lua_type(l, -1) == LUA_TFUNCTION)
if (lua_type(l, -1) == LUA_TFUNCTION)
{
lua_el_func[id].Assign(-1);
lua_pop(l, 1);
lua_el_mode[id] = 1;
}
else if(lua_type(l, -1) == LUA_TBOOLEAN && !lua_toboolean(l, -1))
else if (lua_type(l, -1) == LUA_TBOOLEAN && !lua_toboolean(l, -1))
{
lua_el_func[id].Clear();
lua_pop(l, 1);
lua_el_mode[id] = 0;
luacon_sim->elements[id].Update = NULL;
}
else
lua_pop(l, 1);
lua_pop(l, 1);
lua_getfield(l, -1, "Graphics");
if(lua_type(l, -1) == LUA_TFUNCTION)
if (lua_type(l, -1) == LUA_TFUNCTION)
{
lua_gr_func[id].Assign(-1);
lua_pop(l, 1);
}
else if(lua_type(l, -1) == LUA_TBOOLEAN && !lua_toboolean(l, -1))
else if (lua_type(l, -1) == LUA_TBOOLEAN && !lua_toboolean(l, -1))
{
lua_gr_func[id].Clear();
lua_pop(l, 1);
luacon_sim->elements[id].Graphics = NULL;
}
else
lua_pop(l, 1);
lua_pop(l, 1);
luacon_model->BuildMenus();
luacon_sim->init_can_move();
luacon_ren->graphicscache[id].isready = 0;
lua_pop(l, 1);
return 0;
}
else
{
std::vector<StructProperty> properties = Element::GetProperties();
//Write values from native data to a table
lua_newtable(l);
for(std::vector<StructProperty>::iterator iter = properties.begin(), end = properties.end(); iter != end; ++iter)
for (auto &prop : Element::GetProperties())
{
intptr_t propertyAddress = (intptr_t)(((unsigned char*)&luacon_sim->elements[id]) + (*iter).Offset);
LuaGetProperty(l, (*iter), propertyAddress);
lua_setfield(l, -2, (*iter).Name.c_str());
intptr_t propertyAddress = (intptr_t)(((unsigned char*)&luacon_sim->elements[id]) + prop.Offset);
LuaGetProperty(l, prop, propertyAddress);
lua_setfield(l, -2, prop.Name.c_str());
}
lua_pushstring(l, luacon_sim->elements[id].Identifier.c_str());
lua_setfield(l, -2, "Identifier");
@ -2756,134 +2745,122 @@ int LuaScriptInterface::elements_element(lua_State * l)
int LuaScriptInterface::elements_property(lua_State * l)
{
int args = lua_gettop(l);
int id;
ByteString propertyName;
luaL_checktype(l, 1, LUA_TNUMBER);
id = lua_tointeger(l, 1);
luaL_checktype(l, 2, LUA_TSTRING);
propertyName = ByteString(lua_tostring(l, 2));
if(id < 0 || id >= PT_NUM || !luacon_sim->elements[id].Enabled)
return luaL_error(l, "Invalid element");
if(args > 2)
int id = luaL_checkinteger(l, 1);
if (!luacon_sim->IsValidElement(id))
{
StructProperty property;
bool propertyFound = false;
std::vector<StructProperty> properties = Element::GetProperties();
return luaL_error(l, "Invalid element");
}
ByteString propertyName(luaL_checklstring(l, 2, NULL));
for(std::vector<StructProperty>::iterator iter = properties.begin(), end = properties.end(); iter != end; ++iter)
{
if((*iter).Name == propertyName)
{
property = *iter;
propertyFound = true;
break;
}
}
auto &properties = Element::GetProperties();
auto prop = std::find_if(properties.begin(), properties.end(), [&propertyName](StructProperty const &p) {
return p.Name == propertyName;
});
if(propertyFound)
if (lua_gettop(l) > 2)
{
if (prop != properties.end())
{
if(lua_type(l, 3) != LUA_TNIL)
if (lua_type(l, 3) != LUA_TNIL)
{
intptr_t propertyAddress = (intptr_t)(((unsigned char*)&luacon_sim->elements[id]) + property.Offset);
LuaSetProperty(l, property, propertyAddress, 3);
if (prop->Type == StructProperty::TransitionType)
{
int type = luaL_checkinteger(l, 3);
if (!luacon_sim->IsValidElement(type) && type != NT && type != ST)
{
luaL_error(l, "Invalid element");
}
}
intptr_t propertyAddress = (intptr_t)(((unsigned char*)&luacon_sim->elements[id]) + prop->Offset);
LuaSetProperty(l, *prop, propertyAddress, 3);
}
luacon_model->BuildMenus();
luacon_sim->init_can_move();
luacon_ren->graphicscache[id].isready = 0;
return 0;
}
else if(propertyName == "Update")
else if (propertyName == "Update")
{
if(lua_type(l, 3) == LUA_TFUNCTION)
if (lua_type(l, 3) == LUA_TFUNCTION)
{
if (args > 3)
switch (luaL_optint(l, 4, 0))
{
luaL_checktype(l, 4, LUA_TNUMBER);
int replace = lua_tointeger(l, 4);
if (replace == 2)
lua_el_mode[id] = 3; //update before
else if (replace == 1)
lua_el_mode[id] = 2; //replace
else
lua_el_mode[id] = 1; //update after
case 2:
lua_el_mode[id] = 3; //update before
break;
case 1:
lua_el_mode[id] = 2; //replace
break;
default:
lua_el_mode[id] = 1; //update after
break;
}
else
lua_el_mode[id] = 1;
lua_el_func[id].Assign(3);
}
else if(lua_type(l, 3) == LUA_TBOOLEAN && !lua_toboolean(l, 3))
else if (lua_type(l, 3) == LUA_TBOOLEAN && !lua_toboolean(l, 3))
{
lua_el_func[id].Clear();
lua_el_mode[id] = 0;
luacon_sim->elements[id].Update = NULL;
}
return 0;
}
else if(propertyName == "Graphics")
else if (propertyName == "Graphics")
{
if(lua_type(l, 3) == LUA_TFUNCTION)
if (lua_type(l, 3) == LUA_TFUNCTION)
{
lua_gr_func[id].Assign(3);
}
else if(lua_type(l, 3) == LUA_TBOOLEAN && !lua_toboolean(l, -1))
else if (lua_type(l, 3) == LUA_TBOOLEAN && !lua_toboolean(l, -1))
{
lua_gr_func[id].Clear();
luacon_sim->elements[id].Graphics = NULL;
}
luacon_ren->graphicscache[id].isready = 0;
return 0;
}
else
{
return luaL_error(l, "Invalid element property");
return 0;
}
}
else
{
StructProperty property;
bool propertyFound = false;
std::vector<StructProperty> properties = Element::GetProperties();
for(std::vector<StructProperty>::iterator iter = properties.begin(), end = properties.end(); iter != end; ++iter)
if (prop != properties.end())
{
if((*iter).Name == propertyName)
{
property = *iter;
propertyFound = true;
break;
}
}
if(propertyFound)
{
intptr_t propertyAddress = (intptr_t)(((unsigned char*)&luacon_sim->elements[id]) + property.Offset);
LuaGetProperty(l, property, propertyAddress);
intptr_t propertyAddress = (intptr_t)(((unsigned char*)&luacon_sim->elements[id]) + prop->Offset);
LuaGetProperty(l, *prop, propertyAddress);
return 1;
}
else if(propertyName == "Identifier")
else if (propertyName == "Identifier")
{
lua_pushstring(l, luacon_sim->elements[id].Identifier.c_str());
return 1;
}
else
{
return luaL_error(l, "Invalid element property");
}
}
}
int LuaScriptInterface::elements_free(lua_State * l)
{
int id;
luaL_checktype(l, 1, LUA_TNUMBER);
id = lua_tointeger(l, 1);
if(id < 0 || id >= PT_NUM || !luacon_sim->elements[id].Enabled)
int id = luaL_checkinteger(l, 1);
if (!luacon_sim->IsValidElement(id))
{
return luaL_error(l, "Invalid element");
}
ByteString identifier = luacon_sim->elements[id].Identifier;
if(identifier.BeginsWith("DEFAULT_PT_"))
if (identifier.BeginsWith("DEFAULT_PT_"))
{
return luaL_error(l, "Cannot free default elements");
}
luacon_sim->elements[id].Enabled = false;

View File

@ -55,8 +55,6 @@ class LuaScriptInterface: public CommandInterface
static int simulation_newsign(lua_State *l);
//Simulation
static StructProperty * particleProperties;
static int particlePropertiesCount;
void initSimulationAPI();
static void set_map(int x, int y, int width, int height, float value, int mapType);

View File

@ -1,22 +1,23 @@
#include <cstddef>
#include "Particle.h"
std::vector<StructProperty> Particle::GetProperties()
std::vector<StructProperty> const &Particle::GetProperties()
{
std::vector<StructProperty> properties;
properties.push_back(StructProperty("type", StructProperty::ParticleType, offsetof(Particle, type)));
properties.push_back(StructProperty("life", StructProperty::ParticleType, offsetof(Particle, life)));
properties.push_back(StructProperty("ctype", StructProperty::ParticleType, offsetof(Particle, ctype)));
properties.push_back(StructProperty("x", StructProperty::Float, offsetof(Particle, x)));
properties.push_back(StructProperty("y", StructProperty::Float, offsetof(Particle, y)));
properties.push_back(StructProperty("vx", StructProperty::Float, offsetof(Particle, vx)));
properties.push_back(StructProperty("vy", StructProperty::Float, offsetof(Particle, vy)));
properties.push_back(StructProperty("temp", StructProperty::Float, offsetof(Particle, temp)));
properties.push_back(StructProperty("flags", StructProperty::UInteger, offsetof(Particle, flags)));
properties.push_back(StructProperty("tmp", StructProperty::Integer, offsetof(Particle, tmp)));
properties.push_back(StructProperty("tmp2", StructProperty::Integer, offsetof(Particle, tmp2)));
properties.push_back(StructProperty("dcolour", StructProperty::UInteger, offsetof(Particle, dcolour)));
properties.push_back(StructProperty("pavg0", StructProperty::Float, offsetof(Particle, pavg[0])));
properties.push_back(StructProperty("pavg1", StructProperty::Float, offsetof(Particle, pavg[1])));
static std::vector<StructProperty> properties = {
{ "type" , StructProperty::ParticleType, offsetof(Particle, type ) },
{ "life" , StructProperty::ParticleType, offsetof(Particle, life ) },
{ "ctype" , StructProperty::ParticleType, offsetof(Particle, ctype ) },
{ "x" , StructProperty::Float , offsetof(Particle, x ) },
{ "y" , StructProperty::Float , offsetof(Particle, y ) },
{ "vx" , StructProperty::Float , offsetof(Particle, vx ) },
{ "vy" , StructProperty::Float , offsetof(Particle, vy ) },
{ "temp" , StructProperty::Float , offsetof(Particle, temp ) },
{ "flags" , StructProperty::UInteger , offsetof(Particle, flags ) },
{ "tmp" , StructProperty::Integer , offsetof(Particle, tmp ) },
{ "tmp2" , StructProperty::Integer , offsetof(Particle, tmp2 ) },
{ "dcolour", StructProperty::UInteger , offsetof(Particle, dcolour) },
{ "pavg0" , StructProperty::Float , offsetof(Particle, pavg[0]) },
{ "pavg1" , StructProperty::Float , offsetof(Particle, pavg[1]) },
};
return properties;
}

View File

@ -17,7 +17,7 @@ struct Particle
unsigned int dcolour;
/** Returns a list of properties, their type and offset within the structure that can be changed
by higher-level processes referring to them by name such as Lua or the property tool **/
static std::vector<StructProperty> GetProperties();
static std::vector<StructProperty> const &GetProperties();
};
#endif

View File

@ -6,7 +6,20 @@
struct StructProperty
{
enum PropertyType { ParticleType, Colour, Integer, UInteger, Float, BString, String, Char, UChar, Removed };
enum PropertyType
{
TransitionType,
ParticleType,
Colour,
Integer,
UInteger,
Float,
BString,
String,
Char,
UChar,
Removed
};
ByteString Name;
PropertyType Type;
intptr_t Offset;

View File

@ -48,43 +48,44 @@ Element::Element():
{
}
std::vector<StructProperty> Element::GetProperties()
std::vector<StructProperty> const &Element::GetProperties()
{
std::vector<StructProperty> properties;
properties.push_back(StructProperty("Name", StructProperty::String, 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)));
static std::vector<StructProperty> properties = {
{ "Name", StructProperty::String, offsetof(Element, Name ) },
{ "Colour", StructProperty::Colour, offsetof(Element, Colour ) },
{ "Color", StructProperty::Colour, offsetof(Element, Colour ) },
{ "MenuVisible", StructProperty::Integer, offsetof(Element, MenuVisible ) },
{ "MenuSection", StructProperty::Integer, offsetof(Element, MenuSection ) },
{ "Enabled", StructProperty::Integer, offsetof(Element, Enabled ) },
{ "Advection", StructProperty::Float, offsetof(Element, Advection ) },
{ "AirDrag", StructProperty::Float, offsetof(Element, AirDrag ) },
{ "AirLoss", StructProperty::Float, offsetof(Element, AirLoss ) },
{ "Loss", StructProperty::Float, offsetof(Element, Loss ) },
{ "Collision", StructProperty::Float, offsetof(Element, Collision ) },
{ "Gravity", StructProperty::Float, offsetof(Element, Gravity ) },
{ "Diffusion", StructProperty::Float, offsetof(Element, Diffusion ) },
{ "HotAir", StructProperty::Float, offsetof(Element, HotAir ) },
{ "Falldown", StructProperty::Integer, offsetof(Element, Falldown ) },
{ "Flammable", StructProperty::Integer, offsetof(Element, Flammable ) },
{ "Explosive", StructProperty::Integer, offsetof(Element, Explosive ) },
{ "Meltable", StructProperty::Integer, offsetof(Element, Meltable ) },
{ "Hardness", StructProperty::Integer, offsetof(Element, Hardness ) },
{ "PhotonReflectWavelengths", StructProperty::UInteger, offsetof(Element, PhotonReflectWavelengths ) },
{ "Weight", StructProperty::Integer, offsetof(Element, Weight ) },
{ "Temperature", StructProperty::Float, offsetof(Element, Temperature ) },
{ "HeatConduct", StructProperty::UChar, offsetof(Element, HeatConduct ) },
{ "Description", StructProperty::String, offsetof(Element, Description ) },
{ "State", StructProperty::Removed, 0 },
{ "Properties", StructProperty::Integer, offsetof(Element, Properties ) },
{ "LowPressure", StructProperty::Float, offsetof(Element, LowPressure ) },
{ "LowPressureTransition", StructProperty::TransitionType, offsetof(Element, LowPressureTransition ) },
{ "HighPressure", StructProperty::Float, offsetof(Element, HighPressure ) },
{ "HighPressureTransition", StructProperty::TransitionType, offsetof(Element, HighPressureTransition ) },
{ "LowTemperature", StructProperty::Float, offsetof(Element, LowTemperature ) },
{ "LowTemperatureTransition", StructProperty::TransitionType, offsetof(Element, LowTemperatureTransition ) },
{ "HighTemperature", StructProperty::Float, offsetof(Element, HighTemperature ) },
{ "HighTemperatureTransition", StructProperty::TransitionType, offsetof(Element, HighTemperatureTransition) }
};
return properties;
}

View File

@ -60,7 +60,7 @@ public:
/** Returns a list of properties, their type and offset within the structure that can be changed
by higher-level processes referring to them by name such as Lua or the property tool **/
static std::vector<StructProperty> GetProperties();
static std::vector<StructProperty> const &GetProperties();
};
#endif