Browse Source

Add sample test project

George Marques 4 years ago
parent
commit
b3a4a2cf93

+ 1 - 0
.gitignore

@@ -1,6 +1,7 @@
 # Godot auto generated files
 *.gen.*
 .import/
+.godot/
 /gen/
 
 # Misc

+ 71 - 71
test/SConstruct

@@ -4,33 +4,32 @@ import sys
 
 # Try to detect the host platform automatically.
 # This is used if no `platform` argument is passed
-if sys.platform.startswith('linux'):
-    host_platform = 'linux'
-elif sys.platform == 'darwin':
-    host_platform = 'osx'
-elif sys.platform == 'win32' or sys.platform == 'msys':
-    host_platform = 'windows'
+if sys.platform.startswith("linux"):
+    host_platform = "linux"
+elif sys.platform == "darwin":
+    host_platform = "osx"
+elif sys.platform == "win32" or sys.platform == "msys":
+    host_platform = "windows"
 else:
-    raise ValueError(
-        'Could not detect platform automatically, please specify with '
-        'platform=<platform>'
-    )
+    raise ValueError("Could not detect platform automatically, please specify with " "platform=<platform>")
 
-env = Environment(ENV = os.environ)
+env = Environment(ENV=os.environ)
 
 opts = Variables([], ARGUMENTS)
 
 # Define our options
-opts.Add(EnumVariable('target', "Compilation target", 'debug', ['d', 'debug', 'r', 'release']))
-opts.Add(EnumVariable('platform', "Compilation platform", host_platform, ['', 'windows', 'x11', 'linux', 'osx']))
-opts.Add(EnumVariable('p', "Compilation target, alias for 'platform'", host_platform, ['', 'windows', 'x11', 'linux', 'osx']))
-opts.Add(EnumVariable('bits', 'Target platform bits', '64', ('32', '64')))
-opts.Add(BoolVariable('use_llvm', "Use the LLVM / Clang compiler", 'no'))
-opts.Add(PathVariable('target_path', 'The path where the lib is installed.', 'bin/', PathVariable.PathAccept))
-opts.Add(PathVariable('target_name', 'The library name.', 'libgdexample', PathVariable.PathAccept))
+opts.Add(EnumVariable("target", "Compilation target", "debug", ["d", "debug", "r", "release"]))
+opts.Add(EnumVariable("platform", "Compilation platform", host_platform, ["", "windows", "x11", "linux", "osx"]))
+opts.Add(
+    EnumVariable("p", "Compilation target, alias for 'platform'", host_platform, ["", "windows", "x11", "linux", "osx"])
+)
+opts.Add(EnumVariable("bits", "Target platform bits", "64", ("32", "64")))
+opts.Add(BoolVariable("use_llvm", "Use the LLVM / Clang compiler", "no"))
+opts.Add(PathVariable("target_path", "The path where the lib is installed.", "bin/", PathVariable.PathAccept))
+opts.Add(PathVariable("target_name", "The library name.", "libgdexample", PathVariable.PathAccept))
 
 # Local dependency paths, adapt them to your setup
-godot_headers_path = "../godot-headers/"
+godot_headers_path = "../godot-headers-temp/"
 cpp_bindings_path = "../"
 cpp_library = "libgodot-cpp"
 
@@ -45,25 +44,25 @@ Help(opts.GenerateHelpText(env))
 # This makes sure to keep the session environment variables on Windows.
 # This way, you can run SCons in a Visual Studio 2017 prompt and it will find
 # all the required tools
-if host_platform == 'windows' and env['platform'] != 'android':
-    if env['bits'] == '64':
-        env = Environment(TARGET_ARCH='amd64')
-    elif env['bits'] == '32':
-        env = Environment(TARGET_ARCH='x86')
+if host_platform == "windows" and env["platform"] != "android":
+    if env["bits"] == "64":
+        env = Environment(TARGET_ARCH="amd64")
+    elif env["bits"] == "32":
+        env = Environment(TARGET_ARCH="x86")
 
     opts.Update(env)
 
 # Process some arguments
-if env['use_llvm']:
-    env['CC'] = 'clang'
-    env['CXX'] = 'clang++'
+if env["use_llvm"]:
+    env["CC"] = "clang"
+    env["CXX"] = "clang++"
 
