Commit: 861e553f1db6ee28d909143265528acf8ce5bf52
Author: Lukas Tönne
Date:   Sat Feb 21 12:28:51 2015 +0100
Branches: alembic_pointcache
https://developer.blender.org/rB861e553f1db6ee28d909143265528acf8ce5bf52

BKE functions for managing cache content based on a group.

This uses a complete hierarchy of group instances, based on a path
hierarchy (object names).

Putting

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

M       source/blender/blenkernel/BKE_cache_library.h
M       source/blender/blenkernel/intern/cache_library.c
M       source/blender/makesdna/DNA_cache_library_types.h

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

diff --git a/source/blender/blenkernel/BKE_cache_library.h 
b/source/blender/blenkernel/BKE_cache_library.h
index 92a1f9d..53dd131 100644
--- a/source/blender/blenkernel/BKE_cache_library.h
+++ b/source/blender/blenkernel/BKE_cache_library.h
@@ -32,11 +32,28 @@
  *  \ingroup bke
  */
 
-struct CacheLibrary;
 struct Main;
+struct CacheLibrary;
+struct CacheItem;
+struct CacheItemPath;
 
 struct CacheLibrary *BKE_cache_library_add(struct Main *bmain, const char 
*name);
 struct CacheLibrary *BKE_cache_library_copy(struct CacheLibrary *cachelib);
-void BKE_cache_library_free(struct CacheLibrary *cache);
+void BKE_cache_library_free(struct CacheLibrary *cachelib);
+
+bool BKE_cache_item_path_cmp(const struct CacheItemPath *a, const struct 
CacheItemPath *b);
+int BKE_cache_item_path_len(const struct CacheItemPath *path);
+bool BKE_cache_item_path_append(struct CacheItemPath *path, const char *name);
+void BKE_cache_item_path_replace(struct CacheItemPath *path, const char *name, 
int index);
+void BKE_cache_item_path_clear(struct CacheItemPath *path);
+void BKE_cache_item_path_truncate(struct CacheItemPath *path, int len);
+void BKE_cache_item_path_copy(struct CacheItemPath *dst, const struct 
CacheItemPath *src);
+
+typedef void (*CacheGroupWalkFunc)(void *userdata, struct CacheLibrary 
*cachelib, const struct CacheItemPath *path);
+void BKE_cache_library_walk(struct CacheLibrary *cachelib, CacheGroupWalkFunc 
walk, void *userdata);
+
+struct CacheItem *BKE_cache_library_find_item(struct CacheLibrary *cachelib, 
const struct CacheItemPath *path);
+struct CacheItem *BKE_cache_library_add_item(struct CacheLibrary *cachelib, 
const struct CacheItemPath *path);
+bool BKE_cache_library_remove_item(struct CacheLibrary *cachelib, const struct 
CacheItemPath *path);
 
 #endif
diff --git a/source/blender/blenkernel/intern/cache_library.c 
b/source/blender/blenkernel/intern/cache_library.c
index cbfed7c..0ab19ba 100644
--- a/source/blender/blenkernel/intern/cache_library.c
+++ b/source/blender/blenkernel/intern/cache_library.c
@@ -27,18 +27,83 @@
  *  \ingroup bke
  */
 
+#include <string.h>
+
 #include "MEM_guardedalloc.h"
 
 #include "BLI_blenlib.h"
+#include "BLI_ghash.h"
+#include "BLI_string.h"
 #include "BLI_utildefines.h"
 
 #include "DNA_cache_library_types.h"
+#include "DNA_group_types.h"
+#include "DNA_object_types.h"
 
 #include "BKE_cache_library.h"
 #include "BKE_global.h"
 #include "BKE_library.h"
 #include "BKE_main.h"
 
