[Bf-blender-cvs] [ad9e498] particles_refactor: Replaced the attribute state array with a ListBase. Eventually this should use a hash table for O(1) lookup, but for now a linked list is the easiest implementation.

Lukas Tönne noreply at git.blender.org
Tue Apr 22 12:05:57 CEST 2014


Commit: ad9e4983dc9685e59f1434fa90a92f2028b01cd8
Author: Lukas Tönne
Date:   Tue Dec 17 10:25:23 2013 +0100
https://developer.blender.org/rBad9e4983dc9685e59f1434fa90a92f2028b01cd8

Replaced the attribute state array with a ListBase. Eventually this
should use a hash table for O(1) lookup, but for now a linked list is
the easiest implementation.

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

M	source/blender/blenkernel/intern/nparticle.c
M	source/blender/blenloader/intern/readfile.c
M	source/blender/blenloader/intern/writefile.c
M	source/blender/makesdna/DNA_nparticle_types.h
M	source/blender/makesrna/intern/rna_nparticle.c

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

diff --git a/source/blender/blenkernel/intern/nparticle.c b/source/blender/blenkernel/intern/nparticle.c
index 2e755f9..26091dd 100644
--- a/source/blender/blenkernel/intern/nparticle.c
+++ b/source/blender/blenkernel/intern/nparticle.c
@@ -83,19 +83,15 @@ static void nparticle_attribute_state_copy(NParticleAttributeState *to, NParticl
 static NParticleState *nparticle_state_new(NParticleSystem *UNUSED(psys))
 {
 	NParticleState *state = MEM_callocN(sizeof(NParticleState), "particle state");
-	/* attribute states get initialized lazily,
-	 * zero hashkey is terminator.
-	 */
-	state->attributes = MEM_callocN(sizeof(NParticleAttributeState), "particle attribute states");
 	return state;
 }
 
 static void nparticle_state_free(NParticleState *state)
 {
 	NParticleAttributeState *attrstate;
-	for (attrstate = state->attributes; attrstate->hashkey; ++attrstate)
+	for (attrstate = state->attributes.first; attrstate; attrstate = attrstate->next)
 		nparticle_attribute_state_free(attrstate);
-	MEM_freeN(state->attributes);
+	BLI_freelistN(&state->attributes);
 	MEM_freeN(state);
 }
 
@@ -104,9 +100,11 @@ static NParticleState *nparticle_state_copy(NParticleState *state)
 	NParticleState *nstate = MEM_dupallocN(state);
 	NParticleAttributeState *attrstate, *nattrstate;
 	
-	nstate->attributes = MEM_dupallocN(state->attributes);
+	BLI_duplicatelist(&state->attributes, &nstate->attributes);
 	
-	for (attrstate = state->attributes, nattrstate = nstate->attributes; attrstate->hashkey; ++attrstate, ++nattrstate)
+	for (attrstate = state->attributes.first, nattrstate = nstate->attributes.first;
+	     attrstate;
+	     attrstate = attrstate->next, nattrstate = nattrstate->next)
 		nparticle_attribute_state_copy(nattrstate, attrstate);
 	
 	return nstate;
@@ -114,49 +112,32 @@ static NParticleState *nparticle_state_copy(NParticleState *state)
 
 static int nparticle_state_num_attributes(NParticleState *state)
 {
-	NParticleAttributeState *attrstate;
-	int len = 0;
-	for (attrstate = state->attributes; attrstate->hashkey; ++attrstate)
-		++len;
-	return len;
+	return BLI_countlist(&state->attributes);
 }
 
 static void nparticle_state_add_attribute(NParticleState *state, NParticleAttribute *attr)
 {
-	int totattr = nparticle_state_num_attributes(state);
-	state->attributes = MEM_reallocN(state->attributes, sizeof(NParticleAttributeState) * (totattr+1));
-	nparticle_attribute_state_init(attr, state->attributes + totattr);
+	NParticleAttributeState *attrstate = MEM_callocN(sizeof(NParticleAttributeState), "particle attribute state");
+	nparticle_attribute_state_init(attr, attrstate);
+	BLI_addtail(&state->attributes, attrstate);
 }
 
 static void nparticle_state_remove_attribute(NParticleState *state, const char *name)
 {
 	NParticleAttributeState *attrstate = BKE_nparticle_state_find_attribute(state, name);
 	if (attrstate) {
-		int index = attrstate - state->attributes;
-		NParticleAttributeState *old_attributes = state->attributes;
-		int totattr = nparticle_state_num_attributes(state);
-		
+		BLI_remlink(&state->attributes, attrstate);
 		nparticle_attribute_state_free(attrstate);
-		
-		state->attributes = MEM_mallocN(sizeof(NParticleAttributeState) * (totattr-1), "particle state attributes");
-		if (index > 0)
-			memcpy(state->attributes, old_attributes, sizeof(NParticleAttributeState) * index);
-		if (index < (totattr-1))
-			memcpy(state->attributes + index, old_attributes + index + 1, sizeof(NParticleAttributeState) * (totattr - (index+1)));
-		MEM_freeN(old_attributes);
+		MEM_freeN(attrstate);
 	}
 }
 
 static void nparticle_state_clear(NParticleState *state)
 {
 	NParticleAttributeState *attrstate;
-	for (attrstate = state->attributes; attrstate->hashkey; ++attrstate)
+	for (attrstate = state->attributes.first; attrstate; attrstate = attrstate->next)
 		nparticle_attribute_state_free(attrstate);
-	MEM_freeN(state->attributes);
-	/* attribute states get initialized lazily,
-	 * zero hashkey is terminator.
-	 */
-	state->attributes = MEM_callocN(sizeof(NParticleAttributeState), "particle attribute states");
+	BLI_freelistN(&state->attributes);
 }
 
 
@@ -284,7 +265,7 @@ NParticleAttributeState *BKE_nparticle_state_find_attribute(NParticleState *stat
 {
 	int hashkey = BLI_ghashutil_strhash(name);
 	NParticleAttributeState *attrstate;
-	for (attrstate = state->attributes; attrstate->hashkey; ++attrstate)
+	for (attrstate = state->attributes.first; attrstate; attrstate = attrstate->next)
 		if (attrstate->hashkey == hashkey)
 			return attrstate;
 	return NULL;
@@ -316,7 +297,7 @@ int BKE_nparticle_add(NParticleState *state, NParticleID id)
 	int index = BKE_nparticle_find_index(state, id);
 	if (index < 0) {
 		NParticleAttributeState *attrstate;
-		for (attrstate = state->attributes; attrstate->hashkey; ++attrstate) {
+		for (attrstate = state->attributes.first; attrstate; attrstate = attrstate->next) {
 			BLI_pbuf_add_elements(&attrstate->data, 1);
 			index = attrstate->data.totelem - 1;
 		}
@@ -330,7 +311,7 @@ void BKE_nparticle_remove(NParticleState *state, NParticleID id)
 	int index = BKE_nparticle_find_index(state, id);
 	if (index >= 0) {
 		NParticleAttributeState *attrstate;
-		for (attrstate = state->attributes; attrstate->hashkey; ++attrstate) {
+		for (attrstate = state->attributes.first; attrstate; attrstate = attrstate->next) {
 			/* XXX TODO paged buffer doesn't support removing yet */
 //			BLI_pbuf_remove_elements(&attrstate->data, index);
 		}
diff --git a/source/blender/blenloader/intern/readfile.c b/source/blender/blenloader/intern/readfile.c
index 69340ec..d4a9f29 100644
--- a/source/blender/blenloader/intern/readfile.c
+++ b/source/blender/blenloader/intern/readfile.c
@@ -4265,7 +4265,8 @@ static void direct_link_nparticle_system(FileData *fd, NParticleSystem *psys)
 	
 	psys->state = newdataadr(fd, psys->state);
 	if (psys->state) {
-		for (attrstate = psys->state->attributes; attrstate->hashkey; ++attrstate)
+		link_list(fd, &psys->state->attributes);
+		for (attrstate = psys->state->attributes.first; attrstate; attrstate = attrstate->next)
 			direct_link_pagedbuffer(fd, &attrstate->data);
 	}
 }
diff --git a/source/blender/blenloader/intern/writefile.c b/source/blender/blenloader/intern/writefile.c
index 6afa85d..06a29c3 100644
--- a/source/blender/blenloader/intern/writefile.c
+++ b/source/blender/blenloader/intern/writefile.c
@@ -1384,15 +1384,13 @@ static void write_nparticle_system(WriteData *wd, NParticleSystem *psys)
 	
 	if (psys->state) {
 		NParticleAttributeState *attrstate;
-		int totattr = 0;
 		
 		writestruct(wd, DATA, "NParticleState", 1, psys->state);
 		
-		for (attrstate = psys->state->attributes; attrstate->hashkey; ++attrstate) {
+		for (attrstate = psys->state->attributes.first; attrstate; attrstate = attrstate->next) {
+			writestruct(wd, DATA, "NParticleAttributeState", 1, attrstate);
 			write_pagedbuffer(wd, &attrstate->data);
-			++totattr;
 		}
-		writestruct(wd, DATA, "NParticleAttributeState", totattr+1, psys->state->attributes);
 	}
 }
 
diff --git a/source/blender/makesdna/DNA_nparticle_types.h b/source/blender/makesdna/DNA_nparticle_types.h
index f383b77..773c08d 100644
--- a/source/blender/makesdna/DNA_nparticle_types.h
+++ b/source/blender/makesdna/DNA_nparticle_types.h
@@ -52,6 +52,12 @@ typedef enum eParticleAttributeDataType {
 } eParticleAttributeDataType;
 
 typedef struct NParticleAttributeState {
+	/* XXX next/prev only needed for storing in ListBase,
+	 * can be removed when attribute states get stored
+	 * in a hash table instead.
+	 */
+	struct NParticleAttributeState *next, *prev;
+	
 	int hashkey;
 	int pad;
 	
@@ -59,10 +65,10 @@ typedef struct NParticleAttributeState {
 } NParticleAttributeState;
 
 typedef struct NParticleState {
-	/* XXX just a null-terminated list atm (hashkey==0),
-	 * uses linear search for lookup, could use a GHash instead for O(1) lookup.
+	/* XXX just a list atm, uses linear search for lookup,
+	 * could use a GHash instead for O(1) lookup.
 	 */
-	struct NParticleAttributeState *attributes;
+	ListBase attributes;
 } NParticleState;
 
 typedef struct NParticleAttribute {
diff --git a/source/blender/makesrna/intern/rna_nparticle.c b/source/blender/makesrna/intern/rna_nparticle.c
index ef1b295..c34b2d3 100644
--- a/source/blender/makesrna/intern/rna_nparticle.c
+++ b/source/blender/makesrna/intern/rna_nparticle.c
@@ -34,6 +34,7 @@
 
 #include "MEM_guardedalloc.h"
 
+#include "BLI_listbase.h"
 #include "BLI_math.h"
 #include "BLI_pagedbuffer.h"
 
@@ -217,20 +218,20 @@ static void rna_NParticleDataMatrix_set(PointerRNA *ptr, const float *value)
 static void rna_NParticleState_attributes_begin(CollectionPropertyIterator *iter, PointerRNA *ptr)
 {
 	NParticleState *state = ptr->data;
-	NParticleAttributeState *attrstate = state->attributes;
+	NParticleAttributeState *attrstate = state->attributes.first;
 	
 	iter->internal = attrstate;
-	iter->valid = (attrstate->hashkey != 0);
+	iter->valid = (attrstate != NULL);
 }
 
 static void rna_NParticleState_attributes_next(CollectionPropertyIterator *iter)
 {
 	NParticleAttributeState *attrstate = iter->internal;
 	
-	++attrstate;
+	attrstate = attrstate->next;
 	
 	iter->internal = attrstate;
-	iter->valid = (attrstate->hashkey != 0);
+	iter->valid = (attrstate != NULL);
 }
 
 static void rna_NParticleState_attributes_end(CollectionPropertyIterator *iter)
@@ -249,11 +250,7 @@ static PointerRNA rna_NParticleState_attributes_get(CollectionPropertyIterator *
 static int rna_NParticleState_attributes_length(PointerRNA *ptr)
 {
 	NParticleState *state = ptr->data;
-	NParticleAttributeState *attrstate;
-	int length = 0;
-	for (attrstate = state->attributes; attrstate->hashkey; ++attrstate)
-		++length;
-	return length;
+	return BLI_countlist(&state->attributes);
 }
 
 int rna_NParticleState_attributes_lookup_string(PointerRNA *ptr, const char *key, PointerRNA *r_ptr)




More information about the Bf-blender-cvs mailing list