News:

Do you need help?
Simutrans Wiki Manual can help you to play and extend Simutrans. In 9 languages.

Makeobj no numeric indices for constraints

Started by Mariculous, November 22, 2016, 09:18:28 AM

Previous topic - Next topic

0 Members and 1 Guest are viewing this topic.

Mariculous

This discussion started in another thread so I will just quote the related posts Here:

Quote from: Freahk on November 22, 2016, 12:46:44 AM
Why exactly do we need these numeric indices in the constraints? I mean it's always just 0, 1, ..., n-1, n
Isn't it possible to imply these at compile time of the .dat files? Makeobj doesn't even warn you when you use the same index twice. It's pretty annoying to compile everything, start the game and notice that you can't compose the train as you want it to be because you just missed to increase one of these <insert evil word here> indices.
I added a tiny dat file preprocessor to my little java build-tool that can do the work for me but this feature is more a rage moment feature than a stable and solid solution, it's slow and I don't even use it by myself anymore because I'm not sure if it could destroy my .dat files if the tool terminates in an unusual way. It would be nicer if makeobj could do this for us.

Quote from: jamespetts on November 22, 2016, 12:53:44 AM
We are perhaps now getting into more general makeobj suggestions? If this were implemented, great care would have to be taken to preserve compatibility with existing .dat files.

Without knowing the code of makeobj, I do just naively say backward compatibility shoudln't be a problem if it's not a problem to remove the need of these numeric indices.
makeobj could just count these indices by itself. At the start of each file and for each new object (these --...-- lines) it would have to reset the the index counters to 0.
When it reads a constraint line it will just it will just use the counter to add that index if there is no index in the dat file, otherwise it will just take the index from the dat source. In any case it will increase one of the counters (one for prev one for next) by 1.
That way can lead to unexpected results if you use mixed syntax with and without manually setting the index in a single object and also but that shouldn't be something anyone wants to do anyways.

Leartin

Just something you might not have thought about: There was a shorter method for writing dats implemented, mostly for graphics. If one would expand that with an enum-like functionality, possibly by listing strings divided by ";".

"constraint[next][0-99]=<$0:vehicle01; vehicle02; somethingsomething>"

would be interpreted so that on the right side, index 0 gets replaced by vehicle01, index 1 gets replaces by vehicle02, and an index outside of the range of the enum is blank. That would be equal to the following:

"constraint[next][0]=vehicle01
constraint[next][1]=vehicle02
constraint[next][2]=somethingsomething
constraint[next][3]=
constraint[next][4]=
..."

The additional empty constraints shouldn't matter functionally.

This would be a somewhat crooked implementation, but it would tie in with the "shortened dat" solution and it would be available everywhere in the dat, not just as an improvement of the constraints.

Mariculous

#2
I don't know that shorter method. How did/does it work or do you mean the implicit emptyimage[e]=emptyimage[w] if emptyimage[e] does not exist in the dat? (and so on for the other directions)

Anyways it's also a great idea, however that would lead to many unnecessary, empty constraints so makeobj should determine how many elemnts there exist in reailty.
But if makobj knows how many elements there are, we could also just remove the [0-n] because it's meaningless if makeobj does determine the number of elements by itself.
And btw. I don't understand that <$0: syntax. it it part of the enum syntax in C++ so it tells us that we start to count at 0?

"constraint[next]=v1;v2;v3"
would be the same as
"
constraint[next][0]=v1
constraint[next][1]=v2
constraint[next][2]=v3
"

The same could indeed also be done for other places where numeric indices exist e.g. loadimage however, doing it that way only allows us to use this syntax, if the last index of the array is numeric.

Maybe we could even use a JSON like syntax as constraint is something like a 2-dimensional array with the first key being a string and the 2nd a number.

So maybe we could create something so that

"
constraint[next][0]=v1
constraint[next][1]=v2
constraint[next][2]=v3
constraint[prev][0]=v1
constraint[prev][1]=v2
constraint[prev][2]=v3
"
is the same as
"
constraint[next]=[v1,v2,v3]
constraint[prev]=[v1,v2,v3]
"
and that's the same as
"
constraint={prev:[v1,v2,v3], next:[v1,v2,v3]}
"

so for numeric keys, we would just use brackets and the number would be implied and for string keys, also known as key->value or maps, we would use braces and write down the key explicitly.

If we define an order for non numeric keys (for example prev<next, n<ne<e<se<s<sw<w<nw) we could also use the bracket syntax to even shorten these.
That could for highly dimensional arrays lead to total confusion so it would be a nice feature for 1 or 2 dimensional arrays but should be used with care for more dimensions.

That way it would also be the same to write a (imho not really self explaining nor well readable)
"
constraint=[[v1,v2,v3], [v1,v2,v3]]
"
Nevertheless for emptyimage it would be nice to have such a short hand syntax for example
"
emptyimage=[image.0.0,image.0.1,image.0.2,image.0.3,image.0.4,image.0.5,image.0.6,image.0.7]
"
or even
"
emptyimage=image.0.[0-7]
"
That last syntax would be for sure an overkill of implementation effort.
Well, when I think about it, it shouldn't be that complicated if you implement it recursively, given it's possible to implement the JSON-like syntax.


Just my thoughts. I guess it would be pretty elegant because it's short and easy to understand and removes some common error sources from the dat files, but I do also guess it's not that easy to implement and I won't have time to do this before ~February.

Leartin

Quote from: Freahk on November 22, 2016, 12:33:07 PM
I don't know that shorter method. How did/does it work or do you mean the implicit emptyimage[e]=emptyimage[w] if emptyimage[e] does not exist in the dat? (and so on for the other directions)

It was intended for graphics. Example:
Image[8-15][0][0][0-4] = image/test.<$0-8>.<$1>
would end up in 40 lines, counting up the numbers in square brackets and using the same numbers in the pointy brackets. <$0> would just be the first valuable, the one used in the leftmost bracket.

As for your emptyimage-example, it would be:
emptyimage[0-7]=image.0.<$0>
...and thats something you can already do (although you need a 'nightly' makeobj, not the last main release)
Trust me, it IS very short and handy, I was able to reduce about 200 lines for some buildings down to 7.

However, currently, you can only reuse the index values themselves. You would need to add the ability to write a list of strings that should be used to replace that index, which is why I added $0: in the example.


Link to the original dat-shortening discussion:
http://forum.simutrans.com/index.php?topic=15133.msg149145#msg149145

Mariculous

That's at least in cases where only numeric values are needed pretty nice and indeed also short.
The enum-like syntax could be a nice compromise if the array-like syntax is much more work.
Anyways I do think for most array like definitions it would be better readable and more fail-safe if we could just list up the values without caring about the amount of elements in that list. I don't know what exactly makeobj does with empty constraints. If it just ignores them, it would be ok to just set the range to 0-99. If it compiles these in any way, it would be a waste of memory to have 200 constraints instead of ~10 per vehicle in the compiled pak.

Anyways, nice to know that I will just need 1 line of code for the emptyimages instead of 8 when the next version of makeobj gets released :)

Leartin

It's already available, if you compile it yourself or ask someone who has a compiled version. For windows: http://simutrans-germany.com/files/upload/Makeobj.zip

prissi

Constraits separated by semicolons when there is an empty bracket is surely no problem.

Mariculous

that's great!
Didn't find a request for such a feature nor a documentation about such a feature so I didn't know it is already possible.