[Bf-blender-cvs] SVN commit: /data/svn/bf-blender [52780] trunk/blender: pydna experimental ctypes DNA api was broken with more recent python versions , and some minor doc edits.

Campbell Barton ideasman42 at gmail.com
Wed Dec 5 04:38:04 CET 2012


Revision: 52780
          http://projects.blender.org/scm/viewvc.php?view=rev&root=bf-blender&revision=52780
Author:   campbellbarton
Date:     2012-12-05 03:38:01 +0000 (Wed, 05 Dec 2012)
Log Message:
-----------
pydna experimental ctypes DNA api was broken with more recent python versions, and some minor doc edits.

Modified Paths:
--------------
    trunk/blender/doc/python_api/rst/info_gotcha.rst
    trunk/blender/intern/tools/pydna.py

Modified: trunk/blender/doc/python_api/rst/info_gotcha.rst
===================================================================
--- trunk/blender/doc/python_api/rst/info_gotcha.rst	2012-12-05 01:02:41 UTC (rev 52779)
+++ trunk/blender/doc/python_api/rst/info_gotcha.rst	2012-12-05 03:38:01 UTC (rev 52780)
@@ -494,7 +494,7 @@
        t.join()
 
 
-This an example of a timer which runs many times a second and moves the default cube continuously while Blender runs (Unsupported).
+This an example of a timer which runs many times a second and moves the default cube continuously while Blender runs **(Unsupported)**.
 
 .. code-block:: python
 
@@ -517,7 +517,7 @@
 
 .. note::
 
-   Pythons threads only allow co-currency and won't speed up your scripts on multi-processor systems, the ``subprocess`` and ``multiprocess`` modules can be used with blender and make use of multiple CPU's too.
+   Pythons threads only allow co-currency and won't speed up your scripts on multi-processor systems, the ``subprocess`` and ``multiprocess`` modules can be used with Blender and make use of multiple CPU's too.
 
 
 Help! My script crashes Blender
@@ -540,7 +540,7 @@
 .. note::
 
    To find the line of your script that crashes you can use the ``faulthandler`` module.
-   See `faulthandler docs<http://docs.python.org/dev/library/faulthandler.html>`_.
+   See `faulthandler docs <http://docs.python.org/dev/library/faulthandler.html>`_.
 
    While the crash may be in Blenders C/C++ code, this can help a lot to track down the area of the script that causes the crash.
 
@@ -548,7 +548,7 @@
 Undo/Redo
 ---------
 
-Undo invalidates all :class:`bpy.types.ID` instances (Object, Scene, Mesh etc).
+Undo invalidates all :class:`bpy.types.ID` instances (Object, Scene, Mesh, Lamp... etc).
 
 This example shows how you can tell undo changes the memory locations.
 
@@ -666,9 +666,9 @@
 sys.exit
 ========
 
-Some python modules will call sys.exit() themselves when an error occurs, while not common behavior this is something to watch out for because it may seem as if blender is crashing since sys.exit() will quit blender immediately.
+Some python modules will call ``sys.exit()`` themselves when an error occurs, while not common behavior this is something to watch out for because it may seem as if blender is crashing since ``sys.exit()`` will quit blender immediately.
 
 For example, the ``optparse`` module will print an error and exit if the arguments are invalid.
 
-An ugly way of troubleshooting this is to set ``sys.exit = None`` and see what line of python code is quitting, you could of course replace ``sys.exit``/ with your own function but manipulating python in this way is bad practice.
+An ugly way of troubleshooting this is to set ``sys.exit = None`` and see what line of python code is quitting, you could of course replace ``sys.exit`` with your own function but manipulating python in this way is bad practice.
 

Modified: trunk/blender/intern/tools/pydna.py
===================================================================
--- trunk/blender/intern/tools/pydna.py	2012-12-05 01:02:41 UTC (rev 52779)
+++ trunk/blender/intern/tools/pydna.py	2012-12-05 03:38:01 UTC (rev 52780)
@@ -139,80 +139,103 @@
 
         return blend_sdna_names, blend_sdna_types, blend_sdna_typelens, blend_sdna_structs
 
-    def create_dna_structs(blend_sdna_names, blend_sdna_types, blend_sdna_typelens, blend_sdna_structs):
+    def _create_dna_structs__recursive(ctypes_basic, ctypes_structs, blend_sdna_structs_dict, struct_name, stack):
+        ctype_struct = ctypes_structs[struct_name]
+        if hasattr(ctype_struct, "_fields_"):
+            return
 
-        # create all subclasses of ctypes.Structure
-        ctypes_structs = {name: type(name.decode(), (ctypes.Structure, MixIn), {}) for name in blend_sdna_types}
-        ctypes_basic = {b"float": ctypes.c_float, b"double": ctypes.c_double, b"int": ctypes.c_int, b"short": ctypes.c_short, b"char": ctypes.c_char, b"void": ctypes.c_void_p}
-        ctypes_fields = {}
+        stack.append(struct_name)
+        
+        struct_type_name_pairs = blend_sdna_structs_dict[struct_name]
+        fields = []
+        fields_orig = []
 