+bool BKE_cache_item_path_cmp(const CacheItemPath *a, const CacheItemPath *b)
+{
+       int i, cmp;
+       for (i = 0; i < MAX_CACHE_GROUP_LEVEL; ++i) {
+               if (a->value[i][0] == '\0' && b->value[i][0] == '\0')
+                       break;
+               cmp = strcmp(a->value[i], b->value[i]);
+               if (cmp != 0)
+                       return cmp;
+       }
+       return 0;
+}
+
+int BKE_cache_item_path_len(const CacheItemPath *path)
+{
+       int i;
+       for (i = 0; i < MAX_CACHE_GROUP_LEVEL; ++i) {
+               if (path->value[i][0] == '\0')
+                       break;
+       }
+       return i;
+}
+
+bool BKE_cache_item_path_append(CacheItemPath *path, const char *name)
+{
+       int i;
+       for (i = 0; i < MAX_CACHE_GROUP_LEVEL; ++i) {
+               if (path->value[i][0] == '\0') {
+                       BLI_strncpy(path->value[i], name, 
sizeof(path->value[i]));
+                       return true;
+               }
+       }
+       return false;
+}
+
+void BKE_cache_item_path_replace(CacheItemPath *path, const char *name, int 
index)
+{
+       BLI_assert(index < MAX_CACHE_GROUP_LEVEL);
+       BLI_strncpy(path->value[index], name, sizeof(path->value[index]));
+}
+
+void BKE_cache_item_path_clear(CacheItemPath *path)
+{
+       path->value[0][0] = '\0';
+}
+
+void BKE_cache_item_path_truncate(CacheItemPath *path, int len)
+{
+       BLI_assert(len < MAX_CACHE_GROUP_LEVEL);
+       path->value[len][0] = '\0';
+}
+
+void BKE_cache_item_path_copy(CacheItemPath *dst, const CacheItemPath *src)
+{
+       memcpy(dst->value, src->value, sizeof(CacheItemPath));
+}
+
+/* ========================================================================= */
+
 CacheLibrary *BKE_cache_library_add(Main *bmain, const char *name)
 {
        CacheLibrary *cachelib;
@@ -56,6 +121,8 @@ CacheLibrary *BKE_cache_library_copy(CacheLibrary *cachelib)
        
        cachelibn = BKE_libblock_copy(&cachelib->id);
        
+       BLI_duplicatelist(&cachelibn->items, &cachelib->items);
+       
        if (cachelib->id.lib) {
                BKE_id_lib_local_paths(G.main, cachelib->id.lib, 
&cachelibn->id);
        }
@@ -63,6 +130,188 @@ CacheLibrary *BKE_cache_library_copy(CacheLibrary 
*cachelib)
        return cachelibn;
 }
 