-if env['p'] != '':
-    env['platform'] = env['p']
+if env["p"] != "":
+    env["platform"] = env["p"]
 
-if env['platform'] == '':
+if env["platform"] == "":
     print("No valid target platform selected.")
-    quit();
+    quit()
 
 # For the reference:
 # - CCFLAGS are compilation flags shared between C and C++
@@ -73,63 +72,64 @@ if env['platform'] == '':
 # - CPPDEFINES are for pre-processor defines
 # - LINKFLAGS are for linking flags
 
+if env["target"] == "debug":
+    env.Append(CPPDEFINES=["DEBUG_ENABLED", "DEBUG_METHODS_ENABLED"])
+
 # Check our platform specifics
-if env['platform'] == "osx":
-    env['target_path'] += 'osx/'
-    cpp_library += '.osx'
-    env.Append(CCFLAGS=['-arch', 'x86_64'])
-    env.Append(CXXFLAGS=['-std=c++17'])
-    env.Append(LINKFLAGS=['-arch', 'x86_64'])
-    if env['target'] in ('debug', 'd'):
-        env.Append(CCFLAGS=['-g', '-O2'])
+if env["platform"] == "osx":
+    env["target_path"] += "osx/"
+    cpp_library += ".osx"
+    env.Append(CCFLAGS=["-arch", "x86_64"])
+    env.Append(CXXFLAGS=["-std=c++17"])
+    env.Append(LINKFLAGS=["-arch", "x86_64"])
+    if env["target"] in ("debug", "d"):
+        env.Append(CCFLAGS=["-g", "-O2"])
     else:
-        env.Append(CCFLAGS=['-g', '-O3'])
-
-elif env['platform'] in ('x11', 'linux'):
-    env['target_path'] += 'x11/'
-    cpp_library += '.linux'
-    env.Append(CCFLAGS=['-fPIC'])
-    env.Append(CXXFLAGS=['-std=c++17'])
-    if env['target'] in ('debug', 'd'):
-        env.Append(CCFLAGS=['-g3', '-Og'])
+        env.Append(CCFLAGS=["-g", "-O3"])
+
+elif env["platform"] in ("x11", "linux"):
+    env["target_path"] += "x11/"
+    cpp_library += ".linux"
+    env.Append(CCFLAGS=["-fPIC"])
+    env.Append(CXXFLAGS=["-std=c++17"])
+    if env["target"] in ("debug", "d"):
+        env.Append(CCFLAGS=["-g3", "-Og"])
     else:
-        env.Append(CCFLAGS=['-g', '-O3'])
+        env.Append(CCFLAGS=["-g", "-O3"])
 
-elif env['platform'] == "windows":
-    env['target_path'] += 'win64/'
-    cpp_library += '.windows'
+elif env["platform"] == "windows":
+    env["target_path"] += "win64/"
+    cpp_library += ".windows"
     # This makes sure to keep the session environment variables on windows,
     # that way you can run scons in a vs 2017 prompt and it will find all the required tools
     env.Append(ENV=os.environ)
 
-    env.Append(CPPDEFINES=['WIN32', '_WIN32', '_WINDOWS', '_CRT_SECURE_NO_WARNINGS'])
-    env.Append(CCFLAGS=['-W3', '-GR'])
-    env.Append(CXXFLAGS=['-std:c++17'])
-    if env['target'] in ('debug', 'd'):
-        env.Append(CPPDEFINES=['_DEBUG'])
-        env.Append(CCFLAGS=['-EHsc', '-MDd', '-ZI'])
-        env.Append(LINKFLAGS=['-DEBUG'])
+    env.Append(CPPDEFINES=["WIN32", "_WIN32", "_WINDOWS", "_CRT_SECURE_NO_WARNINGS"])
+    env.Append(CCFLAGS=["-W3", "-GR"])
+    if env["target"] in ("debug", "d"):
+        env.Append(CPPDEFINES=["_DEBUG"])
+        env.Append(CCFLAGS=["-EHsc", "-MDd", "-ZI"])
+        env.Append(LINKFLAGS=["-DEBUG"])
     else:
-        env.Append(CPPDEFINES=['NDEBUG'])
-        env.Append(CCFLAGS=['-O2', '-EHsc', '-MD'])
+        env.Append(CPPDEFINES=["NDEBUG"])
+        env.Append(CCFLAGS=["-O2", "-EHsc", "-MD"])
 
