Jammer-Thread
Re: Jammer-Thread
Devader läuft nicht mehr richtig in der neuen version von Chrome, ein neuer WebGL error
"[.WebGL-0C7B85A8] GL_INVALID_OPERATION: Feedback loop formed between Framebuffer and active Texture."
Unity hat eine "support Retina" option für mac die ich immer noch nicht verstehe und input problem habe ich immer noch bei tiefen Frameraten. Spass!
"[.WebGL-0C7B85A8] GL_INVALID_OPERATION: Feedback loop formed between Framebuffer and active Texture."
Unity hat eine "support Retina" option für mac die ich immer noch nicht verstehe und input problem habe ich immer noch bei tiefen Frameraten. Spass!
Discord: https://discord.gg/AWhsvN3 für Devader: http://devader.space
- Krishty
- Establishment
- Beiträge: 8316
- Registriert: 26.02.2009, 11:18
- Benutzertext: state is the enemy
- Kontaktdaten:
Re: Jammer-Thread
Oh, Tracking-Links in URLs sind lustig.
Kickstarter baut Tracking-Links in alle Mails ein, die sie verschicken. Woher ich das weiß? Ich musste gerade in meine Server-Logs schauen, und darin finde ich Referral-Links von vier verschiedenen Anbietern:
Jedenfalls weiß ich nun ziemlich genau, in wessen Newsletter ich aufgetaucht bin. Und weiß, wie viele Leute mindestens auf den Link geklickt haben.
Das ist nach meinem Verständnis nicht die Vorschau, die Anbieter wie Outlook automatisch in empfangene Mails einbauen. Dort würde ich nur Kickstarters Link als Referral bekommen.
Google und Yahoo sind sauber; da kommt nix durch.
Kickstarter baut Tracking-Links in alle Mails ein, die sie verschicken. Woher ich das weiß? Ich musste gerade in meine Server-Logs schauen, und darin finde ich Referral-Links von vier verschiedenen Anbietern:
- deref-gmx.net
- deref-web-02.de
- mail.google.com
- mail.yahoo.com
Jedenfalls weiß ich nun ziemlich genau, in wessen Newsletter ich aufgetaucht bin. Und weiß, wie viele Leute mindestens auf den Link geklickt haben.
Das ist nach meinem Verständnis nicht die Vorschau, die Anbieter wie Outlook automatisch in empfangene Mails einbauen. Dort würde ich nur Kickstarters Link als Referral bekommen.
Google und Yahoo sind sauber; da kommt nix durch.
-
- Moderator
- Beiträge: 2138
- Registriert: 25.02.2009, 13:37
Re: Jammer-Thread
Gib doch mal den Link zu dem Kickstarter.
- xq
- Establishment
- Beiträge: 1589
- Registriert: 07.10.2012, 14:56
- Alter Benutzername: MasterQ32
- Echter Name: Felix Queißner
- Wohnort: Stuttgart & Region
- Kontaktdaten:
Re: Jammer-Thread
Dazu ein kleiner Einwurf von meiner Seite:
Da mich das ganze Tracking ziemlich ankäst, habe ich angefangen, ein kleines Userscript zu basteln, welches mir bekannte Tracking-Kacke aus den Links entfernt:
https://github.com/MasterQ32/Userscript ... hygiene.js
Freu mich natürlich hier auch über mehr Domain-Query-Paare, die ich wegwerfen kann
Da mich das ganze Tracking ziemlich ankäst, habe ich angefangen, ein kleines Userscript zu basteln, welches mir bekannte Tracking-Kacke aus den Links entfernt:
https://github.com/MasterQ32/Userscript ... hygiene.js
Freu mich natürlich hier auch über mehr Domain-Query-Paare, die ich wegwerfen kann
War mal MasterQ32, findet den Namen aber mittlerweile ziemlich albern…
Programmiert viel in Zig und nervt Leute damit.
Programmiert viel in Zig und nervt Leute damit.
- Krishty
- Establishment
- Beiträge: 8316
- Registriert: 26.02.2009, 11:18
- Benutzertext: state is the enemy
- Kontaktdaten:
Re: Jammer-Thread
Zu der Kampagne? Klar! Hat ja sogar mit Game Design zu tun. Die personalisierten Links natürlich nicht, oder hast du was vor?!
xq hat geschrieben:Freu mich natürlich hier auch über mehr Domain-Query-Paare, die ich wegwerfen kann
Code: Alles auswählen
https://deref-web-02.de/mail/client/XXXXXXXXXXX/dereferrer/?redirectUrl=https%3A%2F%2F…
https://deref-gmx.net/mail/client/XXXXXXXXXXX/dereferrer/?redirectUrl=https%3A%2F%2F…
-
- Moderator
- Beiträge: 2138
- Registriert: 25.02.2009, 13:37
Re: Jammer-Thread
Ich glaube ich habe nicht verstanden, wie der zusammenhang zwischen Kickstartet und deinen Serverlogs ist. Ich dachte, dass die Kickstarter-Kampagne zu deinem Server linkt, aber Kickstarter die Links dekoriert. Bist du hier auf der Seite der Kampagne oder als Backer involviert?
Diese konkrete Kampagne scheint Kickstarter als Verkaufsplattform und nicht zur Vorfinazierung zu verwenden?!
Re: Jammer-Thread
Wie benutzt man das? Es wäre vielleicht nicht schlecht eine genauere Beschreibung oder ein kleines Tutorial in die Github Seite zu integrieren. Oder beides ^^xq hat geschrieben: ↑05.06.2020, 11:26 Dazu ein kleiner Einwurf von meiner Seite:
Da mich das ganze Tracking ziemlich ankäst, habe ich angefangen, ein kleines Userscript zu basteln, welches mir bekannte Tracking-Kacke aus den Links entfernt:
https://github.com/MasterQ32/Userscript ... hygiene.js
Freu mich natürlich hier auch über mehr Domain-Query-Paare, die ich wegwerfen kann
- Krishty
- Establishment
- Beiträge: 8316
- Registriert: 26.02.2009, 11:18
- Benutzertext: state is the enemy
- Kontaktdaten:
Re: Jammer-Thread
Involviert bin ich gar nicht. Der Zusammenhang ist folgender:Alexander Kornrumpf hat geschrieben: ↑05.06.2020, 12:34Ich glaube ich habe nicht verstanden, wie der zusammenhang zwischen Kickstartet und deinen Serverlogs ist. Ich dachte, dass die Kickstarter-Kampagne zu deinem Server linkt, aber Kickstarter die Links dekoriert. Bist du hier auf der Seite der Kampagne oder als Backer involviert?
- Die Kampagne verschickt einen Newsletter an ihre registrierten Backer.
- Der Newsletter enthält einen Link zu meiner Webseite. In welchem Kontext – ob als Empfehlung des Künstlers oder bloß als Teil einer Zusammenfassung von Chats unter registrierten Benutzern – kann ich nicht sagen.
- Kickstarter findet, dass sie unbedingt wissen müssen, wann ein Backer auf einen Link im Newsletter klickt. Darum ändern sie den Link von http://example.com zu http://emails.kickstarter.com/mps/uBLAB ... /123123123…. Klickt jemand auf den Link, registriert das erstmal deren Server, und dann wird der Klick zu meiner Seite weitergeleitet.
- GMX und Web.de finden, dass sie unbedingt wissen müssen, wann ein User auf einen Link in einer Email klickt. (Oder Sicherheitsfeature oder so.) Darum ändern sie den Link von https://example.com zu https://deref-web-02.de/mail/client/XXX ... %2Fexample…. Klickt jemand auf den Link, registriert das erstmal deren Server, und dann wird der Link zu meiner Seite weitergeleitet.
- Einer (oder beide; ich kenne mich da nicht so gut aus) vergessen bei ihrer Weiterleitung, den Tracking-Teil des Links zu löschen.
- Wenn ich nun in die Logs meines Webservers schaue, finde ich darin als Referral für bestimmte Besucher die vollen Tracking-Links für GMX/Web.de und Kickstarter, inklusive solchen Zeugs wie client/UNIQUE_ID.
- Ich glaube nicht, dass das im Sinne des Erfinders ist. Und auch nicht im Sinne der DSGVO, einen anonymen Link in einen teils-personalisierten umzuwandeln und dann blind an den Zielserver zu schicken, den man gar nicht kennt. Und auch nicht im Sinne der User.
Ich denke, die Vorfinanzierung war erfolgreich – das Projekt scheint finanziert und fertig zu sein.Alexander Kornrumpf hat geschrieben:Diese konkrete Kampagne scheint Kickstarter als Verkaufsplattform und nicht zur Vorfinazierung zu verwenden?!
- xq
- Establishment
- Beiträge: 1589
- Registriert: 07.10.2012, 14:56
- Alter Benutzername: MasterQ32
- Echter Name: Felix Queißner
- Wohnort: Stuttgart & Region
- Kontaktdaten:
Re: Jammer-Thread
Ich bin mal so frei und dreist und verweise dich auf: https://lmgtfy.com/?q=userscriptTiles hat geschrieben: ↑05.06.2020, 12:36Wie benutzt man das? Es wäre vielleicht nicht schlecht eine genauere Beschreibung oder ein kleines Tutorial in die Github Seite zu integrieren. Oder beides ^^xq hat geschrieben: ↑05.06.2020, 11:26 Dazu ein kleiner Einwurf von meiner Seite:
Da mich das ganze Tracking ziemlich ankäst, habe ich angefangen, ein kleines Userscript zu basteln, welches mir bekannte Tracking-Kacke aus den Links entfernt:
https://github.com/MasterQ32/Userscript ... hygiene.js
Freu mich natürlich hier auch über mehr Domain-Query-Paare, die ich wegwerfen kann
War mal MasterQ32, findet den Namen aber mittlerweile ziemlich albern…
Programmiert viel in Zig und nervt Leute damit.
Programmiert viel in Zig und nervt Leute damit.
Re: Jammer-Thread
Da steht was ein Userscript generell ist. Was ich übrigens das erste Mal lese. Da steht aber nicht was dein Script tut oder wie man dein Script benutzt. Oder für welchen Browser dein Script überhaupt ist. Sprich wie so oft ist auch dieser LMGTFY Link einfach fürn Popo :)
- xq
- Establishment
- Beiträge: 1589
- Registriert: 07.10.2012, 14:56
- Alter Benutzername: MasterQ32
- Echter Name: Felix Queißner
- Wohnort: Stuttgart & Region
- Kontaktdaten:
Re: Jammer-Thread
Dann eine ausführlichere Antwort: Das Script löscht aus den Seiten, die du besuchst, Tracking-Informationen aus den Links, damit du diese bequem aus der Adresszeile bei anderen einfügen kannst.Tiles hat geschrieben: ↑05.06.2020, 14:31 Da steht was ein Userscript generell ist. Was ich übrigens das erste Mal lese. Da steht aber nicht was dein Script tut oder wie man dein Script benutzt. Oder für welchen Browser dein Script überhaupt ist. Sprich wie so oft ist auch dieser LMGTFY Link einfach fürn Popo :)
Benutzen: Installiere das Userscript in der Userscript-Extension deiner Wahl im Browser deiner Wahl durch "Copy&Paste"
War mal MasterQ32, findet den Namen aber mittlerweile ziemlich albern…
Programmiert viel in Zig und nervt Leute damit.
Programmiert viel in Zig und nervt Leute damit.
Re: Jammer-Thread
Wieso hat C++ eigentlich immer noch keine named parameter / keyword parameter? Insbesondere wenn ich irgendwo hinten noch ein paar Standardtypen habe bei denen dei Reihenfolge nicht unbedingt intuitiv ist, wird das halt schnell unübersichtlich (process_object(my_object, true, false, true statt process_object(my_object, print_progress=true, optimize_more=false, strict_mode=true). Insbesondere wenn die hinteren Parameter Standardwerte haben, man dann aber die Funktion nochmal um zusätzliche Parameter erweitern will, die vielleicht nicht unbedingt ganz hinten stehen sollen, wird sowas schnell unrobust. Könnte man die Parameternamen angeben, hätte man viel lesbareren Code der nicht so schnell kaputt geht.
Und im Gegensatz zu großartigen Features wie Modulen, ist das hier ja trivial umsetzbar. Ein bisschen syntaktischer Zucker, es betrifft wirklich nur die eine Zeile.
Es gibt ein paar Hacks (https://www.fluentcpp.com/2018/12/14/na ... ments-cpp/) aber sowas will ich eigentlich nicht benutzen. Es soll halt einfach im Standard sein. Klappt bei anderen Sprachen doch auch. Vermutlich ist der Grund irgendwie so was dummes wie das man theoretisch ja call(tmp = ComputeParameters()); SomethingElse(tmp); schreiben dürfte, was dann kaputt gehen könnte. Aber sowas will ich eigentlich eh nicht in normalem Code sehen...
Und im Gegensatz zu großartigen Features wie Modulen, ist das hier ja trivial umsetzbar. Ein bisschen syntaktischer Zucker, es betrifft wirklich nur die eine Zeile.
Es gibt ein paar Hacks (https://www.fluentcpp.com/2018/12/14/na ... ments-cpp/) aber sowas will ich eigentlich nicht benutzen. Es soll halt einfach im Standard sein. Klappt bei anderen Sprachen doch auch. Vermutlich ist der Grund irgendwie so was dummes wie das man theoretisch ja call(tmp = ComputeParameters()); SomethingElse(tmp); schreiben dürfte, was dann kaputt gehen könnte. Aber sowas will ich eigentlich eh nicht in normalem Code sehen...
Lieber dumm fragen, als dumm bleiben!
https://jonathank.de/games/
https://jonathank.de/games/
- Krishty
- Establishment
- Beiträge: 8316
- Registriert: 26.02.2009, 11:18
- Benutzertext: state is the enemy
- Kontaktdaten:
Re: Jammer-Thread
Die würde ich auch gar nicht haben wollen, weil Parameternamen Implementierungsdetails sind. Du sollst sowas eigentlich über den Typ abbilden. Also in deinem Beispiel
Code: Alles auswählen
enum progress_verbosity;
enum optimization_level;
enum conformance_level;
void process_object(object const &, progress_verbosity, optimization_level, conformance_level);
process_object(my_object, progress_verbosity::info, optimization_level::off, conformance_level::din1234_1997a);
Re: Jammer-Thread
Ach, ich weiß nicht. Ein Objekttyp und wofür das Objekt verwendet wird sind ja auch zwei verschiedene Paar Schuhe. Was ist wenn ich ein from_position und to_position habe, soll ich dann meine Vektorklasse zweimal überladen? Und dann jeden Vektor explizit casten müssen (implizit casten würde ja vermutlich alles kaputt machen)? Und überhaupt für jeden Parameter jeder Funktion mindestens eine Zeile Boilerplatecode haben? Code sollte ja auch kompakt sein um verständlich zu sein.
Ich würde behaupten, sinnvolle Parameternamen stehen auf einer Stufe mit sinnvollen Funktionsnamen. Die sind vielleicht nicht selber die Implementierung, aber zumindest ein starker Hinweis darauf, wie sich diese Verhalten sollte. Parameter nicht nach dem zu benennen, was sie machen, finde ich auch überhaupt nicht schön. Wenn man einen "float generic_parameter_3" braucht, sollte man halt lieber eine zweite Funktion dafür schreiben...
Ich würde behaupten, sinnvolle Parameternamen stehen auf einer Stufe mit sinnvollen Funktionsnamen. Die sind vielleicht nicht selber die Implementierung, aber zumindest ein starker Hinweis darauf, wie sich diese Verhalten sollte. Parameter nicht nach dem zu benennen, was sie machen, finde ich auch überhaupt nicht schön. Wenn man einen "float generic_parameter_3" braucht, sollte man halt lieber eine zweite Funktion dafür schreiben...
Lieber dumm fragen, als dumm bleiben!
https://jonathank.de/games/
https://jonathank.de/games/
- Chromanoid
- Moderator
- Beiträge: 4273
- Registriert: 16.10.2002, 19:39
- Echter Name: Christian Kulenkampff
- Wohnort: Lüneburg
Re: Jammer-Thread
Ich bin prinzipiell eher gegen diese Möglichkeit. Das führt nur dazu, dass man kein schlechtes Gefühl bekommt, wenn es zu viele Parameter werden. Lieber Parameter-Objekte (ggf. mit Builder) nutzen und IDE-Unterstützung (inline parameter hints). Wobei ich letzteres recht gewöhnungsbedürftig fand.
@Krishty also Parameternamen gehören für mich zum Schnittstellenvertrag. Implementierungsdetail werden sie in der Implementierung.
@Krishty also Parameternamen gehören für mich zum Schnittstellenvertrag. Implementierungsdetail werden sie in der Implementierung.
-
- Establishment
- Beiträge: 426
- Registriert: 23.01.2013, 15:55
Re: Jammer-Thread
In C++20 hat man sich nach 20 Jahren Verspätung nun dazu durchgerungen, Strukturen mit Variablennamen initialisieren zu können wie man das in C schon seit C99 kann. Einge Features von C wurden leider noch rausgeworfen, aber man wird wenigstens so was schreiben können:
Ich glaube dieses "Designated Initializers" genannte Feature ist ernsthaft in der Praxis wahrscheinlich die nützlichste Neuerung in C++20.
Code: Alles auswählen
struct process_object_args { float from; float to; };
void process_object(const process_object_args& args);
process_object({ .from = 0.0f, .to = 8.0f });
Warum sollte man bei vielen Paramtern denn ein schlechtes Gefühl bekommen? Ich bekomme ehrlich gesagt bei den Structs oder gar Builder Patterns ein schlechtes Gefühl, da das viel mehr Code und mentalen Overhead erfordert als simple Parameter.Chromanoid hat geschrieben: ↑07.06.2020, 15:32Das führt nur dazu, dass man kein schlechtes Gefühl bekommt, wenn es zu viele Parameter werden.
Re: Jammer-Thread
Ich hatte ja damals Irrklang eingebaut und war eigentlich auch ganz ok zufrieden damit. Aber jetzt wollte ich mal auf 3D Sound umstellen und irgendwie will das absolut nicht. In der Doku sieht es alles total simpel aus, Position der Quelle setzen, Position des Listeners setzen, fertig. Aber alles wird abgespielt als sei es am selben Ort und im Internet findet sich tatsächlich extrem wenig dazu. Und so langsam gehen mir die Ideen aus, was ich testen sollte...
Lieber dumm fragen, als dumm bleiben!
https://jonathank.de/games/
https://jonathank.de/games/
- Krishty
- Establishment
- Beiträge: 8316
- Registriert: 26.02.2009, 11:18
- Benutzertext: state is the enemy
- Kontaktdaten:
Re: Jammer-Thread
Nein, dann sollst du Line oder Path o. ä. übergeben! Aber klar, jede Empfehlung hat irgendwann ihre Grenze ;) Ich finde es halt einfacher, das Typsystem dafür anzuwenden, als den Sprachkern um ein weiteres Feature zu erweitern, das dann nur ab und zu benutzt wird.
Praktisch ist das oft so, aber anstreben würde ich das nie. Ich würde eher sagen: Wenn man Parameter benennen muss, ist die Schnittstelle schon zu schwer benutzbar. Ich sehe das als Übung, meine Funktionen so zu schreiben, dass man die Parameternamen weglassen kann.Chromanoid hat geschrieben: ↑07.06.2020, 15:32@Krishty also Parameternamen gehören für mich zum Schnittstellenvertrag. Implementierungsdetail werden sie in der Implementierung.
- Chromanoid
- Moderator
- Beiträge: 4273
- Registriert: 16.10.2002, 19:39
- Echter Name: Christian Kulenkampff
- Wohnort: Lüneburg
Re: Jammer-Thread
Mmh, also wenn jeder Parameter eindeutig getypt ist, meinetwegen, aber ich kenne da vor allem gruselige Sachen mit Parametern ala int long long Boolean... da gibt es dann schnell mal ein durcheinander.Spiele Programmierer hat geschrieben: ↑07.06.2020, 15:50Warum sollte man bei vielen Paramtern denn ein schlechtes Gefühl bekommen? Ich bekomme ehrlich gesagt bei den Structs oder gar Builder Patterns ein schlechtes Gefühl, da das viel mehr Code und mentalen Overhead erfordert als simple Parameter.Chromanoid hat geschrieben: ↑07.06.2020, 15:32Das führt nur dazu, dass man kein schlechtes Gefühl bekommt, wenn es zu viele Parameter werden.
Hier mal ein Artikel von vielen dazu:
https://hackernoon.com/object-oriented- ... 70ac86d996 Lesbarkeit ist natürlich recht subjektiv. Mir fällt bei vielen Argumenten meist auf, dass eine Art Kontext/Zustand herumgereicht wird oder eine komplexe Konfiguration einer komplexen Operation erfolgt. Da macht es für mich viel Sinn eigene Objekte für einzuführen. Gerade bei letzterem kann man dann auch gleich wunderbar defaults in das Parameterobjekt gießen und presets über builder o.ä. anbieten.
Re: Jammer-Thread
Hm, überzeugt mich nicht wirklich. Klar man könnte eine Line-Klasse schreiben. Aber ist ja jetzt nicht so, dass man die für hundert Funktionen braucht. Vielleicht nur für ein paar, vielleicht nur für eine. Dafür eine ganze Klasse (am besten sauber mit eigenem Header?) bläht doch Code doch arg auf.
Anderes Beispiel: Irrklang hat eine Funktion SetListenerPosition(vec3 Position, vec3 ViewDirection, vec3 Velocity, vec3 UpVector). Kann man jetzt nicht wirklich zusammenfassen, außer in eine SetListenerPositionParemeter-Klasse. Aber dann geht es ja noch weiter, man möchte ja auch Standardwerte definieren. Geht in C++ nur in einer Richtung, wenn man den letzten Wert angeben will, muss man alle davor angeben. Mit benannten Parametern könnte man einfach jedem Parameter einen Standardwert geben, und nur die ändern, die man wirklich ändern will.
In diesem Beispiel wurde sich offensichtlich dazu entschieden, dass der Up-Vector der langweiligste Wert ist, weil der ja eh immer (0,1,0) sei. Ich verwende aber seit Jahren immer Koordinatensysteme in XY Ebene, also muss ich den Wert auf (0,0,1) setzen und dementsprechend immer auch die Listener-Velocity angeben. Ich habe also einen Funktionsaufruf wo 4 mal der selbe Typ übergeben wird, und die Reihenfolge nicht wirklich intuitiv ist. Könnte man Namen angeben, wäre sofort jedem klar, was passiert, ohne dass man sich die Funktionsdeklaration anschauen muss. Und das ohne eine einzelne Zeile zusätzlichen Code.
Ich meine, gibt es irgendeinen vernünftigen Grund, der wirklich gegen benannte Parameter spricht? C++ war ja seit jeher eine Multiparadigmen-Sprache, man muss ja auch keine Klassen oder Exceptions verwenden, wenn man nicht mag. Aber ich sehe in diesem Fall definitiv eine Berechtigung und es erscheint mir vergleichsweise simpel umzusetzen und das Kompilieren jetzt auch nicht wirklich langsamer zu machen.
Anderes Beispiel: Irrklang hat eine Funktion SetListenerPosition(vec3 Position, vec3 ViewDirection, vec3 Velocity, vec3 UpVector). Kann man jetzt nicht wirklich zusammenfassen, außer in eine SetListenerPositionParemeter-Klasse. Aber dann geht es ja noch weiter, man möchte ja auch Standardwerte definieren. Geht in C++ nur in einer Richtung, wenn man den letzten Wert angeben will, muss man alle davor angeben. Mit benannten Parametern könnte man einfach jedem Parameter einen Standardwert geben, und nur die ändern, die man wirklich ändern will.
In diesem Beispiel wurde sich offensichtlich dazu entschieden, dass der Up-Vector der langweiligste Wert ist, weil der ja eh immer (0,1,0) sei. Ich verwende aber seit Jahren immer Koordinatensysteme in XY Ebene, also muss ich den Wert auf (0,0,1) setzen und dementsprechend immer auch die Listener-Velocity angeben. Ich habe also einen Funktionsaufruf wo 4 mal der selbe Typ übergeben wird, und die Reihenfolge nicht wirklich intuitiv ist. Könnte man Namen angeben, wäre sofort jedem klar, was passiert, ohne dass man sich die Funktionsdeklaration anschauen muss. Und das ohne eine einzelne Zeile zusätzlichen Code.
Ich meine, gibt es irgendeinen vernünftigen Grund, der wirklich gegen benannte Parameter spricht? C++ war ja seit jeher eine Multiparadigmen-Sprache, man muss ja auch keine Klassen oder Exceptions verwenden, wenn man nicht mag. Aber ich sehe in diesem Fall definitiv eine Berechtigung und es erscheint mir vergleichsweise simpel umzusetzen und das Kompilieren jetzt auch nicht wirklich langsamer zu machen.
Lieber dumm fragen, als dumm bleiben!
https://jonathank.de/games/
https://jonathank.de/games/
- Krishty
- Establishment
- Beiträge: 8316
- Registriert: 26.02.2009, 11:18
- Benutzertext: state is the enemy
- Kontaktdaten:
Re: Jammer-Thread
Ich weiß nicht, wie oft man in deinem imaginären Programm so eineJonathan hat geschrieben: ↑08.06.2020, 00:05Hm, überzeugt mich nicht wirklich. Klar man könnte eine Line-Klasse schreiben. Aber ist ja jetzt nicht so, dass man die für hundert Funktionen braucht. Vielleicht nur für ein paar, vielleicht nur für eine. Dafür eine ganze Klasse (am besten sauber mit eigenem Header?) bläht doch Code doch arg auf.
Äh … eine Funktion, die SetPosition heißt, und gleichzeitig die Geschwindigkeit und Orientierung setzt?! Aber gut, zur Frage:Anderes Beispiel: Irrklang hat eine Funktion SetListenerPosition(vec3 Position, vec3 ViewDirection, vec3 Velocity, vec3 UpVector). Kann man jetzt nicht wirklich zusammenfassen, außer in eine SetListenerPositionParemeter-Klasse.
void Update(Listener &, GlobalPoint, GlobalVelocity, GlobalOrientation);
… wobei GlobalOrientation halt ein Konzept ist, das du durch View+Up konstruieren kannst, oder durch Quaternion, oder durch Matrix, etc.
Wenn du deine Koordinaten versehentlich relativ zum Fahrzeug des Spielers speicherst, sagt dir auch direkt der Compiler, dass du deinen LocalPoint zu GlobalPoint konvertieren musst, statt dass du zwanzig Minuten debuggst, warum die Sounds dauernd um dich zu kreisen scheinen.
vec3 für alles ist sowieso scheiße, weil Leute dann anfangen, Positionen aufzuaddieren oder lokale Koordinaten von globalen Geschwindigkeiten zu subtrahieren und sowas …
Du hast also überall magische Konstanten copy-pasted anstatt dir beim zweiten Mal direkt eine Hilfsfunktion (mit wirklich nur einer einzigen Zeile Länge!) zu schreiben?! Und jetzt ist der C++-Standard schuld, dass der Code Grütze ist?!In diesem Beispiel wurde sich offensichtlich dazu entschieden, dass der Up-Vector der langweiligste Wert ist, weil der ja eh immer (0,1,0) sei. Ich verwende aber seit Jahren immer Koordinatensysteme in XY Ebene, also muss ich den Wert auf (0,0,1) setzen und dementsprechend immer auch die Listener-Velocity angeben. Ich habe also einen Funktionsaufruf wo 4 mal der selbe Typ übergeben wird, und die Reihenfolge nicht wirklich intuitiv ist. Könnte man Namen angeben, wäre sofort jedem klar, was passiert, ohne dass man sich die Funktionsdeklaration anschauen muss. Und das ohne eine einzelne Zeile zusätzlichen Code.
- Chromanoid
- Moderator
- Beiträge: 4273
- Registriert: 16.10.2002, 19:39
- Echter Name: Christian Kulenkampff
- Wohnort: Lüneburg
Re: Jammer-Thread
@Jonathan: Das Ding heißt doch schon setListenerPosition. Warum nicht ein struct namens ListenerPosition oder sowas?!
-
- Establishment
- Beiträge: 308
- Registriert: 25.08.2019, 05:00
- Alter Benutzername: gdsWizard
- Kontaktdaten:
Re: Jammer-Thread
meine ich auch. Das minimiert schon erheblich die Fehlersuche...Chromanoid hat geschrieben: Das Ding heißt doch schon setListenerPosition. Warum nicht ein struct namens ListenerPosition oder sowas?!
Hat den StormWizard 1.0 und 2.0 verbrochen. https://mirrorcad.com
Re: Jammer-Thread
Und das ist kein hypothetischer Fall. Ich habe mal eine Codebasis übernommen, da wurde ein Vec3 gleichzeitig für
- x, y, z
- x, y, Orientierung in Grad
- x, y, Orientierung in Rad
- WGS84; mal (Latitude, Longitude, Altitude), mal (Longitude, Latitude, Altitude)
- Chromanoid
- Moderator
- Beiträge: 4273
- Registriert: 16.10.2002, 19:39
- Echter Name: Christian Kulenkampff
- Wohnort: Lüneburg
Re: Jammer-Thread
Wenn mit Datenbank-IDs hantiert wird, sind typisierte IDs also z.B. einfache Wrapper statt direkt Long oder Uuid zu verwenden übrigens ein Segen.
- Krishty
- Establishment
- Beiträge: 8316
- Registriert: 26.02.2009, 11:18
- Benutzertext: state is the enemy
- Kontaktdaten:
Re: Jammer-Thread
Nicht nur mit Datenbanken; eigentlich mit allem … das ist ja der Punkt – wenn die Funktion render(ModelIndex) statt render(int) deklariert ist, brauche ich keinen Parameternamen mehr.
- Chromanoid
- Moderator
- Beiträge: 4273
- Registriert: 16.10.2002, 19:39
- Echter Name: Christian Kulenkampff
- Wohnort: Lüneburg
Re: Jammer-Thread
Ja, sehe ich auch so. Das ist halt bei Java leider manchmal eine Trade-off Entscheidung... Aber i.d.R. ist es unproblematisch, da man solche Späße ja auch über Flyweight oder sonst wie lösen kann.
-
- Establishment
- Beiträge: 426
- Registriert: 23.01.2013, 15:55
Re: Jammer-Thread
Hm, also das sehe ich komplett anders. Ich war noch nie ein Fan davon, aber früher hatte ich in meiner Bibliothek noch einen eigenen Typ um Farbwerte abzuspeichern. Heute ist das sogar auch einfach ein Vektor und dieses Refactoring hat mal eben so viele hundert Zeilen Farb-Code in Wohlgefallen aufgelöst. Dabei kann mich nicht erinnern, deswegen mal einen Bug gehabt zu haben. In bestimmten Fällen würde ich höchstens ein typedef verwenden, aber das hilft natürlich nicht wirklich bei Jonathans Problem.Krishty hat geschrieben: ↑08.06.2020, 00:28Wenn du deine Koordinaten versehentlich relativ zum Fahrzeug des Spielers speicherst, sagt dir auch direkt der Compiler, dass du deinen LocalPoint zu GlobalPoint konvertieren musst, statt dass du zwanzig Minuten debuggst, warum die Sounds dauernd um dich zu kreisen scheinen.
vec3 für alles ist sowieso scheiße, weil Leute dann anfangen, Positionen aufzuaddieren oder lokale Koordinaten von globalen Geschwindigkeiten zu subtrahieren und sowas …
Überhaupt in einem normalen Programm gibt es aber derart viele verschiedene Koordinatensysteme, da kannst du doch wohl kaum jedesmal einen neuen Datentyp einführen? Und jedesmal müsste man dann ja jede Menge Operationen implementieren... Ich meine, schauen wir uns mal den aller einfachsten Fall an, lineare Bewegungen ohne Rotation oder sowas:
Man braucht doch bereits mindestens die 3 Typen Position, Geschwindigkeit und Beschleunigung! Und was kommt dabei rum wenn man jetzt eine Position von einer anderen subtrahiert? Braucht man jetzt schon wieder weitere Typen, diesmal relative Positionen, Geschwindigkeiten und potentiell Beschleunigungen? Und wie hängt der jetzt mit Geschwindigkeit und Beschleunigung zusammen? Braucht man dann noch einen Zeitpunkt und Zeitspannen-Typ um alle physikalischen Einheiten abzubilden? Oder kann man den Unterschied dann einfach in Geschwindigkeit und Beschleunigung konvertieren und dann skalieren? Wenn ja, ich glaube da wird es aber ganz schön viele zusätzliche Casts geben. Und eigentlich sind das alles ja noch Spezialfälle, in jeder Menge Situationen/Algorithmen braucht man dann ja noch höhere Ableitungen und andere mathematische Größen, die noch schwerer in so ein System passen. In deinem Beispiel fallen mir auch gute Gründe ein die Positionen aufzuaddieren (z.B. um den Mittelpunkt zu finden) oder lokale Koordinaten von von globalen Geschwindigkeiten zu subtrahieren (z.B. um in diese Richtung zu beschleunigen). Ich kann mir ehrlich gesagt kaum vorstellen so ein System allgemein genug zu implementieren, so dass man nicht doch ständig hinter die Kulissen schauen muss.
Und dann sind diese ganzen Konzepte doch unglaublich Situationsbezogen. In einem anderen Projekt, oder vlt. sogar einen Untermodul, machen höchstwahrscheinlich ganz andere Koordinatensysteme Sinn. Letztendlich bekommt man so doch nur Unmengen von Code, der eigentlich nichts anderes macht als das mathematische Konzept des (euklidischen) Vektorräums immer und immer wieder neu zu implementieren! Um unterschiedliche Interpretation einer Struktur/eines Objekt auseinanderzuhalten, kann man auch einfach aussagekräftige Variablennamen verwenden. Und sollte man Programmierer im Team haben die dazu neigen fehlerhaft zwei Positionen zu addieren obwohl die Variablen klar als Positionen im gleichen Koordinatensystem gekennzeichnet sind, dann werden die besagten Programmierer auch die ganzen Einzeltypen des Öfteren falsch einsetzen...
Ja okay, das ist wirklich doof. Allerdings ist das hier in meinen Augen nicht angebracht über den generischen Vektor-Typ zu lästern, weil man hier einfach Daten in einen Vektor abgespeichert hat, die halt nunmal eigentlich gar kein Vektor sind und dadurch vermutlich praktisch alle Operationen keinen Sinn ergeben. Dieses Beispiel ist analog dazu im von Krishty vorgeschlagenen System lokale Positionskoordinaten in einem GlobalVelocity-Typ zu packen.EyDu hat geschrieben: ↑08.06.2020, 07:56 Und das ist kein hypothetischer Fall. Ich habe mal eine Codebasis übernommen, da wurde ein Vec3 gleichzeitig fürverwendet. Die ersten drei Varianten wurden auch munter addiert und haben zu sehr schwer nachvollziehbaren Bugs geführt.
- x, y, z
- x, y, Orientierung in Grad
- x, y, Orientierung in Rad
- WGS84; mal (Latitude, Longitude, Altitude), mal (Longitude, Latitude, Altitude)
- Krishty
- Establishment
- Beiträge: 8316
- Registriert: 26.02.2009, 11:18
- Benutzertext: state is the enemy
- Kontaktdaten:
Re: Jammer-Thread
enum CoordinateSpace { global, local, wasauchimmer };Spiele Programmierer hat geschrieben: ↑08.06.2020, 15:48Überhaupt in einem normalen Programm gibt es aber derart viele verschiedene Koordinatensysteme, da kannst du doch wohl kaum jedesmal einen neuen Datentyp einführen? Und jedesmal müsste man dann ja jede Menge Operationen implementieren...
[…]
Letztendlich bekommt man so doch nur Unmengen von Code, der eigentlich nichts anderes macht als das mathematische Konzept des (euklidischen) Vektorräums immer und immer wieder neu zu implementieren!
template <CoordinateSpace space> class Vector…;
using GlobalVector = Vector<CoordinateSpace::global>;
using LocalVector = Vector<CoordinateSpace::local>;
Ist eigentlich gar nicht so viel immer wieder neuer Code. Ist aber hingegen irre praktisch, wenn du wirklich mal unterschiedlichen Code für globale und lokale Koordinaten brauchst, etwa weil du einen Flugsimulator schreibst und nicht von Grund auf alles nach double portieren möchtest. Und dass das in komplexen Formeln nicht mehr ausreicht, klar – aber man muss ja auch nichts auf die Spitze treiben.
Ja, braucht man tatsächlich. Darum gibt es z. B. std::chrono::time_point und std::chrono::duration. Für sowas möchte man übrigens auch oft unterschiedliche Datentypen, weil bei Geschwindigkeiten Gleitkommazahlen ganz gut funktionieren und bei Positionen Festkommazahlen, aber nicht umgekehrt.Und was kommt dabei rum wenn man jetzt eine Position von einer anderen subtrahiert? Braucht man jetzt schon wieder weitere Typen, diesmal relative Positionen, Geschwindigkeiten und potentiell Beschleunigungen?
Mir fallen auch gute Gründe ein, einen Zeiger zu int zu konvertieren, aber geben wir dafür das Typsystem auf?! Mittel ist bei mir übrigens in der Position drin, und wird nicht jedes Mal neu implementiert.In deinem Beispiel fallen mir auch gute Gründe ein die Positionen aufzuaddieren (z.B. um den Mittelpunkt zu finden)
Hier sind wir bei der eigentlichen Fragestellung – ich behaupte, dass man sich die Variablennamen sparen kann, wenn die Typen für ausreichend Sicherheit sorgen. Und im Gegensatz zu Namen werden die halt vom Compiler auf Korrektheit geprüft.Um unterschiedliche Interpretation einer Struktur/eines Objekt auseinanderzuhalten, kann man auch einfach aussagekräftige Variablennamen verwenden.