This adds a new `DNA_sdna_type_ids.hh` header:
```cpp
namespace blender::dna {
/**
* Each DNA struct has an integer identifier which is unique within a specific
* Blender build, but not necessarily across different builds. The identifier
* can be used to index into `SDNA.structs`.
*/
template<typename T> int sdna_struct_id_get();
/**
* The maximum identifier that will be returned by #sdna_struct_id_get in this
* Blender build.
*/
int sdna_struct_id_get_max();
} // namespace blender::dna
```
The `sdna_struct_id_get` function is used as replacement of
`SDNA_TYPE_FROM_STRUCT` in all places except the DNA defaults system. The
defaults system is C code and therefore can't use the template. There is ongoing
work to replace the defaults system as well though: #134531.
Using this templated function has some benefits over the old approach:
* No need to rely on macros.
* Can use type inferencing in functions like `BLO_write_struct` which avoids
redundancy on the call site. E.g. `BLO_write_struct(writer, ActionStrip,
strip);` can become `BLO_write_struct(writer, strip);` which could even become
`writer.write_struct(strip);`. None of that is implemented as part of this
patch though.
* No need to include the generated `dna_type_offsets.h` file which contains a
huge enum.
Implementation wise, this is done using explicit template instantiations in a
new file generated by `makesdna.cc`: `dna_struct_ids.cc`. The generated file
looks like so:
```cpp
namespace blender::dna {
template<typename T> int sdna_struct_id_get();
int sdna_struct_id_get_max();
int sdna_struct_id_get_max() { return 951; }
}
struct IDPropertyUIData;
template<> int blender:🧬:sdna_struct_id_get<IDPropertyUIData>() { return 1; }
struct IDPropertyUIDataEnumItem;
template<> int blender:🧬:sdna_struct_id_get<IDPropertyUIDataEnumItem>() { return 2; }
```
I tried using static variables instead of separate functions, but I didn't
manage to link it properly. Not quite sure yet if that's an actual limitation or
if I was just missing something.
Pull Request: https://projects.blender.org/blender/blender/pulls/138706
50 lines
1.5 KiB
C++
50 lines
1.5 KiB
C++
/* SPDX-FileCopyrightText: 2025 Blender Authors
|
|
*
|
|
* SPDX-License-Identifier: GPL-2.0-or-later */
|
|
|
|
#pragma once
|
|
|
|
#include <cstdint>
|
|
#include <iosfwd>
|
|
|
|
#include "DNA_sdna_type_ids.hh"
|
|
|
|
struct SDNA;
|
|
struct SDNA_Struct;
|
|
|
|
namespace blender::dna {
|
|
|
|
/**
|
|
* Print all members of the struct assuming that the data has the given address. This is mainly
|
|
* useful for observing what data is written to a .blend file.
|
|
*
|
|
* \param sdna: Contains reflection information about DNA structs.
|
|
* \param struct_id: The type the data points to. Used to index into `sdna.structs`.
|
|
* \param data: Where the data is stored.
|
|
* \param address: The address that should be printed. Often it's the same as `data`.
|
|
* \param element_num: The number of elements in the array, or 1 if there is only one struct.
|
|
* \param stream: Where to print the output.
|
|
*/
|
|
void print_structs_at_address(const SDNA &sdna,
|
|
int struct_id,
|
|
const void *data,
|
|
const void *address,
|
|
int64_t element_num,
|
|
std::ostream &stream);
|
|
|
|
/**
|
|
* Prints all members of the struct to stdout.
|
|
*/
|
|
void print_struct_by_id(int struct_id, const void *data);
|
|
|
|
} // namespace blender::dna
|
|
|
|
/**
|
|
* Prints all members of the struct to stdout.
|
|
*
|
|
* Usage:
|
|
* DNA_print_struct(bNode, node);
|
|
*/
|
|
#define DNA_print_struct(struct_name, data_ptr) \
|
|
blender::dna::print_struct_by_id(blender::dna::sdna_struct_id_get<struct_name>(), data_ptr)
|