Themabewertung:
  • 0 Bewertung(en) - 0 im Durchschnitt
  • 1
  • 2
  • 3
  • 4
  • 5
Haltestellen eindeutig im script bestimmen
#1
Ausgangslage:
Ziel ist es von einer gegebenen Linie eines Spielers alle Haltestellen ohne Doppelungen zu erfassen.

Via line_x.get_schedule() erhält man alle Wegpunkte der Linie und kann zu jedem Wegpunkt via get_halt( player_x(pl) ) einen eventuell vorhandenen Haltepunkt bestimmen. Hat man nun diese Liste an Haltestellen, können dort Doppelungen vorkommen. Ein Vergleich der coord3d Werte ist mit der Instanz der class halt_x nicht möglich. Ein Vergleich der Namen via get_name() ist nicht zuverlässig, da der Name vom Benutzer im Spiel geändert werden kann und es mehrere Haltestellen mit dem selben Namen geben kann

Wie also vergleiche ich zwei halt_x Objekte der Liste um herauszufinden ob diese eine identische Haltestelle darstellen ?
Zitieren
#2
Intern hat jeder Halt eine eindeutige Id, das handle. Das muesste man dann dem Skript lesbar machen. Ich muss mal in den Skriptteil nachschauen.
Zitieren
#3
Ich bin squirrel-Anfänger. Versuch mal angehängten Patch EDIT: bzw. die angehängte api_halt.cc Falls es geht wird das auch gleich für Convois und Linien hinzugefügt, schließlich muss man die auch vergleichen können.

Code:
Index: trunk/script/api/api_halt.cc
===================================================================
--- trunk/script/api/api_halt.cc    (revision 7340)
+++ trunk/script/api/api_halt.cc    (working copy)
@@ -76,6 +76,13 @@
}


+// compare two halts to find out if they are the same
+SQInteger halt_compare(halthandle_t a, halthandle_t b)
+{
+    return (SQInteger)a.get_id() - (SQInteger)b.get_id();
+}
+
+
void export_halt(HSQUIRRELVM vm)
{
    /**
@@ -119,6 +126,13 @@
    register_method(vm, &haltestelle_t::get_besitzer, "get_owner");

    /**
+     * compare classes using metamethods
+     * @param halt the other halt
+     * @returns difference in the unique id of the halthandle
+     */
+    register_method(vm, &halt_compare, "_cmp", true);
+
+    /**
     * Quick check if there is connection for certain freight to the other halt.
     * @param halt the other halt
     * @param freight_type freight type


Angehängte Dateien
.zip   api_halt.zip (Größe: 1,84 KB / Downloads: 637)
Zitieren
#4
Habe simutrans mit dem neuen code api_halt.cc compiliert und kann es erfolgreich starten. Nur auf die Methode kann ich nicht zugreifen. Diese müsste in der Klasse halt_x mit _cmp( compare_halt ) aufzurufen sein. Erhalte aber die script Fehlermeldung : index '_cmp' does not exist. Habe ich da etwas falsch verstanden?

edit: Habe nichts falsch verstanden, Code Änderung ist in Ordnung und funktioniert, nur Sqirrel mag wohl kein führenden Tiefstrich im Methodennamen! Daher die Methode ohne führenden Tiefstrich einbinden.
Zitieren
#5
bezugnehmend auf
github : commit 8ec2397daa7f80a8093000240432c229ad99e5a1

muss in Zeile 133 Datei script/api/api_halt.cc
der Methodenname für squirrel "_cmp" geändert werden. Kein Tiefstrich verwenden !!!
Oder umbenennen in "compare", da "_cmp" seitens squirrel, wie andere Bezeichnungen mit
Tiefstrich dort bereits eine andere Funktion haben.
Zitieren
#6
Dummerweise kann man mit _cmp nicht auf Gleichheit testen. Die _cmp Methode wird aufgerufen, wenn man zwei Objekte mit <,<=,>=,>, <=> vergleicht. Explizit _cmp aufrufen geht nicht.

Zum Testen ob zwei Halte gleich sind, einfach mal (halt1<=>halt2)==0 probieren. Man koennte aber auch gleich (halt1.id == halt2.id) verwenden. Die id ist als Member-Variable da, sollte aber nicht veraendert werden. Beide Methoden sollten mit aktuellen Versionen gehen.
Zitieren
#7
Es geht nicht um die squirrel eigene "_cmp" Methode, sondern darum das eine solche nochmals in in Zeile 133 Datei script/api/api_halt.cc definiert wird. Dies führt zum Fehler, die Methode braucht einen anderen Namen.

Zitat: Man koennte aber auch gleich (halt1.id == halt2.id) verwenden.
Sehr gut. Ein Hinweis auf die ID wäre in für Unkundige und Script-Entwickler hilfreich.
Siehe : http://dwachs.github.io/simutrans-sqapi-...lt__x.html
Zitieren
#8
Die methode ist korrekt als _cmp eingebunden. Man kann diese nur nicht direkt aufrufen.
Code:
b1 = (halt1 <=> halt2) == 0 // ruft intern _cmp auf
b2 = halt1._cmp(halt2) // error _cmp not found
Diese Metamethoden werden intern nicht wie 'normale' Klassen-funktionen gespeichert. Diese Methoden sind dazu da, Operatoren zu ueberladen (wie in C++), d.h. diese Methoden werden intern aufgerufen, wenn Vergleiche (_cmp), Addition (_add) etc gemacht werden.

Das bloede ist halt, dass man die Abfrage auf Gleichheit (== ) nicht direkt ueberladen kann:
Code:
a  = { x=1 }
b = { x=1 }
c = a
print( a==b ) // false!
print( a==c)  // true!
a.x=2
print( a==b ) // false!
print( a==c)  // true!
Bei == wird tatsaechlich nur geprueft, ob es sind um ein und dasselbe Object handelt. In obigen Beispiel sehen a und b zwar gleich aus, sind aber intern zwei verschiedene Tabellen. Durch die Zuweisung c=a ist aber c dann die gleiche Tabelle wie a.

Die Variable id habe ich extra nicht dokumentiert. Die Variable wird benutzt, um Skript-intern dann das zugehoerige C++ Objekt zu finden. Wenn man id veraendert, bekommt man eine andere Haltestelle geliefert...
Zitieren
#9
Jetzt habe ich es verstanden und auch gleich mal mit r4348 umgesetzt. Vielen Dank für die Erklärung.

Zitat:Die Variable id habe ich extra nicht dokumentiert. Die Variable wird benutzt, um Skript-intern dann das zugehörige C++ Objekt zu finden. Wenn man id verändert, bekommt man eine andere Haltestelle geliefert...
Verständlich.

Kann man dann vielleicht, da ich annehme das nicht nur sattelfeste Programmierer sich an Szenarien Scripten versuchen, die Beispiel _cmp Nutzung in die Dokumentation aufzunehmen?
Zitieren
#10
ny911,'index.php?page=Thread&postID=104541#post104541' schrieb:Kann man dann vielleicht, da ich annehme das nicht nur sattelfeste Programmierer sich an Szenarien Scripten versuchen, die Beispiel _cmp Nutzung in die Dokumentation aufzunehmen?

So richtig bedienerfreundlich ist es ja nicht, so wie es ist.

Wie waere es, einen neuen Vergleichs-Operator === einzufuehren? Der dann tatsaechlich _cmp aufruft?

Oder stattdessen == so umzuleiten, dass _cmp aufgerufen wird, und der Operator === dann das alte Verhalten abbildet?
Zitieren


Gehe zu:


Benutzer, die gerade dieses Thema anschauen: 2 Gast/Gäste