-void BKE_cache_library_free(CacheLibrary *UNUSED(cache))
+void BKE_cache_library_free(CacheLibrary *cachelib)
+{
+       BLI_freelistN(&cachelib->items);
+}
+
+/* ========================================================================= */
+
+static void cache_library_walk_recursive(CacheLibrary *cachelib, 
CacheGroupWalkFunc walk, void *userdata, const CacheItemPath *path, int level, 
Object *ob)
+{
+       /* object dm */
+       walk(userdata, cachelib, path);
+       
+       /* dupli group recursion */
+       if ((ob->transflag & OB_DUPLIGROUP) && ob->dup_group) {
+               GroupObject *gob;
+               
+               for (gob = ob->dup_group->gobject.first; gob; gob = gob->next) {
+                       CacheItemPath gpath;
+                       BKE_cache_item_path_copy(&gpath, path);
+                       BKE_cache_item_path_append(&gpath, ob->id.name+2);
+                       cache_library_walk_recursive(cachelib, walk, userdata, 
&gpath, level + 1, gob->ob);
+               }
+       }
+}
+
+void BKE_cache_library_walk(CacheLibrary *cachelib, CacheGroupWalkFunc walk, 
void *userdata)
+{
+       CacheItemPath path;
+       BKE_cache_item_path_clear(&path);
+       
+       if (cachelib && cachelib->group) {
+               GroupObject *gob;
+               
+               for (gob = cachelib->group->gobject.first; gob; gob = 
gob->next) {
+                       cache_library_walk_recursive(cachelib, walk, userdata, 
&path, 0, gob->ob);
+               }
+       }
+}
+
+/* ========================================================================= */
+
+BLI_INLINE unsigned int hash_int_2d(unsigned int kx, unsigned int ky)
+{
+#define rot(x,k) (((x)<<(k)) | ((x)>>(32-(k))))
+
+       uint a, b, c;
+
+       a = b = c = 0xdeadbeef + (2 << 2) + 13;
+       a += kx;
+       b += ky;
+
+       c ^= b; c -= rot(b,14);
+       a ^= c; a -= rot(c,11);
+       b ^= a; b -= rot(a,25);
+       c ^= b; c -= rot(b,16);
+       a ^= c; a -= rot(c,4);
+       b ^= a; b -= rot(a,14);
+       c ^= b; c -= rot(b,24);
+
+       return c;
+
+#undef rot
+}
+
+static unsigned int cache_item_hash(const void *key)
+{
+       const CacheItemPath *path = key;
+       int i;
+       unsigned int hash = 0;
+       
+       for (i = 0; i < MAX_CACHE_GROUP_LEVEL; ++i) {
+               hash = hash_int_2d(hash, BLI_ghashutil_strhash(path->value[i]));
+       }
+       return hash;
+}
+
+static bool cache_item_cmp(const void *key_a, const void *key_b)
+{
+       return BKE_cache_item_path_cmp(key_a, key_b) != 0;
+}
+
+static void cache_library_insert_item_hash(CacheLibrary *cachelib, CacheItem 
*item, bool replace)
+{
+       CacheItemPath *path = &item->path;
+       CacheItem *exist = BLI_ghash_lookup(cachelib->items_hash, path);
+       if (exist && replace) {
+               BLI_remlink(&cachelib->items, exist);
+               BLI_ghash_remove(cachelib->items_hash, path, NULL, NULL);
+               MEM_freeN(exist);
+       }
+       if (!exist || replace)
+               BLI_ghash_insert(cachelib->items_hash, path, item);
+}
+
+static void cache_library_ensure_items_hash(CacheLibrary *cachelib)
+{
+       CacheItem *item;
+       
+       if (cachelib->items_hash) {
+               BLI_ghash_clear(cachelib->items_hash, NULL, NULL);
+       }
+       else {
+               cachelib->items_hash = BLI_ghash_new(cache_item_hash, 
cache_item_cmp, "cache item hash");
+       }
+       
+       for (item = cachelib->items.first; item; item = item->next) {
+               cache_library_insert_item_hash(cachelib, item, true);
+       }
+}
+
+CacheItem *BKE_cache_library_find_item(CacheLibrary *cachelib, const 
CacheItemPath *path)
 {
+       return BLI_ghash_lookup(cachelib->items_hash, path);
+}
+
+CacheItem *BKE_cache_library_add_item(CacheLibrary *cachelib, const 
CacheItemPath *path)
+{
+       CacheItem *item = BLI_ghash_lookup(cachelib->items_hash, path);
+       
+       if (!item) {
+               item = MEM_callocN(sizeof(CacheItem), "cache library item");
+               BKE_cache_item_path_copy(&item->path, path);
+               
+               BLI_addtail(&cachelib->items, item);
+               cache_library_insert_item_hash(cachelib, item, false);
+       }
+       
+       return item;
+}
+
+bool BKE_cache_library_remove_item(CacheLibrary *cachelib, const CacheItemPath 
*path)
+{
+       CacheItem *item = BLI_ghash_lookup(cachelib->items_hash, path);
+       if (item) {
+               BLI_ghash_remove(cachelib->items_hash, (CacheItemPath *)path, 
NULL, NULL);
+               BLI_remlink(&cachelib->items, item);
+               MEM_freeN(item);
+               return true;
+       }
+       else
+               return false;
+}
+
+/* ========================================================================= */
+
+#if 0
+typedef struct UpdateItemsData {
+       CacheItem *cur;
+} UpdateItemsData;
+
+static void cache_library_update_items_walk(void *userdata, CacheLibrary 
*cachelib)
+{
+       UpdateItemsData *data = userdata;
+       CacheItem *item;
+       
+       if (data->cur) {
+               item = data->cur;
+               data->cur = data->cur->next;
+       }
+       else {
+               item = MEM_callocN(sizeof(CacheItem), "cache library item");
+               BLI_addtail(&cachelib->items, item);
+       }
+}
+
+void BKE_cache_library_update_items(CacheLibrary *cachelib)
+{
+       UpdateItemsData data;
+       
+       data.cur = cachelib->items.first;
+       BKE_cache_library_walk(cachelib, cache_library_update_items_walk, 
&data);
+       
+       /* truncate items list */
+       if (data.cur) {
+               cachelib->items.last = data.cur->prev;
+               while (data.cur) {
+                       CacheItem *item = data.cur;
+                       data.cur = data.cur->next;
+                       
+                       BLI_remlink(&cachelib->items, item);
+                       MEM_freeN(item);
+               }
+       }
 }
+#endif
diff --git a/source/blender/makesdna/DNA_cache_library_types.h 
b/source/blender/makesdna/DNA_cache_library_types.h
index 223cde1..36b60d7 100644
--- a/source/blender/makesdna/DNA_cache_library_types.h
+++ b/source/blender/makesdna/DNA_cache_library_types.h
@@ -34,12 +34,28 @@
 
 #include "DNA_defs.h"
 #include "DNA_ID.h"
+#include "DNA_listBase.h"
+
+#define MAX_CACHE_GROUP_LEVEL 8
+
+typedef struct CacheItemPath {
+       char value[8][64]; /* MAX_CACHE_GROUP_LEVEL, MAX_NAME */
+} CacheItemPath;
+
+typedef struct CacheItem {
+       struct CacheItem *next, *prev;
+       
+       CacheItemPath path;
+} CacheItem;
 
 typedef struct CacheLibrary {
        ID id;
        
        char filepath[1024]; /* 1024 = FILE_MAX */
        struct Group *group;
+       
+       ListBase items;                         /* cached items */
+       struct GHash *items_hash;       /* runtime: cached items hash for fast 
lookup */
 } CacheLibrary;
 
 #endif

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

Reply via email to