Blender  V3.3
fcurve_cache.c
Go to the documentation of this file.
1 /* SPDX-License-Identifier: GPL-2.0-or-later */
2 
9 #include <stdlib.h>
10 #include <string.h>
11 
12 #include "MEM_guardedalloc.h"
13 
14 #include "DNA_anim_types.h"
15 
16 #include "BLI_ghash.h"
17 #include "BLI_listbase.h"
18 
19 #include "BKE_fcurve.h"
20 
21 /* -------------------------------------------------------------------- */
32 };
33 
42 };
43 
47 static int fcurve_cmp_for_cache(const void *fcu_a_p, const void *fcu_b_p)
48 {
49  const FCurve *fcu_a = *((const FCurve **)fcu_a_p);
50  const FCurve *fcu_b = *((const FCurve **)fcu_b_p);
51  const int cmp = strcmp(fcu_a->rna_path, fcu_b->rna_path);
52  if (cmp != 0) {
53  return cmp;
54  }
55  if (fcu_a->array_index < fcu_b->array_index) {
56  return -1;
57  }
58  if (fcu_a->array_index > fcu_b->array_index) {
59  return 1;
60  }
61  return 0;
62 }
63 
65 {
68  uint i;
69  LISTBASE_FOREACH_INDEX (FCurve *, fcu, list, i) {
70  fcurve_array[i] = fcu;
71  }
73 
74  /* Allow for the case no F-Curves share an RNA-path, otherwise this is over-allocated.
75  * Although in practice it's likely to only be 3-4x as large as is needed
76  * (with transform channels for e.g.). */
77  struct FCurvePathCache_Span *span_table = MEM_mallocN(sizeof(*span_table) * fcurve_array_len,
78  __func__);
79 
80  /* May over reserve, harmless. */
81  GHash *span_from_rna_path = BLI_ghash_str_new_ex(__func__, fcurve_array_len);
82  uint span_index = 0;
83  i = 0;
84  while (i < fcurve_array_len) {
85  uint i_end;
86  for (i_end = i + 1; i_end < fcurve_array_len; i_end++) {
87  /* As the indices are sorted, we know a decrease means a new RNA path is found. */
88  if (fcurve_array[i]->array_index > fcurve_array[i_end]->array_index) {
89  BLI_assert(!STREQ(fcurve_array[i]->rna_path, fcurve_array[i_end]->rna_path));
90  break;
91  }
92  if (!STREQ(fcurve_array[i]->rna_path, fcurve_array[i_end]->rna_path)) {
93  break;
94  }
95  }
96 
97  struct FCurvePathCache_Span *span = &span_table[span_index++];
98  span->index = i;
99  span->len = i_end - i;
100  BLI_ghash_insert(span_from_rna_path, fcurve_array[i]->rna_path, span);
101  i = i_end;
102  }
103 
104  struct FCurvePathCache *fcache = MEM_callocN(sizeof(struct FCurvePathCache), __func__);
105  fcache->fcurve_array = fcurve_array;
107  fcache->span_table = span_table;
109 
110  return fcache;
111 }
112 
114 {
115  MEM_freeN(fcache->fcurve_array);
116  MEM_freeN(fcache->span_table);
118  MEM_freeN(fcache);
119 }
120 
122  const char *rna_path,
123  const int array_index)
124 {
125  const struct FCurvePathCache_Span *span = BLI_ghash_lookup(fcache->span_from_rna_path, rna_path);
126  if (span == NULL) {
127  return NULL;
128  }
129 
130  FCurve **fcurve = fcache->fcurve_array + span->index;
131  const uint len = span->len;
132  for (int i = 0; i < len; i++) {
133  if (fcurve[i]->array_index == array_index) {
134  return fcurve[i];
135  }
136  /* As these are sorted, early exit. */
137  if (fcurve[i]->array_index > array_index) {
138  break;
139  }
140  }
141  return NULL;
142 }
143 
145  const char *rna_path,
146  FCurve **fcurve_result,
147  int fcurve_result_len)
148 {
149  memset(fcurve_result, 0x0, sizeof(*fcurve_result) * fcurve_result_len);
150 
151  const struct FCurvePathCache_Span *span = BLI_ghash_lookup(fcache->span_from_rna_path, rna_path);
152  if (span == NULL) {
153  return 0;
154  }
155 
156  int found = 0;
157  FCurve **fcurve = fcache->fcurve_array + span->index;
158  const uint len = span->len;
159  for (int i = 0; i < len; i++) {
160  /* As these are sorted, early exit. */
161  if ((uint)fcurve[i]->array_index > (uint)fcurve_result_len) {
162  break;
163  }
164  fcurve_result[fcurve[i]->array_index] = fcurve[i];
165  found += 1;
166  }
167  return found;
168 }
169 
#define BLI_assert(a)
Definition: BLI_assert.h:46
GHash * BLI_ghash_str_new_ex(const char *info, unsigned int nentries_reserve) ATTR_MALLOC ATTR_WARN_UNUSED_RESULT
void * BLI_ghash_lookup(const GHash *gh, const void *key) ATTR_WARN_UNUSED_RESULT
Definition: BLI_ghash.c:734
void BLI_ghash_insert(GHash *gh, void *key, void *val)
Definition: BLI_ghash.c:710
void BLI_ghash_free(GHash *gh, GHashKeyFreeFP keyfreefp, GHashValFreeFP valfreefp)
Definition: BLI_ghash.c:863
#define LISTBASE_FOREACH_INDEX(type, var, list, index_var)
Definition: BLI_listbase.h:344
int BLI_listbase_count(const struct ListBase *listbase) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL(1)
unsigned int uint
Definition: BLI_sys_types.h:67
#define STREQ(a, b)
Read Guarded memory(de)allocation.
int len
Definition: draw_manager.c:108
struct FCurvePathCache * BKE_fcurve_pathcache_create(ListBase *list)
Definition: fcurve_cache.c:64
FCurve * BKE_fcurve_pathcache_find(struct FCurvePathCache *fcache, const char *rna_path, const int array_index)
Definition: fcurve_cache.c:121
int BKE_fcurve_pathcache_find_array(struct FCurvePathCache *fcache, const char *rna_path, FCurve **fcurve_result, int fcurve_result_len)
Definition: fcurve_cache.c:144
static int fcurve_cmp_for_cache(const void *fcu_a_p, const void *fcu_b_p)
Definition: fcurve_cache.c:47
void BKE_fcurve_pathcache_destroy(struct FCurvePathCache *fcache)
Definition: fcurve_cache.c:113
void(* MEM_freeN)(void *vmemh)
Definition: mallocn.c:27
void *(* MEM_callocN)(size_t len, const char *str)
Definition: mallocn.c:31
void *(* MEM_mallocN)(size_t len, const char *str)
Definition: mallocn.c:33
GHash * span_from_rna_path
Definition: fcurve_cache.c:41
struct FCurvePathCache_Span * span_table
Definition: fcurve_cache.c:39
FCurve ** fcurve_array
Definition: fcurve_cache.c:36
char * rna_path
int array_index