var adfly_protocol = 'https';

Τρίτη 23 Αυγούστου 2016

Η εξαιρετική ομορφιά του πηγαίου κώδικα για το Doom 3

Η εξαιρετική ομορφιά του πηγαίου κώδικα για το Doom 3

Αυτή είναι μια ιστορία για το Doom 3 - πηγαίου κώδικα και πόσο όμορφο είναι. Ναι, όμορφη. Επιτρέψτε μου να εξηγήσω.

Μετά την αφαίρεση βιντεοπαιχνίδι μου Dyad πήρε λίγη ξεκούραση. Διάβασα βιβλία και παρακολούθησαν ένα ζευγάρι των ταινιών που θα πάρει πάρα πολύ καιρό. Δούλευα στην ευρωπαϊκή εκδοχή της Εθνικής Ημέρας, αλλά ο καιρός ήταν ως επί το πλείστον σε αναμονή για τα σχόλια της διασφάλισης της ποιότητας της Sony, έτσι είχα πολύ ελεύθερο χρόνο. Μετά από ένα μήνα, περιφέρονται άσκοπα ή έτσι άρχισα να εξετάσει σοβαρά τι θα κάνω στη συνέχεια. Ήθελα να εξαγάγετε σε μέρη επαναχρησιμοποιήσιμα / κινητήρα πριν δυάδα για ένα νέο έργο.

Το άρθρο αυτό δημοσιεύθηκε στις 14 Ιανουαρίου 2013.

Όταν ξεκίνησα το έργο Dyad είχε ένα παιχνίδι - Μηχανή πολύ καθαρό, πολύ βολικό, έχω άλλα σχέδια συσσώρευση των ετών εργασίας. Στο τέλος της DIADA είχα μια τρομερή καταστροφή.

Στις τελευταίες έξι εβδομάδες της ανάπτυξης δυάδα προστίθενται περίπου 13k γραμμές κώδικα. MainMenu.cc αυξήθηκε σε 24.501 γραμμές. Μόλις πηγή ήταν ένα ωραίο πληγείσες #ifdefs, hands free λειτουργίες, κωδικό γραμμή ASM SIMD άσχημο χάος, και έμαθα ένα νέο όρο: ". Κωδικός εντροπία" Έψαχνα στο διαδίκτυο για άλλα έργα που θα μπορούσαν να χρησιμοποιηθούν για να μάθουν, καθώς εκατοντάδες χιλιάδες γραμμές κώδικα για να οργανώσετε. Μετά από αναζήτηση μέσα από πολλές μεγάλες μηχανές παιχνίδι, είμαι αρκετά αποκαρδιωμένοι? ο πηγαίος κώδικας για την DIADA δεν ήταν τόσο κακό σε σύγκριση με ό, τι άλλο υπάρχει - δεν υπάρχει!

Δυσαρεστημένοι, συνεχίζω να δούμε και βρήκε μια πολύ καλή ανάλυση του Doom 3 - Πηγή - Λογισμικό - τον κωδικό αναγνώρισης από τον υπολογιστή - εμπειρογνώμονα Fabien Sanglard.

Πέρασα μερικές ημέρες μέσω του πηγαίου κώδικα του Doom 3 πάτε και να διαβάσετε το εξαιρετικό άρθρο από τον Fabien όταν έγραψε:

Ήταν η αλήθεια. Ποτέ δεν έχω ανησυχούν Πηγή. Η αλήθεια είναι, δεν θεωρώ τον εαυτό μου "προγραμματιστής". Είμαι καλά, αλλά για μένα είναι απλά ένα μέσο για ένα τέλος. Ο πηγαίος κώδικας για το Doom 3, θα ήθελα πραγματικά να με ξέρουν καλά προγραμματιστές εκτιμήσουν.


Για να βάλουμε τα πράγματα σε μια προοπτική. Dyad έχει θερμοκρασία 193 K γραμμές κώδικα, όλα C ++ Doom 3 έχει 601k, 229K Quake III και Quake II 136K. Έτσι Dyad είναι κάπου μεταξύ Quake II και του Quake III. Αυτά τα μεγάλα έργα.

Όταν μου ζητήθηκε να γράψω αυτό το άρθρο, έχω διαβάσει ως δικαιολογία για περισσότερες πηγαίο κώδικα από άλλα παιχνίδια, και τα πρότυπα προγραμματισμού. Μετά από μέρες έρευνας, είμαι της δικής μου τιτίβισμα συγκεχυμένη που ξεκίνησαν όλα: ότι θα ήταν "διασκεδαστικό να βλέπει κανείς" ή στην πραγματικότητα λένε "ωραία" σε αυτό το ερώτημα, σε σχέση με τον πηγαίο κώδικα που σου ζήτησα; , Προγραμματιστές μερικούς φίλους ό, τι νόμιζαν σήμαινε απαντήσεις του ήταν προφανής, αλλά εξακολουθεί να αξίζει να αναφερθούν:

  • κωδικό του πρέπει να είναι τοπική, συνεπή και μοναδικά έργα: Μια συνάρτηση πρέπει να κάνει ένα πράγμα. Πρέπει να είναι σαφές τι κάνει.
  • τοπικό κώδικα πρέπει να εξηγήσει ή τουλάχιστον να παρεισφρήσουν συνολικό σχεδιασμό του συστήματος.
  • Ο κώδικας θα πρέπει να είναι αυτονόητα. Σχόλια θα πρέπει να αποφεύγεται όποτε είναι δυνατόν. Σχόλια διπλή εργασία κατά τη σύνταξη και την ανάγνωση των κωδικών. Αν χρειάζεται να σχολιάσω κάτι για να καταστεί κατανοητό, θα πρέπει μάλλον να ξαναγραφεί.

