Commit: 0ba92bcf683a57c428590b44c2fcebe22f30be3d
Author: Julian Eisel
Date:   Tue Jul 12 15:43:12 2016 +0200
Branches: soc-2016-layer_manager
https://developer.blender.org/rB0ba92bcf683a57c428590b44c2fcebe22f30be3d

Add/use layer type idname for reliable lookups on file read

The previously used enum wouldn't be safe to use with custom layers from python.

===================================================================

M       source/blender/blenkernel/BKE_layer.h
M       source/blender/blenkernel/intern/layer.c
M       source/blender/blenloader/intern/readfile.c
M       source/blender/editors/scene/layer_types.c
M       source/blender/makesdna/DNA_scene_types.h

===================================================================

diff --git a/source/blender/blenkernel/BKE_layer.h 
b/source/blender/blenkernel/BKE_layer.h
index c6a9544..1a5f137 100644
--- a/source/blender/blenkernel/BKE_layer.h
+++ b/source/blender/blenkernel/BKE_layer.h
@@ -79,6 +79,9 @@ typedef enum eLayerTreeItem_Type {
 } eLayerTreeItem_Type;
 
 typedef struct LayerType {
+       /* idname is needed to support reading custom (.py defined) layers. 
During normal runtime
+        * using type below should be preferred though, avoids slow string 
comparisons */
+       const char *idname;
        eLayerTreeItem_Type type;
 
        /* drawing of the item in the list */
@@ -95,7 +98,7 @@ typedef struct LayerType {
 
 void BKE_layertype_append(void (*ltfunc)(LayerType *));
 void BKE_layertypes_free(void);
-LayerType *BKE_layertype_get(const eLayerTree_Type type_id);
+LayerType *BKE_layertype_find(const char *idname);
 
 /* -------------------------------------------------------------------- */
 /* Layer Tree Item */
diff --git a/source/blender/blenkernel/intern/layer.c 
b/source/blender/blenkernel/intern/layer.c
index 7f08e4f..97164fb 100644
--- a/source/blender/blenkernel/intern/layer.c
+++ b/source/blender/blenkernel/intern/layer.c
@@ -41,6 +41,7 @@
 
 #include "BLI_alloca.h"
 #include "BLI_listbase.h"
+#include "BLI_ghash.h"
 #include "BLI_string.h"
 
 #include "MEM_guardedalloc.h"
@@ -132,10 +133,14 @@ int BKE_layertree_get_totitems(const LayerTree *ltree)
  * \{ */
 
 /**
+ * String hash table for quick LayerType.idname lookups.
+ */
+static GHash *layertypes_hash = NULL;
+/**
  * Array of all registered layer types. The index of a layer type matches items
  * in eLayerTreeItem_Type. Length should always match #LAYER_ITEMTYPE_TOT.
 */
-static LayerType *layertypes[LAYER_ITEMTYPE_TOT] = {NULL};
+static LayerType *layertypes_vec[LAYER_ITEMTYPE_TOT] = {NULL};
 
 
 void BKE_layertype_append(void (*ltfunc)(LayerType *))
@@ -144,24 +149,25 @@ void BKE_layertype_append(void (*ltfunc)(LayerType *))
        lt->srna = RNA_def_struct_ptr(&BLENDER_RNA, "", &RNA_LayerProperties);
        ltfunc(lt);
 
+       /* insert into array */
        BLI_assert(lt->type >= 0 && lt->type < LAYER_ITEMTYPE_TOT);
-       layertypes[lt->type] = lt;
+       layertypes_vec[lt->type] = lt;
+       /* insert into hash */
+       if (UNLIKELY(!layertypes_hash)) {
+               /* reserve size is set based on blender default setup */
+               layertypes_hash = BLI_ghash_str_new_ex("wm_operatortype_init 
gh", 2);
+       }
+       BLI_ghash_insert(layertypes_hash, (void *)lt->idname, lt);
 }
 
 void BKE_layertypes_free(void)
 {
-       for (int i = 0; i < ARRAY_SIZE(layertypes); i++) {
-               if (layertypes[i]) {
-                       MEM_freeN(layertypes[i]);
-               }
-       }
+       BLI_ghash_free(layertypes_hash, NULL, MEM_freeN);
 }
 
-/* TODO if we want to support custom (in .py defined) layer types, using 
eLayerTree_Type
- * will not be reliable. Could use string instead, just like operators */
-LayerType *BKE_layertype_get(const eLayerTree_Type type_id)
+LayerType *BKE_layertype_find(const char *idname)
 {
-       return layertypes[type_id];
+       return BLI_ghash_lookup(layertypes_hash, idname);
 }
 
 /** \} */ /* Layer Type */
@@ -184,7 +190,8 @@ void BKE_layeritem_register(
         LayerTree *tree, LayerTreeItem *litem, LayerTreeItem *parent,
         const eLayerTreeItem_Type type, const char *name)
 {
-       litem->type = layertypes[type];
+       litem->type = layertypes_vec[type];
+       BLI_strncpy(litem->idname, litem->type->idname, MAX_NAME);
 
        /* initialize properties */
        IDPropertyTemplate val = {0};
diff --git a/source/blender/blenloader/intern/readfile.c 
b/source/blender/blenloader/intern/readfile.c
index 8361602..d2f57fa 100644
--- a/source/blender/blenloader/intern/readfile.c
+++ b/source/blender/blenloader/intern/readfile.c
@@ -5849,7 +5849,7 @@ static void direct_link_layeritems(FileData *fd, ListBase 
*layeritems, LayerTree
 
                litem->tree = ltree;
                litem->parent = newdataadr(fd, litem->parent);
-               litem->type = BKE_layertype_get(litem->type_id);
+               litem->type = BKE_layertype_find(litem->idname);
 
                /* custom property stuff */
                litem->prop = newdataadr(fd, litem->prop);
diff --git a/source/blender/editors/scene/layer_types.c 
b/source/blender/editors/scene/layer_types.c
index 1cdb8a2..ae50410 100644
--- a/source/blender/editors/scene/layer_types.c
+++ b/source/blender/editors/scene/layer_types.c
@@ -74,6 +74,7 @@ static void object_layer_draw_settings(const bContext 
*UNUSED(C), LayerTreeItem
 
 static void LAYERTYPE_object(LayerType *lt)
 {
+       lt->idname = __func__;
        /* XXX Should re-evaluate how eLayerTreeItem_Type is used */
        lt->type = LAYER_ITEMTYPE_LAYER;
 
@@ -106,6 +107,7 @@ static void layer_group_draw(const bContext *C, 
LayerTreeItem *litem, uiLayout *
 
 static void LAYERTYPE_group(LayerType *lt)
 {
+       lt->idname = __func__;
        lt->type = LAYER_ITEMTYPE_GROUP;
 
        lt->draw = layer_group_draw;
diff --git a/source/blender/makesdna/DNA_scene_types.h 
b/source/blender/makesdna/DNA_scene_types.h
index 9c0f534..0e708a8 100644
--- a/source/blender/makesdna/DNA_scene_types.h
+++ b/source/blender/makesdna/DNA_scene_types.h
@@ -108,9 +108,9 @@ typedef struct LayerTreeItem {
        struct LayerTreeItem *next, *prev;
 
        struct LayerType *type;
-       int type_id;    /* eLayerTreeItem_Type item to get LayerType pointer - 
needed for file read */
+       char idname[64]; /* LayerType.idname, for finding type on file read */
 
-       int index;      /* index of the item - stored to avoid loockups */
+       int pad, index; /* index of the item - stored to avoid loockups */
        char name[64];  /* MAX_NAME */
 
        LayerTree *tree; /* pointer back to layer tree - TODO check if needed */

_______________________________________________
Bf-blender-cvs mailing list
[email protected]
https://lists.blender.org/mailman/listinfo/bf-blender-cvs

Reply via email to