-if env['target'] in ('debug', 'd'):
-    cpp_library += '.debug'
+if env["target"] in ("debug", "d"):
+    cpp_library += ".debug"
 else:
-    cpp_library += '.release'
+    cpp_library += ".release"
 
-cpp_library += '.' + str(bits)
+cpp_library += "." + str(bits)
 
 # make sure our binding library is properly includes
-env.Append(CPPPATH=['.', godot_headers_path, cpp_bindings_path + 'include/', cpp_bindings_path + 'include/core/', cpp_bindings_path + 'include/gen/'])
-env.Append(LIBPATH=[cpp_bindings_path + 'bin/'])
+env.Append(CPPPATH=[".", godot_headers_path, cpp_bindings_path + "include/", cpp_bindings_path + "gen/include/"])
+env.Append(LIBPATH=[cpp_bindings_path + "bin/"])
 env.Append(LIBS=[cpp_library])
 
 # tweak this if you want to use different folders, or more folders, to store your source code in.
-env.Append(CPPPATH=['src/'])
-sources = Glob('src/*.cpp')
+env.Append(CPPPATH=["src/"])
+sources = Glob("src/*.cpp")
 
-library = env.SharedLibrary(target=env['target_path'] + env['target_name'] , source=sources)
+library = env.SharedLibrary(target=env["target_path"] + env["target_name"], source=sources)
 
 Default(library)
-

+ 7 - 0
test/default_env.tres

@@ -0,0 +1,7 @@
+[gd_resource type="Environment" load_steps=2 format=3 uid="uid://dtd3q2x2ulcsi"]
+
+[sub_resource type="Sky" id="1"]
+
+[resource]
+background_mode = 2
+sky = SubResource( "1" )

+ 7 - 0
test/example.gdextension

@@ -0,0 +1,7 @@
+[configuration]
+
+entry_symbol = "example_library_init"
+
+[libraries]
+
+Linux.64 = "bin/x11/libgdexample.so"

BIN
test/icon.png


+ 35 - 0
test/icon.png.import

@@ -0,0 +1,35 @@
+[remap]
+
+importer="texture"
+type="StreamTexture2D"
+uid="uid://cswr8vy4lt7dt"
+path="res://.godot/imported/icon.png-487276ed1e3a0c39cad0279d744ee560.stex"
+metadata={
+"vram_texture": false
+}
+
+[deps]
+
+source_file="res://icon.png"
+dest_files=["res://.godot/imported/icon.png-487276ed1e3a0c39cad0279d744ee560.stex"]
+
+[params]
+
+compress/mode=0
+compress/lossy_quality=0.7
+compress/hdr_compression=1
+compress/bptc_ldr=0
+compress/normal_map=0
+compress/channel_pack=0
+compress/streamed=false
+mipmaps/generate=false
+mipmaps/limit=-1
+roughness/mode=0
+roughness/src_normal=""
+process/fix_alpha_border=true
+process/premult_alpha=false
+process/normal_map_invert_y=false
+process/HDR_as_SRGB=false
+process/size_limit=0
+detect_3d/compress_to=1
+svg/scale=1.0

+ 26 - 0
test/main.gd

@@ -0,0 +1,26 @@
+extends Node
+
+func _ready():
+	# Connect signals.
+	$Button.button_up.connect($Example.emit_custom_signal, ["Button", 42])
+	$Example.custom_signal.connect(on_signal)
+
+	# Call methods.
+	$Example.simple_func()
+	($Example as Example).simple_const_func() # Force use of ptrcall
+	prints("returned", $Example.return_something("some string"))
+	prints("returned const", $Example.return_something_const())
+	prints("vararg args", $Example.varargs_func("some", "arguments", "to", "test"))
+
+	# Use properties.
+	prints("custom postion is", $Example.custom_position)
+	$Example.custom_position = Vector2(50, 50)
+	prints("custom postion now is", $Example.custom_position)
+
+	# Get constants
+	prints("FIRST", $Example.FIRST)
+	prints("ANSWER_TO_EVERYTHING", $Example.ANSWER_TO_EVERYTHING)
+	prints("CONSTANT_WITHOUT_ENUM", $Example.CONSTANT_WITHOUT_ENUM)
+
+func on_signal(name, value):
+	prints("Example emitted:", name, value)