Πρόκειται για μια κωδικοποίηση idtech 4 - Πρότυπο ( .doc ) που πιστεύω ότι αξίζει να διαβαστεί. Είμαι περισσότεροι από αυτούς τους κανόνες, και εγώ θα προσπαθήσω να εξηγήσω γιατί είναι και γιατί ειδικά Doom - 3 - κάνουν κώδικα τόσο όμορφο.

ομοιόμορφη ανάλυση και λεξιλογική ανάλυση

Ένα από τα πιο έξυπνα πράγματα που έχω δει Doom είναι η γενική χρήση των λεξιλογική ανάλυση τους [ 1 ] και τον αναλυτή [ 2 αρχεία] όλων των πόρων - αρχεία είναι ASCII - αρχεία με μια ομοιόμορφη σύνταξη, συμπεριλαμβανομένων: σενάρια, κινούμενα σχέδια, τα αρχεία ρυθμίσεων, κλπ ;. τα πάντα είναι η ίδια. Αυτό επιτρέπει σε όλα τα αρχεία που πρέπει να διαβάσει και να υποβάλλονται σε επεξεργασία από ένα μόνο κομμάτι του κώδικα. Ο αναλυτής είναι ιδιαίτερα ισχυρή, υποστηρίζοντας ένα σημαντικό υποσύνολο της C ++. Με την προσκόλληση σε ένα ενιαίο Lexer και όλα τα άλλα εξαρτήματα του κινητήρα δεν έχετε να ανησυχείτε για serialization δεδομένων, επειδή είναι ήδη ένας κωδικός για αυτούς. Αυτό κάνει άλλες πτυχές της καθαρότερο κώδικα.

Κωνστ και άκαμπτες παραμέτρους

Κωδικός Doom είναι αρκετά άκαμπτο, αλλά όχι αρκετά άκαμπτο κατά τη γνώμη μου, σε σύγκριση με const [ 3 ]. Σταθ εξυπηρετεί πολλούς σκοπούς που πιστεύω ότι πολλοί προγραμματιστές αγνοούν. κανόνας μου είναι "όλα πρέπει να χτιστεί όταν δεν μπορεί να είναι." Θέλω ότι όλες οι μεταβλητές στη C ++ const ερήμην απόφαση ήταν σχεδόν πάντα υπεύθυνη πολιτική ρύθμιση "δεν υπάρχει μέσα-έξω". ό, τι αυτό σημαίνει ότι όλες οι παράμετροι λειτουργίας είναι είτε εισόδου ή εξόδου ποτέ και τα δύο. Το γεγονός αυτό καθιστά πολύ πιο εύκολο να καταλάβουμε τι συμβαίνει σε μια μεταβλητή όταν πηγαίνετε σε μια λειτουργία. Για παράδειγμα:

Η εξαιρετική ομορφιά του πηγαίου κώδικα για το Doom 3

Ο ορισμός της συνάρτησης που με κάνει ευτυχισμένη!

Μερικά consts γνωρίζουμε πολλά πράγματα:

  • Η idPlane που έχει περάσει ως επιχείρημα δεν θα αλλάξει από αυτή τη λειτουργία. Μπορώ να τη χρησιμοποιήσετε με ασφάλεια το αεροπλάνο μετά από αυτή τη λειτουργία, χωρίς να ελέγξει τις αλλαγές idPlane τρέχει.
  • Epsilon δεν ξέρουν να αλλάξει στη λειτουργία (αν και μπορεί εύκολα να αντιγραφεί σε διαφορετική τιμή και την αλλαγή, για παράδειγμα, αλλά θα ήταν αντιπαραγωγικό)
  • εμπρός, πίσω και frontOnPlaneEdges backOnPlaceEdges είναι OUT μεταβλητές. Αυτά είναι γραμμένα.
  • τελευταία const μετά τη λίστα παραμέτρων είναι το αγαπημένο μου. Είναι idSurface :: διάσπαση (), η επιφάνεια δεν θα μόνη της να αλλάξει. Αυτό είναι ένα από τα αγαπημένα μου C ++ από άλλες γλώσσες λείπουν λειτουργίες. Αυτό μου επιτρέπει να κάνω κάτι σαν αυτό: void f (const idSurface & s) {
    ΜΕΤΟΧΗ (....)?
    Μοιραστείτε} Θα δεν όπως ορίζεται ένα τμήμα (...) const? Αυτός ο κωδικός δεν θα συγκεντρώνουν. Τώρα ξέρω ότι τα πάντα ονομάζεται f () δεν αλλάζει την επιφάνεια, ακόμα και αν η f () αλλάζει την επιφάνεια σε μια άλλη λειτουργία ή να καλέσετε οποιαδήποτε περιοχή :: μέθοδο (). Κωνστ μου είπε πολλά για τη λειτουργία και συμβουλές για μια ευρύτερη και το σχεδιασμό του συστήματος. Μόνο με αυτή τη λειτουργία δήλωση που ανέγνωσε, επιφάνειες μπορεί να διαιρεθεί με ένα δυναμικό σχέδιο. Αντί για την τροποποίηση της επιφάνειας, υπάρχουν νέες επιφάνειες, εμπρός και πίσω, και, ενδεχομένως, frontOnPlaneEdges και backOnPlaneEdges.

