Add a script that automates the code replacements

Various other things:
 - Try to use newer c++ features
 - Rename travelcm
 - Remove wheel radius
This commit is contained in:
Flakebi 2015-08-16 15:48:27 +02:00
parent ec3083827d
commit acbc629610
10 changed files with 165 additions and 103 deletions

View File

@ -113,7 +113,7 @@
position of the physics raycast wheels relative to the center of
gravity. Default is to use the corners of the chassis to attach
the wheels to. -->
<wheels damping-relaxation="35" damping-compression="5" radius="0.25">
<wheels damping-relaxation="35" damping-compression="5">
<front-right position="0.38 0 0.6" />
<front-left position="-0.38 0 0.6" />
<rear-right position="0.38 0 -0.6" />

View File

@ -45,7 +45,11 @@ AbstractCharacteristic::ValueType AbstractCharacteristic::getType(Characteristic
case CHARACTERISTIC_COUNT:
Log::fatal("AbstractCharacteristic::getType", "Can't get type of COUNT");
break;
// Script-generated content get-prop first part
// Script-generated content generated by tools/create_kart_properties.py getProp1
// Please don't change the following tag. It will be automatically detected
// by the script and replace the contained content.
// To update the code, use tools/update_characteristics.py
/* <characteristics-start getProp1> */
case SUSPENSION_STIFFNESS:
return TYPE_FLOAT;
case SUSPENSION_REST:
@ -218,6 +222,7 @@ AbstractCharacteristic::ValueType AbstractCharacteristic::getType(Characteristic
return TYPE_FLOAT;
case SLIPSTREAM_FADE_OUT_TIME:
return TYPE_FLOAT;
/* <characteristics-start getProp1> */
}
Log::fatal("AbstractCharacteristic::getType", "Unknown type");
return TYPE_FLOAT;
@ -229,13 +234,17 @@ std::string AbstractCharacteristic::getName(CharacteristicType type)
{
case CHARACTERISTIC_COUNT:
return "CHARACTERISTIC_COUNT";
// Script-generated content get-prop second part
// Script-generated content generated by tools/create_kart_properties.py getProp2
// Please don't change the following tag. It will be automatically detected
// by the script and replace the contained content.
// To update the code, use tools/update_characteristics.py
/* <characteristics-start getProp2> */
case SUSPENSION_STIFFNESS:
return "SUSPENSION_STIFFNESS";
case SUSPENSION_REST:
return "SUSPENSION_REST";
case SUSPENSION_TRAVEL_CM:
return "SUSPENSION_TRAVEL_CM";
case SUSPENSION_TRAVEL:
return "SUSPENSION_TRAVEL";
case SUSPENSION_EXP_SPRING_RESPONSE:
return "SUSPENSION_EXP_SPRING_RESPONSE";
case SUSPENSION_MAX_FORCE:
@ -278,8 +287,6 @@ std::string AbstractCharacteristic::getName(CharacteristicType type)
return "WHEELS_DAMPING_RELAXATION";
case WHEELS_DAMPING_COMPRESSION:
return "WHEELS_DAMPING_COMPRESSION";
case WHEELS_RADIUS:
return "WHEELS_RADIUS";
case WHEELS_POSITION:
return "WHEELS_POSITION";
case CAMERA_DISTANCE:
@ -402,12 +409,18 @@ std::string AbstractCharacteristic::getName(CharacteristicType type)
return "SLIPSTREAM_MAX_SPEED_INCREASE";
case SLIPSTREAM_FADE_OUT_TIME:
return "SLIPSTREAM_FADE_OUT_TIME";
/* <characteristics-end getProp2> */
}
Log::error("AbstractCharacteristic::getName", "Unknown type");
return "Unknown type";
}
// Script-generated getter
// Script-generated content generated by tools/create_kart_properties.py getter
// Please don't change the following tag. It will be automatically detected
// by the script and replace the contained content.
// To update the code, use tools/update_characteristics.py
/* <characteristics-start getter> */
float AbstractCharacteristic::getSuspensionStiffness() const
{
float result;
@ -428,13 +441,13 @@ float AbstractCharacteristic::getSuspensionRest() const
return result;
}
float AbstractCharacteristic::getSuspensionTravelCm() const
float AbstractCharacteristic::getSuspensionTravel() const
{
float result;
bool is_set = false;
process(SUSPENSION_TRAVEL_CM, &result, &is_set);
process(SUSPENSION_TRAVEL, &result, &is_set);
if (!is_set)
Log::fatal("AbstractCharacteristic", "Can't get characteristic %s", getName(SUSPENSION_TRAVEL_CM).c_str());
Log::fatal("AbstractCharacteristic", "Can't get characteristic %s", getName(SUSPENSION_TRAVEL).c_str());
return result;
}
@ -648,16 +661,6 @@ float AbstractCharacteristic::getWheelsDampingCompression() const
return result;
}
float AbstractCharacteristic::getWheelsRadius() const
{
float result;
bool is_set = false;
process(WHEELS_RADIUS, &result, &is_set);
if (!is_set)
Log::fatal("AbstractCharacteristic", "Can't get characteristic %s", getName(WHEELS_RADIUS).c_str());
return result;
}
std::vector<float> AbstractCharacteristic::getWheelsPosition() const
{
std::vector<float> result;
@ -1268,3 +1271,6 @@ float AbstractCharacteristic::getSlipstreamFadeOutTime() const
return result;
}
/* <characteristics-end getter> */

