Add option to extract constant tables, fix string.start
This commit is contained in:
parent
00fa1a8b67
commit
aae20662e2
5 changed files with 78 additions and 59 deletions
|
@ -218,6 +218,7 @@ namespace AspectedRouting.IO.LuaSkeleton
|
|||
|
||||
public string MappingToLua(Mapping m)
|
||||
{
|
||||
var isConstant = true;
|
||||
var contents = m.StringToResultFunctions.Select(kv =>
|
||||
{
|
||||
var (key, expr) = kv;
|
||||
|
@ -228,13 +229,23 @@ namespace AspectedRouting.IO.LuaSkeleton
|
|||
left = key;
|
||||
}
|
||||
|
||||
return left + " = " + ToLua(expr, key);
|
||||
var luaExpr = ToLua(expr, key);
|
||||
if (luaExpr.Contains("tags")) {
|
||||
isConstant = false;
|
||||
}
|
||||
return left + " = " + luaExpr ;
|
||||
}
|
||||
);
|
||||
return
|
||||
var mapping =
|
||||
"{\n " +
|
||||
string.Join(",\n ", contents) +
|
||||
"\n}";
|
||||
if (_staticTables && isConstant) {
|
||||
return AddConstant(mapping);
|
||||
}
|
||||
|
||||
return mapping;
|
||||
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
|
|
@ -1,30 +1,38 @@
|
|||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using AspectedRouting.Language;
|
||||
|
||||
namespace AspectedRouting.IO.LuaSkeleton
|
||||
{
|
||||
|
||||
/// <summary>
|
||||
/// The 'LuaSkeleton' is a class which is used in Lua generation of profiles.
|
||||
///
|
||||
/// The lua skeleton basically keeps track of dependencies, and added functions.
|
||||
/// Once done, all these can be retrieved as code.
|
||||
///
|
||||
/// E.g. if an expression is turned into lua with 'ToExpression', then the dependencies will be automatically added.
|
||||
///
|
||||
/// The 'LuaSkeleton' is a class which is used in Lua generation of profiles.
|
||||
/// The lua skeleton basically keeps track of dependencies, and added functions.
|
||||
/// Once done, all these can be retrieved as code.
|
||||
/// E.g. if an expression is turned into lua with 'ToExpression', then the dependencies will be automatically added.
|
||||
/// </summary>
|
||||
public partial class LuaSkeleton
|
||||
{
|
||||
private readonly HashSet<string> _alreadyAddedFunctions = new HashSet<string>();
|
||||
|
||||
private readonly List<string> _constants = new List<string>();
|
||||
private readonly Context _context;
|
||||
|
||||
private readonly HashSet<string> _dependencies = new HashSet<string>();
|
||||
private readonly List<string> _functionImplementations = new List<string>();
|
||||
private readonly HashSet<string> _alreadyAddedFunctions = new HashSet<string>();
|
||||
|
||||
public LuaSkeleton(Context context)
|
||||
/// <summary>
|
||||
/// It turns out that creating lua tables is a huge performance overhead.
|
||||
/// Lots of functions however need a constant table to be invoked. Creating this table over and over is performance
|
||||
/// issue.
|
||||
/// If this flag is set, those constant tables are exported so they are created only once
|
||||
/// </summary>
|
||||
private readonly bool _staticTables;
|
||||
|
||||
public LuaSkeleton(Context context, bool staticTables = false)
|
||||
{
|
||||
_context = context;
|
||||
_staticTables = staticTables;
|
||||
}
|
||||
|
||||
internal void AddDep(string name)
|
||||
|
@ -45,15 +53,11 @@ namespace AspectedRouting.IO.LuaSkeleton
|
|||
public void AddDependenciesFor(IExpression e)
|
||||
{
|
||||
var (_, functionNames) = e.InList().DirectlyAndInderectlyCalled(_context);
|
||||
foreach (var functionName in functionNames)
|
||||
{
|
||||
|
||||
if (_context.DefinedFunctions.TryGetValue(functionName, out var aspectemeta))
|
||||
{
|
||||
AddFunction(aspectemeta);
|
||||
foreach (var functionName in functionNames) {
|
||||
if (_context.DefinedFunctions.TryGetValue(functionName, out var aspectMeta)) {
|
||||
AddFunction(aspectMeta);
|
||||
}
|
||||
else
|
||||
{
|
||||
else {
|
||||
AddDep(functionName);
|
||||
}
|
||||
}
|
||||
|
@ -63,15 +67,12 @@ namespace AspectedRouting.IO.LuaSkeleton
|
|||
{
|
||||
var imps = new List<string>();
|
||||
|
||||
foreach (var name in _dependencies)
|
||||
{
|
||||
foreach (var name in _dependencies) {
|
||||
var path = $"IO/lua/{name}.lua";
|
||||
if (File.Exists(path))
|
||||
{
|
||||
if (File.Exists(path)) {
|
||||
imps.Add(File.ReadAllText(path));
|
||||
}
|
||||
else
|
||||
{
|
||||
else {
|
||||
throw new FileNotFoundException(path);
|
||||
}
|
||||
}
|
||||
|
@ -79,5 +80,15 @@ namespace AspectedRouting.IO.LuaSkeleton
|
|||
return imps;
|
||||
}
|
||||
|
||||
public string AddConstant(string luaExpression)
|
||||
{
|
||||
_constants.Add(luaExpression);
|
||||
return "c" + (_constants.Count - 1);
|
||||
}
|
||||
|
||||
public IEnumerable<string> GenerateConstants()
|
||||
{
|
||||
return _constants.Select((c, i) => $"c{i} = {c}");
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,4 +1,3 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using AspectedRouting.Language;
|
||||
|
@ -88,6 +87,7 @@ namespace AspectedRouting.IO.itinero1
|
|||
functions,
|
||||
"---------------------- UTILS ------------------------".InList(),
|
||||
dependencies,
|
||||
_skeleton.GenerateConstants().ToList(),
|
||||
"----------------------- TESTS ------------------------".InList(),
|
||||
tests.InList(),
|
||||
GenerateLegacyTail().InList()
|
||||
|
|
|
@ -9,33 +9,30 @@ using AspectedRouting.Tests;
|
|||
namespace AspectedRouting.IO.itinero2
|
||||
{
|
||||
/// <summary>
|
||||
/// Lua printer for itinero2-lua format
|
||||
///
|
||||
/// The itinero 2.0 lua profile is a whole lot simpler then the 1.0 format,
|
||||
/// as a single profile there only describes a single behaviour of a vehicle:
|
||||
///
|
||||
/// It has:
|
||||
/// - name: string, e.g. 'bicycle.fastest'
|
||||
/// - factor(attributes, result): void, where 'attributes' are all the tags of the way,
|
||||
/// and result must contain (after calling):
|
||||
/// - 'forward_speed', a double describing the forward speed (in km/h)
|
||||
/// - 'backward_speed', the speed when travelling in the opposite direction (0 if not possible)
|
||||
/// - 'forward', a double describing the forwardfactor
|
||||
/// - 'backward', the backward factor
|
||||
/// - 'canstop', a boolean indicating if stopping along the road is possible
|
||||
///
|
||||
/// Lua printer for itinero2-lua format
|
||||
/// The itinero 2.0 lua profile is a whole lot simpler then the 1.0 format,
|
||||
/// as a single profile there only describes a single behaviour of a vehicle:
|
||||
/// It has:
|
||||
/// - name: string, e.g. 'bicycle.fastest'
|
||||
/// - factor(attributes, result): void, where 'attributes' are all the tags of the way,
|
||||
/// and result must contain (after calling):
|
||||
/// - 'forward_speed', a double describing the forward speed (in km/h)
|
||||
/// - 'backward_speed', the speed when travelling in the opposite direction (0 if not possible)
|
||||
/// - 'forward', a double describing the forwardfactor
|
||||
/// - 'backward', the backward factor
|
||||
/// - 'canstop', a boolean indicating if stopping along the road is possible
|
||||
/// </summary>
|
||||
public partial class LuaPrinter2
|
||||
{
|
||||
private readonly ProfileMetaData _profile;
|
||||
private readonly string _behaviourName;
|
||||
private readonly Context _context;
|
||||
private readonly List<AspectTestSuite> _aspectTests;
|
||||
private readonly string _behaviourName;
|
||||
private readonly IEnumerable<BehaviourTestSuite> _behaviourTestSuite;
|
||||
private readonly Context _context;
|
||||
private readonly DateTime _lastChangeTime;
|
||||
private readonly LuaParameterPrinter _parameterPrinter;
|
||||
private readonly ProfileMetaData _profile;
|
||||
|
||||
private readonly LuaSkeleton.LuaSkeleton _skeleton;
|
||||
private readonly LuaParameterPrinter _parameterPrinter;
|
||||
|
||||
|
||||
public LuaPrinter2(ProfileMetaData profile, string behaviourName,
|
||||
|
@ -43,7 +40,7 @@ namespace AspectedRouting.IO.itinero2
|
|||
List<AspectTestSuite> aspectTests, IEnumerable<BehaviourTestSuite> behaviourTestSuite,
|
||||
DateTime lastChangeTime)
|
||||
{
|
||||
_skeleton = new LuaSkeleton.LuaSkeleton(context);
|
||||
_skeleton = new LuaSkeleton.LuaSkeleton(context, false);
|
||||
_profile = profile;
|
||||
_behaviourName = behaviourName;
|
||||
_context = context;
|
||||
|
@ -55,23 +52,21 @@ namespace AspectedRouting.IO.itinero2
|
|||
|
||||
public string ToLua()
|
||||
{
|
||||
var profileDescr = _profile.Behaviours[_behaviourName]["description"].Evaluate(_context).ToString();
|
||||
var profileDescr = _profile.Behaviours[_behaviourName]["description"].Evaluate(_context).ToString();
|
||||
var header =
|
||||
new List<string>
|
||||
{
|
||||
new List<string> {
|
||||
$"name = \"{_profile.Name}.{_behaviourName}\"",
|
||||
$"generationDate = \"{_lastChangeTime:s}\"",
|
||||
$"description = \"{profileDescr} ({_profile.Description})\""
|
||||
};
|
||||
|
||||
var testPrinter = new LuaTestPrinter(_skeleton,
|
||||
new List<string>() {"unitTestProfile2"});
|
||||
new List<string> {"unitTestProfile2"});
|
||||
var tests = testPrinter.GenerateFullTestSuite(
|
||||
_behaviourTestSuite.ToList(),
|
||||
new List<AspectTestSuite>(),
|
||||
true);
|
||||
var all = new List<string>
|
||||
{
|
||||
var all = new List<string> {
|
||||
header.Lined(),
|
||||
"",
|
||||
GenerateMainFunction(),
|
||||
|
@ -85,6 +80,8 @@ namespace AspectedRouting.IO.itinero2
|
|||
"",
|
||||
string.Join("\n\n", _skeleton.GenerateDependencies()), // Should be AFTER generating the main function!
|
||||
"",
|
||||
string.Join("\n\n", _skeleton.GenerateConstants()),
|
||||
"",
|
||||
tests,
|
||||
"",
|
||||
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
function string.start(strt, s)
|
||||
function string_start(strt, s)
|
||||
return string.sub(s, 1, string.len(strt)) == strt
|
||||
end
|
||||
|
||||
|
@ -9,7 +9,7 @@ function remove_relation_prefix(tags, name)
|
|||
local new_tags = {}
|
||||
for k, v in pairs(tags) do
|
||||
local prefix = "_relation:" .. name .. ":";
|
||||
if (string.start(prefix, k)) then
|
||||
if (string_start(prefix, k)) then
|
||||
local new_key = "_relation:" .. string.sub(k, string.len(prefix) + 1) -- plus 1: sub uses one-based indexing to select the start
|
||||
new_tags[new_key] = v
|
||||
else
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue