38#define MAX_NUMBER 1000000000
53 size_t number_str_len =
SNPRINTF_RLEN(number_str,
".%.3d", number);
58 if (base_name_len + number_str_len >=
MAX_NAME) {
59 base_name_len =
MAX_NAME - number_str_len - 1;
64 base_name[base_name_len] =
'\0';
71 name[base_name_len] =
'\0';
76 BLI_strncpy(name + base_name_len, number_str, number_str_len + 1);
155 mask[0] |= prev_first & 1;
175 return index >= 0 ? &
type_maps[index] :
nullptr;
187#ifdef DEBUG_PRINT_MEMORY_USAGE
191 size_sets += type_map.full_names.size_in_bytes();
192 size_maps += type_map.base_name_to_num_suffix.size_in_bytes();
195 "NameMap memory usage: sets %.1fKB, maps %.1fKB\n", size_sets / 1024.0, size_maps / 1024.0);
197 MEM_delete<UniqueName_Map>(*r_name_map);
198 *r_name_map =
nullptr;
203 for (
Main *bmain_iter = bmain; bmain_iter !=
nullptr; bmain_iter = bmain_iter->
next) {
204 if (bmain_iter->name_map !=
nullptr) {
207 if (bmain_iter->name_map_global !=
nullptr) {
210 for (
Library *lib_iter =
static_cast<Library *
>(bmain_iter->libraries.first);
212 lib_iter =
static_cast<Library *
>(lib_iter->id.next))
214 if (lib_iter->runtime.name_map !=
nullptr) {
227 BLI_assert_msg(name_map !=
nullptr,
"name_map should not be null");
229 type_map.base_name_to_num_suffix.clear();
233 if ((
id == ignore_id) || (!do_global && (id->lib != library))) {
247 "The key (name) already exists in the namemap, should only happen when "
248 "`do_global` is true.");
269 const bool ensure_created,
270 const bool do_global)
280 if (id->lib !=
nullptr) {
281 if (ensure_created && id->lib->runtime.name_map ==
nullptr) {
285 return id->lib->runtime.name_map;
287 if (ensure_created && bmain->
name_map ==
nullptr) {
328 bool is_name_changed =
false;
340 bool added_new =
false;
345 if (added_new || !has_dup) {
356 if (name_map_other !=
nullptr) {
359 return is_name_changed;
365 is_name_changed =
true;
368 int number_to_use = -1;
371 number_to_use = number;
378 if (number_to_use == -1) {
381 number_to_use = number;
398 if (name_map_other !=
nullptr) {
405 return is_name_changed;
422 if (val ==
nullptr) {
425 if (number == 0 && val->
max_value == 0) {
441 if (name[0] ==
'\0') {
446 if (name_map_local !=
nullptr) {
451 if (name_map_global !=
nullptr) {
478 if (id_validated.
contains(id_iter)) {
485 key.
lib = id_iter->lib;
486 if (!id_names_libs.
add(key)) {
490 "ID name '%s' (from library '%s') is found more than once",
492 id_iter->lib !=
nullptr ? id_iter->lib->filepath :
"<None>");
504 if (!id_names_libs.
add(key)) {
508 "\tID has been renamed to '%s', but it still seems to be already in use",
512 CLOG_WARN(&
LOG,
"\tID has been renamed to '%s'", id_iter->name);
513 id_validated.
add(id_iter);
518 "ID name '%s' (from library '%s') is found more than once",
520 id_iter->lib !=
nullptr ? id_iter->lib->filepath :
"<None>");
525 if (name_map ==
nullptr) {
540 "ID name '%s' (from library '%s') exists in current Main, but is not listed in "
543 id_iter->lib !=
nullptr ? id_iter->lib->filepath :
"<None>");
548 "ID name '%s' (from library '%s') exists in current Main, but is not listed in "
551 id_iter->lib !=
nullptr ? id_iter->lib->filepath :
"<None>");
561 if (name_map !=
nullptr) {
567 if (type_map !=
nullptr) {
570 *(
reinterpret_cast<short *
>(key.
name)) = idcode;
579 "ID name '%s' (from library '%s') is listed in the namemap, but does not "
580 "exists in current Main",
582 lib !=
nullptr ?
lib->filepath :
"<None>");
587 "ID name '%s' (from library '%s') is listed in the namemap, but does not "
588 "exists in current Main",
590 lib !=
nullptr ?
lib->filepath :
"<None>");
598 name_map = (
lib !=
nullptr) ?
lib->runtime.name_map :
nullptr;
599 }
while (
lib !=
nullptr);
int BKE_idtype_idcode_to_index(short idcode)
short BKE_idtype_idcode_iter_step(int *idtype_index)
IDNewNameResult BKE_id_new_name_validate(Main &bmain, ListBase &lb, ID &id, const char *newname, IDNewNameMode mode, bool do_linked_data)
#define FOREACH_MAIN_ID_END
ListBase * which_libbase(Main *bmain, short type)
#define FOREACH_MAIN_LISTBASE_END
#define FOREACH_MAIN_LISTBASE_BEGIN(_bmain, _lb)
#define FOREACH_MAIN_ID_BEGIN(_bmain, _id)
#define BLI_assert_msg(a, msg)
#define BLI_BITMAP_ENABLE(_bitmap, _index)
#define BLI_BITMAP_DISABLE(_bitmap, _index)
int BLI_bitmap_find_first_unset(const BLI_bitmap *bitmap, size_t bits)
#define BLI_BITMAP_TEST_BOOL(_bitmap, _index)
bool BLI_ghashutil_strcmp(const void *a, const void *b)
size_t BLI_ghashutil_combine_hash(size_t hash_a, size_t hash_b)
unsigned int BLI_ghashutil_strhash_n(const char *key, size_t n)
unsigned int BLI_ghashutil_ptrhash(const void *key)
#define LISTBASE_FOREACH_MUTABLE(type, var, list)
#define STRNCPY(dst, src)
#define SNPRINTF_RLEN(dst, format,...)
char * BLI_strncpy(char *__restrict dst, const char *__restrict src, size_t dst_maxncpy) ATTR_NONNULL(1
int BLI_str_utf8_invalid_strip(char *str, size_t length) ATTR_NONNULL(1)
size_t BLI_string_split_name_number(const char *name, char delim, char *r_name_left, int *r_number) ATTR_NONNULL(1
#define CLOG_ERROR(clg_ref,...)
#define CLOG_WARN(clg_ref,...)
#define CLOG_INFO(clg_ref, level,...)
ID and Library types, which are fundamental for SDNA.
Read Guarded memory(de)allocation.
const Value * lookup_ptr(const Key &key) const
Value & lookup_or_add_default(const Key &key)
Value & lookup_or_add_cb(const Key &key, const CreateValueF &create_value)
bool remove(const Key &key)
Value & lookup_or_add(const Key &key, const Value &value)
bool contains(const Key &key) const
bool remove(const Key &key)
std::string id_name(void *id)
void BKE_main_namemap_destroy(UniqueName_Map **r_name_map)
bool BKE_main_namemap_get_name(Main *bmain, ID *id, char *name, const bool do_unique_in_bmain)
bool BKE_main_namemap_validate_and_fix(Main *bmain)
static bool namemap_add_name(UniqueName_Map *name_map, ID *id, const char *name, const int number)
static UniqueName_Map * get_namemap_for(Main *bmain, ID *id, const bool ensure_created, const bool do_global)
void BKE_main_namemap_remove_name(Main *bmain, ID *id, const char *name)
UniqueName_Map * BKE_main_namemap_create()
static bool id_name_final_build(char *name, char *base_name, size_t base_name_len, int number)
void BKE_main_namemap_clear(Main *bmain)
bool BKE_main_namemap_validate(Main *bmain)
static void main_namemap_populate(UniqueName_Map *name_map, Main *bmain, Library *library, ID *ignore_id, const bool do_global)
static bool main_namemap_validate_and_fix(Main *bmain, const bool do_fix)
static void namemap_remove_name(UniqueName_Map *name_map, ID *id, const char *name)
void max_inplace(T &a, const T &b)
unsigned __int64 uint64_t
UniqueName_Map * name_map_global
UniqueName_Map * name_map
bool operator==(const UniqueName_Key &o) const
UniqueName_TypeMap * find_by_type(short id_type)
UniqueName_TypeMap type_maps[INDEX_ID_MAX]
Set< UniqueName_Key > full_names
Map< UniqueName_Key, UniqueName_Value > base_name_to_num_suffix
int use_smallest_unused()
static constexpr uint max_exact_tracking
void mark_used(int number)
BLI_BITMAP_DECLARE(mask, max_exact_tracking)
void mark_unused(int number)
bool use_if_unused(int number)
bool operator==(const Uniqueness_Key &o) const
static DynamicLibrary lib