View File

@ -66,11 +66,16 @@ public:
enum CharacteristicType
{
// Script-generated content
// Script-generated content generated by tools/create_kart_properties.py enum
// Please don't change the following tag. It will be automatically detected
// by the script and replace the contained content.
// To update the code, use tools/update_characteristics.py
/* <characteristics-start enum> */
// Suspension
SUSPENSION_STIFFNESS,
SUSPENSION_REST,
SUSPENSION_TRAVEL_CM,
SUSPENSION_TRAVEL,
SUSPENSION_EXP_SPRING_RESPONSE,
SUSPENSION_MAX_FORCE,
@ -104,7 +109,6 @@ public:
// Wheels
WHEELS_DAMPING_RELAXATION,
WHEELS_DAMPING_COMPRESSION,
WHEELS_RADIUS,
WHEELS_POSITION,
// Camera
@ -195,6 +199,8 @@ public:
SLIPSTREAM_MAX_SPEED_INCREASE,
SLIPSTREAM_FADE_OUT_TIME,
/* <characteristics-end enum> */
// Count
CHARACTERISTIC_COUNT
@ -228,10 +234,15 @@ public:
static ValueType getType(CharacteristicType type);
static std::string getName(CharacteristicType type);
// Script-generated content
// Script-generated content generated by tools/create_kart_properties.py defs
// Please don't change the following tag. It will be automatically detected
// by the script and replace the contained content.
// To update the code, use tools/update_characteristics.py
/* <characteristics-start defs> */
float getSuspensionStiffness() const;
float getSuspensionRest() const;
float getSuspensionTravelCm() const;
float getSuspensionTravel() const;
bool getSuspensionExpSpringResponse() const;
float getSuspensionMaxForce() const;
@ -259,7 +270,6 @@ public:
float getWheelsDampingRelaxation() const;
float getWheelsDampingCompression() const;
float getWheelsRadius() const;
std::vector<float> getWheelsPosition() const;
float getCameraDistance() const;
@ -335,6 +345,8 @@ public:
float getSlipstreamMinSpeed() const;
float getSlipstreamMaxSpeedIncrease() const;
float getSlipstreamFadeOutTime() const;
/* <characteristics-end defs> */
};
#endif

View File

@ -101,7 +101,7 @@ void AbstractKart::reset()
// ----------------------------------------------------------------------------
const AbstractCharacteristic* AbstractKart::getCharacteristic() const
{
return &(*m_characteristic);
return m_characteristic.get();
}
// ----------------------------------------------------------------------------

