0

setup.py now auto-discovers available render primitives

This commit is contained in:
Aaron Griffith
2012-01-08 00:52:30 -05:00
parent a682b8a689
commit 7cacc59428
4 changed files with 70 additions and 58 deletions

3
.gitignore vendored
View File

@@ -22,8 +22,9 @@ overviewer_core/c_overviewer.pyd
overviewer_core/c_overviewer_d.pyd
overviewer_core/c_overviewer.dylib
# generated version file
# generated files
overviewer_core/overviewer_version.py
overviewer_core/src/primitives.h
# Mac OS X noise
.DS_Store

View File

@@ -19,29 +19,13 @@
#include <string.h>
#include <stdarg.h>
extern RenderPrimitiveInterface primitive_base;
extern RenderPrimitiveInterface primitive_nether;
extern RenderPrimitiveInterface primitive_height_fading;
extern RenderPrimitiveInterface primitive_depth;
extern RenderPrimitiveInterface primitive_edge_lines;
/* list of all render primitives, ending in NULL
/* this file defines render_primitives,
a list of all render primitives, ending in NULL
all of these will be available to the user, so DON'T include primitives
that are only useful as a base for other primitives. */
static RenderPrimitiveInterface *render_primitives[] = {
&primitive_base,
&primitive_nether,
&primitive_height_fading,
&primitive_depth,
&primitive_edge_lines,
//&rendermode_lighting,
//&rendermode_smooth_lighting,
//&rendermode_cave,
that are only useful as a base for other primitives.
//&rendermode_spawn,
//&rendermode_mineral,
NULL
};
this file is auto-generated by setup.py */
#include "primitives.h"
/* rendermode encapsulation */

View File

@@ -15,15 +15,27 @@
* with the Overviewer. If not, see <http://www.gnu.org/licenses/>.
*/
/*
* To make a new render primitive (the C part, at least):
/* To make a new render primitive:
*
* * add a data struct and extern'd interface declaration below
* * add a new class to rendermodes.py
* there are a ton of examples there, the syntax is pretty simple. If
* you need any extra objects that are easy to create in python, this
* is where you put them.
*
* * fill in this interface struct in primitives/(yourmode).c
* (see primitives/base.c for an example: the "base" primitive)
* * create a file in src/primitives with the same name
* so, Nether (named "nether") goes in `nether.c`.
*
* * add your primitive to the list in rendermodes.c
* * declare a RenderPrimitiveInterface with the name primitive_name
* if you have an underscore in the name, replace it with a
* hyphen. height-fading uses primitive_height_fading.
*
* * fill in the entries of this struct
* the name should match, and you should declare an 'instance' struct
* to use as the self argument to each function. See nether.c and
* height-fading.c for simple examples.
*
* setup.py will pick up your primitive, add it to the global list, and build
* it for you if you follow these conventions.
*/
#ifndef __RENDERMODES_H_INCLUDED__

View File

@@ -15,6 +15,7 @@ import glob
import platform
import time
import overviewer_core.util as util
import numpy
try:
import py2exe
@@ -133,7 +134,6 @@ if py2exe is None:
#
# Third-party modules - we depend on numpy for everything
import numpy
# Obtain the numpy include directory. This logic works across numpy versions.
try:
numpy_include = numpy.get_include()
@@ -149,9 +149,13 @@ except Exception:
# used to figure out what files to compile
#render_modes = ['normal', 'lighting', 'smooth-lighting', 'cave']
#render_modes += ['overlay', 'spawn', 'mineral']
primitives = ['base', 'nether', 'height-fading', 'depth', 'edge-lines']
# auto-created from files in primitives/, but we need the raw names so
# we can use them later.
primitives = []
for name in glob.glob("overviewer_core/src/primitives/*.c"):
name = os.path.split(name)[-1]
name = os.path.splitext(name)[0]
primitives.append(name)
c_overviewer_files = ['main.c', 'composite.c', 'iterate.c', 'endian.c', 'rendermodes.c']
c_overviewer_files += map(lambda mode: 'primitives/%s.c' % (mode,), primitives)
@@ -169,7 +173,7 @@ setup_kwargs['ext_modules'].append(Extension('overviewer_core.c_overviewer', c_o
setup_kwargs['options']['build_ext'] = {'inplace' : 1}
# custom clean command to remove in-place extension
# and the version file
# and the version file, primitives header
class CustomClean(clean):
def run(self):
# do the normal cleanup
@@ -178,30 +182,23 @@ class CustomClean(clean):
# try to remove '_composite.{so,pyd,...}' extension,
# regardless of the current system's extension name convention
build_ext = self.get_finalized_command('build_ext')
pretty_fname = build_ext.get_ext_filename('overviewer_core.c_overviewer')
fname = pretty_fname
ext_fname = build_ext.get_ext_filename('overviewer_core.c_overviewer')
versionpath = os.path.join("overviewer_core", "overviewer_version.py")
primspath = os.path.join("overviewer_core", "src", "primitives.h")
for fname in [ext_fname, versionpath, primspath]:
if os.path.exists(fname):
try:
log.info("removing '%s'", fname)
if not self.dry_run:
os.remove(fname)
log.info("removing '%s'", pretty_fname)
except OSError:
log.warn("'%s' could not be cleaned -- permission denied",
pretty_fname)
fname)
else:
log.debug("'%s' does not exist -- can't clean it",
pretty_fname)
versionpath = os.path.join("overviewer_core", "overviewer_version.py")
if os.path.exists(versionpath):
try:
if not self.dry_run:
os.remove(versionpath)
log.info("removing '%s'", versionpath)
except OSError:
log.warn("'%s' could not be cleaned -- permission denied", versionpath)
else:
log.debug("'%s' does not exist -- can't clean it", versionpath)
fname)
# now try to purge all *.pyc files
for root, dirs, files in os.walk(os.path.join(os.path.dirname(__file__), ".")):
@@ -226,16 +223,34 @@ def generate_version_py():
except Exception:
print "WARNING: failed to build overviewer_version file"
def generate_primitives_h():
global primitives
prims = [p.lower().replace('-', '_') for p in primitives]
outstr = "/* this file is auto-generated by setup.py */\n"
for p in prims:
outstr += "extern RenderPrimitiveInterface primitive_{0};\n".format(p)
outstr += "static RenderPrimitiveInterface *render_primitives[] = {\n"
for p in prims:
outstr += " &primitive_{0},\n".format(p)
outstr += " NULL\n"
outstr += "};\n"
with open("overviewer_core/src/primitives.h", "w") as f:
f.write(outstr)
class CustomSDist(sdist):
def run(self):
# generate the version file
generate_version_py()
generate_primitives_h()
sdist.run(self)
class CustomBuild(build):
def run(self):
# generate the version file
generate_version_py()
generate_primitives_h()
build.run(self)
print "\nBuild Complete"