Η const συνήθως δεν έχουν οριστεί ρυθμίσεις / εισόδου-εξόδου είναι ίσως το πιο σημαντικό, κατά τη γνώμη μου, το διαχωρισμό καλό κώδικα από την όμορφη κώδικα. Αυτό το καθιστά ευκολότερο να κατανοήσουμε το όλο σύστημα, και εύκολο να αλλάξει ή Refactor.

ελάχιστη σχόλια

Αυτό είναι θέμα στυλ, αλλά ένα καλό πράγμα είναι η πραγματικότητα να μην σχολιάσω Doom κανονικά. Έχω δει πάρα πολύ κώδικα που μοιάζει με αυτό:

Η εξαιρετική ομορφιά του πηγαίου κώδικα για το Doom 3

Θεωρώ ότι είναι εξαιρετικά ενοχλητικό. Μπορώ να πω ότι αυτή η μέθοδος είναι στο όνομά του. Εάν η λειτουργία σας μπορεί να προέρχεται από το όνομα του, το όνομα θα πρέπει να αλλάξει. Εάν είναι πάρα πολύ για να περιγράψει το όνομά του, να το πράξει. Αν πραγματικά δεν μπορεί να αναθεωρηθεί και να μετονομαστεί για να περιγράψει μόνο τους στόχο, τότε είναι σωστό να σχολιάσει. Νομίζω ότι οι προγραμματιστές διδάσκονται στο σχολείο ότι τα σχόλια είναι καλό? Δεν είναι αυτοί. Τα σχόλια δεν είναι κακό, εκτός αν είναι απολύτως απαραίτητο και μόνο σπάνια χρειάζεται. Μοιραίες δεν είναι να κρατήσει μια λογική προσφορά εργασίας αφενός την ελάχιστη σχόλια. Χρησιμοποιώντας το παράδειγμα idSurface :: διάσπαση (), όπως ο ίδιος είπε:

// Τα τμήματα επιφάνειας σε ένα μπροστινό και πίσω επιφάνεια, η ίδια η επιφάνεια παραμένει αμετάβλητη
// FrontOnPlaneEdges backOnPlaneEdges και μπορεί να αποθηκεύσει τον δείκτη των τραπεζών, που ήταν στο επίπεδο του διαχωρισμού
// Μια SIDE_ Επιστροφή;

Η πρώτη γραμμή είναι εντελώς περιττή. Μάθαμε όλες αυτές τις πληροφορίες από τον ορισμό της συνάρτησης. Η δεύτερη και τρίτη γραμμές είναι κατάλληλα. Ήμασταν σε θέση να αντλήσει τα δεύτερα ιδιότητες γραμμή, αλλά το σχόλιο αφαιρεί κάθε ασάφεια.

Doom - κώδικας είναι, για τους περισσότερους θέματα, δικαστήριο, το οποίο το καθιστά πολύ πιο εύκολο να το διαβάσετε. Ξέρω ότι αυτό είναι ένα θέμα στυλ για μερικούς ανθρώπους, αλλά πραγματικά πιστεύω ότι είναι να κάνει "καλή" σαφώς. Για παράδειγμα, τι θα συμβεί αν κάποιος αλλάξει τη συνεχή λειτουργία και τελικά να αποσυρθεί; Στη συνέχεια, η επιφάνεια * της λειτουργίας μπορεί να αλλάξει, και τώρα το σχόλιο δεν συγχρονίζεται με τον κωδικό. περίεργα σχόλια βλάψει την αναγνωσιμότητα και την ακρίβεια του κώδικα ως κωδικός πιο άσχημη.

απόσταση

Φράγματος δεν χάνει την κάθετη χώρο:

Ένα παράδειγμα t_stencilShadow :: R_ChopWinding ():

Η εξαιρετική ομορφιά του πηγαίου κώδικα για το Doom 3

Είμαι σε θέση να διαβάσει όλα αυτά αλγόριθμο 1/4 της οθόνης μου, έτσι ώστε οι άλλοι 3 / 4s καταλάβουμε ότι αυτή η ακολουθία κώδικα σε σχέση με τον περιβάλλοντα κώδικα. Έχω δει πάρα πολύ κώδικα ως εξής:

