diff options
-rw-r--r-- | scene/2d/tile_map.cpp | 211 | ||||
-rw-r--r-- | scene/2d/tile_map.h | 11 | ||||
-rw-r--r-- | scene/gui/file_dialog.cpp | 55 | ||||
-rw-r--r-- | scene/gui/file_dialog.h | 13 | ||||
-rw-r--r-- | scene/gui/menu_button.cpp | 54 | ||||
-rw-r--r-- | scene/gui/menu_button.h | 8 | ||||
-rw-r--r-- | scene/gui/option_button.cpp | 64 | ||||
-rw-r--r-- | scene/gui/option_button.h | 11 | ||||
-rw-r--r-- | scene/gui/popup_menu.h | 4 | ||||
-rw-r--r-- | scene/gui/tab_bar.cpp | 61 | ||||
-rw-r--r-- | scene/gui/tab_bar.h | 14 | ||||
-rw-r--r-- | scene/property_list_helper.cpp | 56 | ||||
-rw-r--r-- | scene/property_list_helper.h | 6 | ||||
-rw-r--r-- | servers/audio/audio_stream.cpp | 67 | ||||
-rw-r--r-- | servers/audio/audio_stream.h | 14 |
15 files changed, 213 insertions, 436 deletions
diff --git a/scene/2d/tile_map.cpp b/scene/2d/tile_map.cpp index 84d3a5f7fa..165d4d5a67 100644 --- a/scene/2d/tile_map.cpp +++ b/scene/2d/tile_map.cpp @@ -161,6 +161,10 @@ Vector<int> TileMap::_get_tile_map_data_using_compatibility_format(int p_layer) return tile_data; } +void TileMap::_set_layer_tile_data(int p_layer, const PackedInt32Array &p_data) { + _set_tile_map_data_using_compatibility_format(p_layer, format, p_data); +} + void TileMap::_notification(int p_what) { switch (p_what) { case TileMap::NOTIFICATION_INTERNAL_PHYSICS_PROCESS: { @@ -740,41 +744,23 @@ Rect2 TileMap::_edit_get_rect() const { #endif bool TileMap::_set(const StringName &p_name, const Variant &p_value) { + int index; + const String sname = p_name; + Vector<String> components = String(p_name).split("/", true, 2); - if (p_name == "format") { + if (sname == "format") { if (p_value.get_type() == Variant::INT) { format = (TileMapDataFormat)(p_value.operator int64_t()); // Set format used for loading. return true; } } #ifndef DISABLE_DEPRECATED - else if (p_name == "tile_data") { // Kept for compatibility reasons. - if (p_value.is_array()) { - if (layers.size() == 0) { - TileMapLayer *new_layer = memnew(TileMapLayer); - add_child(new_layer, false, INTERNAL_MODE_FRONT); - new_layer->set_as_tile_map_internal_node(0); - new_layer->set_name("Layer0"); - new_layer->set_tile_set(tile_set); - new_layer->connect(CoreStringNames::get_singleton()->changed, callable_mp(this, &TileMap::_emit_changed)); - layers.push_back(new_layer); - } - _set_tile_map_data_using_compatibility_format(0, format, p_value); - _emit_changed(); - return true; - } - return false; - } else if (p_name == "cell_quadrant_size") { + else if (sname == "cell_quadrant_size") { set_rendering_quadrant_size(p_value); return true; } #endif // DISABLE_DEPRECATED - else if (components.size() == 2 && components[0].begins_with("layer_") && components[0].trim_prefix("layer_").is_valid_int()) { - int index = components[0].trim_prefix("layer_").to_int(); - if (index < 0) { - return false; - } - + else if (property_helper.is_property_valid(sname, &index)) { if (index >= (int)layers.size()) { while (index >= (int)layers.size()) { TileMapLayer *new_layer = memnew(TileMapLayer); @@ -791,172 +777,38 @@ bool TileMap::_set(const StringName &p_name, const Variant &p_value) { update_configuration_warnings(); } - if (components[1] == "name") { - set_layer_name(index, p_value); - return true; - } else if (components[1] == "enabled") { - set_layer_enabled(index, p_value); - return true; - } else if (components[1] == "modulate") { - set_layer_modulate(index, p_value); - return true; - } else if (components[1] == "y_sort_enabled") { - set_layer_y_sort_enabled(index, p_value); - return true; - } else if (components[1] == "y_sort_origin") { - set_layer_y_sort_origin(index, p_value); - return true; - } else if (components[1] == "z_index") { - set_layer_z_index(index, p_value); - return true; - } else if (components[1] == "navigation_enabled") { - set_layer_navigation_enabled(index, p_value); - return true; - } else if (components[1] == "tile_data") { - _set_tile_map_data_using_compatibility_format(index, format, p_value); - _emit_changed(); + if (property_helper.property_set_value(sname, p_value)) { + if (components[1] == "tile_data") { + _emit_changed(); + } return true; - } else { - return false; } } return false; } bool TileMap::_get(const StringName &p_name, Variant &r_ret) const { + const String sname = p_name; + Vector<String> components = String(p_name).split("/", true, 2); if (p_name == "format") { r_ret = TileMapDataFormat::TILE_MAP_DATA_FORMAT_MAX - 1; // When saving, always save highest format. return true; } #ifndef DISABLE_DEPRECATED - else if (p_name == "cell_quadrant_size") { // Kept for compatibility reasons. + else if (sname == "cell_quadrant_size") { // Kept for compatibility reasons. r_ret = get_rendering_quadrant_size(); return true; } #endif - else if (components.size() == 2 && components[0].begins_with("layer_") && components[0].trim_prefix("layer_").is_valid_int()) { - int index = components[0].trim_prefix("layer_").to_int(); - if (index < 0 || index >= (int)layers.size()) { - return false; - } - - if (components[1] == "name") { - r_ret = get_layer_name(index); - return true; - } else if (components[1] == "enabled") { - r_ret = is_layer_enabled(index); - return true; - } else if (components[1] == "modulate") { - r_ret = get_layer_modulate(index); - return true; - } else if (components[1] == "y_sort_enabled") { - r_ret = is_layer_y_sort_enabled(index); - return true; - } else if (components[1] == "y_sort_origin") { - r_ret = get_layer_y_sort_origin(index); - return true; - } else if (components[1] == "z_index") { - r_ret = get_layer_z_index(index); - return true; - } else if (components[1] == "navigation_enabled") { - r_ret = is_layer_navigation_enabled(index); - return true; - } else if (components[1] == "tile_data") { - r_ret = _get_tile_map_data_using_compatibility_format(index); - return true; - } else { - return false; - } + else { + return property_helper.property_get_value(sname, r_ret); } - return false; } void TileMap::_get_property_list(List<PropertyInfo> *p_list) const { p_list->push_back(PropertyInfo(Variant::INT, "format", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_NO_EDITOR | PROPERTY_USAGE_INTERNAL)); - p_list->push_back(PropertyInfo(Variant::NIL, "Layers", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_GROUP)); - -#define MAKE_LAYER_PROPERTY(m_type, m_name, m_hint) \ - { \ - const String property_name = vformat("layer_%d/" m_name, i); \ - p_list->push_back(PropertyInfo(m_type, property_name, PROPERTY_HINT_NONE, m_hint, (get(property_name) == property_get_revert(property_name)) ? PROPERTY_USAGE_EDITOR : PROPERTY_USAGE_DEFAULT)); \ - } - - for (uint32_t i = 0; i < layers.size(); i++) { - MAKE_LAYER_PROPERTY(Variant::STRING, "name", ""); - MAKE_LAYER_PROPERTY(Variant::BOOL, "enabled", ""); - MAKE_LAYER_PROPERTY(Variant::COLOR, "modulate", ""); - MAKE_LAYER_PROPERTY(Variant::BOOL, "y_sort_enabled", ""); - MAKE_LAYER_PROPERTY(Variant::INT, "y_sort_origin", "suffix:px"); - MAKE_LAYER_PROPERTY(Variant::INT, "z_index", ""); - MAKE_LAYER_PROPERTY(Variant::BOOL, "navigation_enabled", ""); - p_list->push_back(PropertyInfo(Variant::OBJECT, vformat("layer_%d/tile_data", i), PROPERTY_HINT_NONE, "", PROPERTY_USAGE_NO_EDITOR)); - } - -#undef MAKE_LAYER_PROPERTY -} - -bool TileMap::_property_can_revert(const StringName &p_name) const { - Vector<String> components = String(p_name).split("/", true, 2); - if (components.size() == 2 && components[0].begins_with("layer_")) { - int index = components[0].trim_prefix("layer_").to_int(); - if (index <= 0 || index >= (int)layers.size()) { - return false; - } - - if (components[1] == "name") { - return layers[index]->get_name() != default_layer->get_name(); - } else if (components[1] == "enabled") { - return layers[index]->is_enabled() != default_layer->is_enabled(); - } else if (components[1] == "modulate") { - return layers[index]->get_modulate() != default_layer->get_modulate(); - } else if (components[1] == "y_sort_enabled") { - return layers[index]->is_y_sort_enabled() != default_layer->is_y_sort_enabled(); - } else if (components[1] == "y_sort_origin") { - return layers[index]->get_y_sort_origin() != default_layer->get_y_sort_origin(); - } else if (components[1] == "z_index") { - return layers[index]->get_z_index() != default_layer->get_z_index(); - } else if (components[1] == "navigation_enabled") { - return layers[index]->is_navigation_enabled() != default_layer->is_navigation_enabled(); - } - } - - return false; -} - -bool TileMap::_property_get_revert(const StringName &p_name, Variant &r_property) const { - Vector<String> components = String(p_name).split("/", true, 2); - if (components.size() == 2 && components[0].begins_with("layer_")) { - int index = components[0].trim_prefix("layer_").to_int(); - if (index <= 0 || index >= (int)layers.size()) { - return false; - } - - if (components[1] == "name") { - r_property = default_layer->get_name(); - return true; - } else if (components[1] == "enabled") { - r_property = default_layer->is_enabled(); - return true; - } else if (components[1] == "modulate") { - r_property = default_layer->get_modulate(); - return true; - } else if (components[1] == "y_sort_enabled") { - r_property = default_layer->is_y_sort_enabled(); - return true; - } else if (components[1] == "y_sort_origin") { - r_property = default_layer->get_y_sort_origin(); - return true; - } else if (components[1] == "z_index") { - r_property = default_layer->get_z_index(); - return true; - } else if (components[1] == "navigation_enabled") { - r_property = default_layer->is_navigation_enabled(); - return true; - } - } - - return false; + property_helper.get_property_list(p_list, layers.size()); } Vector2 TileMap::map_to_local(const Vector2i &p_pos) const { @@ -1214,11 +1066,26 @@ TileMap::TileMap() { new_layer->set_tile_set(tile_set); new_layer->connect(CoreStringNames::get_singleton()->changed, callable_mp(this, &TileMap::_emit_changed)); layers.push_back(new_layer); - default_layer = memnew(TileMapLayer); -} -TileMap::~TileMap() { - memdelete(default_layer); + if (!base_property_helper.is_initialized()) { + // Initialize static PropertyListHelper if it wasn't yet. This has to be done here, + // because creating TileMapLayer in a static context is not always safe. + TileMapLayer *defaults = memnew(TileMapLayer); + + base_property_helper.set_prefix("layer_"); + base_property_helper.register_property(PropertyInfo(Variant::STRING, "name"), defaults->get_name(), &TileMap::set_layer_name, &TileMap::get_layer_name); + base_property_helper.register_property(PropertyInfo(Variant::BOOL, "enabled"), defaults->is_enabled(), &TileMap::set_layer_enabled, &TileMap::is_layer_enabled); + base_property_helper.register_property(PropertyInfo(Variant::COLOR, "modulate"), defaults->get_modulate(), &TileMap::set_layer_modulate, &TileMap::get_layer_modulate); + base_property_helper.register_property(PropertyInfo(Variant::BOOL, "y_sort_enabled"), defaults->is_y_sort_enabled(), &TileMap::set_layer_y_sort_enabled, &TileMap::is_layer_y_sort_enabled); + base_property_helper.register_property(PropertyInfo(Variant::INT, "y_sort_origin", PROPERTY_HINT_NONE, "suffix:px"), defaults->get_y_sort_origin(), &TileMap::set_layer_y_sort_origin, &TileMap::get_layer_y_sort_origin); + base_property_helper.register_property(PropertyInfo(Variant::INT, "z_index"), defaults->get_z_index(), &TileMap::set_layer_z_index, &TileMap::get_layer_z_index); + base_property_helper.register_property(PropertyInfo(Variant::BOOL, "navigation_enabled"), defaults->is_navigation_enabled(), &TileMap::set_layer_navigation_enabled, &TileMap::is_layer_navigation_enabled); + base_property_helper.register_property(PropertyInfo(Variant::PACKED_INT32_ARRAY, "tile_data", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_NO_EDITOR), Vector<int>(), &TileMap::_set_layer_tile_data, &TileMap::_get_tile_map_data_using_compatibility_format); + + memdelete(defaults); + } + + property_helper.setup_for_instance(base_property_helper, this); } #undef TILEMAP_CALL_FOR_LAYER diff --git a/scene/2d/tile_map.h b/scene/2d/tile_map.h index 41068ea978..45604bfb8a 100644 --- a/scene/2d/tile_map.h +++ b/scene/2d/tile_map.h @@ -32,6 +32,7 @@ #define TILE_MAP_H #include "scene/2d/tile_map_layer.h" +#include "scene/property_list_helper.h" #include "scene/resources/2d/tile_set.h" class Control; @@ -73,7 +74,9 @@ private: // Layers. LocalVector<TileMapLayer *> layers; - TileMapLayer *default_layer; // Dummy layer to fetch default values. + + static inline PropertyListHelper base_property_helper; + PropertyListHelper property_helper; // Transforms for collision_animatable. Transform2D last_valid_transform; @@ -86,13 +89,14 @@ private: // Kept for compatibility with TileMap. With TileMapLayers as individual nodes, the format is stored directly in the array. void _set_tile_map_data_using_compatibility_format(int p_layer, TileMapDataFormat p_format, const Vector<int> &p_data); Vector<int> _get_tile_map_data_using_compatibility_format(int p_layer) const; + void _set_layer_tile_data(int p_layer, const PackedInt32Array &p_data); protected: bool _set(const StringName &p_name, const Variant &p_value); bool _get(const StringName &p_name, Variant &r_ret) const; void _get_property_list(List<PropertyInfo> *p_list) const; - bool _property_can_revert(const StringName &p_name) const; - bool _property_get_revert(const StringName &p_name, Variant &r_property) const; + bool _property_can_revert(const StringName &p_name) const { return property_helper.property_can_revert(p_name); } + bool _property_get_revert(const StringName &p_name, Variant &r_property) const { return property_helper.property_get_revert(p_name, r_property); } void _notification(int p_what); static void _bind_methods(); @@ -235,7 +239,6 @@ public: PackedStringArray get_configuration_warnings() const override; TileMap(); - ~TileMap(); }; VARIANT_ENUM_CAST(TileMap::VisibilityMode); diff --git a/scene/gui/file_dialog.cpp b/scene/gui/file_dialog.cpp index 12b2364ddf..c3a586a1ee 100644 --- a/scene/gui/file_dialog.cpp +++ b/scene/gui/file_dialog.cpp @@ -1255,52 +1255,6 @@ int FileDialog::get_option_count() const { return options.size(); } -bool FileDialog::_set(const StringName &p_name, const Variant &p_value) { - Vector<String> components = String(p_name).split("/", true, 2); - if (components.size() >= 2 && components[0].begins_with("option_") && components[0].trim_prefix("option_").is_valid_int()) { - int item_index = components[0].trim_prefix("option_").to_int(); - String property = components[1]; - if (property == "name") { - set_option_name(item_index, p_value); - return true; - } else if (property == "values") { - set_option_values(item_index, p_value); - return true; - } else if (property == "default") { - set_option_default(item_index, p_value); - return true; - } - } - return false; -} - -bool FileDialog::_get(const StringName &p_name, Variant &r_ret) const { - Vector<String> components = String(p_name).split("/", true, 2); - if (components.size() >= 2 && components[0].begins_with("option_") && components[0].trim_prefix("option_").is_valid_int()) { - int item_index = components[0].trim_prefix("option_").to_int(); - String property = components[1]; - if (property == "name") { - r_ret = get_option_name(item_index); - return true; - } else if (property == "values") { - r_ret = get_option_values(item_index); - return true; - } else if (property == "default") { - r_ret = get_option_default(item_index); - return true; - } - } - return false; -} - -void FileDialog::_get_property_list(List<PropertyInfo> *p_list) const { - for (int i = 0; i < options.size(); i++) { - p_list->push_back(PropertyInfo(Variant::STRING, vformat("option_%d/name", i))); - p_list->push_back(PropertyInfo(Variant::PACKED_STRING_ARRAY, vformat("option_%d/values", i))); - p_list->push_back(PropertyInfo(Variant::INT, vformat("option_%d/default", i))); - } -} - void FileDialog::_bind_methods() { ClassDB::bind_method(D_METHOD("_cancel_pressed"), &FileDialog::_cancel_pressed); @@ -1386,6 +1340,13 @@ void FileDialog::_bind_methods() { BIND_THEME_ITEM_EXT(Theme::DATA_TYPE_COLOR, FileDialog, icon_hover_color, "font_hover_color", "Button"); BIND_THEME_ITEM_EXT(Theme::DATA_TYPE_COLOR, FileDialog, icon_focus_color, "font_focus_color", "Button"); BIND_THEME_ITEM_EXT(Theme::DATA_TYPE_COLOR, FileDialog, icon_pressed_color, "font_pressed_color", "Button"); + + Option defaults; + + base_property_helper.set_prefix("option_"); + base_property_helper.register_property(PropertyInfo(Variant::STRING, "name"), defaults.name, &FileDialog::set_option_name, &FileDialog::get_option_name); + base_property_helper.register_property(PropertyInfo(Variant::PACKED_STRING_ARRAY, "values"), defaults.values, &FileDialog::set_option_values, &FileDialog::get_option_values); + base_property_helper.register_property(PropertyInfo(Variant::INT, "default"), defaults.default_idx, &FileDialog::set_option_default, &FileDialog::get_option_default); } void FileDialog::set_show_hidden_files(bool p_show) { @@ -1563,6 +1524,8 @@ FileDialog::FileDialog() { if (register_func) { register_func(this); } + + property_helper.setup_for_instance(base_property_helper, this); } FileDialog::~FileDialog() { diff --git a/scene/gui/file_dialog.h b/scene/gui/file_dialog.h index 7caae7e216..4236f0a56b 100644 --- a/scene/gui/file_dialog.h +++ b/scene/gui/file_dialog.h @@ -37,6 +37,7 @@ #include "scene/gui/line_edit.h" #include "scene/gui/option_button.h" #include "scene/gui/tree.h" +#include "scene/property_list_helper.h" class GridContainer; @@ -137,6 +138,10 @@ private: Vector<String> values; int default_idx = 0; }; + + static inline PropertyListHelper base_property_helper; + PropertyListHelper property_helper; + Vector<Option> options; Dictionary selected_options; bool options_dirty = false; @@ -187,9 +192,11 @@ private: protected: void _validate_property(PropertyInfo &p_property) const; void _notification(int p_what); - bool _set(const StringName &p_name, const Variant &p_value); - bool _get(const StringName &p_name, Variant &r_ret) const; - void _get_property_list(List<PropertyInfo> *p_list) const; + bool _set(const StringName &p_name, const Variant &p_value) { return property_helper.property_set_value(p_name, p_value); } + bool _get(const StringName &p_name, Variant &r_ret) const { return property_helper.property_get_value(p_name, r_ret); } + void _get_property_list(List<PropertyInfo> *p_list) const { property_helper.get_property_list(p_list, options.size()); } + bool _property_can_revert(const StringName &p_name) const { return property_helper.property_can_revert(p_name); } + bool _property_get_revert(const StringName &p_name, Variant &r_property) const { return property_helper.property_get_revert(p_name, r_property); } static void _bind_methods(); public: diff --git a/scene/gui/menu_button.cpp b/scene/gui/menu_button.cpp index 89c627a7a8..e83d9c7c1b 100644 --- a/scene/gui/menu_button.cpp +++ b/scene/gui/menu_button.cpp @@ -153,54 +153,25 @@ void MenuButton::_notification(int p_what) { } bool MenuButton::_set(const StringName &p_name, const Variant &p_value) { - Vector<String> components = String(p_name).split("/", true, 2); - if (components.size() >= 2 && components[0] == "popup") { + const String sname = p_name; + if (property_helper.is_property_valid(sname)) { bool valid; - popup->set(String(p_name).trim_prefix("popup/"), p_value, &valid); + popup->set(sname.trim_prefix("popup/"), p_value, &valid); return valid; } return false; } bool MenuButton::_get(const StringName &p_name, Variant &r_ret) const { - Vector<String> components = String(p_name).split("/", true, 2); - if (components.size() >= 2 && components[0] == "popup") { + const String sname = p_name; + if (property_helper.is_property_valid(sname)) { bool valid; - r_ret = popup->get(String(p_name).trim_prefix("popup/"), &valid); + r_ret = popup->get(sname.trim_prefix("popup/"), &valid); return valid; } return false; } -void MenuButton::_get_property_list(List<PropertyInfo> *p_list) const { - for (int i = 0; i < popup->get_item_count(); i++) { - p_list->push_back(PropertyInfo(Variant::STRING, vformat("popup/item_%d/text", i))); - - PropertyInfo pi = PropertyInfo(Variant::OBJECT, vformat("popup/item_%d/icon", i), PROPERTY_HINT_RESOURCE_TYPE, "Texture2D"); - pi.usage &= ~(popup->get_item_icon(i).is_null() ? PROPERTY_USAGE_STORAGE : 0); - p_list->push_back(pi); - - pi = PropertyInfo(Variant::INT, vformat("popup/item_%d/checkable", i), PROPERTY_HINT_ENUM, "No,As Checkbox,As Radio Button"); - pi.usage &= ~(!popup->is_item_checkable(i) ? PROPERTY_USAGE_STORAGE : 0); - p_list->push_back(pi); - - pi = PropertyInfo(Variant::BOOL, vformat("popup/item_%d/checked", i)); - pi.usage &= ~(!popup->is_item_checked(i) ? PROPERTY_USAGE_STORAGE : 0); - p_list->push_back(pi); - - pi = PropertyInfo(Variant::INT, vformat("popup/item_%d/id", i), PROPERTY_HINT_RANGE, "0,10,1,or_greater"); - p_list->push_back(pi); - - pi = PropertyInfo(Variant::BOOL, vformat("popup/item_%d/disabled", i)); - pi.usage &= ~(!popup->is_item_disabled(i) ? PROPERTY_USAGE_STORAGE : 0); - p_list->push_back(pi); - - pi = PropertyInfo(Variant::BOOL, vformat("popup/item_%d/separator", i)); - pi.usage &= ~(!popup->is_item_separator(i) ? PROPERTY_USAGE_STORAGE : 0); - p_list->push_back(pi); - } -} - void MenuButton::_bind_methods() { ClassDB::bind_method(D_METHOD("get_popup"), &MenuButton::get_popup); ClassDB::bind_method(D_METHOD("show_popup"), &MenuButton::show_popup); @@ -215,6 +186,17 @@ void MenuButton::_bind_methods() { ADD_ARRAY_COUNT("Items", "item_count", "set_item_count", "get_item_count", "popup/item_"); ADD_SIGNAL(MethodInfo("about_to_popup")); + + PopupMenu::Item defaults(true); + + base_property_helper.set_prefix("popup/item_"); + base_property_helper.register_property(PropertyInfo(Variant::STRING, "text"), defaults.text); + base_property_helper.register_property(PropertyInfo(Variant::OBJECT, "icon", PROPERTY_HINT_RESOURCE_TYPE, "Texture2D"), defaults.icon); + base_property_helper.register_property(PropertyInfo(Variant::INT, "checkable", PROPERTY_HINT_ENUM, "No,As Checkbox,As Radio Button"), defaults.checkable_type); + base_property_helper.register_property(PropertyInfo(Variant::BOOL, "checked"), defaults.checked); + base_property_helper.register_property(PropertyInfo(Variant::INT, "id", PROPERTY_HINT_RANGE, "0,10,1,or_greater"), defaults.id); + base_property_helper.register_property(PropertyInfo(Variant::BOOL, "disabled"), defaults.disabled); + base_property_helper.register_property(PropertyInfo(Variant::BOOL, "separator"), defaults.separator); } void MenuButton::set_disable_shortcuts(bool p_disabled) { @@ -235,6 +217,8 @@ MenuButton::MenuButton(const String &p_text) : add_child(popup, false, INTERNAL_MODE_FRONT); popup->connect("about_to_popup", callable_mp(this, &MenuButton::_popup_visibility_changed).bind(true)); popup->connect("popup_hide", callable_mp(this, &MenuButton::_popup_visibility_changed).bind(false)); + + property_helper.setup_for_instance(base_property_helper, this); } MenuButton::~MenuButton() { diff --git a/scene/gui/menu_button.h b/scene/gui/menu_button.h index eea6b8e877..2bd577ddd0 100644 --- a/scene/gui/menu_button.h +++ b/scene/gui/menu_button.h @@ -33,6 +33,7 @@ #include "scene/gui/button.h" #include "scene/gui/popup_menu.h" +#include "scene/property_list_helper.h" class MenuButton : public Button { GDCLASS(MenuButton, Button); @@ -42,13 +43,18 @@ class MenuButton : public Button { bool disable_shortcuts = false; PopupMenu *popup = nullptr; + static inline PropertyListHelper base_property_helper; + PropertyListHelper property_helper; + void _popup_visibility_changed(bool p_visible); protected: void _notification(int p_what); bool _set(const StringName &p_name, const Variant &p_value); bool _get(const StringName &p_name, Variant &r_ret) const; - void _get_property_list(List<PropertyInfo> *p_list) const; + void _get_property_list(List<PropertyInfo> *p_list) const { property_helper.get_property_list(p_list, popup->get_item_count()); } + bool _property_can_revert(const StringName &p_name) const { return property_helper.property_can_revert(p_name); } + bool _property_get_revert(const StringName &p_name, Variant &r_property) const { return property_helper.property_get_revert(p_name, r_property); } static void _bind_methods(); virtual void shortcut_input(const Ref<InputEvent> &p_event) override; diff --git a/scene/gui/option_button.cpp b/scene/gui/option_button.cpp index 0e10652f07..509c6aca99 100644 --- a/scene/gui/option_button.cpp +++ b/scene/gui/option_button.cpp @@ -154,23 +154,20 @@ void OptionButton::_notification(int p_what) { } bool OptionButton::_set(const StringName &p_name, const Variant &p_value) { - Vector<String> components = String(p_name).split("/", true, 2); - if (components.size() >= 2 && components[0] == "popup") { - const String &property = components[2]; - if (property != "text" && property != "icon" && property != "id" && property != "disabled" && property != "separator") { - return false; - } + int index; + const String sname = p_name; + if (property_helper.is_property_valid(sname, &index)) { bool valid; - popup->set(String(p_name).trim_prefix("popup/"), p_value, &valid); + popup->set(sname.trim_prefix("popup/"), p_value, &valid); - int idx = components[1].get_slice("_", 1).to_int(); - if (idx == current) { + if (index == current) { // Force refreshing currently displayed item. current = NONE_SELECTED; - _select(idx, false); + _select(index, false); } + const String property = sname.get_slice("/", 2); if (property == "text" || property == "icon") { _queue_update_size_cache(); } @@ -180,42 +177,6 @@ bool OptionButton::_set(const StringName &p_name, const Variant &p_value) { return false; } -bool OptionButton::_get(const StringName &p_name, Variant &r_ret) const { - Vector<String> components = String(p_name).split("/", true, 2); - if (components.size() >= 2 && components[0] == "popup") { - const String &property = components[2]; - if (property != "text" && property != "icon" && property != "id" && property != "disabled" && property != "separator") { - return false; - } - - bool valid; - r_ret = popup->get(String(p_name).trim_prefix("popup/"), &valid); - return valid; - } - return false; -} - -void OptionButton::_get_property_list(List<PropertyInfo> *p_list) const { - for (int i = 0; i < popup->get_item_count(); i++) { - p_list->push_back(PropertyInfo(Variant::STRING, vformat("popup/item_%d/text", i))); - - PropertyInfo pi = PropertyInfo(Variant::OBJECT, vformat("popup/item_%d/icon", i), PROPERTY_HINT_RESOURCE_TYPE, "Texture2D"); - pi.usage &= ~(popup->get_item_icon(i).is_null() ? PROPERTY_USAGE_STORAGE : 0); - p_list->push_back(pi); - - pi = PropertyInfo(Variant::INT, vformat("popup/item_%d/id", i), PROPERTY_HINT_RANGE, "0,10,1,or_greater"); - p_list->push_back(pi); - - pi = PropertyInfo(Variant::BOOL, vformat("popup/item_%d/disabled", i)); - pi.usage &= ~(!popup->is_item_disabled(i) ? PROPERTY_USAGE_STORAGE : 0); - p_list->push_back(pi); - - pi = PropertyInfo(Variant::BOOL, vformat("popup/item_%d/separator", i)); - pi.usage &= ~(!popup->is_item_separator(i) ? PROPERTY_USAGE_STORAGE : 0); - p_list->push_back(pi); - } -} - void OptionButton::_focused(int p_which) { emit_signal(SNAME("item_focused"), p_which); } @@ -606,6 +567,15 @@ void OptionButton::_bind_methods() { BIND_THEME_ITEM_CUSTOM(Theme::DATA_TYPE_ICON, OptionButton, arrow_icon, "arrow"); BIND_THEME_ITEM(Theme::DATA_TYPE_CONSTANT, OptionButton, arrow_margin); BIND_THEME_ITEM(Theme::DATA_TYPE_CONSTANT, OptionButton, modulate_arrow); + + PopupMenu::Item defaults(true); + + base_property_helper.set_prefix("popup/item_"); + base_property_helper.register_property(PropertyInfo(Variant::STRING, "text"), defaults.text, &OptionButton::_dummy_setter, &OptionButton::get_item_text); + base_property_helper.register_property(PropertyInfo(Variant::OBJECT, "icon", PROPERTY_HINT_RESOURCE_TYPE, "Texture2D"), defaults.icon, &OptionButton::_dummy_setter, &OptionButton::get_item_icon); + base_property_helper.register_property(PropertyInfo(Variant::INT, "id", PROPERTY_HINT_RANGE, "0,10,1,or_greater"), defaults.id, &OptionButton::_dummy_setter, &OptionButton::get_item_id); + base_property_helper.register_property(PropertyInfo(Variant::BOOL, "disabled"), defaults.disabled, &OptionButton::_dummy_setter, &OptionButton::is_item_disabled); + base_property_helper.register_property(PropertyInfo(Variant::BOOL, "separator"), defaults.separator, &OptionButton::_dummy_setter, &OptionButton::is_item_separator); } void OptionButton::set_disable_shortcuts(bool p_disabled) { @@ -625,6 +595,8 @@ OptionButton::OptionButton(const String &p_text) : popup->connect("index_pressed", callable_mp(this, &OptionButton::_selected)); popup->connect("id_focused", callable_mp(this, &OptionButton::_focused)); popup->connect("popup_hide", callable_mp((BaseButton *)this, &BaseButton::set_pressed).bind(false)); + + property_helper.setup_for_instance(base_property_helper, this); } OptionButton::~OptionButton() { diff --git a/scene/gui/option_button.h b/scene/gui/option_button.h index 9c15b295a9..4b5164161a 100644 --- a/scene/gui/option_button.h +++ b/scene/gui/option_button.h @@ -33,6 +33,7 @@ #include "scene/gui/button.h" #include "scene/gui/popup_menu.h" +#include "scene/property_list_helper.h" class OptionButton : public Button { GDCLASS(OptionButton, Button); @@ -64,11 +65,15 @@ class OptionButton : public Button { int modulate_arrow = 0; } theme_cache; + static inline PropertyListHelper base_property_helper; + PropertyListHelper property_helper; + void _focused(int p_which); void _selected(int p_which); void _select(int p_which, bool p_emit = false); void _select_int(int p_which); void _refresh_size_cache(); + void _dummy_setter() {} // Stub for PropertyListHelper (_set() doesn't use it). virtual void pressed() override; @@ -78,8 +83,10 @@ protected: void _notification(int p_what); bool _set(const StringName &p_name, const Variant &p_value); - bool _get(const StringName &p_name, Variant &r_ret) const; - void _get_property_list(List<PropertyInfo> *p_list) const; + bool _get(const StringName &p_name, Variant &r_ret) const { return property_helper.property_get_value(p_name, r_ret); } + void _get_property_list(List<PropertyInfo> *p_list) const { property_helper.get_property_list(p_list, popup->get_item_count()); } + bool _property_can_revert(const StringName &p_name) const { return property_helper.property_can_revert(p_name); } + bool _property_get_revert(const StringName &p_name, Variant &r_property) const { return property_helper.property_get_revert(p_name, r_property); } void _validate_property(PropertyInfo &p_property) const; static void _bind_methods(); diff --git a/scene/gui/popup_menu.h b/scene/gui/popup_menu.h index f7097fffaf..832c1bcc8b 100644 --- a/scene/gui/popup_menu.h +++ b/scene/gui/popup_menu.h @@ -97,6 +97,10 @@ class PopupMenu : public Popup { static inline PropertyListHelper base_property_helper; PropertyListHelper property_helper; + // To make Item available. + friend class OptionButton; + friend class MenuButton; + RID global_menu; RID system_menu; NativeMenu::SystemMenus system_menu_id = NativeMenu::INVALID_MENU_ID; diff --git a/scene/gui/tab_bar.cpp b/scene/gui/tab_bar.cpp index d20fef8164..2d687eb201 100644 --- a/scene/gui/tab_bar.cpp +++ b/scene/gui/tab_bar.cpp @@ -1720,58 +1720,6 @@ bool TabBar::get_deselect_enabled() const { return deselect_enabled; } -bool TabBar::_set(const StringName &p_name, const Variant &p_value) { - Vector<String> components = String(p_name).split("/", true, 2); - if (components.size() >= 2 && components[0].begins_with("tab_") && components[0].trim_prefix("tab_").is_valid_int()) { - int tab_index = components[0].trim_prefix("tab_").to_int(); - const String &property = components[1]; - if (property == "title") { - set_tab_title(tab_index, p_value); - return true; - } else if (property == "icon") { - set_tab_icon(tab_index, p_value); - return true; - } else if (property == "disabled") { - set_tab_disabled(tab_index, p_value); - return true; - } - } - return false; -} - -bool TabBar::_get(const StringName &p_name, Variant &r_ret) const { - Vector<String> components = String(p_name).split("/", true, 2); - if (components.size() >= 2 && components[0].begins_with("tab_") && components[0].trim_prefix("tab_").is_valid_int()) { - int tab_index = components[0].trim_prefix("tab_").to_int(); - const String &property = components[1]; - if (property == "title") { - r_ret = get_tab_title(tab_index); - return true; - } else if (property == "icon") { - r_ret = get_tab_icon(tab_index); - return true; - } else if (property == "disabled") { - r_ret = is_tab_disabled(tab_index); - return true; - } - } - return false; -} - -void TabBar::_get_property_list(List<PropertyInfo> *p_list) const { - for (int i = 0; i < tabs.size(); i++) { - p_list->push_back(PropertyInfo(Variant::STRING, vformat("tab_%d/title", i))); - - PropertyInfo pi = PropertyInfo(Variant::OBJECT, vformat("tab_%d/icon", i), PROPERTY_HINT_RESOURCE_TYPE, "Texture2D"); - pi.usage &= ~(get_tab_icon(i).is_null() ? PROPERTY_USAGE_STORAGE : 0); - p_list->push_back(pi); - - pi = PropertyInfo(Variant::BOOL, vformat("tab_%d/disabled", i)); - pi.usage &= ~(!is_tab_disabled(i) ? PROPERTY_USAGE_STORAGE : 0); - p_list->push_back(pi); - } -} - void TabBar::_bind_methods() { ClassDB::bind_method(D_METHOD("set_tab_count", "count"), &TabBar::set_tab_count); ClassDB::bind_method(D_METHOD("get_tab_count"), &TabBar::get_tab_count); @@ -1890,10 +1838,19 @@ void TabBar::_bind_methods() { BIND_THEME_ITEM_CUSTOM(Theme::DATA_TYPE_ICON, TabBar, close_icon, "close"); BIND_THEME_ITEM_CUSTOM(Theme::DATA_TYPE_STYLEBOX, TabBar, button_pressed_style, "button_pressed"); BIND_THEME_ITEM_CUSTOM(Theme::DATA_TYPE_STYLEBOX, TabBar, button_hl_style, "button_highlight"); + + Tab defaults(true); + + base_property_helper.set_prefix("tab_"); + base_property_helper.register_property(PropertyInfo(Variant::STRING, "title"), defaults.text, &TabBar::set_tab_title, &TabBar::get_tab_title); + base_property_helper.register_property(PropertyInfo(Variant::OBJECT, "icon", PROPERTY_HINT_RESOURCE_TYPE, "Texture2D"), defaults.icon, &TabBar::set_tab_icon, &TabBar::get_tab_icon); + base_property_helper.register_property(PropertyInfo(Variant::BOOL, "disabled"), defaults.disabled, &TabBar::set_tab_disabled, &TabBar::is_tab_disabled); } TabBar::TabBar() { set_size(Size2(get_size().width, get_minimum_size().height)); set_focus_mode(FOCUS_ALL); connect("mouse_exited", callable_mp(this, &TabBar::_on_mouse_exited)); + + property_helper.setup_for_instance(base_property_helper, this); } diff --git a/scene/gui/tab_bar.h b/scene/gui/tab_bar.h index 65a1d5bd4f..6c09e960f1 100644 --- a/scene/gui/tab_bar.h +++ b/scene/gui/tab_bar.h @@ -32,6 +32,7 @@ #define TAB_BAR_H #include "scene/gui/control.h" +#include "scene/property_list_helper.h" #include "scene/resources/text_line.h" class TabBar : public Control { @@ -77,8 +78,13 @@ private: Tab() { text_buf.instantiate(); } + + Tab(bool p_dummy) {} }; + static inline PropertyListHelper base_property_helper; + PropertyListHelper property_helper; + int offset = 0; int max_drawn_tab = 0; int highlight_arrow = -1; @@ -163,9 +169,11 @@ private: protected: virtual void gui_input(const Ref<InputEvent> &p_event) override; - bool _set(const StringName &p_name, const Variant &p_value); - bool _get(const StringName &p_name, Variant &r_ret) const; - void _get_property_list(List<PropertyInfo> *p_list) const; + bool _set(const StringName &p_name, const Variant &p_value) { return property_helper.property_set_value(p_name, p_value); } + bool _get(const StringName &p_name, Variant &r_ret) const { return property_helper.property_get_value(p_name, r_ret); } + void _get_property_list(List<PropertyInfo> *p_list) const { property_helper.get_property_list(p_list, tabs.size()); } + bool _property_can_revert(const StringName &p_name) const { return property_helper.property_can_revert(p_name); } + bool _property_get_revert(const StringName &p_name, Variant &r_property) const { return property_helper.property_get_revert(p_name, r_property); } void _notification(int p_what); static void _bind_methods(); diff --git a/scene/property_list_helper.cpp b/scene/property_list_helper.cpp index d9a80011b0..b666e4c52d 100644 --- a/scene/property_list_helper.cpp +++ b/scene/property_list_helper.cpp @@ -31,7 +31,7 @@ #include "property_list_helper.h" const PropertyListHelper::Property *PropertyListHelper::_get_property(const String &p_property, int *r_index) const { - const Vector<String> components = p_property.split("/", true, 2); + const Vector<String> components = p_property.rsplit("/", true, 1); if (components.size() < 2 || !components[0].begins_with(prefix)) { return nullptr; } @@ -48,36 +48,73 @@ const PropertyListHelper::Property *PropertyListHelper::_get_property(const Stri } void PropertyListHelper::_call_setter(const MethodBind *p_setter, int p_index, const Variant &p_value) const { + DEV_ASSERT(p_setter); Variant args[] = { p_index, p_value }; const Variant *argptrs[] = { &args[0], &args[1] }; Callable::CallError ce; p_setter->call(object, argptrs, 2, ce); } -Variant PropertyListHelper::_call_getter(const MethodBind *p_getter, int p_index) const { +Variant PropertyListHelper::_call_getter(const Property *p_property, int p_index) const { + if (!p_property->getter) { + return object->get(prefix + itos(p_index) + "/" + p_property->info.name); + } + Callable::CallError ce; Variant args[] = { p_index }; const Variant *argptrs[] = { &args[0] }; - return p_getter->call(object, argptrs, 1, ce); + return p_property->getter->call(object, argptrs, 1, ce); } void PropertyListHelper::set_prefix(const String &p_prefix) { prefix = p_prefix; } +void PropertyListHelper::register_property(const PropertyInfo &p_info, const Variant &p_default) { + Property property; + property.info = p_info; + property.default_value = p_default; + + property_list[p_info.name] = property; +} + +bool PropertyListHelper::is_initialized() const { + return !property_list.is_empty(); +} + void PropertyListHelper::setup_for_instance(const PropertyListHelper &p_base, Object *p_object) { prefix = p_base.prefix; property_list = p_base.property_list; object = p_object; } +bool PropertyListHelper::is_property_valid(const String &p_property, int *r_index) const { + const Vector<String> components = p_property.rsplit("/", true, 1); + if (components.size() < 2 || !components[0].begins_with(prefix)) { + return false; + } + + { + const String index_string = components[0].trim_prefix(prefix); + if (!index_string.is_valid_int()) { + return false; + } + + if (r_index) { + *r_index = index_string.to_int(); + } + } + + return property_list.has(components[1]); +} + void PropertyListHelper::get_property_list(List<PropertyInfo> *p_list, int p_count) const { for (int i = 0; i < p_count; i++) { for (const KeyValue<String, Property> &E : property_list) { const Property &property = E.value; PropertyInfo info = property.info; - if (_call_getter(property.getter, i) == property.default_value) { + if (_call_getter(&property, i) == property.default_value) { info.usage &= (~PROPERTY_USAGE_STORAGE); } @@ -92,7 +129,7 @@ bool PropertyListHelper::property_get_value(const String &p_property, Variant &r const Property *property = _get_property(p_property, &index); if (property) { - r_ret = _call_getter(property->getter, index); + r_ret = _call_getter(property, index); return true; } return false; @@ -110,8 +147,7 @@ bool PropertyListHelper::property_set_value(const String &p_property, const Vari } bool PropertyListHelper::property_can_revert(const String &p_property) const { - int index; - return _get_property(p_property, &index) != nullptr; + return is_property_valid(p_property); } bool PropertyListHelper::property_get_revert(const String &p_property, Variant &r_value) const { @@ -129,8 +165,10 @@ PropertyListHelper::~PropertyListHelper() { // No object = it's the main helper. Do a cleanup. if (!object) { for (const KeyValue<String, Property> &E : property_list) { - memdelete(E.value.setter); - memdelete(E.value.getter); + if (E.value.setter) { + memdelete(E.value.setter); + memdelete(E.value.getter); + } } } } diff --git a/scene/property_list_helper.h b/scene/property_list_helper.h index 6c1ad21a05..eac6b03d47 100644 --- a/scene/property_list_helper.h +++ b/scene/property_list_helper.h @@ -48,10 +48,12 @@ class PropertyListHelper { const Property *_get_property(const String &p_property, int *r_index) const; void _call_setter(const MethodBind *p_setter, int p_index, const Variant &p_value) const; - Variant _call_getter(const MethodBind *p_getter, int p_index) const; + Variant _call_getter(const Property *p_property, int p_index) const; public: void set_prefix(const String &p_prefix); + // Register property without setter/getter. Only use when you don't need PropertyListHelper for _set/_get logic. + void register_property(const PropertyInfo &p_info, const Variant &p_default); template <typename S, typename G> void register_property(const PropertyInfo &p_info, const Variant &p_default, S p_setter, G p_getter) { @@ -64,7 +66,9 @@ public: property_list[p_info.name] = property; } + bool is_initialized() const; void setup_for_instance(const PropertyListHelper &p_base, Object *p_object); + bool is_property_valid(const String &p_property, int *r_index = nullptr) const; void get_property_list(List<PropertyInfo> *p_list, int p_count) const; bool property_get_value(const String &p_property, Variant &r_ret) const; diff --git a/servers/audio/audio_stream.cpp b/servers/audio/audio_stream.cpp index 3e3a7d2381..b5333d91c6 100644 --- a/servers/audio/audio_stream.cpp +++ b/servers/audio/audio_stream.cpp @@ -676,63 +676,6 @@ bool AudioStreamRandomizer::is_monophonic() const { return false; } -bool AudioStreamRandomizer::_get(const StringName &p_name, Variant &r_ret) const { - if (AudioStream::_get(p_name, r_ret)) { - return true; - } - Vector<String> components = String(p_name).split("/", true, 2); - if (components.size() == 2 && components[0].begins_with("stream_") && components[0].trim_prefix("stream_").is_valid_int()) { - int index = components[0].trim_prefix("stream_").to_int(); - if (index < 0 || index >= (int)audio_stream_pool.size()) { - return false; - } - - if (components[1] == "stream") { - r_ret = get_stream(index); - return true; - } else if (components[1] == "weight") { - r_ret = get_stream_probability_weight(index); - return true; - } else { - return false; - } - } - return false; -} - -bool AudioStreamRandomizer::_set(const StringName &p_name, const Variant &p_value) { - if (AudioStream::_set(p_name, p_value)) { - return true; - } - Vector<String> components = String(p_name).split("/", true, 2); - if (components.size() == 2 && components[0].begins_with("stream_") && components[0].trim_prefix("stream_").is_valid_int()) { - int index = components[0].trim_prefix("stream_").to_int(); - if (index < 0 || index >= (int)audio_stream_pool.size()) { - return false; - } - - if (components[1] == "stream") { - set_stream(index, p_value); - return true; - } else if (components[1] == "weight") { - set_stream_probability_weight(index, p_value); - return true; - } else { - return false; - } - } - return false; -} - -void AudioStreamRandomizer::_get_property_list(List<PropertyInfo> *p_list) const { - AudioStream::_get_property_list(p_list); // Define the trivial scalar properties. - p_list->push_back(PropertyInfo(Variant::NIL, "Streams", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_GROUP)); - for (int i = 0; i < audio_stream_pool.size(); i++) { - p_list->push_back(PropertyInfo(Variant::OBJECT, vformat("stream_%d/stream", i), PROPERTY_HINT_RESOURCE_TYPE, "AudioStream")); - p_list->push_back(PropertyInfo(Variant::FLOAT, vformat("stream_%d/weight", i), PROPERTY_HINT_RANGE, "0,100,0.001,or_greater")); - } -} - void AudioStreamRandomizer::_bind_methods() { ClassDB::bind_method(D_METHOD("add_stream", "index", "stream", "weight"), &AudioStreamRandomizer::add_stream, DEFVAL(1.0)); ClassDB::bind_method(D_METHOD("move_stream", "index_from", "index_to"), &AudioStreamRandomizer::move_stream); @@ -764,9 +707,17 @@ void AudioStreamRandomizer::_bind_methods() { BIND_ENUM_CONSTANT(PLAYBACK_RANDOM_NO_REPEATS); BIND_ENUM_CONSTANT(PLAYBACK_RANDOM); BIND_ENUM_CONSTANT(PLAYBACK_SEQUENTIAL); + + PoolEntry defaults; + + base_property_helper.set_prefix("stream_"); + base_property_helper.register_property(PropertyInfo(Variant::OBJECT, "stream", PROPERTY_HINT_RESOURCE_TYPE, "AudioStream"), defaults.stream, &AudioStreamRandomizer::set_stream, &AudioStreamRandomizer::get_stream); + base_property_helper.register_property(PropertyInfo(Variant::FLOAT, "weight", PROPERTY_HINT_RANGE, "0,100,0.001,or_greater"), defaults.weight, &AudioStreamRandomizer::set_stream_probability_weight, &AudioStreamRandomizer::get_stream_probability_weight); } -AudioStreamRandomizer::AudioStreamRandomizer() {} +AudioStreamRandomizer::AudioStreamRandomizer() { + property_helper.setup_for_instance(base_property_helper, this); +} void AudioStreamPlaybackRandomizer::start(double p_from_pos) { playing = playback; diff --git a/servers/audio/audio_stream.h b/servers/audio/audio_stream.h index f8123fbe15..01a4a09942 100644 --- a/servers/audio/audio_stream.h +++ b/servers/audio/audio_stream.h @@ -33,6 +33,7 @@ #include "core/io/image.h" #include "core/io/resource.h" +#include "scene/property_list_helper.h" #include "servers/audio/audio_filter_sw.h" #include "servers/audio_server.h" @@ -236,9 +237,12 @@ private: struct PoolEntry { Ref<AudioStream> stream; - float weight; + float weight = 1.0; }; + static inline PropertyListHelper base_property_helper; + PropertyListHelper property_helper; + HashSet<AudioStreamPlaybackRandomizer *> playbacks; Vector<PoolEntry> audio_stream_pool; float random_pitch_scale = 1.0f; @@ -254,9 +258,11 @@ private: protected: static void _bind_methods(); - bool _set(const StringName &p_name, const Variant &p_value); - bool _get(const StringName &p_name, Variant &r_ret) const; - void _get_property_list(List<PropertyInfo> *p_list) const; + bool _set(const StringName &p_name, const Variant &p_value) { return property_helper.property_set_value(p_name, p_value); } + bool _get(const StringName &p_name, Variant &r_ret) const { return property_helper.property_get_value(p_name, r_ret); } + void _get_property_list(List<PropertyInfo> *p_list) const { property_helper.get_property_list(p_list, audio_stream_pool.size()); } + bool _property_can_revert(const StringName &p_name) const { return property_helper.property_can_revert(p_name); } + bool _property_get_revert(const StringName &p_name, Variant &r_property) const { return property_helper.property_get_revert(p_name, r_property); } public: void add_stream(int p_index, Ref<AudioStream> p_stream, float p_weight = 1.0); |