Creating a new module is a piece of cake. In order to maintain a similar layout for all modules, you should respect some minor rules.
Create an new directory under src, using the name of the module you would like to create (see below, “Module naming”). All source files related to your module should go into that directory (and stay there!). You should use the Python 2.5 and 3.0 API for programming. In order to support Python 2.4, include the “pgcompat.h” header file, where appropriate.
In case the module is a wrapper around an existing library, the module’s should be similar to that of the library. The module name should be all lowercase and do not have any other characters besides a-z in its name.
Example:
SDL_gfx -> sdlgfx
SDL -> sdl
MyOwnLib -> myownlib
...
The module (or modules) source files should match the following naming conventions:
Module C source: MODULENAMEmod.c
C API header: pgMODULENAME.h
Classes: CLASSNAME.c
The file names are all lowercase, MODULENAME has to be replaced with the name of the module (see above), CLASSNAME is the name of the class to wrap. Both are not absolutely strict in their convention, but it should be easy to determine the module header, module code and class code files on a first glance, without looking at the contents of the files.
Example:
Module C source: sdlimage -> sdlimagemod.c, imagemod.c, ...
C API header: sdlimage -> pgsdlimage.h, pgimage.h, ...
Classes: Surface -> surface.c,
Mask -> mask.c
Make sure, the C API header does not conflict with another header to be installed. Headers used on the module scope only (internally used headers) can be named as you like. The C API headers should use the “pg” prefix to avoid naming issues with system or 3rd party library headers.
To import a module from C code, import_pygame2_MODULENAME_SUBMODULE() or import_pygame2_MODULENAME() should be used, where MODULENAME has to be replaced with the name of the module and SUBMODULE with an existing submodule.
pygame2.sdl.video import_pygame2_sdl_video() pygame2.sdlttf import_pygame2_sdlttf() ... ...
The rest of the C API should follow the Python naming conventions. You can take a look at the existing headers for examples on how to do it. If you have plain C functions you would like to become an own C library, use the pyg_ prefix to indicate it. Those functions must not have any reference to the Python API and should be seperated from the rest of the code so that merging them into an own library is as easy as possible.
Example (see src/sdlext, draw.c and draw.h):
int pyg_draw_aaline (...);
int pyg_draw_line (...);
...
Add your newly created module to the modules list in modules.py. Doing that is pretty straight forward and should not be too complex. A new entry looks like this:
Module ("MODULENAME", [ "SOURCEFILE.c", "SOURCEFILE.c", ... ],
[ "pgCAPIHEADER.h", "pgCAPIHEADER.h", ...], "DOCFILE.xml",
['DEPENDENCY1', 'DEPENDENCY2', ...])
In case you have submodules, you would split anything according to your needs. You can see how submodules are added by looking at the various sdl.XXX modules. Aside from that MODULENAME will be replaced with the name of your module, SOURCEFILE with the source file(s) of your module, including the full path to them. The pgCAPIHEADER.h list is only necessary, if you have C API header files to install. pgCAPIHEADER.h then will be replaced with the name and full path of the header file(s) to install. DOCFILE.xml is the name of the documentation file to use, which is located under doc/src (see below, “Documenting”). Each entry in the DEPENDENCYx list represents an external library reference which must be linked with the module. The names of these libraries can be found/modified in the config.config_modules file.
Example:
Module ("myownlib",[ "src/myownlib/myownlibmod.c", "src/myownlib/myclass.c" ],
[ "src/myownlib/pgmyownlib.h" ], "myownlib.xml", ['SDL'])
If you need to define a new library reference, you may do so in the dependencies dictionary in config.config_modules
'dependency_name' :
dep(['header.h', header2.h, ...], 'library_id', ...),
When defining a new dependency, ‘dependency_name’ is its full name (as referenced when instantiating a new Module object), [ ‘header.h’, ... ] is a representative list of required headers for the library, and ‘library_id’ is the linking id for the library: For example, a library that is linked with ‘-ljpeg’ has ‘jpeg’ as its id.
All the modules which depend on such library will be automatically configured and built using it.
Additionally, you may disable/enable the compilation of such library (and hence of all the modules which rely on it) by adding an entry to the ‘build’ dictionary in the cfg.py module
build['dependency_name'] = False
If you have inter-module dependencies (e.g. parts of pygame.myownlib can make use of pygame.sdl.video), you have to check, whether the specific module is available. In your C code, you can test for certain defines, which ease this process. Each module creates a HAVE_PYGAME_MODULENAME define to test for. To check for e.g. pygame.sdl.video, you can use:
#ifdef HAVE_PYGAME_SDL_VIDEO
/* Code that relies upon pygame.sdl.video */
#endif
Make sure, you load the correct modules within the module initialization function. Take a look at the src/mask/maskmod.c module file for an example.
If it is necessary to rely on certain features specific to a particular environment, you can check for the build system flags, which are automatically added at compile time. Currently, the following flags are available:
IS_WIN32 Win32 build with Visual C++ IS_MSYS (Win32) Msys build with GCC IS_DARWIN MacOS X and Darin-based platforms IS_UNIX Any other build platform that successfully passes the preparations
You can easily check for those flags in the C code using the usualy preprocessor magic:
#ifdef IS_WIN32
/* Visual C++ specific Win32 instructions */
#elif defined(IS_MSYS)
/* GCC/Msys specific Win32 instructions */
#elif defined(IS_UNIX)
/* Unix specific instructions */
#elif defined(IS_DARWIN)
/* Darwin specific instructions */
#endif
Python modules have no special restriction, but should follow the typical python conventions. The files should be named all lowercase and be placed under lib.
As written above (see “C module build system”), the documentation files reside in doc/src/. They are all XML files and must have a “.xml” suffix in order to be recognized by the documentation build system.
Once you have written your module, you can create a documentation template for it using the create_doc.py script. Simply type
python create_doc.py pygame2.myownlib myownlib.xml
to create the documentation file for the myownlib module. This will create a skeleton with all classes, functions, methods and attributes of your module.
If you documented your python code properly, there won’t be any empty sections within the documentation ;-).
C Modules require the documentation to be available at compile time, which involves two steps to set up the initial documentation. The documentation system creates C header files from the XML files automatically at build time to allow their usage from within the C code.
To make use of them, you can include the “DOCFILE_doc.h” header, which will be generated as soon as a proper “DOCFILE.xml” file is found by the build system. In case you create a new module from scratch, we recommend you to copy the api_template.xml file to your DOCFILE.xml and create the XML documentation as you develop the C code. See below for the C constants to use.
If you have an already written module, integrate it first (as described above), then run the create_doc.py script on it:
python create_doc.py pygame2.myownlib myownlib.xml
This will create a XML documentation file including the documentation you already wrote for the module. A second step now will require you to remove the documentation from the code and use the API constants which will be generated by the documentation system. Include the “DOCFILE_doc.h” header file, then use the proper constants for all things to document.
The C constants are generated using the DOC_MODULENAME_CLASSNAME_NAME scheme. The following constants are used:
DOC_MODULENAME The documentation for the module. DOC_MODULENAME_FUNCNAME The documentation for a module function. DOC_MODULENAME_CLASSNAME The documentation for a class. DOC_MODULENAME_CLASSNAME_X The documentation for a class method or attribute.
Take a look at the src/base code to learn more about it.