+ 31 - 0
test/main.tscn

@@ -0,0 +1,31 @@
+[gd_scene load_steps=2 format=3 uid="uid://dmx2xuigcpvt4"]
+
+[ext_resource type="Script" path="res://main.gd" id="1_c326s"]
+
+[node name="Node" type="Node"]
+script = ExtResource( "1_c326s" )
+
+[node name="Example" type="Example" parent="."]
+offset_right = 40.0
+offset_bottom = 40.0
+script = null
+__meta__ = {
+"_edit_use_anchors_": false
+}
+
+[node name="Label" type="Label" parent="Example"]
+offset_left = 194.0
+offset_top = -2.0
+offset_right = 234.0
+offset_bottom = 21.0
+structured_text_bidi_override_options = []
+script = null
+
+[node name="Button" type="Button" parent="."]
+offset_right = 79.0
+offset_bottom = 29.0
+text = "Click me!"
+script = null
+__meta__ = {
+"_edit_use_anchors_": false
+}

+ 23 - 0
test/project.godot

@@ -0,0 +1,23 @@
+; Engine configuration file.
+; It's best edited using the editor UI and not directly,
+; since the parameters that go here are not all obvious.
+;
+; Format:
+;   [section] ; section goes between []
+;   param=value ; assign values to parameters
+
+config_version=4
+
+[application]
+
+config/name="GDExtension Test Project"
+run/main_scene="res://main.tscn"
+config/icon="res://icon.png"
+
+[native_extensions]
+
+paths=["res://example.gdextension"]
+
+[rendering]
+
+environment/defaults/default_environment="res://default_env.tres"

+ 91 - 0
test/src/example.cpp

@@ -0,0 +1,91 @@
+#include "example.h"
+
+#include <godot_cpp/core/class_db.hpp>
+
+#include <godot_cpp/classes/global_constants.hpp>
+#include <godot_cpp/classes/label.hpp>
+#include <godot_cpp/variant/utility_functions.hpp>
+
+using namespace godot;
+
+void Example::_bind_methods() {
+	// Methods.
+	ClassDB::bind_method(D_METHOD("simple_func"), &Example::simple_func);
+	ClassDB::bind_method(D_METHOD("simple_const_func"), &Example::simple_const_func);
+	ClassDB::bind_method(D_METHOD("return_something"), &Example::return_something);
+	ClassDB::bind_method(D_METHOD("return_something_const"), &Example::return_something_const);
+
+	{
+		MethodInfo mi;
+		mi.arguments.push_back(PropertyInfo(Variant::STRING, "some_argument"));
+		mi.name = "varargs_func";
+		ClassDB::bind_vararg_method(METHOD_FLAGS_DEFAULT, "varargs_func", &Example::varargs_func, mi);
+	}
+
+	// Properties.
+	ClassDB::bind_method(D_METHOD("get_custom_position"), &Example::get_custom_position);
+	ClassDB::bind_method(D_METHOD("set_custom_position", "position"), &Example::set_custom_position);
+	ADD_PROPERTY(PropertyInfo(Variant::VECTOR2, "custom_position"), "set_custom_position", "get_custom_position");
+
+	// Signals.
+	ADD_SIGNAL(MethodInfo("custom_signal", PropertyInfo(Variant::STRING, "name"), PropertyInfo(Variant::INT, "value")));
+	ClassDB::bind_method(D_METHOD("emit_custom_signal", "name", "value"), &Example::emit_custom_signal);
+
+	// Constants.
+	BIND_ENUM_CONSTANT(FIRST);
+	BIND_ENUM_CONSTANT(ANSWER_TO_EVERYTHING);
+
+	BIND_CONSTANT(CONSTANT_WITHOUT_ENUM);
+
+	// Virtual function override.
+	BIND_VIRTUAL_METHOD(_has_point);
+}
+
+// Methods.
+void Example::simple_func() {
+	UtilityFunctions::print("Simple func called.");
+}
+
+void Example::simple_const_func() const {
+	UtilityFunctions::print("Simple const func called.");
+}
+
+String Example::return_something(const String &base) {
+	UtilityFunctions::print("Return something called.");
+	return base;
+}
+
+Viewport *Example::return_something_const() const {
+	UtilityFunctions::print("Return something const called.");
+	if (is_inside_tree()) {
+		Viewport *result = get_viewport();
+		return result;
+	}
+	return nullptr;
+}
+
+Variant Example::varargs_func(const Variant **args, GDNativeInt arg_count, GDNativeCallError &error) {
+	UtilityFunctions::print("Varargs called with ", String::num(arg_count), " arguments");
+	return arg_count;
+}
+
+void Example::emit_custom_signal(const String &name, int value) {
+	emit_signal("custom_signal", name, value);
+}
+
+// Properties.
+void Example::set_custom_position(const Vector2 &pos) {
+	custom_position = pos;
+}
+
+Vector2 Example::get_custom_position() const {
+	return custom_position;
+}
+
+// Virtual function override.
+bool Example::_has_point(const Vector2 &point) {
+	Label *label = get_node<Label>("Label");
+	label->set_text("Got point: " + Variant(point).stringify());
+
+	return false;
+}

