diff --git a/core/SCsub b/core/SCsub index 31f9a49e..d0a847f2 100644 --- a/core/SCsub +++ b/core/SCsub @@ -10,3 +10,6 @@ if env["goost_math_enabled"]: env_goost.add_source_files(env.modules_sources, "*.cpp") env_goost.add_source_files(env.modules_sources, "types/*.cpp") + +if env["tools"]: + env_goost.add_source_files(env.modules_sources, "types/editor/*.cpp") diff --git a/core/register_core_types.cpp b/core/register_core_types.cpp index 399bff2f..d73ff0ef 100644 --- a/core/register_core_types.cpp +++ b/core/register_core_types.cpp @@ -1,14 +1,37 @@ #include "register_core_types.h" -#include "types/list.h" +#include "core/engine.h" + #include "image/register_image_types.h" #include "math/register_math_types.h" +#include "types/list.h" +#include "types/variant_resource.h" + +#ifdef TOOLS_ENABLED +#include "editor/editor_node.h" +#include "editor/editor_resource_preview.h" +#include "types/editor/variant_resource_preview.h" +#endif namespace goost { +#ifdef TOOLS_ENABLED +static void _variant_resource_preview_init() { + Ref variant_resource_preview; + variant_resource_preview.instance(); + EditorResourcePreview::get_singleton()->add_preview_generator(variant_resource_preview); +} +#endif + void register_core_types() { ClassDB::register_class(); ClassDB::register_class(); + + ClassDB::register_class(); +#ifdef TOOLS_ENABLED + EditorNode::add_init_callback(_variant_resource_preview_init); +#endif + #ifdef GOOST_IMAGE_ENABLED register_image_types(); #endif diff --git a/core/types/editor/variant_resource_preview.cpp b/core/types/editor/variant_resource_preview.cpp new file mode 100644 index 00000000..467bb18b --- /dev/null +++ b/core/types/editor/variant_resource_preview.cpp @@ -0,0 +1,56 @@ +#include "variant_resource_preview.h" +#include "editor/editor_node.h" + +bool VariantResourcePreviewGenerator::handles(const String &p_type) const { + return p_type == "VariantResource"; +} + +Ref VariantResourcePreviewGenerator::generate(const Ref &p_from, const Size2 &p_size) const { + Ref var = p_from; + ERR_FAIL_COND_V_MSG(var.is_null(), Ref(), "Invalid reference to a VariantResource object."); + + const Variant &value = var->get_value(); + + Ref tex; + + switch (value.get_type()) { + case Variant::NIL: { + tex = EditorNode::get_singleton()->get_class_icon("Variant"); + } break; + case Variant::BOOL: { + bool b = value; + String builtin_name = Variant::get_type_name(value.get_type()); + String name = b ? "GuiChecked" : "GuiUnchecked"; + tex = EditorNode::get_singleton()->get_class_icon(name, builtin_name); + } break; + case Variant::COLOR: { + Color color = value; + Ref image; + image.instance(); + // The small icon will be stretched anyway, speed up generation. + image->create(2, 2, false, Image::FORMAT_RGBA8); + image->fill(color); + Ref img_tex; + img_tex.instance(); + img_tex->create_from_image(image, 0); + tex = img_tex; + } break; + case Variant::OBJECT: { + Object *obj = value; + Ref obj_tex = Ref(Object::cast_to(obj)); + if (obj_tex.is_valid()) { + Ref image = obj_tex->get_data(); + image->resize(p_size.x, p_size.y); + Ref img_tex; + img_tex.instance(); + img_tex->create_from_image(image, 0); + tex = img_tex; + } + } break; + default: { + String name = Variant::get_type_name(value.get_type()); + tex = EditorNode::get_singleton()->get_class_icon(name, "Resource"); + }; + } + return tex; +} diff --git a/core/types/editor/variant_resource_preview.h b/core/types/editor/variant_resource_preview.h new file mode 100644 index 00000000..5bacb326 --- /dev/null +++ b/core/types/editor/variant_resource_preview.h @@ -0,0 +1,18 @@ +#ifndef VARIANT_RESOURCE_PREVIEW_H +#define VARIANT_RESOURCE_PREVIEW_H + +#include "editor/editor_resource_preview.h" +#include "../variant_resource.h" + +class VariantResourcePreviewGenerator : public EditorResourcePreviewGenerator { + GDCLASS(VariantResourcePreviewGenerator, EditorResourcePreviewGenerator); + +public: + virtual bool handles(const String &p_type) const; + virtual Ref generate(const RES &p_from, const Size2 &p_size) const; + + virtual bool generate_small_preview_automatically() const { return true; }; + virtual bool can_generate_small_preview() const { return true; }; +}; + +#endif // VARIANT_RESOURCE_PREVIEW_H diff --git a/core/types/variant_resource.cpp b/core/types/variant_resource.cpp new file mode 100644 index 00000000..228f6b18 --- /dev/null +++ b/core/types/variant_resource.cpp @@ -0,0 +1,245 @@ +#include "variant_resource.h" + +void VariantResource::set_type(Variant::Type p_type) { + const Variant::Type prev_type = type; + type = p_type; + // Convert previous value to a new type, if possible. + if (prev_type != Variant::NIL) { + value = convert(value, type); + } else { + value = create(type); + } + emit_changed(); + _change_notify(); +} + +Variant VariantResource::create(const Variant::Type &p_type) { + Variant::CallError error; + return Variant::construct(p_type, nullptr, 0, error); +} + +Variant VariantResource::convert(const Variant &p_value, const Variant::Type &p_to_type) { + Variant::CallError error; + const Variant *args[1]; + args[0] = &p_value; + return Variant::construct(p_to_type, args, 1, error, false); // Non-strict. +} + +bool VariantResource::_set(const StringName &p_name, const Variant &p_value) { + String name = p_name.operator String(); + if (name == pi.name) { + value = p_value; + type = p_value.get_type(); + emit_changed(); + } else { + return false; + } + return true; +} + +bool VariantResource::_get(const StringName &p_name, Variant &r_ret) const { + String name = p_name.operator String(); + if (name == pi.name) { + r_ret = value; + } else { + return false; + } + return true; +} + +void VariantResource::set_property_name(const String &p_property_name) { + pi.name = p_property_name; + _change_notify(); +} + +void VariantResource::set_property_hint(PropertyHint p_property_hint) { + pi.hint = p_property_hint; + _change_notify(); +} + +void VariantResource::set_property_hint_string(const String &p_property_hint_string) { + pi.hint_string = p_property_hint_string; + _change_notify(); +} + +void VariantResource::set_property_usage(PropertyUsageFlags p_property_usage) { + pi.usage = p_property_usage; + _change_notify(); +} + +void VariantResource::_get_property_list(List *p_list) const { + // This property is changed dynamically from other properties. + p_list->push_back(PropertyInfo(type, pi.name, pi.hint, pi.hint_string, pi.usage)); +} + +String VariantResource::get_type_hints() { + String type_hints; + for (int i = 0; i < Variant::VARIANT_MAX; ++i) { + type_hints += Variant::get_type_name(Variant::Type(i)); + if (i < Variant::VARIANT_MAX - 1) { + type_hints += ","; + } + } + return type_hints; +} + +String VariantResource::get_property_hint_name(const PropertyHint &p_hint) { + switch (p_hint) { + case PROPERTY_HINT_NONE: { + return "None"; + } break; + case PROPERTY_HINT_RANGE: { + return "Range"; + } break; + case PROPERTY_HINT_EXP_RANGE: { + return "Exponential Range"; + } break; + case PROPERTY_HINT_ENUM: { + return "Enum"; + } break; + case PROPERTY_HINT_EXP_EASING: { + return "Exponential Easing"; + } break; + case PROPERTY_HINT_LENGTH: { + return "Length"; + } break; + case PROPERTY_HINT_SPRITE_FRAME: { + return "SpriteFrame"; + } break; + case PROPERTY_HINT_KEY_ACCEL: { + return "Key Accel"; + } break; + case PROPERTY_HINT_FLAGS: { + return "Flags"; + } break; + case PROPERTY_HINT_LAYERS_2D_RENDER: { + return "Layers 2D Render"; + } break; + case PROPERTY_HINT_LAYERS_2D_PHYSICS: { + return "Layers 2D Physics"; + } break; + case PROPERTY_HINT_LAYERS_3D_RENDER: { + return "Layers 3D Render"; + } break; + case PROPERTY_HINT_LAYERS_3D_PHYSICS: { + return "Layers 3D Physics"; + } break; + case PROPERTY_HINT_FILE: { + return "File"; + } break; + case PROPERTY_HINT_DIR: { + return "Directory"; + } break; + case PROPERTY_HINT_GLOBAL_FILE: { + return "Global File"; + } break; + case PROPERTY_HINT_GLOBAL_DIR: { + return "Global Directory"; + } break; + case PROPERTY_HINT_RESOURCE_TYPE: { + return "Resource Type"; + } break; + case PROPERTY_HINT_MULTILINE_TEXT: { + return "Multiline Text"; + } break; + case PROPERTY_HINT_PLACEHOLDER_TEXT: { + return "Placeholder Text"; + } break; + case PROPERTY_HINT_COLOR_NO_ALPHA: { + return "Color No Alpha"; + } break; + case PROPERTY_HINT_IMAGE_COMPRESS_LOSSY: { + return "Image Compress Lossy"; + } break; + case PROPERTY_HINT_IMAGE_COMPRESS_LOSSLESS: { + return "Image Compress Lossless"; + } break; + case PROPERTY_HINT_OBJECT_ID: { + return "ObjectID"; + } break; + case PROPERTY_HINT_TYPE_STRING: { + return "String"; + } break; + case PROPERTY_HINT_NODE_PATH_TO_EDITED_NODE: { + return "NodePath To Edited Node"; + } break; + case PROPERTY_HINT_METHOD_OF_VARIANT_TYPE: { + return "Method Of Variant Type"; + } break; + case PROPERTY_HINT_METHOD_OF_BASE_TYPE: { + return "Method Of Base Type"; + } break; + case PROPERTY_HINT_METHOD_OF_INSTANCE: { + return "Method Of Instance"; + } break; + case PROPERTY_HINT_METHOD_OF_SCRIPT: { + return "Method Of Script"; + } break; + case PROPERTY_HINT_PROPERTY_OF_VARIANT_TYPE: { + return "Property Of Variant Type"; + } break; + case PROPERTY_HINT_PROPERTY_OF_BASE_TYPE: { + return "Property Of Base Type"; + } break; + case PROPERTY_HINT_PROPERTY_OF_INSTANCE: { + return "Property Of Instance"; + } break; + case PROPERTY_HINT_PROPERTY_OF_SCRIPT: { + return "Property Of Script"; + } break; + case PROPERTY_HINT_OBJECT_TOO_BIG: { + return "Object Too Big"; + } break; + case PROPERTY_HINT_NODE_PATH_VALID_TYPES: { + return "NodePath Valid Types"; + } break; + case PROPERTY_HINT_SAVE_FILE: { + return "Save File"; + } break; + case PROPERTY_HINT_MAX: { + ERR_FAIL_V_MSG("", "Invalid property hint type."); + } break; + } + return ""; +} + +String VariantResource::get_property_hint_types() { + String hint_types; + for (int i = 0; i < PropertyHint::PROPERTY_HINT_MAX; ++i) { + hint_types += VariantResource::get_property_hint_name(PropertyHint(i)); + if (i < PropertyHint::PROPERTY_HINT_MAX - 1) { + hint_types += ","; + } + } + return hint_types; +} + +void VariantResource::_bind_methods() { + ClassDB::bind_method(D_METHOD("set_type", "type"), &VariantResource::set_type); + ClassDB::bind_method(D_METHOD("get_type"), &VariantResource::get_type); + + ClassDB::bind_method(D_METHOD("set_value", "value"), &VariantResource::set_value); + ClassDB::bind_method(D_METHOD("get_value"), &VariantResource::get_value); + + ClassDB::bind_method(D_METHOD("set_property_name", "name"), &VariantResource::set_property_name); + ClassDB::bind_method(D_METHOD("get_property_name"), &VariantResource::get_property_name); + + ClassDB::bind_method(D_METHOD("set_property_hint", "hint"), &VariantResource::set_property_hint); + ClassDB::bind_method(D_METHOD("get_property_hint"), &VariantResource::get_property_hint); + + ClassDB::bind_method(D_METHOD("set_property_hint_string", "hint_string"), &VariantResource::set_property_hint_string); + ClassDB::bind_method(D_METHOD("get_property_hint_string"), &VariantResource::get_property_hint_string); + + ClassDB::bind_method(D_METHOD("set_property_usage", "usage"), &VariantResource::set_property_usage); + ClassDB::bind_method(D_METHOD("get_property_usage"), &VariantResource::get_property_usage); + + // DO NOT expose `value` as a property here, this is handled by `_get_property_list()` instead. + + ADD_PROPERTY(PropertyInfo(Variant::INT, "type", PROPERTY_HINT_ENUM, get_type_hints()), "set_type", "get_type"); + + ADD_GROUP("Property", "property_"); + ADD_PROPERTY(PropertyInfo(Variant::STRING, "property_name"), "set_property_name", "get_property_name"); + ADD_PROPERTY(PropertyInfo(Variant::INT, "property_hint", PROPERTY_HINT_ENUM, get_property_hint_types()), "set_property_hint", "get_property_hint"); + ADD_PROPERTY(PropertyInfo(Variant::STRING, "property_hint_string"), "set_property_hint_string", "get_property_hint_string"); + ADD_PROPERTY(PropertyInfo(Variant::INT, "property_usage"), "set_property_usage", "get_property_usage"); +} diff --git a/core/types/variant_resource.h b/core/types/variant_resource.h new file mode 100644 index 00000000..861e2258 --- /dev/null +++ b/core/types/variant_resource.h @@ -0,0 +1,55 @@ +#ifndef GOOST_VARIANT_RESOURCE_H +#define GOOST_VARIANT_RESOURCE_H + +#include "core/resource.h" +#include "core/variant.h" + +class VariantResource : public Resource { + GDCLASS(VariantResource, Resource); + +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 *p_list) const; + static void _bind_methods(); + + Variant value; + Variant::Type type = Variant::NIL; + PropertyInfo pi; + +public: + void set_type(Variant::Type p_type); + int get_type() const { return type; } + + void set_value(const Variant &p_value) { set(pi.name, p_value); } + Variant get_value() const { return get(pi.name); } + + void set_property_name(const String &p_property_name); + String get_property_name() const { return pi.name; }; + + void set_property_hint(PropertyHint p_property_hint); + PropertyHint get_property_hint() const { return pi.hint; }; + + void set_property_hint_string(const String &p_property_hint_string); + String get_property_hint_string() const { return pi.hint_string; }; + + void set_property_usage(PropertyUsageFlags p_property_usage); + PropertyUsageFlags get_property_usage() const { return PropertyUsageFlags(pi.usage); }; + + static Variant create(const Variant::Type &p_type); + static Variant convert(const Variant &p_value, const Variant::Type &p_to_type); + + static String get_type_hints(); + // This should be in Godot, just like `Variant::get_type_name()` method. + static String get_property_hint_name(const PropertyHint &p_hint); + static String get_property_hint_types(); + + virtual String to_string() { return String(value); } + + VariantResource() { + // Default, but can be configured with `property_name` property. + pi.name = "value"; + } +}; + +#endif // GOOST_VARIANT_RESOURCE_H diff --git a/doc/VariantResource.xml b/doc/VariantResource.xml new file mode 100644 index 00000000..45cd2928 --- /dev/null +++ b/doc/VariantResource.xml @@ -0,0 +1,73 @@ + + + + A [Resource] which holds any [Variant] compatible type. + + + This class allows to store any [Variant] compatible built-in types as a [Resource], such as [Vector2], [Dictionary], [Array], and even nested[VariantResource]s themselves. These can be edited in the inspector and saved to disk to be reused throughout the project, as resources are shared between instances by default. + [VariantResource] is normally edited via the editor inspector, but the [member type] and [code]value[/code] can be changed via code as well: + [codeblock] + var res = VariantResource.new() + res.value = Vector3(1, 2, 3) # The type is set automatically. + print(res.value) # prints (1, 2, 3) + res.type = TYPE_VECTOR2 # The previous value is converted to a new type. + print(res.value) # prints (1, 2) + [/codeblock] + The conversion logic is mostly equivalent to [method @GDScript.convert], except that the [constant @GlobalScope.TYPE_NIL] is never automatically converted to other types, and a new empty [Variant] is constructed instead. + + + + + + + + + Returns [Variant] data associated with this resource. The method is recommended to use over [method Object.get] as the property's name may be customized with [member property_name]. + + + + + + + + + Modifies existing value of this resource. The value's type is updated automatically if types differ. The method is recommended to use over [method Object.set] as the property's name may be customized with [member property_name]. + + + + + + Specifies how the value is represented in the editor, one of [enum @GlobalScope.PropertyHint] values. + + + Configures [member property_hint]. + + + Specifies the value's property name. By default, the data can be fetched via code by referencing the [code]value[/code] property, but this can be customized. Prefer to use the implicit default [code]value[/code] property, unless you're not sure whether the property's name is customized. + + + Specifies how the value should be used throughout the editor and code, a combination of [enum @GlobalScope.PropertyUsageFlags] values. + + + Sets the type of the [Variant], one of the [code]TYPE_*[/code] constants available at [@GlobalScope], such as [constant @GlobalScope.TYPE_INT]. + Once the type is set, an implicit [Variant] [code]value[/code] property is constructed. The [code]value[/code] property can be changed dynamically anytime, and this emits the [signal changed] signal, which can be connected to other script or engine methods: + [codeblock] + extends Node2D + + export(VariantResource) var res = VariantResource.new() + + func _ready(): + # Whenever the color is changed, redraw the canvas. + res.connect("changed", self, "update") + # This emits the "changed" signal above. + res.value = Color.blue + + func _draw(): + if res.type == TYPE_COLOR: + draw_circle(Vector2(), 100, res.value) + [/codeblock] + + + + + diff --git a/editor/icons/icon_variant_resource.svg b/editor/icons/icon_variant_resource.svg new file mode 100644 index 00000000..2dd72ecb --- /dev/null +++ b/editor/icons/icon_variant_resource.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/goost.py b/goost.py index 2100e37e..579a0085 100644 --- a/goost.py +++ b/goost.py @@ -59,6 +59,7 @@ def get_child_components(parent): "PolyNode2D", "Random", "ShapeCast2D", + "VariantResource", "VisualShape2D", ] classes_dependencies = { diff --git a/tests/project/goost/core/types/resources/0.tres b/tests/project/goost/core/types/resources/0.tres new file mode 100644 index 00000000..e77163e5 --- /dev/null +++ b/tests/project/goost/core/types/resources/0.tres @@ -0,0 +1,4 @@ +[gd_resource type="VariantResource" format=2] + +[resource] +value = null diff --git a/tests/project/goost/core/types/resources/1.tres b/tests/project/goost/core/types/resources/1.tres new file mode 100644 index 00000000..bb3405ae --- /dev/null +++ b/tests/project/goost/core/types/resources/1.tres @@ -0,0 +1,5 @@ +[gd_resource type="VariantResource" format=2] + +[resource] +type = 1 +value = true diff --git a/tests/project/goost/core/types/resources/10.tres b/tests/project/goost/core/types/resources/10.tres new file mode 100644 index 00000000..39d2d9eb --- /dev/null +++ b/tests/project/goost/core/types/resources/10.tres @@ -0,0 +1,5 @@ +[gd_resource type="VariantResource" format=2] + +[resource] +type = 10 +value = Quat( 0, 0, 0, 1 ) diff --git a/tests/project/goost/core/types/resources/11.tres b/tests/project/goost/core/types/resources/11.tres new file mode 100644 index 00000000..9fb5418d --- /dev/null +++ b/tests/project/goost/core/types/resources/11.tres @@ -0,0 +1,5 @@ +[gd_resource type="VariantResource" format=2] + +[resource] +type = 11 +value = AABB( 0, 0, 0, 0, 0, 0 ) diff --git a/tests/project/goost/core/types/resources/12.tres b/tests/project/goost/core/types/resources/12.tres new file mode 100644 index 00000000..338c702a --- /dev/null +++ b/tests/project/goost/core/types/resources/12.tres @@ -0,0 +1,5 @@ +[gd_resource type="VariantResource" format=2] + +[resource] +type = 12 +value = Basis( 1, 0, 0, 0, 1, 0, 0, 0, 1 ) diff --git a/tests/project/goost/core/types/resources/13.tres b/tests/project/goost/core/types/resources/13.tres new file mode 100644 index 00000000..4581518a --- /dev/null +++ b/tests/project/goost/core/types/resources/13.tres @@ -0,0 +1,5 @@ +[gd_resource type="VariantResource" format=2] + +[resource] +type = 13 +value = Transform( 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0 ) diff --git a/tests/project/goost/core/types/resources/14.tres b/tests/project/goost/core/types/resources/14.tres new file mode 100644 index 00000000..70e8fe70 --- /dev/null +++ b/tests/project/goost/core/types/resources/14.tres @@ -0,0 +1,5 @@ +[gd_resource type="VariantResource" format=2] + +[resource] +type = 14 +value = Color( 0.105882, 0.501961, 0.819608, 1 ) diff --git a/tests/project/goost/core/types/resources/15.tres b/tests/project/goost/core/types/resources/15.tres new file mode 100644 index 00000000..192ffa8d --- /dev/null +++ b/tests/project/goost/core/types/resources/15.tres @@ -0,0 +1,5 @@ +[gd_resource type="VariantResource" format=2] + +[resource] +type = 15 +value = NodePath("") diff --git a/tests/project/goost/core/types/resources/16.tres b/tests/project/goost/core/types/resources/16.tres new file mode 100644 index 00000000..4f3dc978 --- /dev/null +++ b/tests/project/goost/core/types/resources/16.tres @@ -0,0 +1,5 @@ +[gd_resource type="VariantResource" format=2] + +[resource] +type = 16 +value = diff --git a/tests/project/goost/core/types/resources/17.tres b/tests/project/goost/core/types/resources/17.tres new file mode 100644 index 00000000..3aefac07 --- /dev/null +++ b/tests/project/goost/core/types/resources/17.tres @@ -0,0 +1,4 @@ +[gd_resource type="VariantResource" format=2] + +[resource] +type = 17 diff --git a/tests/project/goost/core/types/resources/18.tres b/tests/project/goost/core/types/resources/18.tres new file mode 100644 index 00000000..50566f9d --- /dev/null +++ b/tests/project/goost/core/types/resources/18.tres @@ -0,0 +1,6 @@ +[gd_resource type="VariantResource" format=2] + +[resource] +type = 18 +value = { +} diff --git a/tests/project/goost/core/types/resources/19.tres b/tests/project/goost/core/types/resources/19.tres new file mode 100644 index 00000000..8757e368 --- /dev/null +++ b/tests/project/goost/core/types/resources/19.tres @@ -0,0 +1,5 @@ +[gd_resource type="VariantResource" format=2] + +[resource] +type = 19 +value = [ ] diff --git a/tests/project/goost/core/types/resources/2.tres b/tests/project/goost/core/types/resources/2.tres new file mode 100644 index 00000000..b2c7a687 --- /dev/null +++ b/tests/project/goost/core/types/resources/2.tres @@ -0,0 +1,5 @@ +[gd_resource type="VariantResource" format=2] + +[resource] +type = 20 +value = PoolByteArray( ) diff --git a/tests/project/goost/core/types/resources/20.tres b/tests/project/goost/core/types/resources/20.tres new file mode 100644 index 00000000..0920218a --- /dev/null +++ b/tests/project/goost/core/types/resources/20.tres @@ -0,0 +1,5 @@ +[gd_resource type="VariantResource" format=2] + +[resource] +type = 21 +value = PoolIntArray( ) diff --git a/tests/project/goost/core/types/resources/21.tres b/tests/project/goost/core/types/resources/21.tres new file mode 100644 index 00000000..a97f6943 --- /dev/null +++ b/tests/project/goost/core/types/resources/21.tres @@ -0,0 +1,5 @@ +[gd_resource type="VariantResource" format=2] + +[resource] +type = 22 +value = PoolRealArray( ) diff --git a/tests/project/goost/core/types/resources/22.tres b/tests/project/goost/core/types/resources/22.tres new file mode 100644 index 00000000..ed974744 --- /dev/null +++ b/tests/project/goost/core/types/resources/22.tres @@ -0,0 +1,5 @@ +[gd_resource type="VariantResource" format=2] + +[resource] +type = 23 +value = PoolStringArray( ) diff --git a/tests/project/goost/core/types/resources/23.tres b/tests/project/goost/core/types/resources/23.tres new file mode 100644 index 00000000..c306e513 --- /dev/null +++ b/tests/project/goost/core/types/resources/23.tres @@ -0,0 +1,5 @@ +[gd_resource type="VariantResource" format=2] + +[resource] +type = 24 +value = PoolVector2Array( ) diff --git a/tests/project/goost/core/types/resources/24.tres b/tests/project/goost/core/types/resources/24.tres new file mode 100644 index 00000000..5ecc4e44 --- /dev/null +++ b/tests/project/goost/core/types/resources/24.tres @@ -0,0 +1,5 @@ +[gd_resource type="VariantResource" format=2] + +[resource] +type = 25 +value = PoolVector3Array( ) diff --git a/tests/project/goost/core/types/resources/25.tres b/tests/project/goost/core/types/resources/25.tres new file mode 100644 index 00000000..5ecc4e44 --- /dev/null +++ b/tests/project/goost/core/types/resources/25.tres @@ -0,0 +1,5 @@ +[gd_resource type="VariantResource" format=2] + +[resource] +type = 25 +value = PoolVector3Array( ) diff --git a/tests/project/goost/core/types/resources/26.tres b/tests/project/goost/core/types/resources/26.tres new file mode 100644 index 00000000..53735fac --- /dev/null +++ b/tests/project/goost/core/types/resources/26.tres @@ -0,0 +1,5 @@ +[gd_resource type="VariantResource" format=2] + +[resource] +type = 26 +value = PoolColorArray( 0.705882, 0, 0, 1, 0, 0.721569, 0, 1, 0, 0, 0.92549, 1 ) diff --git a/tests/project/goost/core/types/resources/3.tres b/tests/project/goost/core/types/resources/3.tres new file mode 100644 index 00000000..aa0eb330 --- /dev/null +++ b/tests/project/goost/core/types/resources/3.tres @@ -0,0 +1,5 @@ +[gd_resource type="VariantResource" format=2] + +[resource] +type = 3 +value = 0.0 diff --git a/tests/project/goost/core/types/resources/4.tres b/tests/project/goost/core/types/resources/4.tres new file mode 100644 index 00000000..f1257931 --- /dev/null +++ b/tests/project/goost/core/types/resources/4.tres @@ -0,0 +1,6 @@ +[gd_resource type="VariantResource" format=2] + +[resource] +type = 4 +property_hint = 18 +value = "Hello World!" diff --git a/tests/project/goost/core/types/resources/5.tres b/tests/project/goost/core/types/resources/5.tres new file mode 100644 index 00000000..e26f8ab3 --- /dev/null +++ b/tests/project/goost/core/types/resources/5.tres @@ -0,0 +1,5 @@ +[gd_resource type="VariantResource" format=2] + +[resource] +type = 5 +value = Vector2( 0, 0 ) diff --git a/tests/project/goost/core/types/resources/6.tres b/tests/project/goost/core/types/resources/6.tres new file mode 100644 index 00000000..8d4566b9 --- /dev/null +++ b/tests/project/goost/core/types/resources/6.tres @@ -0,0 +1,5 @@ +[gd_resource type="VariantResource" format=2] + +[resource] +type = 6 +value = Rect2( 0, 0, 0, 0 ) diff --git a/tests/project/goost/core/types/resources/7.tres b/tests/project/goost/core/types/resources/7.tres new file mode 100644 index 00000000..20aa75db --- /dev/null +++ b/tests/project/goost/core/types/resources/7.tres @@ -0,0 +1,5 @@ +[gd_resource type="VariantResource" format=2] + +[resource] +type = 7 +value = Vector3( 0, 0, 0 ) diff --git a/tests/project/goost/core/types/resources/8.tres b/tests/project/goost/core/types/resources/8.tres new file mode 100644 index 00000000..9ccf8f8f --- /dev/null +++ b/tests/project/goost/core/types/resources/8.tres @@ -0,0 +1,5 @@ +[gd_resource type="VariantResource" format=2] + +[resource] +type = 8 +value = Transform2D( 1, 0, 0, 1, 0, 0 ) diff --git a/tests/project/goost/core/types/resources/9.tres b/tests/project/goost/core/types/resources/9.tres new file mode 100644 index 00000000..3ffcec64 --- /dev/null +++ b/tests/project/goost/core/types/resources/9.tres @@ -0,0 +1,5 @@ +[gd_resource type="VariantResource" format=2] + +[resource] +type = 9 +value = Plane( 0, 0, 0, 0 ) diff --git a/tests/project/goost/core/types/test_variant_resource.gd b/tests/project/goost/core/types/test_variant_resource.gd new file mode 100644 index 00000000..a6d681d3 --- /dev/null +++ b/tests/project/goost/core/types/test_variant_resource.gd @@ -0,0 +1,58 @@ +extends "res://addons/gut/test.gd" + +var res: VariantResource + + +func before_each(): + res = VariantResource.new() + + +func test_set_type(): + res.type = TYPE_VECTOR2 + assert_eq(res.type, TYPE_VECTOR2) + + +func test_set_value(): + res.value = Color.blue + assert_eq(res.value, Color.blue) + assert_eq(res.type, TYPE_COLOR, "Should automatically switch type.") + + +func test_set_value_convert_type(): + res.value = PoolStringArray(["Godot", "merge", "Goost"]) + assert_eq(res.type, TYPE_STRING_ARRAY) + + res.type = TYPE_STRING + assert_eq(res.value, "[Godot, merge, Goost]", + "Should automatically convert previous value to compatible type.") + + res.value = Vector3(1, 2, 3) + assert_eq(res.type, TYPE_VECTOR3) + res.type = TYPE_VECTOR2 + assert_eq(res.value, Vector2(1, 2), + "Should automatically convert previous value to compatible type.") + + +func test_changed_signal(): + watch_signals(res) + res.value = "Godot" + var err = res.connect("changed", self, "_on_changed", [res], CONNECT_ONESHOT) + assert_eq(err, OK) + res.value = "Goost" + assert_signal_emitted(res, "changed") + + +func _on_changed(p_res): + assert_eq(p_res.value, "Goost") + + +func test_convert_from_null_to_string(): + res.value = null + assert_eq(res.type, TYPE_NIL) + + res.type = TYPE_STRING + assert_ne(res.value, "Null") + assert_ne(res.value, "Nil") + assert_ne(res.value, "null") + assert_ne(res.value, "nil") + assert_eq(res.value, "")