summaryrefslogtreecommitdiffstats
path: root/libdimension-python
diff options
context:
space:
mode:
Diffstat (limited to 'libdimension-python')
-rw-r--r--libdimension-python/Makefile.am4
-rw-r--r--libdimension-python/dimension.pxd15
-rw-r--r--libdimension-python/dimension.pyx58
-rw-r--r--libdimension-python/platform.c41
-rw-r--r--libdimension-python/platform.h29
5 files changed, 140 insertions, 7 deletions
diff --git a/libdimension-python/Makefile.am b/libdimension-python/Makefile.am
index c1f5274..90d7d45 100644
--- a/libdimension-python/Makefile.am
+++ b/libdimension-python/Makefile.am
@@ -29,7 +29,9 @@ dimension.c: dimension.pyx dimension.pxd
cython --line-directives dimension.pyx
pyexec_LTLIBRARIES = dimension.la
-dimension_la_SOURCES = dimension.c
+dimension_la_SOURCES = dimension.c \
+ platform.c \
+ platform.h
dimension_la_LDFLAGS = -avoid-version -module
dimension_la_LIBADD = $(top_builddir)/libdimension/libdimension.la
diff --git a/libdimension-python/dimension.pxd b/libdimension-python/dimension.pxd
index b73b99c..6ac6319 100644
--- a/libdimension-python/dimension.pxd
+++ b/libdimension-python/dimension.pxd
@@ -64,6 +64,16 @@ cdef extern from "../libdimension/dimension.h":
void dmnsn_array_remove(dmnsn_array *array, size_t i)
void dmnsn_array_apply(dmnsn_array *array, dmnsn_callback_fn *callback)
+ ############
+ # Progress #
+ ############
+
+ ctypedef struct dmnsn_progress
+
+ int dmnsn_finish_progress(dmnsn_progress *progress)
+ double dmnsn_get_progress(dmnsn_progress *progress)
+ void dmnsn_wait_progress(dmnsn_progress *progress, double prog)
+
##########
# Timers #
##########
@@ -178,6 +188,7 @@ cdef extern from "../libdimension/dimension.h":
int dmnsn_png_optimize_canvas(dmnsn_canvas *canvas)
int dmnsn_png_write_canvas(dmnsn_canvas *canvas, FILE *file)
+ dmnsn_progress *dmnsn_png_write_canvas_async(dmnsn_canvas *canvas, FILE *file)
int dmnsn_gl_optimize_canvas(dmnsn_canvas *canvas)
int dmnsn_gl_write_canvas(dmnsn_canvas *canvas)
@@ -377,3 +388,7 @@ cdef extern from "../libdimension/dimension.h":
void dmnsn_delete_scene(dmnsn_scene *scene)
void dmnsn_raytrace_scene(dmnsn_scene *scene)
+ dmnsn_progress *dmnsn_raytrace_scene_async(dmnsn_scene *scene)
+
+cdef extern from "platform.h":
+ unsigned int dmnsn_terminal_width()
diff --git a/libdimension-python/dimension.pyx b/libdimension-python/dimension.pyx
index d5fbd1f..e1aba28 100644
--- a/libdimension-python/dimension.pyx
+++ b/libdimension-python/dimension.pyx
@@ -28,11 +28,53 @@ import os
# Globals #
###########
-# Make warnings fatal
def die_on_warnings(always_die):
"""Whether to treat Dimension warnings as errors."""
dmnsn_die_on_warnings(always_die)
+def terminal_width():
+ """Return the width of the terminal, if present."""
+ return dmnsn_terminal_width()
+
+############
+# Progress #
+############
+
+cdef class Progress:
+ cdef dmnsn_progress *_progress
+
+ def __cinit__(self):
+ self._progress = NULL
+
+ def __init__(self):
+ raise RuntimeError("attempt to create a Progress object.")
+
+ def __dealloc__(self):
+ self.finish()
+
+ def finish(self):
+ if self._progress != NULL:
+ try:
+ if dmnsn_finish_progress(self._progress) != 0:
+ raise RuntimeError("background task failed.")
+ finally:
+ self._progress = NULL
+
+ def progress(self):
+ if self._progress == NULL:
+ raise RuntimeError("background task finished.")
+ return dmnsn_get_progress(self._progress)
+
+ def wait(self, progress):
+ if self._progress == NULL:
+ raise RuntimeError("background task finished.")
+ dmnsn_wait_progress(self._progress, progress)
+
+cdef _Progress(dmnsn_progress *progress):
+ cdef Progress self = Progress.__new__(Progress)
+ self._progress = progress
+ return self
+
##########
# Timers #
##########
@@ -107,7 +149,7 @@ cdef class Vector:
elif args[0] == 0:
self._v = dmnsn_zero
else:
- raise TypeError, "expected a sequence or 0"
+ raise TypeError("expected a sequence or 0")
else:
self._real_init(*args, **kwargs)
@@ -471,14 +513,16 @@ cdef class Canvas:
def write_PNG(self, path):
"""Export the canvas as a PNG file."""
+ self.write_PNG_async(path).finish()
+ def write_PNG_async(self, path):
+ """Export the canvas as a PNG file, in the background."""
bpath = path.encode("UTF-8")
cdef char *cpath = bpath
cdef FILE *file = fopen(cpath, "wb")
if file == NULL:
raise OSError(errno, os.strerror(errno))
- if dmnsn_png_write_canvas(self._canvas, file) != 0:
- raise OSError(errno, os.strerror(errno))
+ return _Progress(dmnsn_png_write_canvas_async(self._canvas, file))
def draw_GL(self):
"""Export the canvas to the current OpenGL context."""
@@ -1317,11 +1361,13 @@ cdef class Scene:
def raytrace(self):
"""Render the scene."""
+ self.raytrace_async().finish()
+ def raytrace_async(self):
+ """Render the scene, in the background."""
# Ensure the default texture is complete
cdef Texture default = Texture(Black)
dmnsn_texture_cascade(default._texture, &self._scene.default_texture)
-
- dmnsn_raytrace_scene(self._scene)
+ return _Progress(dmnsn_raytrace_scene_async(self._scene))
def __dealloc__(self):
dmnsn_delete_scene(self._scene)
diff --git a/libdimension-python/platform.c b/libdimension-python/platform.c
new file mode 100644
index 0000000..30dde93
--- /dev/null
+++ b/libdimension-python/platform.c
@@ -0,0 +1,41 @@
+/*************************************************************************
+ * Copyright (C) 2011 Tavian Barnes <tavianator@tavianator.com> *
+ * *
+ * This file is part of The Dimension Python Module. *
+ * *
+ * The Dimension Python Module is free software; you can redistribute it *
+ * and/or modify it under the terms of the GNU General Public License as *
+ * published by the Free Software Foundation; either version 3 of the *
+ * License, or (at your option) any later version. *
+ * *
+ * The Dimension Python Module is distributed in the hope that it will *
+ * be useful, but WITHOUT ANY WARRANTY; without even the implied *
+ * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See *
+ * the GNU General Public License for more details. *
+ * *
+ * You should have received a copy of the GNU General Public License *
+ * along with this program. If not, see <http://www.gnu.org/licenses/>. *
+ *************************************************************************/
+
+#include "platform.h"
+#if HAVE_UNISTD_H
+ #include <unistd.h>
+#endif
+#if DMNSN_TIOCGWINSZ
+ #include <sys/ioctl.h>
+#endif
+
+unsigned int
+dmnsn_terminal_width(void)
+{
+ unsigned int width = 80;
+
+#if DMNSN_TIOCGWINSZ
+ struct winsize ws;
+ if (ioctl(STDOUT_FILENO, TIOCGWINSZ, &ws) == 0) {
+ width = ws.ws_col;
+ }
+#endif
+
+ return width;
+}
diff --git a/libdimension-python/platform.h b/libdimension-python/platform.h
new file mode 100644
index 0000000..892217a
--- /dev/null
+++ b/libdimension-python/platform.h
@@ -0,0 +1,29 @@
+/*************************************************************************
+ * Copyright (C) 2011 Tavian Barnes <tavianator@tavianator.com> *
+ * *
+ * This file is part of The Dimension Python Module. *
+ * *
+ * The Dimension Python Module is free software; you can redistribute it *
+ * and/or modify it under the terms of the GNU General Public License as *
+ * published by the Free Software Foundation; either version 3 of the *
+ * License, or (at your option) any later version. *
+ * *
+ * The Dimension Python Module is distributed in the hope that it will *
+ * be useful, but WITHOUT ANY WARRANTY; without even the implied *
+ * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See *
+ * the GNU General Public License for more details. *
+ * *
+ * You should have received a copy of the GNU General Public License *
+ * along with this program. If not, see <http://www.gnu.org/licenses/>. *
+ *************************************************************************/
+
+#ifndef PLATFORM_H
+#define PLATFORM_H
+
+/**
+ * Get the width of the terminal.
+ * @return The width (in characters) of the terminal, defaulting to 80.
+ */
+unsigned int dmnsn_terminal_width(void);
+
+#endif /* PLATFORM_H */