Implement a BitField hint
Allows to specify the binder that an enum must be treated as a bitfield.
This commit is contained in:
parent
9de5698ee2
commit
5ac42cf576
|
@ -147,7 +147,7 @@ void ResourceLoader::_bind_methods() {
|
|||
|
||||
////// ResourceSaver //////
|
||||
|
||||
Error ResourceSaver::save(const String &p_path, const Ref<Resource> &p_resource, uint32_t p_flags) {
|
||||
Error ResourceSaver::save(const String &p_path, const Ref<Resource> &p_resource, BitField<SaverFlags> p_flags) {
|
||||
ERR_FAIL_COND_V_MSG(p_resource.is_null(), ERR_INVALID_PARAMETER, "Can't save empty resource to path '" + String(p_path) + "'.");
|
||||
return ::ResourceSaver::save(p_path, p_resource, p_flags);
|
||||
}
|
||||
|
@ -179,14 +179,14 @@ void ResourceSaver::_bind_methods() {
|
|||
ClassDB::bind_method(D_METHOD("add_resource_format_saver", "format_saver", "at_front"), &ResourceSaver::add_resource_format_saver, DEFVAL(false));
|
||||
ClassDB::bind_method(D_METHOD("remove_resource_format_saver", "format_saver"), &ResourceSaver::remove_resource_format_saver);
|
||||
|
||||
BIND_ENUM_CONSTANT(FLAG_NONE);
|
||||
BIND_ENUM_CONSTANT(FLAG_RELATIVE_PATHS);
|
||||
BIND_ENUM_CONSTANT(FLAG_BUNDLE_RESOURCES);
|
||||
BIND_ENUM_CONSTANT(FLAG_CHANGE_PATH);
|
||||
BIND_ENUM_CONSTANT(FLAG_OMIT_EDITOR_PROPERTIES);
|
||||
BIND_ENUM_CONSTANT(FLAG_SAVE_BIG_ENDIAN);
|
||||
BIND_ENUM_CONSTANT(FLAG_COMPRESS);
|
||||
BIND_ENUM_CONSTANT(FLAG_REPLACE_SUBRESOURCE_PATHS);
|
||||
BIND_BITFIELD_FLAG(FLAG_NONE);
|
||||
BIND_BITFIELD_FLAG(FLAG_RELATIVE_PATHS);
|
||||
BIND_BITFIELD_FLAG(FLAG_BUNDLE_RESOURCES);
|
||||
BIND_BITFIELD_FLAG(FLAG_CHANGE_PATH);
|
||||
BIND_BITFIELD_FLAG(FLAG_OMIT_EDITOR_PROPERTIES);
|
||||
BIND_BITFIELD_FLAG(FLAG_SAVE_BIG_ENDIAN);
|
||||
BIND_BITFIELD_FLAG(FLAG_COMPRESS);
|
||||
BIND_BITFIELD_FLAG(FLAG_REPLACE_SUBRESOURCE_PATHS);
|
||||
}
|
||||
|
||||
////// OS //////
|
||||
|
|
|
@ -109,7 +109,7 @@ public:
|
|||
|
||||
static ResourceSaver *get_singleton() { return singleton; }
|
||||
|
||||
Error save(const String &p_path, const Ref<Resource> &p_resource, uint32_t p_flags);
|
||||
Error save(const String &p_path, const Ref<Resource> &p_resource, BitField<SaverFlags> p_flags);
|
||||
Vector<String> get_recognized_extensions(const Ref<Resource> &p_resource);
|
||||
void add_resource_format_saver(Ref<ResourceFormatSaver> p_format_saver, bool p_at_front);
|
||||
void remove_resource_format_saver(Ref<ResourceFormatSaver> p_format_saver);
|
||||
|
@ -719,7 +719,7 @@ public:
|
|||
VARIANT_ENUM_CAST(core_bind::ResourceLoader::ThreadLoadStatus);
|
||||
VARIANT_ENUM_CAST(core_bind::ResourceLoader::CacheMode);
|
||||
|
||||
VARIANT_ENUM_CAST(core_bind::ResourceSaver::SaverFlags);
|
||||
VARIANT_BITFIELD_CAST(core_bind::ResourceSaver::SaverFlags);
|
||||
|
||||
VARIANT_ENUM_CAST(core_bind::OS::VideoDriver);
|
||||
VARIANT_ENUM_CAST(core_bind::OS::Weekday);
|
||||
|
|
|
@ -38,7 +38,7 @@ void DocData::return_doc_from_retinfo(DocData::MethodDoc &p_method, const Proper
|
|||
} else {
|
||||
p_method.return_type += "*";
|
||||
}
|
||||
} else if (p_retinfo.type == Variant::INT && p_retinfo.usage & PROPERTY_USAGE_CLASS_IS_ENUM) {
|
||||
} else if (p_retinfo.type == Variant::INT && p_retinfo.usage & (PROPERTY_USAGE_CLASS_IS_ENUM | PROPERTY_USAGE_CLASS_IS_BITFIELD)) {
|
||||
p_method.return_enum = p_retinfo.class_name;
|
||||
if (p_method.return_enum.begins_with("_")) { //proxy class
|
||||
p_method.return_enum = p_method.return_enum.substr(1, p_method.return_enum.length());
|
||||
|
@ -69,7 +69,7 @@ void DocData::argument_doc_from_arginfo(DocData::ArgumentDoc &p_argument, const
|
|||
} else {
|
||||
p_argument.type += "*";
|
||||
}
|
||||
} else if (p_arginfo.type == Variant::INT && p_arginfo.usage & PROPERTY_USAGE_CLASS_IS_ENUM) {
|
||||
} else if (p_arginfo.type == Variant::INT && p_arginfo.usage & (PROPERTY_USAGE_CLASS_IS_ENUM | PROPERTY_USAGE_CLASS_IS_BITFIELD)) {
|
||||
p_argument.enumeration = p_arginfo.class_name;
|
||||
if (p_argument.enumeration.begins_with("_")) { //proxy class
|
||||
p_argument.enumeration = p_argument.enumeration.substr(1, p_argument.enumeration.length());
|
||||
|
|
|
@ -103,6 +103,7 @@ public:
|
|||
String value;
|
||||
bool is_value_valid = false;
|
||||
String enumeration;
|
||||
bool is_bitfield = false;
|
||||
String description;
|
||||
bool operator<(const ConstantDoc &p_const) const {
|
||||
return name < p_const.name;
|
||||
|
@ -111,6 +112,7 @@ public:
|
|||
|
||||
struct EnumDoc {
|
||||
String name = "@unnamed_enum";
|
||||
bool is_bitfield = false;
|
||||
String description;
|
||||
Vector<DocData::ConstantDoc> values;
|
||||
};
|
||||
|
|
|
@ -46,7 +46,7 @@ static String get_type_name(const PropertyInfo &p_info) {
|
|||
return p_info.hint_string + "*";
|
||||
}
|
||||
}
|
||||
if (p_info.type == Variant::INT && (p_info.usage & PROPERTY_USAGE_CLASS_IS_ENUM)) {
|
||||
if (p_info.type == Variant::INT && (p_info.usage & (PROPERTY_USAGE_CLASS_IS_ENUM | PROPERTY_USAGE_CLASS_IS_BITFIELD))) {
|
||||
return String("enum::") + String(p_info.class_name);
|
||||
}
|
||||
if (p_info.class_name != StringName()) {
|
||||
|
@ -665,6 +665,7 @@ Dictionary NativeExtensionAPIDump::generate_extension_api() {
|
|||
for (const StringName &F : enum_list) {
|
||||
Dictionary d2;
|
||||
d2["name"] = String(F);
|
||||
d2["is_bitfield"] = ClassDB::is_enum_bitfield(class_name, F);
|
||||
|
||||
Array values;
|
||||
List<StringName> enum_constant_list;
|
||||
|
|
|
@ -536,7 +536,7 @@ MethodBind *ClassDB::get_method(const StringName &p_class, const StringName &p_n
|
|||
return nullptr;
|
||||
}
|
||||
|
||||
void ClassDB::bind_integer_constant(const StringName &p_class, const StringName &p_enum, const StringName &p_name, int64_t p_constant) {
|
||||
void ClassDB::bind_integer_constant(const StringName &p_class, const StringName &p_enum, const StringName &p_name, int64_t p_constant, bool p_is_bitfield) {
|
||||
OBJTYPE_WLOCK;
|
||||
|
||||
ClassInfo *type = classes.getptr(p_class);
|
||||
|
@ -555,13 +555,15 @@ void ClassDB::bind_integer_constant(const StringName &p_class, const StringName
|
|||
enum_name = enum_name.get_slicec('.', 1);
|
||||
}
|
||||
|
||||
List<StringName> *constants_list = type->enum_map.getptr(enum_name);
|
||||
ClassInfo::EnumInfo *constants_list = type->enum_map.getptr(enum_name);
|
||||
|
||||
if (constants_list) {
|
||||
constants_list->push_back(p_name);
|
||||
constants_list->constants.push_back(p_name);
|
||||
constants_list->is_bitfield = p_is_bitfield;
|
||||
} else {
|
||||
List<StringName> new_list;
|
||||
new_list.push_back(p_name);
|
||||
ClassInfo::EnumInfo new_list;
|
||||
new_list.is_bitfield = p_is_bitfield;
|
||||
new_list.constants.push_back(p_name);
|
||||
type->enum_map[enum_name] = new_list;
|
||||
}
|
||||
}
|
||||
|
@ -645,8 +647,8 @@ StringName ClassDB::get_integer_constant_enum(const StringName &p_class, const S
|
|||
ClassInfo *type = classes.getptr(p_class);
|
||||
|
||||
while (type) {
|
||||
for (KeyValue<StringName, List<StringName>> &E : type->enum_map) {
|
||||
List<StringName> &constants_list = E.value;
|
||||
for (KeyValue<StringName, ClassInfo::EnumInfo> &E : type->enum_map) {
|
||||
List<StringName> &constants_list = E.value.constants;
|
||||
const List<StringName>::Element *found = constants_list.find(p_name);
|
||||
if (found) {
|
||||
return E.key;
|
||||
|
@ -669,7 +671,7 @@ void ClassDB::get_enum_list(const StringName &p_class, List<StringName> *p_enums
|
|||
ClassInfo *type = classes.getptr(p_class);
|
||||
|
||||
while (type) {
|
||||
for (KeyValue<StringName, List<StringName>> &E : type->enum_map) {
|
||||
for (KeyValue<StringName, ClassInfo::EnumInfo> &E : type->enum_map) {
|
||||
p_enums->push_back(E.key);
|
||||
}
|
||||
|
||||
|
@ -687,10 +689,10 @@ void ClassDB::get_enum_constants(const StringName &p_class, const StringName &p_
|
|||
ClassInfo *type = classes.getptr(p_class);
|
||||
|
||||
while (type) {
|
||||
const List<StringName> *constants = type->enum_map.getptr(p_enum);
|
||||
const ClassInfo::EnumInfo *constants = type->enum_map.getptr(p_enum);
|
||||
|
||||
if (constants) {
|
||||
for (const List<StringName>::Element *E = constants->front(); E; E = E->next()) {
|
||||
for (const List<StringName>::Element *E = constants->constants.front(); E; E = E->next()) {
|
||||
p_constants->push_back(E->get());
|
||||
}
|
||||
}
|
||||
|
@ -748,6 +750,25 @@ bool ClassDB::has_enum(const StringName &p_class, const StringName &p_name, bool
|
|||
return false;
|
||||
}
|
||||
|
||||
bool ClassDB::is_enum_bitfield(const StringName &p_class, const StringName &p_name, bool p_no_inheritance) {
|
||||
OBJTYPE_RLOCK;
|
||||
|
||||
ClassInfo *type = classes.getptr(p_class);
|
||||
|
||||
while (type) {
|
||||
if (type->enum_map.has(p_name) && type->enum_map[p_name].is_bitfield) {
|
||||
return true;
|
||||
}
|
||||
if (p_no_inheritance) {
|
||||
return false;
|
||||
}
|
||||
|
||||
type = type->inherits_ptr;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
void ClassDB::add_signal(const StringName &p_class, const MethodInfo &p_signal) {
|
||||
OBJTYPE_WLOCK;
|
||||
|
||||
|
|
|
@ -104,7 +104,12 @@ public:
|
|||
|
||||
HashMap<StringName, MethodBind *> method_map;
|
||||
HashMap<StringName, int64_t> constant_map;
|
||||
HashMap<StringName, List<StringName>> enum_map;
|
||||
struct EnumInfo {
|
||||
List<StringName> constants;
|
||||
bool is_bitfield = false;
|
||||
};
|
||||
|
||||
HashMap<StringName, EnumInfo> enum_map;
|
||||
HashMap<StringName, MethodInfo> signal_map;
|
||||
List<PropertyInfo> property_list;
|
||||
HashMap<StringName, PropertyInfo> property_map;
|
||||
|
@ -325,15 +330,17 @@ public:
|
|||
static void add_virtual_method(const StringName &p_class, const MethodInfo &p_method, bool p_virtual = true, const Vector<String> &p_arg_names = Vector<String>(), bool p_object_core = false);
|
||||
static void get_virtual_methods(const StringName &p_class, List<MethodInfo> *p_methods, bool p_no_inheritance = false);
|
||||
|
||||
static void bind_integer_constant(const StringName &p_class, const StringName &p_enum, const StringName &p_name, int64_t p_constant);
|
||||
static void bind_integer_constant(const StringName &p_class, const StringName &p_enum, const StringName &p_name, int64_t p_constant, bool p_is_bitfield = false);
|
||||
static void get_integer_constant_list(const StringName &p_class, List<String> *p_constants, bool p_no_inheritance = false);
|
||||
static int64_t get_integer_constant(const StringName &p_class, const StringName &p_name, bool *p_success = nullptr);
|
||||
static bool has_integer_constant(const StringName &p_class, const StringName &p_name, bool p_no_inheritance = false);
|
||||
|
||||
static StringName get_integer_constant_enum(const StringName &p_class, const StringName &p_name, bool p_no_inheritance = false);
|
||||
static StringName get_integer_constant_bitfield(const StringName &p_class, const StringName &p_name, bool p_no_inheritance = false);
|
||||
static void get_enum_list(const StringName &p_class, List<StringName> *p_enums, bool p_no_inheritance = false);
|
||||
static void get_enum_constants(const StringName &p_class, const StringName &p_enum, List<StringName> *p_constants, bool p_no_inheritance = false);
|
||||
static bool has_enum(const StringName &p_class, const StringName &p_name, bool p_no_inheritance = false);
|
||||
static bool is_enum_bitfield(const StringName &p_class, const StringName &p_name, bool p_no_inheritance = false);
|
||||
|
||||
static void set_method_error_return_values(const StringName &p_class, const StringName &p_method, const Vector<Error> &p_values);
|
||||
static Vector<Error> get_method_error_return_values(const StringName &p_class, const StringName &p_method);
|
||||
|
@ -370,6 +377,9 @@ public:
|
|||
#define BIND_ENUM_CONSTANT(m_constant) \
|
||||
::ClassDB::bind_integer_constant(get_class_static(), __constant_get_enum_name(m_constant, #m_constant), #m_constant, m_constant);
|
||||
|
||||
#define BIND_BITFIELD_FLAG(m_constant) \
|
||||
::ClassDB::bind_integer_constant(get_class_static(), __constant_get_bitfield_name(m_constant, #m_constant), #m_constant, m_constant, true);
|
||||
|
||||
_FORCE_INLINE_ void errarray_add_str(Vector<Error> &arr) {
|
||||
}
|
||||
|
||||
|
@ -401,6 +411,9 @@ _FORCE_INLINE_ Vector<Error> errarray(P... p_args) {
|
|||
#define BIND_ENUM_CONSTANT(m_constant) \
|
||||
::ClassDB::bind_integer_constant(get_class_static(), StringName(), #m_constant, m_constant);
|
||||
|
||||
#define BIND_BITFIELD_FLAG(m_constant) \
|
||||
::ClassDB::bind_integer_constant(get_class_static(), StringName(), #m_constant, m_constant, true);
|
||||
|
||||
#define BIND_METHOD_ERR_RETURN_DOC(m_method, ...)
|
||||
|
||||
#endif
|
||||
|
|
|
@ -109,6 +109,7 @@ enum PropertyUsageFlags {
|
|||
PROPERTY_USAGE_GROUP = 128, //used for grouping props in the editor
|
||||
PROPERTY_USAGE_CATEGORY = 256,
|
||||
PROPERTY_USAGE_SUBGROUP = 512,
|
||||
PROPERTY_USAGE_CLASS_IS_BITFIELD = 1024,
|
||||
PROPERTY_USAGE_NO_INSTANCE_STATE = 2048,
|
||||
PROPERTY_USAGE_RESTART_IF_CHANGED = 4096,
|
||||
PROPERTY_USAGE_SCRIPT_VARIABLE = 8192,
|
||||
|
|
|
@ -106,6 +106,29 @@ struct VariantCaster<const T &> {
|
|||
static void initialize(m_enum &value) { value = (m_enum)0; } \
|
||||
};
|
||||
|
||||
#define VARIANT_BITFIELD_CAST(m_enum) \
|
||||
MAKE_BITFIELD_TYPE_INFO(m_enum) \
|
||||
template <> \
|
||||
struct VariantCaster<BitField<m_enum>> { \
|
||||
static _FORCE_INLINE_ BitField<m_enum> cast(const Variant &p_variant) { \
|
||||
return BitField<m_enum>(p_variant.operator int64_t()); \
|
||||
} \
|
||||
}; \
|
||||
template <> \
|
||||
struct PtrToArg<BitField<m_enum>> { \
|
||||
_FORCE_INLINE_ static BitField<m_enum> convert(const void *p_ptr) { \
|
||||
return BitField<m_enum>(*reinterpret_cast<const int64_t *>(p_ptr)); \
|
||||
} \
|
||||
typedef int64_t EncodeT; \
|
||||
_FORCE_INLINE_ static void encode(BitField<m_enum> p_val, const void *p_ptr) { \
|
||||
*(int64_t *)p_ptr = p_val; \
|
||||
} \
|
||||
}; \
|
||||
template <> \
|
||||
struct ZeroInitializer<BitField<m_enum>> { \
|
||||
static void initialize(BitField<m_enum> &value) { value = 0; } \
|
||||
};
|
||||
|
||||
// Object enum casts must go here
|
||||
VARIANT_ENUM_CAST(Object::ConnectFlags);
|
||||
|
||||
|
|
|
@ -279,6 +279,51 @@ inline StringName __constant_get_enum_name(T param, const String &p_constant) {
|
|||
return GetTypeInfo<T>::get_class_info().class_name;
|
||||
}
|
||||
|
||||
template <class T>
|
||||
class BitField {
|
||||
uint32_t value = 0;
|
||||
|
||||
public:
|
||||
_FORCE_INLINE_ void set_flag(T p_flag) { value |= p_flag; }
|
||||
_FORCE_INLINE_ bool has_flag(T p_flag) const { return value & p_flag; }
|
||||
_FORCE_INLINE_ void clear_flag(T p_flag) { return value &= ~p_flag; }
|
||||
_FORCE_INLINE_ BitField(uint32_t p_value) { value = p_value; }
|
||||
_FORCE_INLINE_ operator uint32_t() const { return value; }
|
||||
};
|
||||
|
||||
#define TEMPL_MAKE_BITFIELD_TYPE_INFO(m_enum, m_impl) \
|
||||
template <> \
|
||||
struct GetTypeInfo<m_impl> { \
|
||||
static const Variant::Type VARIANT_TYPE = Variant::INT; \
|
||||
static const GodotTypeInfo::Metadata METADATA = GodotTypeInfo::METADATA_NONE; \
|
||||
static inline PropertyInfo get_class_info() { \
|
||||
return PropertyInfo(Variant::INT, String(), PROPERTY_HINT_NONE, String(), PROPERTY_USAGE_DEFAULT | PROPERTY_USAGE_CLASS_IS_BITFIELD, \
|
||||
godot::details::enum_qualified_name_to_class_info_name(String(#m_enum))); \
|
||||
} \
|
||||
}; \
|
||||
template <> \
|
||||
struct GetTypeInfo<BitField<m_impl>> { \
|
||||
static const Variant::Type VARIANT_TYPE = Variant::INT; \
|
||||
static const GodotTypeInfo::Metadata METADATA = GodotTypeInfo::METADATA_NONE; \
|
||||
static inline PropertyInfo get_class_info() { \
|
||||
return PropertyInfo(Variant::INT, String(), PROPERTY_HINT_NONE, String(), PROPERTY_USAGE_DEFAULT | PROPERTY_USAGE_CLASS_IS_BITFIELD, \
|
||||
godot::details::enum_qualified_name_to_class_info_name(String(#m_enum))); \
|
||||
} \
|
||||
};
|
||||
|
||||
#define MAKE_BITFIELD_TYPE_INFO(m_enum) \
|
||||
TEMPL_MAKE_BITFIELD_TYPE_INFO(m_enum, m_enum) \
|
||||
TEMPL_MAKE_BITFIELD_TYPE_INFO(m_enum, m_enum const) \
|
||||
TEMPL_MAKE_BITFIELD_TYPE_INFO(m_enum, m_enum &) \
|
||||
TEMPL_MAKE_BITFIELD_TYPE_INFO(m_enum, const m_enum &)
|
||||
|
||||
template <typename T>
|
||||
inline StringName __constant_get_bitfield_name(T param, const String &p_constant) {
|
||||
if (GetTypeInfo<T>::VARIANT_TYPE == Variant::NIL) {
|
||||
ERR_PRINT("Missing VARIANT_ENUM_CAST for constant's bitfield: " + p_constant);
|
||||
}
|
||||
return GetTypeInfo<BitField<T>>::get_class_info().class_name;
|
||||
}
|
||||
#define CLASS_INFO(m_type) (GetTypeInfo<m_type *>::get_class_info())
|
||||
|
||||
template <typename T>
|
||||
|
|
|
@ -155,6 +155,7 @@
|
|||
<xs:attribute type="xs:string" name="name" />
|
||||
<xs:attribute type="xs:string" name="value" />
|
||||
<xs:attribute type="xs:string" name="enum" use="optional" />
|
||||
<xs:attribute type="xs:boolean" name="is_bitfield" use="optional" />
|
||||
</xs:extension>
|
||||
</xs:simpleContent>
|
||||
</xs:complexType>
|
||||
|
|
|
@ -37,7 +37,7 @@
|
|||
<return type="int" enum="Error" />
|
||||
<argument index="0" name="path" type="String" />
|
||||
<argument index="1" name="resource" type="Resource" />
|
||||
<argument index="2" name="flags" type="int" default="0" />
|
||||
<argument index="2" name="flags" type="int" enum="ResourceSaver.SaverFlags" default="0" />
|
||||
<description>
|
||||
Saves a resource to disk to the given path, using a [ResourceFormatSaver] that recognizes the resource object.
|
||||
The [code]flags[/code] bitmask can be specified to customize the save behavior using [enum SaverFlags] flags.
|
||||
|
@ -46,28 +46,28 @@
|
|||
</method>
|
||||
</methods>
|
||||
<constants>
|
||||
<constant name="FLAG_NONE" value="0" enum="SaverFlags">
|
||||
<constant name="FLAG_NONE" value="0" enum="SaverFlags" is_bitfield="true">
|
||||
No resource saving option.
|
||||
</constant>
|
||||
<constant name="FLAG_RELATIVE_PATHS" value="1" enum="SaverFlags">
|
||||
<constant name="FLAG_RELATIVE_PATHS" value="1" enum="SaverFlags" is_bitfield="true">
|
||||
Save the resource with a path relative to the scene which uses it.
|
||||
</constant>
|
||||
<constant name="FLAG_BUNDLE_RESOURCES" value="2" enum="SaverFlags">
|
||||
<constant name="FLAG_BUNDLE_RESOURCES" value="2" enum="SaverFlags" is_bitfield="true">
|
||||
Bundles external resources.
|
||||
</constant>
|
||||
<constant name="FLAG_CHANGE_PATH" value="4" enum="SaverFlags">
|
||||
<constant name="FLAG_CHANGE_PATH" value="4" enum="SaverFlags" is_bitfield="true">
|
||||
Changes the [member Resource.resource_path] of the saved resource to match its new location.
|
||||
</constant>
|
||||
<constant name="FLAG_OMIT_EDITOR_PROPERTIES" value="8" enum="SaverFlags">
|
||||
<constant name="FLAG_OMIT_EDITOR_PROPERTIES" value="8" enum="SaverFlags" is_bitfield="true">
|
||||
Do not save editor-specific metadata (identified by their [code]__editor[/code] prefix).
|
||||
</constant>
|
||||
<constant name="FLAG_SAVE_BIG_ENDIAN" value="16" enum="SaverFlags">
|
||||
<constant name="FLAG_SAVE_BIG_ENDIAN" value="16" enum="SaverFlags" is_bitfield="true">
|
||||
Save as big endian (see [member File.big_endian]).
|
||||
</constant>
|
||||
<constant name="FLAG_COMPRESS" value="32" enum="SaverFlags">
|
||||
<constant name="FLAG_COMPRESS" value="32" enum="SaverFlags" is_bitfield="true">
|
||||
Compress the resource on save using [constant File.COMPRESSION_ZSTD]. Only available for binary resource types.
|
||||
</constant>
|
||||
<constant name="FLAG_REPLACE_SUBRESOURCE_PATHS" value="64" enum="SaverFlags">
|
||||
<constant name="FLAG_REPLACE_SUBRESOURCE_PATHS" value="64" enum="SaverFlags" is_bitfield="true">
|
||||
Take over the paths of the saved subresources (see [method Resource.take_over_path]).
|
||||
</constant>
|
||||
</constants>
|
||||
|
|
|
@ -122,16 +122,18 @@ class MethodDef:
|
|||
|
||||
|
||||
class ConstantDef:
|
||||
def __init__(self, name, value, text): # type: (str, str, Optional[str]) -> None
|
||||
def __init__(self, name, value, text, bitfield): # type: (str, str, Optional[str], Optional[bool]) -> None
|
||||
self.name = name
|
||||
self.value = value
|
||||
self.text = text
|
||||
self.is_bitfield = bitfield
|
||||
|
||||
|
||||
class EnumDef:
|
||||
def __init__(self, name): # type: (str) -> None
|
||||
def __init__(self, name, bitfield): # type: (str, Optional[bool]) -> None
|
||||
self.name = name
|
||||
self.values = OrderedDict() # type: OrderedDict[str, ConstantDef]
|
||||
self.is_bitfield = bitfield
|
||||
|
||||
|
||||
class ThemeItemDef:
|
||||
|
@ -305,7 +307,8 @@ class State:
|
|||
constant_name = constant.attrib["name"]
|
||||
value = constant.attrib["value"]
|
||||
enum = constant.get("enum")
|
||||
constant_def = ConstantDef(constant_name, value, constant.text)
|
||||
is_bitfield = constant.get("is_bitfield") or False
|
||||
constant_def = ConstantDef(constant_name, value, constant.text, is_bitfield)
|
||||
if enum is None:
|
||||
if constant_name in class_def.constants:
|
||||
print_error('{}.xml: Duplicate constant "{}".'.format(class_name, constant_name), self)
|
||||
|
@ -318,7 +321,7 @@ class State:
|
|||
enum_def = class_def.enums[enum]
|
||||
|
||||
else:
|
||||
enum_def = EnumDef(enum)
|
||||
enum_def = EnumDef(enum, is_bitfield)
|
||||
class_def.enums[enum] = enum_def
|
||||
|
||||
enum_def.values[constant_name] = constant_def
|
||||
|
@ -706,7 +709,11 @@ def make_rst_class(class_def, state, dry_run, output_dir): # type: (ClassDef, S
|
|||
for value in e.values.values():
|
||||
f.write(".. _class_{}_constant_{}:\n\n".format(class_name, value.name))
|
||||
|
||||
f.write("enum **{}**:\n\n".format(e.name))
|
||||
if e.is_bitfield:
|
||||
f.write("flags **{}**:\n\n".format(e.name))
|
||||
else:
|
||||
f.write("enum **{}**:\n\n".format(e.name))
|
||||
|
||||
for value in e.values.values():
|
||||
f.write("- **{}** = **{}**".format(value.name, value.value))
|
||||
if value.text is not None and value.text.strip() != "":
|
||||
|
|
|
@ -429,7 +429,7 @@ void DocTools::generate(bool p_basic_types) {
|
|||
PropertyInfo retinfo = mb->get_return_info();
|
||||
|
||||
found_type = true;
|
||||
if (retinfo.type == Variant::INT && retinfo.usage & PROPERTY_USAGE_CLASS_IS_ENUM) {
|
||||
if (retinfo.type == Variant::INT && retinfo.usage & (PROPERTY_USAGE_CLASS_IS_ENUM | PROPERTY_USAGE_CLASS_IS_BITFIELD)) {
|
||||
prop.enumeration = retinfo.class_name;
|
||||
prop.type = "int";
|
||||
} else if (retinfo.class_name != StringName()) {
|
||||
|
@ -575,6 +575,7 @@ void DocTools::generate(bool p_basic_types) {
|
|||
constant.value = itos(ClassDB::get_integer_constant(name, E));
|
||||
constant.is_value_valid = true;
|
||||
constant.enumeration = ClassDB::get_integer_constant_enum(name, E);
|
||||
constant.is_bitfield = ClassDB::is_enum_bitfield(name, constant.enumeration);
|
||||
c.constants.push_back(constant);
|
||||
}
|
||||
|
||||
|
@ -1244,6 +1245,9 @@ Error DocTools::_load(Ref<XMLParser> parser) {
|
|||
if (parser->has_attribute("enum")) {
|
||||
constant2.enumeration = parser->get_attribute_value("enum");
|
||||
}
|
||||
if (parser->has_attribute("is_bitfield")) {
|
||||
constant2.is_bitfield = parser->get_attribute_value("is_bitfield").to_lower() == "true";
|
||||
}
|
||||
if (!parser->is_empty()) {
|
||||
parser->read();
|
||||
if (parser->get_node_type() == XMLParser::NODE_TEXT) {
|
||||
|
@ -1424,7 +1428,11 @@ Error DocTools::save_classes(const String &p_default_path, const HashMap<String,
|
|||
const DocData::ConstantDoc &k = c.constants[i];
|
||||
if (k.is_value_valid) {
|
||||
if (!k.enumeration.is_empty()) {
|
||||
_write_string(f, 2, "<constant name=\"" + k.name + "\" value=\"" + k.value + "\" enum=\"" + k.enumeration + "\">");
|
||||
if (k.is_bitfield) {
|
||||
_write_string(f, 2, "<constant name=\"" + k.name + "\" value=\"" + k.value + "\" enum=\"" + k.enumeration + "\" is_bitfield=\"true\">");
|
||||
} else {
|
||||
_write_string(f, 2, "<constant name=\"" + k.name + "\" value=\"" + k.value + "\" enum=\"" + k.enumeration + "\">");
|
||||
}
|
||||
} else {
|
||||
_write_string(f, 2, "<constant name=\"" + k.name + "\" value=\"" + k.value + "\">");
|
||||
}
|
||||
|
|
|
@ -1105,7 +1105,11 @@ void EditorHelp::_update_doc() {
|
|||
|
||||
class_desc->push_font(doc_code_font);
|
||||
class_desc->push_color(title_color);
|
||||
class_desc->add_text("enum ");
|
||||
if (E.value.size() && E.value[0].is_bitfield) {
|
||||
class_desc->add_text("flags ");
|
||||
} else {
|
||||
class_desc->add_text("enum ");
|
||||
}
|
||||
class_desc->pop();
|
||||
String e = E.key;
|
||||
if ((e.get_slice_count(".") > 1) && (e.get_slice(".", 0) == edited_class)) {
|
||||
|
|
|
@ -569,7 +569,7 @@ static int _get_enum_constant_location(StringName p_class, StringName p_enum_con
|
|||
// END LOCATION METHODS
|
||||
|
||||
static String _get_visual_datatype(const PropertyInfo &p_info, bool p_is_arg = true) {
|
||||
if (p_info.usage & PROPERTY_USAGE_CLASS_IS_ENUM) {
|
||||
if (p_info.usage & (PROPERTY_USAGE_CLASS_IS_ENUM | PROPERTY_USAGE_CLASS_IS_BITFIELD)) {
|
||||
String enum_name = p_info.class_name;
|
||||
if (!enum_name.contains(".")) {
|
||||
return enum_name;
|
||||
|
@ -1292,7 +1292,7 @@ static GDScriptCompletionIdentifier _type_from_property(const PropertyInfo &p_pr
|
|||
return ci;
|
||||
}
|
||||
|
||||
if (p_property.usage & PROPERTY_USAGE_CLASS_IS_ENUM) {
|
||||
if (p_property.usage & (PROPERTY_USAGE_CLASS_IS_ENUM | PROPERTY_USAGE_CLASS_IS_BITFIELD)) {
|
||||
ci.enumeration = p_property.class_name;
|
||||
}
|
||||
|
||||
|
@ -2407,7 +2407,7 @@ static void _find_call_arguments(GDScriptParser::CompletionContext &p_context, c
|
|||
|
||||
if (p_argidx < method_args) {
|
||||
PropertyInfo arg_info = info.arguments[p_argidx];
|
||||
if (arg_info.usage & PROPERTY_USAGE_CLASS_IS_ENUM) {
|
||||
if (arg_info.usage & (PROPERTY_USAGE_CLASS_IS_ENUM | PROPERTY_USAGE_CLASS_IS_BITFIELD)) {
|
||||
_find_enumeration_candidates(p_context, arg_info.class_name, r_result);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -2865,7 +2865,7 @@ bool BindingsGenerator::_populate_object_type_interfaces() {
|
|||
" We only expected Object.free, but found '" +
|
||||
itype.name + "." + imethod.name + "'.");
|
||||
}
|
||||
} else if (return_info.type == Variant::INT && return_info.usage & PROPERTY_USAGE_CLASS_IS_ENUM) {
|
||||
} else if (return_info.type == Variant::INT && return_info.usage & (PROPERTY_USAGE_CLASS_IS_ENUM | PROPERTY_USAGE_CLASS_IS_BITFIELD)) {
|
||||
imethod.return_type.cname = return_info.class_name;
|
||||
imethod.return_type.is_enum = true;
|
||||
} else if (return_info.class_name != StringName()) {
|
||||
|
@ -2903,7 +2903,7 @@ bool BindingsGenerator::_populate_object_type_interfaces() {
|
|||
ArgumentInterface iarg;
|
||||
iarg.name = orig_arg_name;
|
||||
|
||||
if (arginfo.type == Variant::INT && arginfo.usage & PROPERTY_USAGE_CLASS_IS_ENUM) {
|
||||
if (arginfo.type == Variant::INT && arginfo.usage & (PROPERTY_USAGE_CLASS_IS_ENUM | PROPERTY_USAGE_CLASS_IS_BITFIELD)) {
|
||||
iarg.type.cname = arginfo.class_name;
|
||||
iarg.type.is_enum = true;
|
||||
} else if (arginfo.class_name != StringName()) {
|
||||
|
@ -3011,7 +3011,7 @@ bool BindingsGenerator::_populate_object_type_interfaces() {
|
|||
ArgumentInterface iarg;
|
||||
iarg.name = orig_arg_name;
|
||||
|
||||
if (arginfo.type == Variant::INT && arginfo.usage & PROPERTY_USAGE_CLASS_IS_ENUM) {
|
||||
if (arginfo.type == Variant::INT && arginfo.usage & (PROPERTY_USAGE_CLASS_IS_ENUM | PROPERTY_USAGE_CLASS_IS_BITFIELD)) {
|
||||
iarg.type.cname = arginfo.class_name;
|
||||
iarg.type.is_enum = true;
|
||||
} else if (arginfo.class_name != StringName()) {
|
||||
|
@ -3075,9 +3075,9 @@ bool BindingsGenerator::_populate_object_type_interfaces() {
|
|||
List<String> constants;
|
||||
ClassDB::get_integer_constant_list(type_cname, &constants, true);
|
||||
|
||||
const HashMap<StringName, List<StringName>> &enum_map = class_info->enum_map;
|
||||
const HashMap<StringName, ClassDB::ClassInfo::EnumInfo> &enum_map = class_info->enum_map;
|
||||
|
||||
for (const KeyValue<StringName, List<StringName>> &E : enum_map) {
|
||||
for (const KeyValue<StringName, ClassDB::ClassInfo::EnumInfo> &E : enum_map) {
|
||||
StringName enum_proxy_cname = E.key;
|
||||
String enum_proxy_name = enum_proxy_cname.operator String();
|
||||
if (itype.find_property_by_proxy_name(enum_proxy_cname)) {
|
||||
|
@ -3087,7 +3087,7 @@ bool BindingsGenerator::_populate_object_type_interfaces() {
|
|||
enum_proxy_cname = StringName(enum_proxy_name);
|
||||
}
|
||||
EnumInterface ienum(enum_proxy_cname);
|
||||
const List<StringName> &enum_constants = E.value;
|
||||
const List<StringName> &enum_constants = E.value.constants;
|
||||
for (const StringName &constant_cname : enum_constants) {
|
||||
String constant_name = constant_cname.operator String();
|
||||
int64_t *value = class_info->constant_map.getptr(constant_cname);
|
||||
|
|
|
@ -597,7 +597,7 @@ void add_exposed_classes(Context &r_context) {
|
|||
(exposed_class.name != r_context.names_cache.object_class || String(method.name) != "free"),
|
||||
warn_msg.utf8().get_data());
|
||||
|
||||
} else if (return_info.type == Variant::INT && return_info.usage & PROPERTY_USAGE_CLASS_IS_ENUM) {
|
||||
} else if (return_info.type == Variant::INT && return_info.usage & (PROPERTY_USAGE_CLASS_IS_ENUM | PROPERTY_USAGE_CLASS_IS_BITFIELD)) {
|
||||
method.return_type.name = return_info.class_name;
|
||||
method.return_type.is_enum = true;
|
||||
} else if (return_info.class_name != StringName()) {
|
||||
|
@ -626,7 +626,7 @@ void add_exposed_classes(Context &r_context) {
|
|||
ArgumentData arg;
|
||||
arg.name = orig_arg_name;
|
||||
|
||||
if (arg_info.type == Variant::INT && arg_info.usage & PROPERTY_USAGE_CLASS_IS_ENUM) {
|
||||
if (arg_info.type == Variant::INT && arg_info.usage & (PROPERTY_USAGE_CLASS_IS_ENUM | PROPERTY_USAGE_CLASS_IS_BITFIELD)) {
|
||||
arg.type.name = arg_info.class_name;
|
||||
arg.type.is_enum = true;
|
||||
} else if (arg_info.class_name != StringName()) {
|
||||
|
@ -694,7 +694,7 @@ void add_exposed_classes(Context &r_context) {
|
|||
ArgumentData arg;
|
||||
arg.name = orig_arg_name;
|
||||
|
||||
if (arg_info.type == Variant::INT && arg_info.usage & PROPERTY_USAGE_CLASS_IS_ENUM) {
|
||||
if (arg_info.type == Variant::INT && arg_info.usage & (PROPERTY_USAGE_CLASS_IS_ENUM | PROPERTY_USAGE_CLASS_IS_BITFIELD)) {
|
||||
arg.type.name = arg_info.class_name;
|
||||
arg.type.is_enum = true;
|
||||
} else if (arg_info.class_name != StringName()) {
|
||||
|
@ -732,13 +732,13 @@ void add_exposed_classes(Context &r_context) {
|
|||
List<String> constants;
|
||||
ClassDB::get_integer_constant_list(class_name, &constants, true);
|
||||
|
||||
const HashMap<StringName, List<StringName>> &enum_map = class_info->enum_map;
|
||||
const HashMap<StringName, ClassDB::ClassInfo::EnumInfo> &enum_map = class_info->enum_map;
|
||||
|
||||
for (const KeyValue<StringName, List<StringName>> &K : enum_map) {
|
||||
for (const KeyValue<StringName, ClassDB::ClassInfo::EnumInfo> &K : enum_map) {
|
||||
EnumData enum_;
|
||||
enum_.name = K.key;
|
||||
|
||||
for (const StringName &E : K.value) {
|
||||
for (const StringName &E : K.value.constants) {
|
||||
const StringName &constant_name = E;
|
||||
TEST_FAIL_COND(String(constant_name).find("::") != -1,
|
||||
"Enum constant contains '::', check bindings to remove the scope: '",
|
||||
|
|
Loading…
Reference in New Issue