Skip to content

Commit

Permalink
Implemented Struct defaults.
Browse files Browse the repository at this point in the history
  • Loading branch information
nlupugla committed Oct 4, 2023
1 parent dc17d89 commit ddcc90e
Show file tree
Hide file tree
Showing 5 changed files with 97 additions and 150 deletions.
18 changes: 9 additions & 9 deletions core/object/object.h
Original file line number Diff line number Diff line change
Expand Up @@ -166,9 +166,9 @@ struct StructMember {
}
};

#define STRUCT_MEMBER(m_name, m_type) StructMember(SNAME(m_name), m_type)
#define STRUCT_CLASS_MEMBER(m_name, m_class) StructMember(SNAME(m_name), Variant::OBJECT, m_class)
#define STRUCT_STRUCT_MEMBER(m_name, m_struct) StructMember(SNAME(m_name), Variant::ARRAY, m_struct::get_name(), m_struct::get_members())
#define STRUCT_MEMBER(m_name, m_type, m_default) StructMember(SNAME(m_name), m_type, StringName(), nullptr, m_default)
#define STRUCT_CLASS_MEMBER(m_name, m_class_name, m_default) StructMember(SNAME(m_name), Variant::OBJECT, m_class_name, nullptr, m_default)
#define STRUCT_STRUCT_MEMBER(m_name, m_struct, m_default) StructMember(SNAME(m_name), Variant::ARRAY, m_struct::get_name(), m_struct::get_members(), m_default)

#define STRUCT_LAYOUT(m_struct, m_name, ...) \
struct m_struct { \
Expand Down Expand Up @@ -259,12 +259,12 @@ struct PropertyInfo {
};

STRUCT_LAYOUT(PropertyInfoLayout, "PropertyInfo",
STRUCT_MEMBER("name", Variant::STRING),
STRUCT_MEMBER("class_name", Variant::STRING_NAME),
STRUCT_MEMBER("type", Variant::INT),
STRUCT_MEMBER("hint", Variant::INT),
STRUCT_MEMBER("hint_string", Variant::STRING),
STRUCT_MEMBER("usage", Variant::INT));
STRUCT_MEMBER("name", Variant::STRING, String()),
STRUCT_MEMBER("class_name", Variant::STRING_NAME, StringName()),
STRUCT_MEMBER("type", Variant::INT, Variant::NIL),
STRUCT_MEMBER("hint", Variant::INT, PROPERTY_HINT_NONE),
STRUCT_MEMBER("hint_string", Variant::STRING, String()),
STRUCT_MEMBER("usage", Variant::INT, PROPERTY_USAGE_DEFAULT));

TypedArray<Dictionary> convert_property_list(const List<PropertyInfo> *p_list);

