Posted by: Bartimeus
« on: April 26, 2020, 12:22:02 PM »Hello,
I just to say thanks to you Steve for working on this topic. Hope it will work out !
My only problem with installing aurora back in the VB6 was those separator
This is kind of where my understanding of the problem has got to. C#, by default, is doing everything localised. All the methods that transform a string into a number, or a number into a string, are all going to use the user's culture unless they are specifically told not to. So it should all be transparent to the developer.
The only way I can see these problems happening, are numeric string literals, hardcoded either in the db or the code, that are being put directly to the UI. Solving this would seem to be the way to fix it, rather that writing your own number parsing routines.
Or just stop C# from localising at all (which is the current solution, except the user is doing it manually by changing their system settings). Which I believe is pretty trivial, though I admit I've never done it. This article:
https://csharp.net-tutorials.com/working-with-culture-and-regions/application-culture-and-uiculture/
Seems to suggest you can set the entire application's culture with a one-liner.
I'm a little lost on the exact problem here. Ideally:
- Whenever Aurora is reading a string from the UI to transform it into a number in memory, it should use the culture of the computer where the software is running.
- Whenever Aurora is printing a number in memory to the UI, it prints it using the culture of the computer where it is running.
If the DB is storing some numbers as strings with a particular separator, then writing or reading those strings from the DB to a number in memory should be done with whatever culture the DB is expecting. This means that Aurora may need two different code paths to handle transforming between strings and numbers if the DB culture and the user culture are different.
The only problem would be if the DB has a number stored as a string, and then that goes directly to the UI without being transformed to a number in memory, or viceversa. Those cases would need to be changed so there's a middle transformation to a number so the correct culture is applied.
but why use decimal separators to begin with? can't something like picking the rightmost [,.] as comma separator and ignore the rest work?That would require every number to have a decimal separator or the game would confuse 76,000 as 76 and not 76k. Naturally, my personal preference is the thousands separator to be just space and have the decimal be either of the two, less prone for misinterpretation, but it would force everyone to use that instead of what people are used to.
with apsw.Connection('database.sqlite') as db:
db.cursor().executemany('INSERT INTO table1 (foo, bar, bin, baz) VALUES (?, ?, ?, ?);',
((row.foo, row.bar, row.bin, row.baz) for row in data1))
db.cursor().executemany('INSERT INTO table2 (foo, bar, bin, baz) VALUES (?, ?, ?, ?);',
((row.foo, row.bar, row.bin, row.baz) for row in data2))
private string formatString = "+0.00#;-0.00#;0";
private string formatShortString = "+0.###;-0.###;0";
private string formatShortStringNoPlus = "0.###;-0.###;0";
row.Cells[ColumnMaxHitpoints].Value = apparel.MaxHitpoints.ToString(formatShortStringNoPlus);
row.Cells[ColumnInsulationHeatMultiplier].Value = (apparel.InsulationHeatMultiplier * 100).ToString(formatShortStringNoPlus) + "%";
row.Cells[ColumnInsulationHeatdStatic].Value = apparel.InsulationHeat.ToString(formatShortString) + "C";
Besides, the database uses periods so I don't want to have to change input and output of every field based on local culture as I will probably be adding more bugs that I am fixing.
I've run into an issue in my decimal separator quest.For the UI just use C#'s built in conversion functions instead of rolling your own.
I have a function that detects whether the decimal separator is a comma or period in the number I am checking. It can tell the difference between 0.1 and 0,1 and parse them correctly. It can also handle 1,000.01 and 1.000,01 correctly.
Unfortunately, when there is no decimal specified, it struggles, 86,000 is parsed as 86, because the function can't decide if that is 86,000 with a period separator or 86 with a comma separator.
I could check the decimal separator of the PC on which the code is running, but if the player uses the opposite the problem still remains. Besides, the database uses periods so I don't want to have to change input and output of every field based on local culture as I will probably be adding more bugs that I am fixing. The 'detect on input' option would have been a lot easier if I could get it to work.
So at this point, I am going to have to stick with period separators only and players will have to continue changing it when running Aurora.
float.Parse("1.200,00", System.Globalization.CultureInfo.CurrentCulture.NumberFormat);
using (SQLiteTransaction trans = connection.BeginTransaction()) {
using (SQLiteCommand insertTable1 = new SQLiteCommand("INSERT INTO table (foo, bar, bin, baz) VALUES (?, ?, ?, ?);", connection) {
SQliteParameter foo = new SQLiteParameter();
SQliteParameter bar = new SQLiteParameter();
SQliteParameter bin = new SQLiteParameter();
SQliteParameter baz = new SQLiteParameter();
insertTable1.Parameters.add(foo);
insertTable1.Parameters.add(bar);
insertTable1.Parameters.add(bin);
insertTable1.Parameters.add(baz);
for (n=0; n < limit; n++) {
foo = data[n].foo; // 500
bar = data[n].bar; // 3.2
bin = data[n].bin; // "SQLite will escape this string itself"
baz = data[n].baz; // null
insertTable1.ExecuteNonQuery();
}
}
using (SQLiteCommand insertTable2 = new SQLiteCommand("INSERT INTO table2 (foo, bar, bin, baz) VALUES (?, ?, ?, ?);", connection) {
}
trans.Commit();
}
For best performance wrap the entire save operation in a single transaction instead of a transaction for each table, and then wrap the transaction in a try block. This should also help with the missing troops and missing fleets bugs.It's a thing most people never have to fiddle with in their computer so it's a common issue for new players.
Then some few people might be doing statistics or accounting or math or engineering on their PC in which case using the wrong symbol might have serious consequences.
I've run into an issue in my decimal separator quest.
I have a function that detects whether the decimal separator is a comma or period in the number I am checking. It can tell the difference between 0.1 and 0,1 and parse them correctly. It can also handle 1,000.01 and 1.000,01 correctly.
Unfortunately, when there is no decimal specified, it struggles, 86,000 is parsed as 86, because the function can't decide if that is 86,000 with a period separator or 86 with a comma separator.
I could check the decimal separator of the PC on which the code is running, but if the player uses the opposite the problem still remains. Besides, the database uses periods so I don't want to have to change input and output of every field based on local culture as I will probably be adding more bugs that I am fixing. The 'detect on input' option would have been a lot easier if I could get it to work.
So at this point, I am going to have to stick with period separators only and players will have to continue changing it when running Aurora.
I think the biggest issue is no matter how much you tell people, some will still run into the issue because they don't read.
Steve, could you simply detect if a person is using the comma and warn them to change on startup?