Η εξαιρετική ομορφιά του πηγαίου κώδικα για το Doom 3

Αυτό είναι άλλο ένα σημείο που υπάγεται "Στυλ". Έχω προγραμματιστεί για περισσότερα από 10 χρόνια με το τελευταίο μοντέλο, αναγκάζοντάς με να γίνεις πιο δυνατός, ενώ εργαζόταν σε ένα έργο υπάρχουν περίπου έξι χρόνια. Χαίρομαι που πήγα.

Παίρνει 18-11 γραμμές σε σχέση με την πρώτη. Αυτό είναι σχεδόν διπλάσιο από τον αριθμό των γραμμών του κώδικα στο * ίδια ακριβώς λειτουργικότητα. Αυτό σημαίνει ότι το ακόλουθο κομμάτι κώδικα δεν ταιριάζει με την οθόνη για μένα. Ποιο είναι το τραγούδι;

Η εξαιρετική ομορφιά του πηγαίου κώδικα για το Doom 3

Αυτός ο κωδικός δεν είναι χρήσιμο πρωτοφανές για track loop. Εάν το ID δεν είναι δεν συμμορφώθηκε με την κάθετη απόσταση, ο κώδικας θα είναι πολύ πιο δύσκολο να διαβάσει και δύσκολο, πιο δύσκολο να διατηρηθεί και να γράφουν λιγότερο όμορφη.

Ένα άλλο id πράγμα είναι αυτό που νομίζω ότι είναι "σωστό" και δεν είναι θέμα στυλ, πάντα * χρήση {} αλλά προαιρετική. Νομίζω ότι είναι ένα βασικό έγκλημα για να παρακάμψετε. Είδα τόσα πολλά κώδικα ως εξής:

Η εξαιρετική ομορφιά του πηγαίου κώδικα για το Doom 3

Αυτό είναι το άσχημο κώδικα, είναι χειρότερη από τη θέση {} στη δική της γραμμή. Δεν μπόρεσα να βρω ένα μόνο παράδειγμα στον κώδικα αναγνώρισης, ότι η {} χειριστεί. Παραλείποντας προαιρετικό {} την ανάλυση αυτή τη φορά κάνει (μπλοκ) περισσότερο από ό, τι θα έπρεπε. Επιμελήθηκε έναν πόνο, αν, αν μια εντολή διακλάδωσης αν (γ> δ) θέλησε να εισαγάγει τον τρόπο περισσότερο;

ελάχιστη μοντέλα

Αναγνώριση έκανε ένα μεγάλο όχι στον κόσμο, C ++. Έγραψαν όλα τα STL [απαιτούνται 4 Λειτουργίες]. Προσωπικά, έχω μια σχέση αγάπης-μίσους με TEL. Θα χρησιμοποιηθεί σε Dyad στο debug - εκδόσεις για τη δυναμική διαχείριση των πόρων. Στην έκδοση του να μαγειρεύεται όλους τους πόρους, έτσι ώστε να, και δεν είναι όλα τα χαρακτηριστικά της STL είναι όσο το δυνατόν συντομότερα φορτωμένο. Η STL είναι ωραίο, διότι παρέχει γρήγορη γενικές δομές δεδομένων? Είναι κακό, διότι η χρήση του μπορεί να είναι άσχημο συχνά την πιθανότητα σφάλματος. Σκεφτείτε, για παράδειγμα, std :: διάνυσμα <T>. Πείτε Θέλω να επαναλάβω πάνω από κάθε στοιχείο:

Η εξαιρετική ομορφιά του πηγαίου κώδικα για το Doom 3

Αυτό δεν διευκολύνεται με C ++ 11:

Η εξαιρετική ομορφιά του πηγαίου κώδικα για το Doom 3

Εγώ προσωπικά δεν μου αρέσει η χρήση του αυτοκινήτου, νομίζω ότι είναι πιο εύκολο να γράψει τον κώδικα, αλλά πιο δύσκολο να διαβάσει. Θα μπορούσε να είναι η χρήση των αυτοκινήτων τα επόμενα χρόνια για να πάει, αλλά τώρα νομίζω ότι είναι κακό. std :: for_each ή remove_if: Πάω να γελοιοποιήσει κάποια αλγόριθμους STL όπως std δεν αναφέρεται καν.

μια τιμή ενός απομάκρυνσης std :: φορέας δεν προφέρεται:

Η εξαιρετική ομορφιά του πηγαίου κώδικα για το Doom 3

Gee, ότι κάθε φορά για κάθε προγραμματιστής ήταν γραμμένες σωστά!

ID αίρει κάθε ασάφεια: γενική δοχεία ήταν σπιτικά, το είδος των χορδών, κ.λπ. Έχουν πολύ λιγότερο γράψει γενικά ως τα μαθήματα STL, προφανώς για να καταστεί ευκολότερη για να καταλάβετε. Αποστολείς είναι λίγες και συγκεκριμένες χρήσης της μνήμης πρότυπο ταυτότητας. Κωδικός IL είναι γεμάτη μοντέλου ανοησίες που δεν μπορούν να διαβάσουν.

