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