View File

@ -36,8 +36,7 @@ const SkiddingProperties* CombinedCharacteristic::getSkiddingProperties() const
void CombinedCharacteristic::process(CharacteristicType type, Value value, bool *is_set) const
{
for (std::vector<const AbstractCharacteristic*>::const_iterator it = m_childs.cbegin();
it != m_childs.cend(); it++)
(*it)->process(type, value, is_set);
for (const AbstractCharacteristic *characteristic : m_childs)
characteristic->process(type, value, is_set);
}

View File

@ -186,14 +186,13 @@ void KartPropertiesManager::loadCharacteristics(const XMLNode *root)
root->getNodes("characteristic", nodes);
bool found = false;
std::string name;
for (std::vector<XMLNode*>::const_iterator baseNode = nodes.cbegin();
baseNode != nodes.cend(); baseNode++)
for (const XMLNode *baseNode : nodes)
{
(*baseNode)->get("name", &name);
baseNode->get("name", &name);
if (name == "base")
{
found = true;
m_base_characteristic.reset(new XmlCharacteristic(*baseNode));
m_base_characteristic.reset(new XmlCharacteristic(baseNode));
break;
}
}
@ -203,35 +202,32 @@ void KartPropertiesManager::loadCharacteristics(const XMLNode *root)
// Load difficulties
nodes.clear();
root->getNode("difficulties")->getNodes("characteristic", nodes);
for (std::vector<XMLNode*>::const_iterator type = nodes.cbegin();
type != nodes.cend(); type++)
for (const XMLNode *type : nodes)
{
(*type)->get("name", &name);
type->get("name", &name);
m_difficulty_characteristics.insert(std::pair<const std::string,
std::unique_ptr<AbstractCharacteristic> >(name,
std::unique_ptr<AbstractCharacteristic>(new XmlCharacteristic(*type))));
std::unique_ptr<AbstractCharacteristic>(new XmlCharacteristic(type))));
}
// Load kart type characteristics
nodes.clear();
root->getNode("kart-types")->getNodes("characteristic", nodes);
for (std::vector<XMLNode*>::const_iterator type = nodes.cbegin();
type != nodes.cend(); type++)
for (const XMLNode *type : nodes)
{
(*type)->get("name", &name);
type->get("name", &name);
m_kart_type_characteristics.insert(std::pair<const std::string,
std::unique_ptr<AbstractCharacteristic> >(name,
std::unique_ptr<AbstractCharacteristic>(new XmlCharacteristic(*type))));
std::unique_ptr<AbstractCharacteristic>(new XmlCharacteristic(type))));
}
// Load player difficulties
nodes.clear();
root->getNode("player-characteristics")->getNodes("characteristic", nodes);
for (std::vector<XMLNode*>::const_iterator type = nodes.cbegin();
type != nodes.cend(); type++)
for (const XMLNode *type : nodes)
{
(*type)->get("name", &name);
type->get("name", &name);
m_player_characteristics.insert(std::pair<const std::string,
std::unique_ptr<AbstractCharacteristic> >(name,
std::unique_ptr<AbstractCharacteristic>(new XmlCharacteristic(*type))));
std::unique_ptr<AbstractCharacteristic>(new XmlCharacteristic(type))));
}
}
@ -303,7 +299,7 @@ const AbstractCharacteristic* KartPropertiesManager::getDifficultyCharacteristic
it = m_difficulty_characteristics.find(type);
if (it == m_difficulty_characteristics.cend())
return nullptr;
return &(*it->second);
return it->second.get();
} // getDifficultyCharacteristic
//-----------------------------------------------------------------------------
@ -313,7 +309,7 @@ const AbstractCharacteristic* KartPropertiesManager::getKartTypeCharacteristic(c
it = m_kart_type_characteristics.find(type);
if (it == m_kart_type_characteristics.cend())
return nullptr;
return &(*it->second);
return it->second.get();
} // getKartTypeCharacteristic
//-----------------------------------------------------------------------------
@ -323,7 +319,7 @@ const AbstractCharacteristic* KartPropertiesManager::getPlayerCharacteristic(con
it = m_player_characteristics.find(type);
if (it == m_player_characteristics.cend())
return nullptr;
return &(*it->second);
return it->second.get();
} // getPlayerCharacteristic
//-----------------------------------------------------------------------------

View File

@ -99,7 +99,7 @@ public:
void setHatMeshName(const std::string &hat_name);
// ------------------------------------------------------------------------
/** Get the characteristic that holds the base values. */
const AbstractCharacteristic* getBaseCharacteristic() const { return &(*m_base_characteristic); }
const AbstractCharacteristic* getBaseCharacteristic() const { return m_base_characteristic.get(); }
// ------------------------------------------------------------------------
/** Get a characteristic that holds the values for a certain difficulty. */
const AbstractCharacteristic* getDifficultyCharacteristic(const std::string &type) const;

View File

@ -59,17 +59,17 @@ void XmlCharacteristic::process(CharacteristicType type, Value value, bool *is_s
else
{
std::vector<float>::iterator fit = value.fv->begin();
for (std::vector<std::string>::const_iterator it = processors.begin();
it != processors.end(); it++, fit++)
for (const std::string &processor : processors)
{
processFloat(*it, &*fit, is_set);
processFloat(processor, &*fit, is_set);
if (!*is_set)
{
Log::error("XmlCharacteristic::process", "Can't process %s",
it->c_str());
processor.c_str());
value.fv->clear();
break;
}
fit++;
}
}
}
@ -80,11 +80,10 @@ void XmlCharacteristic::process(CharacteristicType type, Value value, bool *is_s
{
value.fv->resize(processors.size());
std::vector<float>::iterator fit = value.fv->begin();
for (std::vector<std::string>::const_iterator it = processors.begin();
it != processors.end(); it++, fit++)
for (const std::string &processor : processors)
{
*is_set = false;
processFloat(*it, &*fit, is_set);
processFloat(processor, &*fit, is_set);
if (!*is_set)
{
@ -93,6 +92,7 @@ void XmlCharacteristic::process(CharacteristicType type, Value value, bool *is_s
value.fv->clear();
break;
}
fit++;
}
}
break;
@ -110,10 +110,9 @@ void XmlCharacteristic::process(CharacteristicType type, Value value, bool *is_s
shouldReplace = true;
else
{
for (std::vector<std::string>::const_iterator it = processors.begin();
it != processors.end(); it++)
for (const std::string &processor : processors)
{
std::vector<std::string> pair = StringUtils::split(*it, ':');
std::vector<std::string> pair = StringUtils::split(processor, ':');
if (pair.size() != 2)
Log::error("XmlCharacteristic::process",
"Can't process %s: Wrong format", getName(type).c_str());
@ -162,10 +161,9 @@ void XmlCharacteristic::process(CharacteristicType type, Value value, bool *is_s
if (shouldReplace)
{
// Replace all values
for (std::vector<std::string>::const_iterator it = processors.begin();
it != processors.end(); it++)
for (const std::string &processor : processors)
{
std::vector<std::string> pair = StringUtils::split(*it,':');
std::vector<std::string> pair = StringUtils::split(processor,':');
if (pair.size() != 2)
Log::error("XmlCharacteristic::process",
"Can't process %s: Wrong format", getName(type).c_str());
@ -289,12 +287,16 @@ void XmlCharacteristic::processBool(const std::string &processor, bool *value, b
void XmlCharacteristic::load(const XMLNode *node)
{
// Script-generated content getXml
// Script-generated content generated by tools/create_kart_properties.py getXml
// Please don't change the following tag. It will be automatically detected
// by the script and replace the contained content.
// To update the code, use tools/update_characteristics.py
/* <characteristics-start getXml> */
if (const XMLNode *sub_node = node->getNode("suspension"))
{
sub_node->get("stiffness", &m_values[SUSPENSION_STIFFNESS]);
sub_node->get("rest", &m_values[SUSPENSION_REST]);
sub_node->get("travel-cm", &m_values[SUSPENSION_TRAVEL_CM]);
sub_node->get("travel", &m_values[SUSPENSION_TRAVEL]);
sub_node->get("exp-spring-response", &m_values[SUSPENSION_EXP_SPRING_RESPONSE]);
sub_node->get("max-force", &m_values[SUSPENSION_MAX_FORCE]);
}
@ -340,7 +342,6 @@ void XmlCharacteristic::load(const XMLNode *node)
{
sub_node->get("damping-relaxation", &m_values[WHEELS_DAMPING_RELAXATION]);
sub_node->get("damping-compression", &m_values[WHEELS_DAMPING_COMPRESSION]);
sub_node->get("radius", &m_values[WHEELS_RADIUS]);
sub_node->get("position", &m_values[WHEELS_POSITION]);
}
@ -459,5 +460,8 @@ void XmlCharacteristic::load(const XMLNode *node)
sub_node->get("max-speed-increase", &m_values[SLIPSTREAM_MAX_SPEED_INCREASE]);
sub_node->get("fade-out-time", &m_values[SLIPSTREAM_FADE_OUT_TIME]);
}
/* <characteristics-end getXml> */
}

View File

@ -17,21 +17,20 @@
# along with this program; if not, write to the Free Software
# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
# This script creates the output for the AbstractCharacteristics
# This script creates code for the characteristics.
# It takes an argument that specifies what the output of the script should be.
# The output options can be seen by running this script without arguments.
import sys
# Input data
#FIXME is wheelPosition needed?
characteristics = """Suspension: stiffness, rest, travelCm, expSpringResponse(bool), maxForce
characteristics = """Suspension: stiffness, rest, travel, expSpringResponse(bool), maxForce
Stability: rollInfluence, chassisLinearDamping, chassisAngularDamping, downwardImpulseFactor, trackConnectionAccel, smoothFlyingImpulse
Turn: radius(InterpolationArray), timeResetSteer, timeFullSteer(InterpolationArray)
Engine: power, maxSpeed, brakeFactor, brakeTimeIncrease, maxSpeedReverseRatio
Gear: switchRatio(std::vector<float>/floatVector), powerIncrease(std::vector<float>/floatVector)
Mass
Wheels: dampingRelaxation, dampingCompression, radius, position(std::vector<float>/floatVector)
Wheels: dampingRelaxation, dampingCompression, position(std::vector<float>/floatVector)
Camera: distance, forwardUpAngle, backwardUpAngle
Jump: animationTime
Lean: max, speed
@ -58,12 +57,12 @@ class GroupMember:
self.typeC = typeC
self.typeStr = typeStr
"""E.g. power(std::vector<float>/floatVector)
or speed(InterpolationArray)
The default type is float
The name 'value' is special: Only the group name will be used to access
the member but in the xml file it will be still value (because we
need a name)."""
""" E.g. power(std::vector<float>/floatVector)
or speed(InterpolationArray)
The default type is float
The name 'value' is special: Only the group name will be used to access
the member but in the xml file it will be still value (because we
need a name). """
def parse(content):
typeC = "float"
typeStr = typeC
@ -93,8 +92,8 @@ class Group:
def getBaseName(self):
return self.baseName
"""E.g. engine: power, gears(std::vector<Gear>/Gears)
or mass(float) or only mass"""
""" E.g. engine: power, gears(std::vector<Gear>/Gears)
or mass(float) or only mass """
def parse(content):
pos = content.find(":")
if pos == -1:
@ -107,7 +106,7 @@ class Group:
group.addMember(m)
return group
"""Creates a list of words from a titlecase string"""
""" Creates a list of words from a titlecase string """
def toList(name):
result = []
cur = ""
@ -120,8 +119,8 @@ def toList(name):
result.append(cur)
return result
"""titleCase: true = result is titlecase
false = result has underscores"""
""" titleCase: true = result is titlecase
false = result has underscores """
def joinSubName(group, member, titleCase):
words = toList(group.baseName) + toList(member.getName)
first = True
@ -134,7 +133,14 @@ def joinSubName(group, member, titleCase):
def main():
# Find out what to do
if len(sys.argv) == 1:
print("Please specify what you want to know [enum|defs|getter|getProp|getXml]")
print("""Usage: ./create_kart_properties.py <operation>
Operations:
enum List the enum values for all characteristics in abstract_characteristic.hpp
defs Create the headers in abstract_characteristic.hpp
getter The getter implementations in abstract_characteristic.cpp
getProp1 Creates the getType function in abstract_characteristic.cpp
getProp2 Creates the getName funciton in abstract_characteristic.cpp
getXml Used to load the characteristics from an xml file in xml_characteristic.cpp""")
return
task = sys.argv[1]
@ -187,14 +193,14 @@ def main():
return {4};
}}
""".format(m.typeC, nameTitle, nameUnderscore.upper(), typeC, result))
elif task == "getProp":
elif task == "getProp1":
for g in groups:
for m in g.members:
nameTitle = joinSubName(g, m, True)
nameUnderscore = joinSubName(g, m, False)
print(" case {0}:\n return TYPE_{1};".
format(nameUnderscore.upper(), "_".join(toList(m.typeStr)).upper()))
print("\n\n-------------------- END --------------------\n")
elif task == "getProp2":
for g in groups:
for m in g.members:
nameTitle = joinSubName(g, m, True)
@ -214,24 +220,6 @@ def main():
else:
print("Unknown task")
#print("Constructor ****************************************")
#lineLength = 4;
#line = " "
#for g in groups:
# for n in g.subNames:
# name = "m_{0} = ".format(joinSubName(g, n, False))
# l = len(name)
# if lineLength + l > 80 and lineLength > 4:
# print(line)
# line = " " + name
# lineLength = l + 4
# else:
# line += name
# lineLength += l
#if lineLength > 4:
# line += "1;"
# print(line)
if __name__ == '__main__':
main()

57
tools/update_characteristics.py Executable file
View File

@ -0,0 +1,57 @@
#!/usr/bin/env python3
#
# SuperTuxKart - a fun racing game with go-kart
# Copyright (C) 2006-2015 SuperTuxKart-Team
#
# This program is free software; you can redistribute it and/or
# modify it under the terms of the GNU General Public License
# as published by the Free Software Foundation; either version 3
# of the License, or (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
# This script uses create_kart_properties.py to create code and then replaces
# the code in the source files. The parts in the source are marked with tags, that
# contain the argument that has to be passed to create_kart_properties.py.
# The script has to be run from the root directory of this project.
import os
import re
import subprocess
# Where and what should be replaced
replacements = [
["enum", "karts/abstract_characteristic.hpp"],
["defs", "karts/abstract_characteristic.hpp"],
["getter", "karts/abstract_characteristic.cpp"],
["getProp1", "karts/abstract_characteristic.cpp"],
["getProp2", "karts/abstract_characteristic.cpp"],
["getXml", "karts/xml_characteristic.cpp"]]
def main():
# Check, if it runs in the root directory
if not os.path.isfile("tools/update_characteristics.py"):
print("Please run this script in the root directory of the project.")
exit(1)
for replacement in replacements:
result = subprocess.Popen("tools/create_kart_properties.py " +
replacement[0] + " 2> /dev/null", shell = True,
stdout = subprocess.PIPE).stdout.read().decode('UTF-8')
with open("src/" + replacement[1], "r") as f:
text = f.read()
# Replace the text by using look behinds and look forwards
text = re.sub("(?<=/\* \<characteristics-start " + replacement[0] +
"\> \*/\\n)(.|\n)*(?=\\n\s*/\* <characteristics-end " + replacement[0] + "> \*/)", result, text)
with open("src/" + replacement[1], "w") as f:
f.write(text)
if __name__ == '__main__':
main()