κώδικα C ++ μπορεί να πάρουν άσχημη γρήγορα ακυβέρνητο, χωρίς επιμέλεια από τους προγραμματιστές. Για να δείτε πόσο άσχημα πάρει κονσέρβα πράγματα, δείτε τον πηγαίο κώδικα του STL. Η Microsoft και [GCC 5 ] υλοποιήσεις της STL είναι ίσως το πιο άσχημο που έχω δει τον πηγαίο κώδικα. Ακόμα κι αν οι προγραμματιστές η μέγιστη δυνατή φροντίδα που λαμβάνουν για να κάνει το μοντέλο κώδικα ως αναγνώσιμη δυνατόν, είναι πάντα μια πλήρης καταστροφή. Ρίξτε μια ματιά στη βιβλιοθήκη Λόκι Αντρέι Alexandrescu ή ώθηση - βιβλιοθήκες Τι μερικές από τις καλύτερες C ++ προγραμματιστές στον κόσμο και έχει γραφτεί με μεγάλη προσοχή ώστε να καταστεί τόσο όμορφο όσο το δυνατόν και είναι πάντα άσχημο και ουσιαστικά δυσανάγνωστες.

ID λύνει αυτό το πρόβλημα με απλά πράγματα πολύ γενική. Έχουν μια Hashtable <V> και HashIndex τάξη. Hashtable δυνάμεις const char * να είναι, και είναι ένα HashIndex int> int παρ. Αυτή είναι μια κακή πρακτική ++ Γ θεωρείται ότι "θα πρέπει" να ήταν μια Hashtable τάξη, και να γράψει μια μερική εξειδίκευση για KeyType = const char * και πλήρως εξειδικευμένο <int, int>. Αυτό που κάνει είναι απολύτως σωστό ID και το κάνει πολύ καλύτερο κώδικα.

Τέτοιες καταστάσεις είναι, αντιθέτως, «καλή πρακτική C ++" να επανεξεταστεί γενιά του κατακερματισμού και πώς αναγνώρισης.

Θα πρέπει να θεωρείται από πολλούς ως μια καλή πρακτική για να δημιουργήσετε ένα ορισμένο είδος του υπολογισμού ως παράμετρος στην Hashtable όπως αυτές:

Η εξαιρετική ομορφιά του πηγαίου κώδικα για το Doom 3

Αυτό μπορεί να εξειδικεύεται για ένα συγκεκριμένο τύπο:

Η εξαιρετική ομορφιά του πηγαίου κώδικα για το Doom 3

Στη συνέχεια, μπορείτε να πάτε ComputeHashForType HashComputer για Hashtable:

Η εξαιρετική ομορφιά του πηγαίου κώδικα για το Doom 3

Αυτό είναι παρόμοιο με το πώς το έκανα. Φαίνεται έξυπνη, αλλά το παιδί είναι άσχημο! Τι και αν υπήρχαν μοντέλο προαιρετικές παραμέτρους; Ίσως ένας κατανεμητής μνήμης; Ίσως debugging σχεδιαστή; Θέλετε έναν ορισμό, όπως:

Η εξαιρετική ομορφιά του πηγαίου κώδικα για το Doom 3

Οι ορισμοί των λειτουργιών θα είναι βάναυση!

Η εξαιρετική ομορφιά του πηγαίου κώδικα για το Doom 3

Τι σημαίνει αυτό; Δεν μπορώ καν να βρει το όνομα της διαδικασίας χωρίς τονισμό σύνταξης επιθετικό. Είναι κατανοητό ότι ορίζουν έναν κωδικό, τον κωδικό του σώματος. Αυτό είναι σαφώς δεν είναι εύκολο να διαβάσει, και ως εκ τούτου όμορφα.

Είδα άλλες μηχανές διαχειριστεί αυτή την καταστροφή, κατεβάζοντας την προδιαγραφή παράμετρο προτύπου για μια ποικιλία typedefs. Αυτό είναι ακόμη χειρότερα! Θα μπορούσατε να κάνετε το τοπικό κώδικα πιο εύκολο να καταλάβει, αλλά δημιουργεί ένα άλλο στρώμα του διαχωρισμού μεταξύ της τοπικής και της λογικής του συστήματος στο σύνολό του, έτσι ώστε η τοπική κώδικας σχετίζεται με το σχεδιασμό του συστήματος, το οποίο δεν είναι ωραίο. Για παράδειγμα, ας υποθέσουμε ότι είχατε κωδικό:

Η εξαιρετική ομορφιά του πηγαίου κώδικα για το Doom 3

και

Η εξαιρετική ομορφιά του πηγαίου κώδικα για το Doom 3

και χρησιμοποίησε δύο και έκανε κάτι σαν:

Η εξαιρετική ομορφιά του πηγαίου κώδικα για το Doom 3

Ίσως ο κατανεμητής StringHashTable μνήμη φοράει StringAllocator δεν την παγκόσμια μνήμη, η οποία θα οδηγούσε σε σύγχυση. Θα επιστρέψει στον κώδικα, διαπιστώθηκε ότι StringHashTable είναι στην πραγματικότητα ένα typedef ενός μοντέλου Χάος, αναλύονται από τον κωδικό μοντέλου, γνωρίζουν ότι χρησιμοποιείτε ένα διαφορετικό συντελεστή κατανομής, βρείτε εκχώρησης ... μπλα, μπλα, άσχημο.

Doom είναι το όλο θέμα «λάθος» σύμφωνα με την κοινή λογική Γ: έγραψε τα πράγματα ως γενικές όσο το δυνατόν, η χρήση των γενόσημων μόνο αν έχει νόημα. Τι Hashtable s 'Doom να κάνει όταν θα πρέπει να δημιουργήσετε ένα κάτι hash; Είναι idStr :: GetHash (), ως το μόνο είδος των βασικών ονομάζεται * const char δεκτή. Τι και αν απαιτεί ένα διαφορετικό κωδικό πρόσβασης; Νομίζω ότι είχε το κλειδί πρότυπο, και μόνο key.getHash δύναμη κλήσης () και έχει ο compiler όλων των τύπων των κλειδιών είναι ένας () int μέθοδο GetHash δύναμη.

Τα ερείπια της C

Δεν ξέρω πώς η αναγνώριση του αρχικού προγραμματιστή - ομάδα με την εταιρεία περισσότερο, αλλά ο John Carmack, τουλάχιστον ένα ταμείο C. Όλα ταυτοποίηση παιχνίδια Quake III πριν γραμμένο σε C ​​++ ότι η C - προγραμματιστές πολλά χωρίς ένα ισχυρό υπόβαθρο στην Κ.Ε. ize ++ κώδικα. Το παράδειγμα του προηγούμενου μοντέλου έχει μόνο μία περίπτωση. Τα τρία άλλα παραδείγματα βρίσκονται συχνά:

  • Η κατάχρηση πάρετε / ορίσετε
  • χρήση ροές εγχόρδων
  • Υπερβολική υπερφόρτωση χειριστή.

ID είναι νόμιμη σε όλες τις περιπτώσεις.

Συχνά, μπορείτε να δημιουργήσετε μια τάξη:

Η εξαιρετική ομορφιά του πηγαίου κώδικα για το Doom 3

Αυτή είναι μια σπατάλη των γραμμές κώδικα και να διαβάσετε το χρόνο. Παίρνει περισσότερο χρόνο για να γράψει και να διαβάσει σχετικά με:

Η εξαιρετική ομορφιά του πηγαίου κώδικα για το Doom 3

Τι και αν θα είναι συχνά ένας αριθμός n var για την ανάπτυξη;

Η εξαιρετική ομορφιά του πηγαίου κώδικα για το Doom 3

κατά

Η εξαιρετική ομορφιά του πηγαίου κώδικα για το Doom 3

Το πρώτο παράδειγμα είναι πολύ πιο εύκολο να διαβάσει και να γράψει.

ID δεν χρησιμοποιούν ρεύματα εγχόρδων. Μια συμβολοσειρά περιέχει ίσως την πιο ακραία υπερφόρτωση γνωρίζουν χειριστή μπαστάρδεμα: <<.

Για παράδειγμα:

Η εξαιρετική ομορφιά του πηγαίου κώδικα για το Doom 3

Είναι άσχημο. Έχει μεγάλα πλεονεκτήματα: μπορείτε να καθορίσετε το Java toString () μέθοδος ισοδύναμο στην κατηγορία w / o αγγίζοντας μια τάξη vtables », αλλά η σύνταξη είναι προσβλητικό και τον εντοπισμό αποφάσισε να μην χρησιμοποιήσει για να χρησιμοποιήσετε την επιλογή printf () αντί του. ρευμάτων στοιχειοσειράς κάνει ο κώδικας ευκολότερο να διαβάσει, και αυτό που νομίζω ότι είναι η σωστή επιλογή.

Η εξαιρετική ομορφιά του πηγαίου κώδικα για το Doom 3

Πολύ καλύτερα!

SomeClass Σύνταξη τελεστή << Θα ήταν γελοίο, όπως:

Η εξαιρετική ομορφιά του πηγαίου κώδικα για το Doom 3

[Υποσημείωση: John Carmack δήλωσε στατική ανάλυση - εργαλεία έχουν δείξει ότι η κοινή τους σφάλμα () λανθασμένη παράμετρος printf αναλόγως. Αναρωτιέμαι αν ρευμάτων στοιχειοσειράς αλλάξει σε θυμό εξαιτίας της. CCG και clinkingOptions, τόσο βρει printf () σφάλματος που αντιστοιχεί -Wall παραμέτρων, έτσι ώστε να μην χρειάζεται ακριβά εργαλεία στατική ανάλυση για να βρει αυτά τα λάθη.]