Expand Down
114 changes: 49 additions & 65 deletions core/variant/array.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -225,9 +225,6 @@ void Array::assign(const Array &p_array) {
const ContainerTypeValidate &typed = _p->typed;
const ContainerTypeValidate &source_typed = p_array._p->typed;

// TODO: I will probably need to add some logic here for structs.

// assign if we don't have a type yet, our type exactly matches the source, or our type can reference the source's
if (typed.type == Variant::NIL || typed == source_typed || (source_typed.type == Variant::OBJECT && typed.can_reference(source_typed))) {
// from same to same or
// from anything to variants or
Expand All @@ -236,17 +233,19 @@ void Array::assign(const Array &p_array) {
return;
}

if (typed.is_struct() && (typed != source_typed)) {
ERR_FAIL_MSG("A struct can only be assigned a struct of matching type.");
}

const Variant *source = p_array._p->array.ptr();
int size = p_array._p->array.size();

// if (we are an object and the source is untyped) or (the source is an object, and it can reference us)
if ((source_typed.type == Variant::NIL && typed.type == Variant::OBJECT) || (source_typed.type == Variant::OBJECT && source_typed.can_reference(typed))) {
// from variants to objects or
// from base classes to subclasses
for (int i = 0; i < size; i++) {
const Variant &element = source[i];
const Variant::Type type = source[i].get_type();
// if source's ith element has a type but that type is an invalid object
if (type != Variant::NIL && (type != Variant::OBJECT || !typed.validate_object(element, "assign"))) {
ERR_FAIL_MSG(vformat(R"(Unable to convert array index %i from "%s" to "%s".)", i, Variant::get_type_name(type), Variant::get_type_name(typed.type)));
}
Expand Down Expand Up @@ -881,6 +880,30 @@ void Array::set_typed(uint32_t p_type, const StringName &p_class_name, const Var
_p->typed.where = "TypedArray";
}

void Array::set_struct(uint32_t p_size, const StringName &p_struct_name, const StructMember &(*p_get_member)(uint32_t)) {
if (validate_set_type() != OK) {
return;
}
_p->array.resize(p_size);
_p->typed.type = Variant::ARRAY;
_p->typed.where = "Struct"; // TODO: is this right?

_p->struct_name = p_struct_name;
_p->typed.class_name = p_struct_name;

_p->array.resize(p_size);
_p->member_count = p_size;
_p->member_names.resize(p_size);
_p->typed.struct_members.resize(p_size);

for (uint32_t i = 0; i < p_size; i++) {
StructMember member = p_get_member(i);
_p->typed.struct_members[i].type = member.type;
_p->typed.struct_members[i].class_name = member.class_name;
_p->member_names[i] = member.name;
}
}

bool Array::is_typed() const {
return _p->typed.type != Variant::NIL;
}
Expand Down Expand Up @@ -920,77 +943,38 @@ Array::Array(const Array &p_from) {
_ref(p_from);
}

Array::Array(const Array &p_from, uint32_t p_size, const StringName &p_name, const StructMember &(*p_get_member)(uint32_t)) {
Array::Array(const Array &p_from, const StringName &p_name, const StructMember &(*p_get_member)(uint32_t)) {
_p = memnew(ArrayPrivate);
_p->refcount.init(); // TODO: should this be _ref(p_from)?
if (validate_set_type() != OK) {
return;
}
assign(p_from);

_p->array.resize(p_size);
_p->typed.type = Variant::ARRAY;
_p->typed.where = "Struct"; // TODO: is this right?

_p->struct_name = p_name;
_p->typed.class_name = p_name;
_p->member_count = p_size;
_p->member_names.resize(p_size);
_p->typed.struct_members.resize(p_size);
for (uint32_t i = 0; i < p_size; i++) {
StructMember source_member = p_get_member(i);
ContainerTypeValidate *member_type = &_p->typed.struct_members[i];
_p->member_names[i] = source_member.name;
member_type->type = source_member.type;
member_type->class_name = source_member.class_name;
}
}

Array::Array(const Array &p_from, uint32_t p_size, const StringName &p_name, const Vector<StringName> &p_member_names) {
_p = memnew(ArrayPrivate);
_p->refcount.init();
if (validate_set_type() != OK) {
return;
}
set_struct(p_from.size(), p_name, p_get_member);
assign(p_from);

_p->array.resize(p_size);
_p->typed.where = "Struct"; // TODO: is this right?

_p->struct_name = p_name;
_p->typed.class_name = p_name;
_p->member_count = p_size;
_p->member_names.resize(p_size);
_p->typed.struct_members.resize(p_size);
for (uint32_t i = 0; i < p_size; i++) {
StructMember source_member = p_member_names[i];
ContainerTypeValidate *member_type = &_p->typed.struct_members[i];
_p->member_names[i] = source_member.name;
member_type->type = source_member.type;
member_type->class_name = source_member.class_name;
}
}

//Array::Array(const Array &p_from, const StringName &p_name, const Vector<StringName> &p_member_names) {
// _p = memnew(ArrayPrivate);
// _p->refcount.init();
// const uint32_t size = p_from.size();
//
// set_struct(size, p_name);
// for (uint32_t i = 0; i < size; i++) {
// StructMember member = p_get_member(i);
// _p->typed.set_struct_member(i, member.type, member.class_name);
// _p->member_names[i] = member.name;
// _p->array.write[i, member.default_value];
// }
//
// assign(p_from);
//}

Array::Array(uint32_t p_size, const StringName &p_name, const StructMember &(*p_get_member)(uint32_t)) {
_p = memnew(ArrayPrivate);
_p->refcount.init();
if (validate_set_type() != OK) {
return;
}
_p->array.resize(p_size);
_p->typed.where = "Struct"; // TODO: is this right?

_p->struct_name = p_name;
_p->typed.class_name = p_name;
_p->member_count = p_size;
_p->member_names.resize(p_size);
_p->typed.struct_members.resize(p_size);
set_struct(p_size, p_name, p_get_member);
Variant *pw = _p->array.ptrw();
for (uint32_t i = 0; i < p_size; i++) {
StructMember source_member = p_get_member(i);
ContainerTypeValidate *member_type = &_p->typed.struct_members[i];
_p->member_names[i] = source_member.name;
member_type->type = source_member.type;
member_type->class_name = source_member.class_name;
pw[i] = p_get_member(i).default_value;
}
}

Expand Down
4 changes: 2 additions & 2 deletions core/variant/array.h
Original file line number Diff line number Diff line change
Expand Up @@ -131,6 +131,7 @@ class Array {

Error validate_set_type();
void set_typed(uint32_t p_type, const StringName &p_class_name, const Variant &p_script);
void set_struct(uint32_t p_size, const StringName &p_class_name, const StructMember &(*p_get_member)(uint32_t));
bool is_typed() const;
bool is_struct() const;
bool is_same_typed(const Array &p_other) const;
Expand All @@ -143,8 +144,7 @@ class Array {

Array(const Array &p_base, uint32_t p_type, const StringName &p_class_name, const Variant &p_script);
Array(const Array &p_from);
Array(const Array &p_from, uint32_t p_size, const StringName &p_name, const StructMember &(*p_get_member)(uint32_t));
Array(const Array &p_from, uint32_t p_size, const StringName &p_name, const Vector<StringName> &p_member_names);
Array(const Array &p_from, const StringName &p_name, const StructMember &(*p_get_member)(uint32_t));
Array(uint32_t p_size, const StringName &p_name, const StructMember &(*p_get_member)(uint32_t));
Array();
~Array();
Expand Down
46 changes: 2 additions & 44 deletions core/variant/struct.h
Original file line number Diff line number Diff line change
Expand Up @@ -35,48 +35,6 @@

class Array;

//// TODO: Another different version
//#define STRUCT_LAYOUT(m_name, m_member_count, ...) \
// struct m_name { \
// static const uint32_t member_count = m_member_count; \
// _FORCE_INLINE_ static const StructMember *get_members() { \
// static const StructMember members[member_count] = { __VA_ARGS__ }; \
// return members; \
// } \
// _FORCE_INLINE_ static const StringName *get_member_names() { \
// const StructMember members[member_count] = get_members(); \
// StringName member_names[member_count]; \
// for (uint32_t i = 0; i < member_count; i++) { \
// member_names[i] = members[i].name; \
// } \
// return member_names; \
// } \
// _FORCE_INLINE_ static const uint32_t *get_member_types() { \
// const StructMember members[member_count] = get_members(); \
// uint32_t member_types[member_count]; \
// for (uint32_t i = 0; i < member_count; i++) { \
// member_types[i] = members[i].type; \
// } \
// return member_types; \
// } \
// _FORCE_INLINE_ static const StringName *get_member_class_names() { \
// const StructMember members[member_count] = get_members(); \
// StringName member_class_names[member_count]; \
// for (uint32_t i = 0; i < member_count; i++) { \
// member_class_names[i] = members[i].class_name; \
// } \
// return member_class_names; \
// } \
// _FORCE_INLINE_ static const Variant *get_member_default_values() { \
// const StructMember members[member_count] = get_members(); \
// Variant member_default_values[member_count]; \
// for (uint32_t i = 0; i < member_count; i++) { \
// member_default_values[i] = members[i].default_value; \
// } \
// return member_default_values; \
// } \
// };

template <class T>
class Struct : public Array {
public:
Expand All @@ -91,10 +49,10 @@ class Struct : public Array {
return get_named(p_member);
}
_FORCE_INLINE_ Struct(const Variant &p_variant) :
Array(Array(p_variant), T::get_member_count(), T::get_name(), T::get_member) {
Array(Array(p_variant), T::get_name(), T::get_member) {
}
_FORCE_INLINE_ Struct(const Array &p_array) :
Array(p_array, T::get_member_count(), T::get_name(), T::get_member) {
Array(p_array, T::get_name(), T::get_member) {
}
_FORCE_INLINE_ Struct() :
Array(T::get_member_count(), T::get_name(), T::get_member) {
Expand Down
Loading

0 comments on commit ddcc90e

Please sign in to comment.