+ 50 - 0
test/src/example.h

@@ -0,0 +1,50 @@
+#ifndef EXAMPLE_CLASS_H
+#define EXAMPLE_CLASS_H
+
+#include <godot_cpp/classes/control.hpp>
+#include <godot_cpp/classes/global_constants.hpp>
+#include <godot_cpp/classes/viewport.hpp>
+
+#include <godot_cpp/core/binder_common.hpp>
+
+using namespace godot;
+
+class Example : public Control {
+	GDCLASS(Example, Control);
+
+protected:
+	static void _bind_methods();
+
+private:
+	Vector2 custom_position;
+
+public:
+	// Constants.
+	enum Constants {
+		FIRST,
+		ANSWER_TO_EVERYTHING = 42,
+	};
+
+	enum {
+		CONSTANT_WITHOUT_ENUM = 314,
+	};
+
+	// Functions
+	void simple_func();
+	void simple_const_func() const;
+	String return_something(const String &base);
+	Viewport *return_something_const() const;
+	Variant varargs_func(const Variant **args, GDNativeInt arg_count, GDNativeCallError &error);
+	void emit_custom_signal(const String &name, int value);
+
+	// Property
+	void set_custom_position(const Vector2 &pos);
+	Vector2 get_custom_position() const;
+
+	// Virtual function override
+	virtual bool _has_point(const Vector2 &point);
+};
+
+VARIANT_ENUM_CAST(Example, Constants);
+
+#endif // ! EXAMPLE_CLASS_H

+ 40 - 0
test/src/register_types.cpp

@@ -0,0 +1,40 @@
+#include "register_types.h"
+
+#include <godot/gdnative_interface.h>
+
+#include <godot_cpp/core/class_db.hpp>
+#include <godot_cpp/core/defs.hpp>
+#include <godot_cpp/godot.hpp>
+
+#include "example.h"
+
+using namespace godot;
+
+void register_example_types() {
+	ClassDB::register_class<Example>();
+}
+
+void unregister_example_types() {}
+
+extern "C" {
+
+// Initialization.
+
+GDNativeBool GDN_EXPORT example_library_init(const GDNativeInterface *p_interface, const GDNativeExtensionClassLibraryPtr p_library, GDNativeInitialization *r_initialization) {
+	GDNativeBool result = godot::GDExtensionBinding::init(p_interface, p_library, r_initialization);
+
+	if (result) {
+		register_example_types();
+	}
+
+	return result;
+}
+
+void GDN_EXPORT initialize_level(void *userdata, GDNativeInitializationLevel p_level) {
+	godot::GDExtensionBinding::initialize_level(userdata, p_level);
+}
+
+void GDN_EXPORT deinitialize_level(void *userdata, GDNativeInitializationLevel p_level) {
+	godot::GDExtensionBinding::deinitialize_level(userdata, p_level);
+}
+}

+ 7 - 0
test/src/register_types.h

@@ -0,0 +1,7 @@
+#ifndef EXAMPLE_REGISTER_TYPES_H
+#define EXAMPLE_REGISTER_TYPES_H
+
+void register_example_types();
+void unregister_example_types();
+
+#endif // ! EXAMPLE_REGISTER_TYPES_H