- rttr/detail/type/type_register.cpp
type data构造完了后会加入到registration_manager,通过调用registration_manager的单例的add_item函数。
type_data* add_item(std::unique_ptr<type_data> obj)
{
auto reg_type = type_register::register_type(obj.get());
const auto was_type_stored = (reg_type == obj.get());
if (was_type_stored)
m_type_data_list.push_back(std::move(obj)); // so we have to unregister it later
return reg_type;
}
这里首先通过type_register::register_type函数来注册type_data信息,这里的type_register类似helper类,里面有大量的静态函数帮助你注册各种功能,比如method,property什么的,这些后面都会用到,这里首先讲注册type_data。调用register_type成功注册后,m_type_data_list会保存type_data的unique_ptr,也就成为type_data管理身存期的地方。
register_type的处理,首先把基类信息调一下,info->get_base_types,这个函数里面会把所有的基类type都get一边,这样可以提前把基类type创建注册好,避免子类在基类之前注册时基类还没有注册好。
后面info->raw_type_data的赋值是判断下raw_type_data是不是invalid_type_data。在前面构造type data的时候有个判断,就是raw_type和T相同,raw_type_data就会赋予invalid_type_data,这里对raw_type_data又进行了一次赋值,让之前raw_data_type = invalid_type_data的raw_type_data等于自己。这一波骚操作的原因也是因为当时的type data还没有构造好。
register_name_if_neccessary做的事情是更新type名和type之间的映射关系。type_register_private单例对象里面有2个map,m_custom_name_to_id和m_orig_name_to_id,前者是自定义命名和type之间的绑定关系,后者是type data构造是推导出的命名和type之间的绑定关系。首先通过寻找m_orig_name_to_id是否已经保存了这个type,如果有就返回type data,没有就将type和name配对放入map。derive_name的作用是把命名规整话,比如星号的位置调整一下。最后再type列表里面存入相关的type类型。
type_data* type_register_private::register_name_if_neccessary(type_data* info)
{
auto ret = m_orig_name_to_id.find(info->type_name);
if (ret != m_orig_name_to_id.end())
return ret->m_type_data;
std::lock_guard<std::mutex> lock(m_mutex);
m_orig_name_to_id.insert(std::make_pair(info->type_name, type(info)));
info->name = derive_name(type(info));
m_custom_name_to_id.insert(std::make_pair(info->name, type(info)));
m_type_list.emplace_back(type(info));
return nullptr;
}
type_data* type_register_private::register_type(type_data* info)
{
// 这里先那一次基类的列表,这个过程中会把基类的type::get<T>调用一变
// 这样子类处理的时候基类都已经注册完成,所有的基类信息是正确的
info->get_base_types();
// 判断type data是否已经创建并存入map中
if (auto t = register_name_if_neccessary(info))
return t;
// 如果raw_type_name是invalid_type_data,就将自己赋值给raw_type_data
info->raw_type_data = !info->raw_type_data->is_valid ? info : info->raw_type_data;
// 这里再保存一份type_data的指针
{
std::lock_guard<std::mutex> lock(m_mutex);
m_type_data_storage.push_back(info);
}
...
}
register_base_class_info里会再一次调用info->get_base_types,这时的基类type都已经创建完毕, base_classes拿到基类列表后去除基类列表中重复的项,然后在对基类列表排序,使得基类在前,派生类在后,然后把这里出来的info的基类按顺序存入info的基类列表,并且为基类列表的每一个基类的派生类类列表中,添加info派生类信息,最后更新类属性列表和类函数列表。
void type_register_private::register_base_class_info(type_data* info)
{
// 获取基类列表
auto base_classes = info->get_base_types();
set<type> double_entries;
for (auto itr = base_classes.rbegin(); itr != base_classes.rend();)
{
if (double_entries.find(itr->m_base_type) == double_entries.end())
{
double_entries.insert(itr->m_base_type);
++itr;
}
else
{
itr = vector<base_class_info>::reverse_iterator(base_classes.erase((++itr).base()));
}
}
// 排序,让基类在前
std::sort(base_classes.begin(), base_classes.end(), [](const base_class_info& left, const base_class_info& right)
{ return left.m_base_type.is_base_of(right.m_base_type); });
auto& class_data = info->get_class_data();
for (const auto& t : base_classes)
{
// 将基类信息存入info的基类列表中
class_data.m_base_types.push_back(t.m_base_type);
// 将转换函数存入列表
class_data.m_conversion_list.push_back(t.m_rttr_cast_func);
// 将info作为派生类信息存入基类的派生类列表中
auto r_type = t.m_base_type.get_raw_type();
r_type.m_type_data->get_class_data().m_derived_types.push_back(type(info));
}
}
type_data* type_register_private::register_type(type_data* info)
{
...
register_base_class_info(info);
...
}
register_type后面的部分主要是类注册的部分,在类注册部分会在详细分析。