Merge pull request #1261 from dsnopek/4.1-cherrypicks-4
Cherry-picks for the godot-cpp 4.1 branch - 4th batchpull/1306/head
commit
e389f7a50c
|
@ -78,8 +78,18 @@ jobs:
|
||||||
run-tests: false
|
run-tests: false
|
||||||
cache-name: ios-arm64
|
cache-name: ios-arm64
|
||||||
|
|
||||||
|
- name: 🌐 Web (wasm32)
|
||||||
|
os: ubuntu-20.04
|
||||||
|
platform: javascript
|
||||||
|
artifact-name: godot-cpp-javascript-wasm32-release
|
||||||
|
artifact-path: bin/libgodot-cpp.javascript.template_release.wasm32.a
|
||||||
|
run-tests: false
|
||||||
|
cache-name: javascript-wasm32
|
||||||
|
|
||||||
env:
|
env:
|
||||||
SCONS_CACHE: ${{ github.workspace }}/.scons-cache/
|
SCONS_CACHE: ${{ github.workspace }}/.scons-cache/
|
||||||
|
EM_VERSION: 3.1.45
|
||||||
|
EM_CACHE_FOLDER: "emsdk-cache"
|
||||||
|
|
||||||
steps:
|
steps:
|
||||||
- name: Checkout
|
- name: Checkout
|
||||||
|
@ -104,6 +114,13 @@ jobs:
|
||||||
sudo apt-get update -qq
|
sudo apt-get update -qq
|
||||||
sudo apt-get install -qqq build-essential pkg-config
|
sudo apt-get install -qqq build-essential pkg-config
|
||||||
|
|
||||||
|
- name: Web dependencies
|
||||||
|
if: ${{ matrix.platform == 'javascript' }}
|
||||||
|
uses: mymindstorm/setup-emsdk@v12
|
||||||
|
with:
|
||||||
|
version: ${{env.EM_VERSION}}
|
||||||
|
actions-cache-folder: ${{env.EM_CACHE_FOLDER}}
|
||||||
|
|
||||||
- name: Install scons
|
- name: Install scons
|
||||||
run: |
|
run: |
|
||||||
python -m pip install scons==4.0.0
|
python -m pip install scons==4.0.0
|
||||||
|
|
|
@ -21,6 +21,10 @@ env.PrependENVPath("PATH", os.getenv("PATH"))
|
||||||
|
|
||||||
# Custom options and profile flags.
|
# Custom options and profile flags.
|
||||||
customs = ["custom.py"]
|
customs = ["custom.py"]
|
||||||
|
try:
|
||||||
|
customs += Import("customs")
|
||||||
|
except:
|
||||||
|
pass
|
||||||
profile = ARGUMENTS.get("profile", "")
|
profile = ARGUMENTS.get("profile", "")
|
||||||
if profile:
|
if profile:
|
||||||
if os.path.isfile(profile):
|
if os.path.isfile(profile):
|
||||||
|
|
|
@ -1519,13 +1519,13 @@ def generate_engine_class_source(class_api, used_classes, fully_used_classes, us
|
||||||
f"\t\tGDExtensionObjectPtr singleton_obj = internal::gdextension_interface_global_get_singleton({class_name}::get_class_static()._native_ptr());"
|
f"\t\tGDExtensionObjectPtr singleton_obj = internal::gdextension_interface_global_get_singleton({class_name}::get_class_static()._native_ptr());"
|
||||||
)
|
)
|
||||||
result.append("#ifdef DEBUG_ENABLED")
|
result.append("#ifdef DEBUG_ENABLED")
|
||||||
result.append("\t\tERR_FAIL_COND_V(singleton_obj == nullptr, nullptr);")
|
result.append("\t\tERR_FAIL_NULL_V(singleton_obj, nullptr);")
|
||||||
result.append("#endif // DEBUG_ENABLED")
|
result.append("#endif // DEBUG_ENABLED")
|
||||||
result.append(
|
result.append(
|
||||||
f"\t\tsingleton = reinterpret_cast<{class_name} *>(internal::gdextension_interface_object_get_instance_binding(singleton_obj, internal::token, &{class_name}::_gde_binding_callbacks));"
|
f"\t\tsingleton = reinterpret_cast<{class_name} *>(internal::gdextension_interface_object_get_instance_binding(singleton_obj, internal::token, &{class_name}::_gde_binding_callbacks));"
|
||||||
)
|
)
|
||||||
result.append("#ifdef DEBUG_ENABLED")
|
result.append("#ifdef DEBUG_ENABLED")
|
||||||
result.append("\t\tERR_FAIL_COND_V(singleton == nullptr, nullptr);")
|
result.append("\t\tERR_FAIL_NULL_V(singleton, nullptr);")
|
||||||
result.append("#endif // DEBUG_ENABLED")
|
result.append("#endif // DEBUG_ENABLED")
|
||||||
result.append("\t}")
|
result.append("\t}")
|
||||||
result.append("\treturn singleton;")
|
result.append("\treturn singleton;")
|
||||||
|
|
|
@ -63,7 +63,7 @@ class Ref {
|
||||||
}
|
}
|
||||||
|
|
||||||
void ref_pointer(T *p_ref) {
|
void ref_pointer(T *p_ref) {
|
||||||
ERR_FAIL_COND(!p_ref);
|
ERR_FAIL_NULL(p_ref);
|
||||||
|
|
||||||
if (p_ref->init_ref()) {
|
if (p_ref->init_ref()) {
|
||||||
reference = p_ref;
|
reference = p_ref;
|
||||||
|
|
|
@ -257,7 +257,7 @@ MethodBind *ClassDB::bind_static_method(StringName p_class, N p_method_name, M p
|
||||||
template <class M>
|
template <class M>
|
||||||
MethodBind *ClassDB::bind_vararg_method(uint32_t p_flags, StringName p_name, M p_method, const MethodInfo &p_info, const std::vector<Variant> &p_default_args, bool p_return_nil_is_variant) {
|
MethodBind *ClassDB::bind_vararg_method(uint32_t p_flags, StringName p_name, M p_method, const MethodInfo &p_info, const std::vector<Variant> &p_default_args, bool p_return_nil_is_variant) {
|
||||||
MethodBind *bind = create_vararg_method_bind(p_method, p_info, p_return_nil_is_variant);
|
MethodBind *bind = create_vararg_method_bind(p_method, p_info, p_return_nil_is_variant);
|
||||||
ERR_FAIL_COND_V(!bind, nullptr);
|
ERR_FAIL_NULL_V(bind, nullptr);
|
||||||
|
|
||||||
bind->set_name(p_name);
|
bind->set_name(p_name);
|
||||||
bind->set_default_arguments(p_default_args);
|
bind->set_default_arguments(p_default_args);
|
||||||
|
|
|
@ -146,7 +146,7 @@ T *memnew_arr_template(size_t p_elements, const char *p_descr = "") {
|
||||||
size_t len = sizeof(T) * p_elements;
|
size_t len = sizeof(T) * p_elements;
|
||||||
uint64_t *mem = (uint64_t *)Memory::alloc_static(len, true);
|
uint64_t *mem = (uint64_t *)Memory::alloc_static(len, true);
|
||||||
T *failptr = nullptr; // Get rid of a warning.
|
T *failptr = nullptr; // Get rid of a warning.
|
||||||
ERR_FAIL_COND_V(!mem, failptr);
|
ERR_FAIL_NULL_V(mem, failptr);
|
||||||
*(mem - 1) = p_elements;
|
*(mem - 1) = p_elements;
|
||||||
|
|
||||||
if (!std::is_trivially_destructible<T>::value) {
|
if (!std::is_trivially_destructible<T>::value) {
|
||||||
|
|
|
@ -102,6 +102,10 @@ private:
|
||||||
}
|
}
|
||||||
|
|
||||||
_FORCE_INLINE_ bool _get_alloc_size_checked(size_t p_elements, size_t *out) const {
|
_FORCE_INLINE_ bool _get_alloc_size_checked(size_t p_elements, size_t *out) const {
|
||||||
|
if (unlikely(p_elements == 0)) {
|
||||||
|
*out = 0;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
#if defined(__GNUC__)
|
#if defined(__GNUC__)
|
||||||
size_t o;
|
size_t o;
|
||||||
size_t p;
|
size_t p;
|
||||||
|
@ -113,13 +117,12 @@ private:
|
||||||
if (__builtin_add_overflow(o, static_cast<size_t>(32), &p)) {
|
if (__builtin_add_overflow(o, static_cast<size_t>(32), &p)) {
|
||||||
return false; // No longer allocated here.
|
return false; // No longer allocated here.
|
||||||
}
|
}
|
||||||
return true;
|
|
||||||
#else
|
#else
|
||||||
// Speed is more important than correctness here, do the operations unchecked
|
// Speed is more important than correctness here, do the operations unchecked
|
||||||
// and hope for the best.
|
// and hope for the best.
|
||||||
*out = _get_alloc_size(p_elements);
|
*out = _get_alloc_size(p_elements);
|
||||||
return true;
|
|
||||||
#endif
|
#endif
|
||||||
|
return *out;
|
||||||
}
|
}
|
||||||
|
|
||||||
void _unref(void *p_data);
|
void _unref(void *p_data);
|
||||||
|
@ -294,7 +297,7 @@ Error CowData<T>::resize(int p_size) {
|
||||||
if (current_size == 0) {
|
if (current_size == 0) {
|
||||||
// alloc from scratch
|
// alloc from scratch
|
||||||
uint32_t *ptr = (uint32_t *)Memory::alloc_static(alloc_size, true);
|
uint32_t *ptr = (uint32_t *)Memory::alloc_static(alloc_size, true);
|
||||||
ERR_FAIL_COND_V(!ptr, ERR_OUT_OF_MEMORY);
|
ERR_FAIL_NULL_V(ptr, ERR_OUT_OF_MEMORY);
|
||||||
*(ptr - 1) = 0; // size, currently none
|
*(ptr - 1) = 0; // size, currently none
|
||||||
new (ptr - 2) SafeNumeric<uint32_t>(1); // refcount
|
new (ptr - 2) SafeNumeric<uint32_t>(1); // refcount
|
||||||
|
|
||||||
|
@ -302,7 +305,7 @@ Error CowData<T>::resize(int p_size) {
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
uint32_t *_ptrnew = (uint32_t *)Memory::realloc_static(_ptr, alloc_size, true);
|
uint32_t *_ptrnew = (uint32_t *)Memory::realloc_static(_ptr, alloc_size, true);
|
||||||
ERR_FAIL_COND_V(!_ptrnew, ERR_OUT_OF_MEMORY);
|
ERR_FAIL_NULL_V(_ptrnew, ERR_OUT_OF_MEMORY);
|
||||||
new (_ptrnew - 2) SafeNumeric<uint32_t>(rc); // refcount
|
new (_ptrnew - 2) SafeNumeric<uint32_t>(rc); // refcount
|
||||||
|
|
||||||
_ptr = (T *)(_ptrnew);
|
_ptr = (T *)(_ptrnew);
|
||||||
|
@ -332,7 +335,7 @@ Error CowData<T>::resize(int p_size) {
|
||||||
|
|
||||||
if (alloc_size != current_alloc_size) {
|
if (alloc_size != current_alloc_size) {
|
||||||
uint32_t *_ptrnew = (uint32_t *)Memory::realloc_static(_ptr, alloc_size, true);
|
uint32_t *_ptrnew = (uint32_t *)Memory::realloc_static(_ptr, alloc_size, true);
|
||||||
ERR_FAIL_COND_V(!_ptrnew, ERR_OUT_OF_MEMORY);
|
ERR_FAIL_NULL_V(_ptrnew, ERR_OUT_OF_MEMORY);
|
||||||
new (_ptrnew - 2) SafeNumeric<uint32_t>(rc); // refcount
|
new (_ptrnew - 2) SafeNumeric<uint32_t>(rc); // refcount
|
||||||
|
|
||||||
_ptr = (T *)(_ptrnew);
|
_ptr = (T *)(_ptrnew);
|
||||||
|
|
|
@ -221,7 +221,7 @@ private:
|
||||||
int size_cache = 0;
|
int size_cache = 0;
|
||||||
|
|
||||||
bool erase(const Element *p_I) {
|
bool erase(const Element *p_I) {
|
||||||
ERR_FAIL_COND_V(!p_I, false);
|
ERR_FAIL_NULL_V(p_I, false);
|
||||||
ERR_FAIL_COND_V(p_I->data != this, false);
|
ERR_FAIL_COND_V(p_I->data != this, false);
|
||||||
|
|
||||||
if (first == p_I) {
|
if (first == p_I) {
|
||||||
|
|
|
@ -186,12 +186,12 @@ public:
|
||||||
}
|
}
|
||||||
void initialize_rid(RID p_rid) {
|
void initialize_rid(RID p_rid) {
|
||||||
T *mem = get_or_null(p_rid, true);
|
T *mem = get_or_null(p_rid, true);
|
||||||
ERR_FAIL_COND(!mem);
|
ERR_FAIL_NULL(mem);
|
||||||
memnew_placement(mem, T);
|
memnew_placement(mem, T);
|
||||||
}
|
}
|
||||||
void initialize_rid(RID p_rid, const T &p_value) {
|
void initialize_rid(RID p_rid, const T &p_value) {
|
||||||
T *mem = get_or_null(p_rid, true);
|
T *mem = get_or_null(p_rid, true);
|
||||||
ERR_FAIL_COND(!mem);
|
ERR_FAIL_NULL(mem);
|
||||||
memnew_placement(mem, T(p_value));
|
memnew_placement(mem, T(p_value));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -374,7 +374,7 @@ public:
|
||||||
|
|
||||||
_FORCE_INLINE_ void replace(const RID &p_rid, T *p_new_ptr) {
|
_FORCE_INLINE_ void replace(const RID &p_rid, T *p_new_ptr) {
|
||||||
T **ptr = alloc.get_or_null(p_rid);
|
T **ptr = alloc.get_or_null(p_rid);
|
||||||
ERR_FAIL_COND(!ptr);
|
ERR_FAIL_NULL(ptr);
|
||||||
*ptr = p_new_ptr;
|
*ptr = p_new_ptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -96,7 +96,7 @@ class ThreadWorkPool {
|
||||||
public:
|
public:
|
||||||
template <class C, class M, class U>
|
template <class C, class M, class U>
|
||||||
void begin_work(uint32_t p_elements, C *p_instance, M p_method, U p_userdata) {
|
void begin_work(uint32_t p_elements, C *p_instance, M p_method, U p_userdata) {
|
||||||
ERR_FAIL_COND(!threads); // never initialized
|
ERR_FAIL_NULL(threads); // Never initialized.
|
||||||
ERR_FAIL_COND(current_work != nullptr);
|
ERR_FAIL_COND(current_work != nullptr);
|
||||||
|
|
||||||
index.store(0, std::memory_order_release);
|
index.store(0, std::memory_order_release);
|
||||||
|
@ -123,18 +123,18 @@ public:
|
||||||
}
|
}
|
||||||
|
|
||||||
bool is_done_dispatching() const {
|
bool is_done_dispatching() const {
|
||||||
ERR_FAIL_COND_V(current_work == nullptr, true);
|
ERR_FAIL_NULL_V(current_work, true);
|
||||||
return index.load(std::memory_order_acquire) >= current_work->max_elements;
|
return index.load(std::memory_order_acquire) >= current_work->max_elements;
|
||||||
}
|
}
|
||||||
|
|
||||||
uint32_t get_work_index() const {
|
uint32_t get_work_index() const {
|
||||||
ERR_FAIL_COND_V(current_work == nullptr, 0);
|
ERR_FAIL_NULL_V(current_work, 0);
|
||||||
uint32_t idx = index.load(std::memory_order_acquire);
|
uint32_t idx = index.load(std::memory_order_acquire);
|
||||||
return Math::min(idx, current_work->max_elements);
|
return Math::min(idx, current_work->max_elements);
|
||||||
}
|
}
|
||||||
|
|
||||||
void end_work() {
|
void end_work() {
|
||||||
ERR_FAIL_COND(current_work == nullptr);
|
ERR_FAIL_NULL(current_work);
|
||||||
for (uint32_t i = 0; i < threads_working; i++) {
|
for (uint32_t i = 0; i < threads_working; i++) {
|
||||||
threads[i].completed.wait();
|
threads[i].completed.wait();
|
||||||
threads[i].work = nullptr;
|
threads[i].work = nullptr;
|
||||||
|
|
|
@ -255,25 +255,33 @@ public:
|
||||||
bool operator!=(const Variant &other) const;
|
bool operator!=(const Variant &other) const;
|
||||||
bool operator<(const Variant &other) const;
|
bool operator<(const Variant &other) const;
|
||||||
|
|
||||||
void call(const StringName &method, const Variant **args, int argcount, Variant &r_ret, GDExtensionCallError &r_error);
|
void callp(const StringName &method, const Variant **args, int argcount, Variant &r_ret, GDExtensionCallError &r_error);
|
||||||
|
|
||||||
template <class... Args>
|
template <class... Args>
|
||||||
Variant call(const StringName &method, Args... args) {
|
Variant call(const StringName &method, Args... args) {
|
||||||
|
std::array<Variant, sizeof...(args)> vargs = { args... };
|
||||||
|
std::array<const Variant *, sizeof...(args)> argptrs;
|
||||||
|
for (size_t i = 0; i < vargs.size(); i++) {
|
||||||
|
argptrs[i] = &vargs[i];
|
||||||
|
}
|
||||||
Variant result;
|
Variant result;
|
||||||
GDExtensionCallError error;
|
GDExtensionCallError error;
|
||||||
std::array<GDExtensionConstVariantPtr, sizeof...(Args)> call_args = { Variant(args)... };
|
callp(method, argptrs.data(), argptrs.size(), result, error);
|
||||||
call(method, call_args.data(), call_args.size(), result, error);
|
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void call_static(Variant::Type type, const StringName &method, const Variant **args, int argcount, Variant &r_ret, GDExtensionCallError &r_error);
|
static void callp_static(Variant::Type type, const StringName &method, const Variant **args, int argcount, Variant &r_ret, GDExtensionCallError &r_error);
|
||||||
|
|
||||||
template <class... Args>
|
template <class... Args>
|
||||||
static Variant call_static(Variant::Type type, const StringName &method, Args... args) {
|
static Variant call_static(Variant::Type type, const StringName &method, Args... args) {
|
||||||
|
std::array<Variant, sizeof...(args)> vargs = { args... };
|
||||||
|
std::array<const Variant *, sizeof...(args)> argptrs;
|
||||||
|
for (size_t i = 0; i < vargs.size(); i++) {
|
||||||
|
argptrs[i] = &vargs[i];
|
||||||
|
}
|
||||||
Variant result;
|
Variant result;
|
||||||
GDExtensionCallError error;
|
GDExtensionCallError error;
|
||||||
std::array<GDExtensionConstVariantPtr, sizeof...(Args)> call_args = { Variant(args)... };
|
callp_static(type, method, argptrs.data(), argptrs.size(), sizeof...(args), result, error);
|
||||||
call_static(type, method, call_args.data(), call_args.size(), result, error);
|
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -77,7 +77,7 @@ void ClassDB::add_property(const StringName &p_class, const PropertyInfo &p_pinf
|
||||||
if (p_setter != String("")) {
|
if (p_setter != String("")) {
|
||||||
setter = get_method(p_class, p_setter);
|
setter = get_method(p_class, p_setter);
|
||||||
|
|
||||||
ERR_FAIL_COND_MSG(!setter, String("Setter method '{0}::{1}()' not found for property '{2}::{3}'.").format(Array::make(p_class, p_setter, p_class, p_pinfo.name)));
|
ERR_FAIL_NULL_MSG(setter, String("Setter method '{0}::{1}()' not found for property '{2}::{3}'.").format(Array::make(p_class, p_setter, p_class, p_pinfo.name)));
|
||||||
|
|
||||||
size_t exp_args = 1 + (p_index >= 0 ? 1 : 0);
|
size_t exp_args = 1 + (p_index >= 0 ? 1 : 0);
|
||||||
ERR_FAIL_COND_MSG((int)exp_args != setter->get_argument_count(), String("Setter method '{0}::{1}()' must take a single argument.").format(Array::make(p_class, p_setter)));
|
ERR_FAIL_COND_MSG((int)exp_args != setter->get_argument_count(), String("Setter method '{0}::{1}()' must take a single argument.").format(Array::make(p_class, p_setter)));
|
||||||
|
@ -86,7 +86,7 @@ void ClassDB::add_property(const StringName &p_class, const PropertyInfo &p_pinf
|
||||||
ERR_FAIL_COND_MSG(p_getter == String(""), String("Getter method must be specified for '{0}::{1}'.").format(Array::make(p_class, p_pinfo.name)));
|
ERR_FAIL_COND_MSG(p_getter == String(""), String("Getter method must be specified for '{0}::{1}'.").format(Array::make(p_class, p_pinfo.name)));
|
||||||
|
|
||||||
MethodBind *getter = get_method(p_class, p_getter);
|
MethodBind *getter = get_method(p_class, p_getter);
|
||||||
ERR_FAIL_COND_MSG(!getter, String("Getter method '{0}::{1}()' not found for property '{2}::{3}'.").format(Array::make(p_class, p_getter, p_class, p_pinfo.name)));
|
ERR_FAIL_NULL_MSG(getter, String("Getter method '{0}::{1}()' not found for property '{2}::{3}'.").format(Array::make(p_class, p_getter, p_class, p_pinfo.name)));
|
||||||
{
|
{
|
||||||
size_t exp_args = 0 + (p_index >= 0 ? 1 : 0);
|
size_t exp_args = 0 + (p_index >= 0 ? 1 : 0);
|
||||||
ERR_FAIL_COND_MSG((int)exp_args != getter->get_argument_count(), String("Getter method '{0}::{1}()' must not take any argument.").format(Array::make(p_class, p_getter)));
|
ERR_FAIL_COND_MSG((int)exp_args != getter->get_argument_count(), String("Getter method '{0}::{1}()' must not take any argument.").format(Array::make(p_class, p_getter)));
|
||||||
|
@ -318,7 +318,18 @@ GDExtensionClassCallVirtual ClassDB::get_virtual_func(void *p_userdata, GDExtens
|
||||||
|
|
||||||
const GDExtensionInstanceBindingCallbacks *ClassDB::get_instance_binding_callbacks(const StringName &p_class) {
|
const GDExtensionInstanceBindingCallbacks *ClassDB::get_instance_binding_callbacks(const StringName &p_class) {
|
||||||
std::unordered_map<StringName, const GDExtensionInstanceBindingCallbacks *>::iterator callbacks_it = instance_binding_callbacks.find(p_class);
|
std::unordered_map<StringName, const GDExtensionInstanceBindingCallbacks *>::iterator callbacks_it = instance_binding_callbacks.find(p_class);
|
||||||
ERR_FAIL_COND_V_MSG(callbacks_it == instance_binding_callbacks.end(), nullptr, String("Cannot find instance binding callbacks for class '{0}'.").format(Array::make(p_class)));
|
if (likely(callbacks_it != instance_binding_callbacks.end())) {
|
||||||
|
return callbacks_it->second;
|
||||||
|
}
|
||||||
|
|
||||||
|
// If we don't have an instance binding callback for the given class, find the closest parent where we do.
|
||||||
|
StringName class_name = p_class;
|
||||||
|
do {
|
||||||
|
class_name = get_parent_class(class_name);
|
||||||
|
ERR_FAIL_COND_V_MSG(class_name == StringName(), nullptr, String("Cannot find instance binding callbacks for class '{0}'.").format(Array::make(p_class)));
|
||||||
|
callbacks_it = instance_binding_callbacks.find(class_name);
|
||||||
|
} while (callbacks_it == instance_binding_callbacks.end());
|
||||||
|
|
||||||
return callbacks_it->second;
|
return callbacks_it->second;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -42,7 +42,7 @@ void *Memory::alloc_static(size_t p_bytes, bool p_pad_align) {
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
void *mem = internal::gdextension_interface_mem_alloc(p_bytes + (prepad ? PAD_ALIGN : 0));
|
void *mem = internal::gdextension_interface_mem_alloc(p_bytes + (prepad ? PAD_ALIGN : 0));
|
||||||
ERR_FAIL_COND_V(!mem, nullptr);
|
ERR_FAIL_NULL_V(mem, nullptr);
|
||||||
|
|
||||||
if (prepad) {
|
if (prepad) {
|
||||||
uint8_t *s8 = (uint8_t *)mem;
|
uint8_t *s8 = (uint8_t *)mem;
|
||||||
|
@ -71,7 +71,7 @@ void *Memory::realloc_static(void *p_memory, size_t p_bytes, bool p_pad_align) {
|
||||||
if (prepad) {
|
if (prepad) {
|
||||||
mem -= PAD_ALIGN;
|
mem -= PAD_ALIGN;
|
||||||
mem = (uint8_t *)internal::gdextension_interface_mem_realloc(mem, p_bytes + PAD_ALIGN);
|
mem = (uint8_t *)internal::gdextension_interface_mem_realloc(mem, p_bytes + PAD_ALIGN);
|
||||||
ERR_FAIL_COND_V(!mem, nullptr);
|
ERR_FAIL_NULL_V(mem, nullptr);
|
||||||
return mem + PAD_ALIGN;
|
return mem + PAD_ALIGN;
|
||||||
} else {
|
} else {
|
||||||
return (uint8_t *)internal::gdextension_interface_mem_realloc(mem, p_bytes);
|
return (uint8_t *)internal::gdextension_interface_mem_realloc(mem, p_bytes);
|
||||||
|
|
|
@ -403,7 +403,7 @@ GDExtensionBool GDExtensionBinding::init(GDExtensionInterfaceGetProcAddress p_ge
|
||||||
r_initialization->deinitialize = deinitialize_level;
|
r_initialization->deinitialize = deinitialize_level;
|
||||||
r_initialization->minimum_initialization_level = minimum_initialization_level;
|
r_initialization->minimum_initialization_level = minimum_initialization_level;
|
||||||
|
|
||||||
ERR_FAIL_COND_V_MSG(init_callback == nullptr, false, "Initialization callback must be defined.");
|
ERR_FAIL_NULL_V_MSG(init_callback, false, "Initialization callback must be defined.");
|
||||||
|
|
||||||
Variant::init_bindings();
|
Variant::init_bindings();
|
||||||
register_engine_classes();
|
register_engine_classes();
|
||||||
|
|
|
@ -549,11 +549,11 @@ bool Variant::operator<(const Variant &other) const {
|
||||||
return result.operator bool();
|
return result.operator bool();
|
||||||
}
|
}
|
||||||
|
|
||||||
void Variant::call(const StringName &method, const Variant **args, int argcount, Variant &r_ret, GDExtensionCallError &r_error) {
|
void Variant::callp(const StringName &method, const Variant **args, int argcount, Variant &r_ret, GDExtensionCallError &r_error) {
|
||||||
internal::gdextension_interface_variant_call(_native_ptr(), method._native_ptr(), reinterpret_cast<GDExtensionConstVariantPtr *>(args), argcount, r_ret._native_ptr(), &r_error);
|
internal::gdextension_interface_variant_call(_native_ptr(), method._native_ptr(), reinterpret_cast<GDExtensionConstVariantPtr *>(args), argcount, r_ret._native_ptr(), &r_error);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Variant::call_static(Variant::Type type, const StringName &method, const Variant **args, int argcount, Variant &r_ret, GDExtensionCallError &r_error) {
|
void Variant::callp_static(Variant::Type type, const StringName &method, const Variant **args, int argcount, Variant &r_ret, GDExtensionCallError &r_error) {
|
||||||
internal::gdextension_interface_variant_call_static(static_cast<GDExtensionVariantType>(type), method._native_ptr(), reinterpret_cast<GDExtensionConstVariantPtr *>(args), argcount, r_ret._native_ptr(), &r_error);
|
internal::gdextension_interface_variant_call_static(static_cast<GDExtensionVariantType>(type), method._native_ptr(), reinterpret_cast<GDExtensionConstVariantPtr *>(args), argcount, r_ret._native_ptr(), &r_error);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -21,3 +21,5 @@ android.debug.x86_64 = "res://bin/libgdexample.android.template_debug.x86_64.so"
|
||||||
android.release.x86_64 = "res://bin/libgdexample.android.template_release.x86_64.so"
|
android.release.x86_64 = "res://bin/libgdexample.android.template_release.x86_64.so"
|
||||||
android.debug.arm64 = "res://bin/libgdexample.android.template_debug.arm64.so"
|
android.debug.arm64 = "res://bin/libgdexample.android.template_debug.arm64.so"
|
||||||
android.release.arm64 = "res://bin/libgdexample.android.template_release.arm64.so"
|
android.release.arm64 = "res://bin/libgdexample.android.template_release.arm64.so"
|
||||||
|
web.debug.wasm32 = "res://bin/libgdexample.javascript.template_debug.wasm32.wasm"
|
||||||
|
web.release.wasm32 = "res://bin/libgdexample.javascript.template_release.wasm32.wasm"
|
||||||
|
|
|
@ -2,6 +2,9 @@ extends "res://test_base.gd"
|
||||||
|
|
||||||
var custom_signal_emitted = null
|
var custom_signal_emitted = null
|
||||||
|
|
||||||
|
class TestClass:
|
||||||
|
func test(p_msg: String) -> String:
|
||||||
|
return p_msg + " world"
|
||||||
|
|
||||||
func _ready():
|
func _ready():
|
||||||
var example: Example = $Example
|
var example: Example = $Example
|
||||||
|
@ -137,6 +140,10 @@ func _ready():
|
||||||
assert_equal(new_tilemap.tile_set, new_tileset)
|
assert_equal(new_tilemap.tile_set, new_tileset)
|
||||||
new_tilemap.queue_free()
|
new_tilemap.queue_free()
|
||||||
|
|
||||||
|
# Test variant call.
|
||||||
|
var test_obj = TestClass.new()
|
||||||
|
assert_equal(example.test_variant_call(test_obj), "hello world")
|
||||||
|
|
||||||
# Constants.
|
# Constants.
|
||||||
assert_equal(Example.FIRST, 0)
|
assert_equal(Example.FIRST, 0)
|
||||||
assert_equal(Example.ANSWER_TO_EVERYTHING, 42)
|
assert_equal(Example.ANSWER_TO_EVERYTHING, 42)
|
||||||
|
|
|
@ -152,6 +152,8 @@ void Example::_bind_methods() {
|
||||||
ClassDB::bind_method(D_METHOD("test_add_child", "node"), &Example::test_add_child);
|
ClassDB::bind_method(D_METHOD("test_add_child", "node"), &Example::test_add_child);
|
||||||
ClassDB::bind_method(D_METHOD("test_set_tileset", "tilemap", "tileset"), &Example::test_set_tileset);
|
ClassDB::bind_method(D_METHOD("test_set_tileset", "tilemap", "tileset"), &Example::test_set_tileset);
|
||||||
|
|
||||||
|
ClassDB::bind_method(D_METHOD("test_variant_call", "variant"), &Example::test_variant_call);
|
||||||
|
|
||||||
ClassDB::bind_method(D_METHOD("test_bitfield", "flags"), &Example::test_bitfield);
|
ClassDB::bind_method(D_METHOD("test_bitfield", "flags"), &Example::test_bitfield);
|
||||||
|
|
||||||
ClassDB::bind_method(D_METHOD("test_rpc", "value"), &Example::test_rpc);
|
ClassDB::bind_method(D_METHOD("test_rpc", "value"), &Example::test_rpc);
|
||||||
|
@ -391,6 +393,10 @@ void Example::test_set_tileset(TileMap *p_tilemap, const Ref<TileSet> &p_tileset
|
||||||
p_tilemap->set_tileset(p_tileset);
|
p_tilemap->set_tileset(p_tileset);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Variant Example::test_variant_call(Variant p_variant) {
|
||||||
|
return p_variant.call("test", "hello");
|
||||||
|
}
|
||||||
|
|
||||||
BitField<Example::Flags> Example::test_bitfield(BitField<Flags> flags) {
|
BitField<Example::Flags> Example::test_bitfield(BitField<Flags> flags) {
|
||||||
return flags;
|
return flags;
|
||||||
}
|
}
|
||||||
|
|
|
@ -21,6 +21,7 @@
|
||||||
#include <godot_cpp/classes/tile_map.hpp>
|
#include <godot_cpp/classes/tile_map.hpp>
|
||||||
#include <godot_cpp/classes/tile_set.hpp>
|
#include <godot_cpp/classes/tile_set.hpp>
|
||||||
#include <godot_cpp/classes/viewport.hpp>
|
#include <godot_cpp/classes/viewport.hpp>
|
||||||
|
#include <godot_cpp/variant/variant.hpp>
|
||||||
|
|
||||||
#include <godot_cpp/core/binder_common.hpp>
|
#include <godot_cpp/core/binder_common.hpp>
|
||||||
|
|
||||||
|
@ -133,6 +134,8 @@ public:
|
||||||
void test_add_child(Node *p_node);
|
void test_add_child(Node *p_node);
|
||||||
void test_set_tileset(TileMap *p_tilemap, const Ref<TileSet> &p_tileset) const;
|
void test_set_tileset(TileMap *p_tilemap, const Ref<TileSet> &p_tileset) const;
|
||||||
|
|
||||||
|
Variant test_variant_call(Variant p_variant);
|
||||||
|
|
||||||
BitField<Flags> test_bitfield(BitField<Flags> flags);
|
BitField<Flags> test_bitfield(BitField<Flags> flags);
|
||||||
|
|
||||||
// RPC
|
// RPC
|
||||||
|
|
|
@ -1,8 +1,9 @@
|
||||||
import os
|
import os
|
||||||
|
from SCons.Util import WhereIs
|
||||||
|
|
||||||
|
|
||||||
def exists(env):
|
def exists(env):
|
||||||
return "EM_CONFIG" in os.environ
|
return WhereIs("emcc") is not None
|
||||||
|
|
||||||
|
|
||||||
def generate(env):
|
def generate(env):
|
||||||
|
@ -10,9 +11,6 @@ def generate(env):
|
||||||
print("Only wasm32 supported on web. Exiting.")
|
print("Only wasm32 supported on web. Exiting.")
|
||||||
env.Exit(1)
|
env.Exit(1)
|
||||||
|
|
||||||
if "EM_CONFIG" in os.environ:
|
|
||||||
env["ENV"] = os.environ
|
|
||||||
|
|
||||||
env["CC"] = "emcc"
|
env["CC"] = "emcc"
|
||||||
env["CXX"] = "em++"
|
env["CXX"] = "em++"
|
||||||
env["AR"] = "emar"
|
env["AR"] = "emar"
|
||||||
|
@ -26,6 +24,10 @@ def generate(env):
|
||||||
env["ARCOM_POSIX"] = env["ARCOM"].replace("$TARGET", "$TARGET.posix").replace("$SOURCES", "$SOURCES.posix")
|
env["ARCOM_POSIX"] = env["ARCOM"].replace("$TARGET", "$TARGET.posix").replace("$SOURCES", "$SOURCES.posix")
|
||||||
env["ARCOM"] = "${TEMPFILE(ARCOM_POSIX)}"
|
env["ARCOM"] = "${TEMPFILE(ARCOM_POSIX)}"
|
||||||
|
|
||||||
|
# Thread support (via SharedArrayBuffer).
|
||||||
|
env.Append(CCFLAGS=["-s", "USE_PTHREADS=1"])
|
||||||
|
env.Append(LINKFLAGS=["-s", "USE_PTHREADS=1"])
|
||||||
|
|
||||||
# All intermediate files are just LLVM bitcode.
|
# All intermediate files are just LLVM bitcode.
|
||||||
env["OBJPREFIX"] = ""
|
env["OBJPREFIX"] = ""
|
||||||
env["OBJSUFFIX"] = ".bc"
|
env["OBJSUFFIX"] = ".bc"
|
||||||
|
@ -39,9 +41,4 @@ def generate(env):
|
||||||
env.Replace(SHLINKFLAGS="$LINKFLAGS")
|
env.Replace(SHLINKFLAGS="$LINKFLAGS")
|
||||||
env.Replace(SHLINKFLAGS="$LINKFLAGS")
|
env.Replace(SHLINKFLAGS="$LINKFLAGS")
|
||||||
|
|
||||||
if env["target"] == "debug":
|
|
||||||
env.Append(CCFLAGS=["-O0", "-g"])
|
|
||||||
elif env["target"] == "release":
|
|
||||||
env.Append(CCFLAGS=["-O3"])
|
|
||||||
|
|
||||||
env.Append(CPPDEFINES=["WEB_ENABLED", "UNIX_ENABLED"])
|
env.Append(CPPDEFINES=["WEB_ENABLED", "UNIX_ENABLED"])
|
||||||
|
|
Loading…
Reference in New Issue