Ένα άλλο πράγμα που το ωραίο κώδικας του Doom κάνει, είναι η ελάχιστη προσπάθεια για τον χειριστή. υπερφόρτωση χειριστής είναι ένα καλό χαρακτηριστικό γνώρισμα της C ++. Σας επιτρέπει να κάνετε πράγματα:

Η εξαιρετική ομορφιά του πηγαίου κώδικα για το Doom 3

Χωρίς τέτοιες πράξεις επιβαρύνει περισσότερο χρόνο θα ήταν να γράψετε και να αναλύσει. Μοιραίες σταματά εδώ. Βλέπω κωδικό που δεν λειτουργεί. Είδα τον κωδικό που ορίζεται από τον φορέα εκμετάλλευσης "%", με την έννοια του προϊόντος φορέα dot παρακαμφθούν ή να κάνουν εκτός από Χειριστή * διάνυσμα πολλαπλασιασμό. Δεν έχει κανένα νόημα για τον χειριστή * για το σταυρό του προϊόντος, επειδή είναι διαθέσιμη μόνο σε 3D, αν θέλετε:
* Some_2d_vec some_2d_vec, τι πρέπει να κάνετε; Τι 4d ή περισσότερο; Αναγνώριση ελάχιστη επιβάρυνση χειριστής αφήνει καμία αμφιβολία για τον αναγνώστη κώδικα.

οριζόντια απόσταση

Ένα από τα πιο σημαντικά πράγματα που έμαθα κώδικας του Doom ήταν μια απλή αλλαγή του στυλ. Θα χρησιμοποιηθεί για να έχουν μαθήματα, εμφανίστηκε:

Η εξαιρετική ομορφιά του πηγαίου κώδικα για το Doom 3

Μετά από Doom 3 id πρότυπο κωδικοποίησης, με το πραγματικό καρτέλες, οι οποίες είναι τέσσερα δωμάτια. ένα ενοποιημένο περιβάλλον για όλους τους προγραμματιστές με την καρτέλα που μπορούν να ευθυγραμμιστούν οι ορισμοί της τάξης τους σε οριζόντια θέση:

Η εξαιρετική ομορφιά του πηγαίου κώδικα για το Doom 3

Σπάνια πάρετε on-line λειτουργίες στον ορισμό της κατηγορίας. Η μόνη φορά που τον είδα ήταν όταν ο κώδικας είναι γραπτή, στην ίδια γραμμή με τη δήλωση της συνάρτησης. Φαίνεται ότι η πρακτική αυτή δεν είναι στάνταρ και ίσως παρακινδυνευμένο. Αυτό το είδος της οργάνωσης του ορισμού τάξης είναι εξαιρετικά εύκολο να αναλυθούν. Μπορεί να πάρει λίγο περισσότερο χρόνο για να γράψω, γιατί θα πρέπει να εισάγετε πολλές μεθόδους πληροφόρησης στον ορισμό:

Η εξαιρετική ομορφιά του πηγαίου κώδικα για το Doom 3

Είμαι ενάντια σε περαιτέρω επιθέσεις. Κάνω τα πράγματα όσο το δυνατόν γρηγορότερα, αλλά αυτό είναι μια κατάσταση όπου νομίζω να ορίσετε λίγο περισσότερο τάξη που εισέρχονται περισσότερο για να πληρώνετε κάθε φορά που ο ορισμός της κατηγορίας πρέπει να αναλύονται από έναν προγραμματιστή. Υπάρχουν πολλές άλλες στιλιστικές παραδείγματα στο Doom 3 Πρότυπα Κωδικοποίησης (υποθέτοντας .doc ) που συμβάλλουν στην ομορφιά του πηγαίου κώδικα του Doom.

Το όνομά μέθοδο

Νομίζω ότι η μέθοδος των κανόνων ονομασίας Doom δεν είναι αρκετά. Προσωπικά χρησιμοποιώ τον κανόνα ότι όλα τα ονόματα μέθοδο θα πρέπει να αρχίσει με ένα ρήμα, εκτός αν δεν μπορεί.

Για παράδειγμα:

Η εξαιρετική ομορφιά του πηγαίου κώδικα για το Doom 3

Είναι πολύ καλύτερα από ό, τι:

Η εξαιρετική ομορφιά του πηγαίου κώδικα για το Doom 3

Ναι, είναι ωραίο.

Είμαι πολύ χαρούμενος για να γράψω αυτό το άρθρο, γιατί πραγματικά μου έδωσε μια δικαιολογία για να σκεφτούμε τι ένα καλό κώδικα. Εγώ ακόμα δεν νομίζω ότι ξέρω, και ίσως αυτός είναι πολύ υποκειμενική. Πιστεύω ότι τα δύο πιο σημαντικά, τουλάχιστον για μένα, τα πράγματα είναι const-ness εγκοπή υφολογικά και το μέγιστο.

