1 /*
2  * This program is free software; you can redistribute it and/or
3  * modify it under the terms of the GNU General Public License
4  * as published by the Free Software Foundation; either version 2
5  * of the License, or (at your option) any later version.
6  *
7  * This program is distributed in the hope that it will be useful,
8  * but WITHOUT ANY WARRANTY; without even the implied warranty of
9  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
10  * GNU General Public License for more details.
11  *
12  * You should have received a copy of the GNU General Public License
13  * along with this program; if not, write to the Free Software Foundation,
14  * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
15  *
16  * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
17  * All rights reserved.
18  */
19 
20 #pragma once
21 
22 /** \file
23  * \ingroup bke
24  *
25  * ID type structure, helping to factorize common operations and data for all data-block types.
26  */
27 
28 #include "BLI_sys_types.h"
29 
30 #ifdef __cplusplus
31 extern "C" {
32 #endif
33 
34 struct BlendDataReader;
35 struct BlendExpander;
36 struct BlendLibReader;
37 struct BlendWriter;
38 struct ID;
39 struct LibraryForeachIDData;
40 struct Main;
41 
42 /** IDTypeInfo.flags. */
43 enum {
44   /** Indicates that the given IDType does not support copying. */
45   IDTYPE_FLAGS_NO_COPY = 1 << 0,
46   /** Indicates that the given IDType does not support linking/appending from a library file. */
47   IDTYPE_FLAGS_NO_LIBLINKING = 1 << 1,
48   /** Indicates that the given IDType does not support making a library-linked ID local. */
49   IDTYPE_FLAGS_NO_MAKELOCAL = 1 << 2,
50   /** Indicates that the given IDType does not have animation data. */
51   IDTYPE_FLAGS_NO_ANIMDATA = 1 << 3,
52 };
53 
54 typedef struct IDCacheKey {
55   /* The session UUID of the ID owning the cached data. */
56   unsigned int id_session_uuid;
57   /* Value uniquely identifying the cache within its ID.
58    * Typically the offset of its member in the data-block struct, but can be anything. */
59   size_t offset_in_ID;
60   /* Actual address of the cached data to save and restore. */
61   void *cache_v;
62 } IDCacheKey;
63 
64 uint BKE_idtype_cache_key_hash(const void *key_v);
65 bool BKE_idtype_cache_key_cmp(const void *key_a_v, const void *key_b_v);
66 
67 /* ********** Prototypes for #IDTypeInfo callbacks. ********** */
68 
69 typedef void (*IDTypeInitDataFunction)(struct ID *id);
70 
71 /** \param flag: Copying options (see BKE_lib_id.h's LIB_ID_COPY_... flags for more). */
72 typedef void (*IDTypeCopyDataFunction)(struct Main *bmain,
73                                        struct ID *id_dst,
74                                        const struct ID *id_src,
75                                        const int flag);
76 
77 typedef void (*IDTypeFreeDataFunction)(struct ID *id);
78 
79 /** \param flag: See BKE_lib_id.h's LIB_ID_MAKELOCAL_... flags. */
80 typedef void (*IDTypeMakeLocalFunction)(struct Main *bmain, struct ID *id, const int flags);
81 
82 typedef void (*IDTypeForeachIDFunction)(struct ID *id, struct LibraryForeachIDData *data);
83 
84 typedef enum eIDTypeInfoCacheCallbackFlags {
85   /** Indicates to the callback that that cache may be stored in the .blend file, so its pointer
86    * should not be cleared at read-time. */
87   IDTYPE_CACHE_CB_FLAGS_PERSISTENT = 1 << 0,
88 } eIDTypeInfoCacheCallbackFlags;
89 typedef void (*IDTypeForeachCacheFunctionCallback)(struct ID *id,
90                                                    const struct IDCacheKey *cache_key,
91                                                    void **cache_p,
92                                                    uint flags,
93                                                    void *user_data);
94 typedef void (*IDTypeForeachCacheFunction)(struct ID *id,
95                                            IDTypeForeachCacheFunctionCallback function_callback,
96                                            void *user_data);
97 
98 typedef void (*IDTypeBlendWriteFunction)(struct BlendWriter *writer,
99                                          struct ID *id,
100                                          const void *id_address);
101 typedef void (*IDTypeBlendReadDataFunction)(struct BlendDataReader *reader, struct ID *id);
102 typedef void (*IDTypeBlendReadLibFunction)(struct BlendLibReader *reader, struct ID *id);
103 typedef void (*IDTypeBlendReadExpandFunction)(struct BlendExpander *expander, struct ID *id);
104 
105 typedef struct IDTypeInfo {
106   /* ********** General IDType data. ********** */
107 
108   /**
109    * Unique identifier of this type, either as a short or an array of two chars, see DNA_ID.h's
110    * ID_XX enums.
111    */
112   short id_code;
113   /**
114    * Bitflag matching id_code, used for filtering (e.g. in file browser), see DNA_ID.h's
115    * FILTER_ID_XX enums.
116    */
117   uint64_t id_filter;
118 
119   /**
120    * Define the position of this data-block type in the virtual list of all data in a Main that is
121    * returned by `set_listbasepointers()`.
122    * Very important, this has to be unique and below INDEX_ID_MAX, see DNA_ID.h.
123    */
124   int main_listbase_index;
125 
126   /** Memory size of a data-block of that type. */
127   size_t struct_size;
128 
129   /** The user visible name for this data-block, also used as default name for a new data-block. */
130   const char *name;
131   /** Plural version of the user-visble name. */
132   const char *name_plural;
133   /** Translation context to use for UI messages related to that type of data-block. */
134   const char *translation_context;
135 
136   /** Generic info flags about that data-block type. */
137   uint32_t flags;
138 
139   /* ********** ID management callbacks ********** */
140 
141   /* TODO: Note about callbacks: Ideally we could also handle here `BKE_lib_query`'s behavior, as
142    * well as read/write of files. However, this is a bit more involved than basic ID management
143    * callbacks, so we'll check on this later. */
144 
145   /**
146    * Initialize a new, empty calloc'ed data-block. May be NULL if there is nothing to do.
147    */
148   IDTypeInitDataFunction init_data;
149 
150   /**
151    * Copy the given data-block's data from source to destination. May be NULL if mere memcopy of
152    * the ID struct itself is enough.
153    */
154   IDTypeCopyDataFunction copy_data;
155 
156   /**
157    * Free the data of the data-block (NOT the ID itself). May be NULL if there is nothing to do.
158    */
159   IDTypeFreeDataFunction free_data;
160 
161   /**
162    * Make a linked data-block local. May be NULL if default behavior from
163    * `BKE_lib_id_make_local_generic()` is enough.
164    */
165   IDTypeMakeLocalFunction make_local;
166 
167   /**
168    * Called by `BKE_library_foreach_ID_link()` to apply a callback over all other ID usages (ID
169    * pointers) of given data-block.
170    */
171   IDTypeForeachIDFunction foreach_id;
172 
173   /**
174    * Iterator over all cache pointers of given ID.
175    */
176   IDTypeForeachCacheFunction foreach_cache;
177 
178   /* ********** Callbacks for reading and writing .blend files. ********** */
179 
180   /**
181    * Write all structs that should be saved in a .blend file.
182    */
183   IDTypeBlendWriteFunction blend_write;
184 
185   /**
186    * Update pointers for all structs directly owned by this data block.
187    */
188   IDTypeBlendReadDataFunction blend_read_data;
189 
190   /**
191    * Update pointers to other id data blocks.
192    */
193   IDTypeBlendReadLibFunction blend_read_lib;
194 
195   /**
196    * Specify which other id data blocks should be loaded when the current one is loaded.
197    */
198   IDTypeBlendReadExpandFunction blend_read_expand;
199 } IDTypeInfo;
200 
201 /* ********** Declaration of each IDTypeInfo. ********** */
202 
203 /* Those are defined in the respective BKE files. */
204 extern IDTypeInfo IDType_ID_SCE;
205 extern IDTypeInfo IDType_ID_LI;
206 extern IDTypeInfo IDType_ID_OB;
207 extern IDTypeInfo IDType_ID_ME;
208 extern IDTypeInfo IDType_ID_CU;
209 extern IDTypeInfo IDType_ID_MB;
210 extern IDTypeInfo IDType_ID_MA;
211 extern IDTypeInfo IDType_ID_TE;
212 extern IDTypeInfo IDType_ID_IM;
213 extern IDTypeInfo IDType_ID_LT;
214 extern IDTypeInfo IDType_ID_LA;
215 extern IDTypeInfo IDType_ID_CA;
216 extern IDTypeInfo IDType_ID_IP;
217 extern IDTypeInfo IDType_ID_KE;
218 extern IDTypeInfo IDType_ID_WO;
219 extern IDTypeInfo IDType_ID_SCR;
220 extern IDTypeInfo IDType_ID_VF;
221 extern IDTypeInfo IDType_ID_TXT;
222 extern IDTypeInfo IDType_ID_SPK;
223 extern IDTypeInfo IDType_ID_SO;
224 extern IDTypeInfo IDType_ID_GR;
225 extern IDTypeInfo IDType_ID_AR;
226 extern IDTypeInfo IDType_ID_AC;
227 extern IDTypeInfo IDType_ID_NT;
228 extern IDTypeInfo IDType_ID_BR;
229 extern IDTypeInfo IDType_ID_PA;
230 extern IDTypeInfo IDType_ID_GD;
231 extern IDTypeInfo IDType_ID_WM;
232 extern IDTypeInfo IDType_ID_MC;
233 extern IDTypeInfo IDType_ID_MSK;
234 extern IDTypeInfo IDType_ID_LS;
235 extern IDTypeInfo IDType_ID_PAL;
236 extern IDTypeInfo IDType_ID_PC;
237 extern IDTypeInfo IDType_ID_CF;
238 extern IDTypeInfo IDType_ID_WS;
239 extern IDTypeInfo IDType_ID_LP;
240 extern IDTypeInfo IDType_ID_HA;
241 extern IDTypeInfo IDType_ID_PT;
242 extern IDTypeInfo IDType_ID_VO;
243 extern IDTypeInfo IDType_ID_SIM;
244 
245 extern IDTypeInfo IDType_ID_LINK_PLACEHOLDER;
246 
247 /* ********** Helpers/Utils API. ********** */
248 
249 /* Module initialization. */
250 void BKE_idtype_init(void);
251 
252 /* General helpers. */
253 const struct IDTypeInfo *BKE_idtype_get_info_from_idcode(const short id_code);
254 const struct IDTypeInfo *BKE_idtype_get_info_from_id(const struct ID *id);
255 
256 const char *BKE_idtype_idcode_to_name(const short idcode);
257 const char *BKE_idtype_idcode_to_name_plural(const short idcode);
258 const char *BKE_idtype_idcode_to_translation_context(const short idcode);
259 bool BKE_idtype_idcode_is_linkable(const short idcode);
260 bool BKE_idtype_idcode_is_valid(const short idcode);
261 
262 short BKE_idtype_idcode_from_name(const char *idtype_name);
263 
264 uint64_t BKE_idtype_idcode_to_idfilter(const short idcode);
265 short BKE_idtype_idcode_from_idfilter(const uint64_t idfilter);
266 
267 int BKE_idtype_idcode_to_index(const short idcode);
268 short BKE_idtype_idcode_from_index(const int index);
269 
270 short BKE_idtype_idcode_iter_step(int *index);
271 
272 /* Some helpers/wrappers around callbacks defined in #IDTypeInfo, dealing e.g. with embedded IDs.
273  * XXX Ideally those would rather belong to #BKE_lib_id, but using callback function pointers makes
274  * this hard to do properly if we want to avoid headers includes in headers. */
275 
276 void BKE_idtype_id_foreach_cache(struct ID *id,
277                                  IDTypeForeachCacheFunctionCallback function_callback,
278                                  void *user_data);
279 
280 #ifdef __cplusplus
281 }
282 #endif
283