-        # collect fields
-        for struct_id, struct_type_name_pairs in blend_sdna_structs:
-            struct_name = blend_sdna_types[struct_id]
-            ctype_struct = ctypes_structs[struct_name]
-            fields = []
+        for stype, sname in struct_type_name_pairs:
+            name_string = blend_sdna_names[sname]
+            type_string = blend_sdna_types[stype]
+            type_py = ctypes_basic.get(type_string)
+            type_py_orig = None
+            if type_py is None:
+                type_py = type_py_orig = ctypes_structs.get(type_string)
 
-            for stype, sname in struct_type_name_pairs:
-                name_string = blend_sdna_names[sname]
-                type_string = blend_sdna_types[stype]
-                type_py = ctypes_basic.get(type_string)
-                if type_py is None:
-                    type_py = ctypes_structs.get(type_string)
+            # todo, these might need to be changed
+            name_string = name_string.replace(b"(", b"")
+            name_string = name_string.replace(b")", b"")
 
-                # todo, these might need to be changed
-                name_string = name_string.replace(b"(", b"")
-                name_string = name_string.replace(b")", b"")
+            # * First parse the pointer *
+            pointer_count = 0
+            while name_string[0] == 42:  # '*'
+                pointer_count += 1
+                name_string = name_string[1:]
 
-                # * First parse the pointer *
+            # alredy a pointer
+            if type_py is ctypes.c_void_p:
+                pointer_count -= 1
+            elif type_py is ctypes.c_char and pointer_count == 1:
+                type_py = ctypes.c_char_p
                 pointer_count = 0
-                while name_string[0] == 42:  # '*'
-                    pointer_count += 1
-                    name_string = name_string[1:]
 
-                # alredy a pointer
-                if type_py is ctypes.c_void_p:
-                    pointer_count -= 1
-                elif type_py is ctypes.c_char and pointer_count == 1:
-                    type_py = ctypes.c_char_p
-                    pointer_count = 0
+            if pointer_count < 0:
+                Exception("error parsing pointer")
 
-                if pointer_count < 0:
-                    Exception("error parsing pointer")
+            for i in range(pointer_count):
+                type_py = ctypes.POINTER(type_py)
 
-                for i in range(pointer_count):
-                    type_py = ctypes.POINTER(type_py)
+            # ---
+            # Ensure we have the members initialized!
+            if type_py is type_py_orig:
+                if type_py_orig.orig_name not in stack:
+                    _create_dna_structs__recursive(ctypes_basic, ctypes_structs, blend_sdna_structs_dict, type_py_orig.orig_name, stack)
+            # ---
 
-                # * Now parse the array [] *
-                if b'[' in name_string:
-                    name_string = name_string.replace(b'[', b' ')
-                    name_string = name_string.replace(b']', b' ')
-                    name_split = name_string.split()
-                    name_string = name_split[0]
-                    for array_dim in reversed(name_split[1:]):
-                        type_py = type_py * int(array_dim)
+            # * Now parse the array [] *
+            if b'[' in name_string:
+                name_string = name_string.replace(b'[', b' ')
+                name_string = name_string.replace(b']', b' ')
+                name_split = name_string.split()
+                name_string = name_split[0]
+                for array_dim in reversed(name_split[1:]):
+                    type_py = type_py * int(array_dim)
 
-                fields.append((name_string.decode(), type_py))
+            fields.append((name_string.decode(), type_py))
+        stack.pop()
 
-            ctypes_fields[struct_name] = fields
+        ctype_struct._fields_ = fields
+        del fields
 
+    def create_dna_structs(blend_sdna_names, blend_sdna_types, blend_sdna_typelens, blend_sdna_structs):
+
+        # create all subclasses of ctypes.Structure
+        ctypes_structs = {name: type(name.decode(), (ctypes.Structure, MixIn), {"orig_name": name}) for name in blend_sdna_types}
+        ctypes_basic = {
+            b"float": ctypes.c_float,
+            b"double": ctypes.c_double,
+            b"int": ctypes.c_int,
+            b"uint64_t": ctypes.c_uint64,
+            b"short": ctypes.c_short,
+            b"char": ctypes.c_char,
+            b"void": ctypes.c_void_p,
+        }
+        ctypes_fields = {}
+
         # apply fields all in one go!
+        blend_sdna_structs_dict = {
+            blend_sdna_types[struct_id]: struct_type_name_pairs
+            for struct_id, struct_type_name_pairs in blend_sdna_structs}
+
         for struct_id, struct_type_name_pairs in blend_sdna_structs:
             struct_name = blend_sdna_types[struct_id]
-            ctype_struct = ctypes_structs[struct_name]
-            try:
-                ctype_struct._fields_ = ctypes_fields[struct_name]
-            except:
-                print("Error:", struct_name)
-                import traceback
-                traceback.print_exc()
-                # print(fields)
+            _create_dna_structs__recursive(ctypes_basic, ctypes_structs, blend_sdna_structs_dict, struct_name, [struct_name])
 
+
         # test fields
+        error = 0
         for struct_id, struct_type_name_pairs in blend_sdna_structs:
             ctype_struct = ctypes_structs[blend_sdna_types[struct_id]]
             if blend_sdna_typelens[struct_id] != ctypes.sizeof(ctype_struct):
                 print("Size Mismatch for %r blender:%d vs python:%d" % (blend_sdna_types[struct_id], blend_sdna_typelens[struct_id], ctypes.sizeof(ctype_struct)))
-
+                error += 1
+        print("Size Mismatch errors (total): %d!" % error)
         return ctypes_structs
 
     def decorate_api(struct_dict):




More information about the Bf-blender-cvs mailing list