| 1 | PySoy Hacking Guidelines |
|---|
| 2 | ======================== |
|---|
| 3 | or, how to contribute code that doesn't suck |
|---|
| 4 | -------------------------------------------- |
|---|
| 5 | |
|---|
| 6 | Introduction |
|---|
| 7 | ~~~~~~~~~~~~ |
|---|
| 8 | As a free software community project PySoy is worked on by a large number of |
|---|
| 9 | users. Each of these users have their own preferences for code layout and |
|---|
| 10 | with their own unique styles. Without some structure applied to this process |
|---|
| 11 | the project would devolve into an unparsable, unmaintainable mess. |
|---|
| 12 | |
|---|
| 13 | We also benefit a great deal from developers working from "different angles". |
|---|
| 14 | A problem addressed with one solution may be very difficult, while by another |
|---|
| 15 | method very easy. Guidelines set too strictly would thus dampen the beautiful |
|---|
| 16 | dissonance that makes our community so strong. |
|---|
| 17 | |
|---|
| 18 | So in an attempted balance these guidelines are set forth. Use them when it |
|---|
| 19 | makes sense to, bend or break them when nessesary, and don't complain if |
|---|
| 20 | someone cleans your code up to better meet these guidelines. :-) |
|---|
| 21 | |
|---|
| 22 | |
|---|
| 23 | Code Layout |
|---|
| 24 | ~~~~~~~~~~~ |
|---|
| 25 | |
|---|
| 26 | * Lines should be no longer than 80 characters (maximum) |
|---|
| 27 | |
|---|
| 28 | - most terminals and editors default to 80 columns |
|---|
| 29 | |
|---|
| 30 | - wrap parameter lists indented to start of list (stacked vertically) |
|---|
| 31 | |
|---|
| 32 | - move function returns to variables to shorten long lines |
|---|
| 33 | |
|---|
| 34 | - try to minimize deeply-nested code |
|---|
| 35 | |
|---|
| 36 | - use "\" to escape carrage returns when needed |
|---|
| 37 | |
|---|
| 38 | * 2 space indententation |
|---|
| 39 | |
|---|
| 40 | - tabs do not copy/paste for some |
|---|
| 41 | |
|---|
| 42 | - 1 space is difficult to see on 80 column display |
|---|
| 43 | |
|---|
| 44 | - many editors (kate, gedit) allow you to see this in more intuitive ways |
|---|
| 45 | |
|---|
| 46 | |
|---|
| 47 | Label Conventions |
|---|
| 48 | ~~~~~~~~~~~~~~~~~ |
|---|
| 49 | |
|---|
| 50 | * Internal (cdef) variables and functions should begin with a single _ |
|---|
| 51 | |
|---|
| 52 | - ie, _core._scenes, _core.Window._windowID |
|---|
| 53 | |
|---|
| 54 | * Modules should be all lowercase |
|---|
| 55 | |
|---|
| 56 | * Classes should begin with uppercase |
|---|
| 57 | |
|---|
| 58 | - this allows classes to be easily discernable from modules and methods |
|---|
| 59 | |
|---|
| 60 | - if MultiWord, use CamelCase, ie, "forces.MonoPole" |
|---|
| 61 | |
|---|
| 62 | * Methods and properties should be with lowercase |
|---|
| 63 | |
|---|
| 64 | - ie, "forces.MonoPole.strength" |
|---|
| 65 | |
|---|
| 66 | * Avoid functions outside of a class |
|---|
| 67 | |
|---|
| 68 | |
|---|
| 69 | Module Layout |
|---|
| 70 | ~~~~~~~~~~~~~ |
|---|
| 71 | |
|---|
| 72 | * Modules should contain many classes |
|---|
| 73 | |
|---|
| 74 | - consider merging with another module if only one or two classes |
|---|
| 75 | |
|---|
| 76 | * Each class should exist in it's own .pxi file |
|---|
| 77 | |
|---|
| 78 | - it's much easier to track API changes and navigate code this way |
|---|
| 79 | |
|---|
| 80 | - temporary "testing" classes are an exception to this |
|---|
| 81 | |
|---|
| 82 | * Modules should often be named plural with base class the singular |
|---|
| 83 | |
|---|
| 84 | - ie, soy.bodies.Body, soy.widgets.Widget, soy.joints.Joint |
|---|
| 85 | |
|---|
| 86 | * Modules should be nested by level of class inheritance |
|---|
| 87 | |
|---|
| 88 | - ie, soy.bodies.particles.Flame, soy.widgets.containers.VBox |
|---|
| 89 | |
|---|
| 90 | * Modules must begin with pydoc strings |
|---|
| 91 | |
|---|
| 92 | - begin with standard multiline pydoc help for the module |
|---|
| 93 | |
|---|
| 94 | - include GPLv3 license information in __credits__ |
|---|
| 95 | |
|---|
| 96 | - __author__ should contain the module's current maintainer |
|---|
| 97 | |
|---|
| 98 | - __version__ string should be $Rev:$ so users can find code revisions |
|---|
| 99 | |
|---|
| 100 | |
|---|
| 101 | Class Layout |
|---|
| 102 | ~~~~~~~~~~~~ |
|---|
| 103 | |
|---|
| 104 | * Dimensions and ranges should be combined into a single property |
|---|
| 105 | |
|---|
| 106 | - reduces code and API complexity |
|---|
| 107 | |
|---|
| 108 | - ie, Body.position, not Body.x Body.y Body.z |
|---|
| 109 | |
|---|
| 110 | - ie, Joint.stops, not Joint.lostop Joint.histop |
|---|
| 111 | |
|---|
| 112 | * Classes should accept common (or all) properties as __new__/__init__ kw's |
|---|
| 113 | |
|---|
| 114 | - ie, soy.widgets.Projector(scene, camera=cam, position=(0,25)) |
|---|
| 115 | |
|---|
| 116 | * Every class and every property MUST be documented |
|---|
| 117 | |
|---|
| 118 | - this is done with a multiline string directly in the code |
|---|
| 119 | |
|---|
| 120 | - pydocs are copied to both .c and compiled modules, comments are not |
|---|
| 121 | |
|---|
| 122 | |
|---|
| 123 | Documentation |
|---|
| 124 | ~~~~~~~~~~~~~ |
|---|
| 125 | TODO, see above for now |
|---|