Skip to content

Commit

Permalink
Merge pull request #30 from goostengine/variant-resource
Browse files Browse the repository at this point in the history
  • Loading branch information
Xrayez authored Nov 1, 2020
2 parents 2b82de1 + 4c33f28 commit 48f5452
Show file tree
Hide file tree
Showing 37 changed files with 669 additions and 1 deletion.
3 changes: 3 additions & 0 deletions core/SCsub
Original file line number Diff line number Diff line change
Expand Up @@ -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")
25 changes: 24 additions & 1 deletion core/register_core_types.cpp
Original file line number Diff line number Diff line change
@@ -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<VariantResourcePreviewGenerator> variant_resource_preview;
variant_resource_preview.instance();
EditorResourcePreview::get_singleton()->add_preview_generator(variant_resource_preview);
}
#endif

void register_core_types() {
ClassDB::register_class<ListNode>();
ClassDB::register_class<LinkedList>();

ClassDB::register_class<VariantResource>();
#ifdef TOOLS_ENABLED
EditorNode::add_init_callback(_variant_resource_preview_init);
#endif

#ifdef GOOST_IMAGE_ENABLED
register_image_types();
#endif
Expand Down
56 changes: 56 additions & 0 deletions core/types/editor/variant_resource_preview.cpp
Original file line number Diff line number Diff line change
@@ -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<Texture> VariantResourcePreviewGenerator::generate(const Ref<Resource> &p_from, const Size2 &p_size) const {
Ref<VariantResource> var = p_from;
ERR_FAIL_COND_V_MSG(var.is_null(), Ref<VariantResource>(), "Invalid reference to a VariantResource object.");

const Variant &value = var->get_value();

Ref<Texture> 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;
image.instance();
// The small icon will be stretched anyway, speed up generation.
image->create(2, 2, false, Image::FORMAT_RGBA8);
image->fill(color);
Ref<ImageTexture> img_tex;
img_tex.instance();
img_tex->create_from_image(image, 0);
tex = img_tex;
} break;
case Variant::OBJECT: {
Object *obj = value;
Ref<Texture> obj_tex = Ref<Texture>(Object::cast_to<Texture>(obj));
if (obj_tex.is_valid()) {
Ref<Image> image = obj_tex->get_data();
image->resize(p_size.x, p_size.y);
Ref<ImageTexture> 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;
}
18 changes: 18 additions & 0 deletions core/types/editor/variant_resource_preview.h
Original file line number Diff line number Diff line change
@@ -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<Texture> 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
245 changes: 245 additions & 0 deletions core/types/variant_resource.cpp
Original file line number Diff line number Diff line change
@@ -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<PropertyInfo> *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");
}
Loading

0 comments on commit 48f5452

Please sign in to comment.