Πολλές επιλογές στυλ είναι σίγουρα προσωπική μου προτίμηση, και είμαι βέβαιος ότι και άλλοι προγραμματιστές έχουν διαφορετικές απόψεις. Νομίζω ότι η επιλογή του στυλ που χρησιμοποιείται είναι ο ένας να διαβάσει τον κώδικα και να γράψω, αλλά νομίζω ότι είναι σίγουρα κάτι που αξίζει τον προβληματισμό.

Θα έλεγα ότι ο καθένας στο Doom 3 πηγή φαίνεται, γιατί νομίζω ότι είναι καλό κώδικα δείχνει ως ένα πλήρες πακέτο: ο σχεδιασμός μειώνει την μορφή του συστήματος δωματίου καρτέλες.

Shawn Osborne είναι ένας προγραμματιστής παιχνίδι που βασίζεται στο Τορόντο και ο δημιουργός του διάσημου ψυχεδελικό PlayStation, να μάθουν περισσότερα 3 Dyad αγωνιστικά παιχνίδι παζλ πάνω. Το παιχνίδι του συνεχίζεται -. Είναι στο Twitter .


αρχεία

[ 1 ] Ένας σαρωτής μετατρέπει τον κωδικό χαρακτήρα εξόδου εμφανίζονται (σε σχέση με την relevent), μια σειρά από σύμβολα που έχουν μια σημασιολογική έννοια του πηγαίου κώδικα .:

x + y = 5?

Ένα Lexer (ή «λεξικό» για συντομία) θα μπορούσε αυτή η πηγή tokenize όπως:
x => μεταβλητές
= => Τελεστή εκχώρησης
y => Μεταβλητό
+ => Περισσότερα χειριστή
5 => ακέραιος γραμματική
? => Τελική Διακήρυξη

Αυτή η συμβολοσειρά - Token είναι το πρώτο από τα πολλά βήματα στη μετατροπή του πηγαίου κώδικα, ένα πρόγραμμα που εκτελείται. λεξιλογική ανάλυση, αφού το τσιπ εισάγεται σε έναν αναλυτή, και compiler, σύνδεσης, και, τέλος, μια εικονική μηχανή (συντάχθηκε στην περίπτωση ενός CPU γλώσσες). Μπορεί να παρεμβάλλεται μεταξύ αυτών ορόσημα ενδιάμεσα βήματα, αλλά εμφανίζονται σε γενικές γραμμές αυτές που θεωρούνται ως το πιο βασικό.

[ 2 ] Ένας αναλυτής είναι (συνήθως) να κατανοήσουν το επόμενο λογικό βήμα στην γλώσσα μηχανής η ακόλουθη λεξιλογική ανάλυση (υπολογιστή - θα κωδικό γλώσσας / πηγή, στο πλαίσιο αυτό, αλλά ισχύει η ίδια φυσική γλώσσα) εισόδου -. Analyzer είναι ένα κατάλογο των μαρκών που παράγεται από ένα λεξικογραφικό αναλυτή και παρέχει ένα συντακτικό δέντρο: ένα "parsing - δέντρο".

Στο παράδειγμα: x = y + 5 το parsing θα - δέντρο μοιάζει με αυτό:

Η εξαιρετική ομορφιά του πηγαίου κώδικα για το Doom 3

[ 3 ] "const" είναι μια λέξη - C ++ κώδικα, η οποία εξασφαλίζει ότι μια μεταβλητή δεν μπορεί να αλλάξει, ή ότι μια μέθοδος η οποία δεν αλλάζει το περιεχόμενο της τάξης σας. "Const" είναι συντομογραφία Ενδιαφέρον C ++ περιέχει ένα διάλυμα ή "σταθερή" μέσω const_cast [T] ή το στυλ γύψο C. (T *) να αγνοήσει τη χρήση αυτών των διαλειμμάτων μεταξύ τους. Const, και για χάρη της συζήτησης, ότι προτιμώ να την ύπαρξή του και ποτέ δεν το χρησιμοποιούν στην πράξη.

[ 4 ] STL σημαίνει "Standard Library Template" είναι μια συλλογή των εμπορευματοκιβωτίων, αλγόριθμους και τις λειτουργίες που οι περισσότεροι προγραμματιστές C + που χρησιμοποιείται είναι από όλους τους μεγάλους κατασκευαστές των compilers με διαφορετικά επίπεδα εξοπλισμού -. Υποστηριζόμενα βελτιστοποίηση και αναφορά σφαλμάτων.

[ 5 ] GCC - GNU Compiler Collection: ένα σύνολο compiler που υποστηρίζει πολλαπλές γλώσσες προγραμματισμού. Στην περίπτωση αυτού του άρθρου, το ΣΣΚ αναφέρεται - Compiler GNU C / C είναι ένα δωρεάν compiler με πλήρη πηγαίο κώδικα είναι δωρεάν και τρέχει σε ένα ευρύ φάσμα των συστημάτων υλικού και το λειτουργικό συχνά να χρησιμοποιηθούν άλλα μεταγλωττιστές περιλαμβάνουν: Clang, Microsoft Visual C ++ IBM. XL C / C ++, η Intel C ++ compiler.

Δεν υπάρχουν σχόλια:

Δημοσίευση σχολίου