Merge pull request #38738 from akien-mga/cause-we-never-go-out-of-style
Style: Remove new line at block start, enforce line between functions, enforce braces in if and loop blocks
This commit is contained in:
commit
00949f0c5f
@ -76,7 +76,7 @@ IndentWidth: 4
|
||||
# IndentWrappedFunctionNames: false
|
||||
# JavaScriptQuotes: Leave
|
||||
# JavaScriptWrapImports: true
|
||||
# KeepEmptyLinesAtTheStartOfBlocks: true
|
||||
KeepEmptyLinesAtTheStartOfBlocks: false
|
||||
# MacroBlockBegin: ''
|
||||
# MacroBlockEnd: ''
|
||||
# MaxEmptyLinesToKeep: 1
|
||||
|
@ -1,5 +1,5 @@
|
||||
---
|
||||
Checks: 'clang-diagnostic-*,clang-analyzer-*,-*,modernize-redundant-void-arg,modernize-use-bool-literals,modernize-use-default-member-init,modernize-use-nullptr'
|
||||
Checks: 'clang-diagnostic-*,clang-analyzer-*,-*,modernize-redundant-void-arg,modernize-use-bool-literals,modernize-use-default-member-init,modernize-use-nullptr,readability-braces-around-statements'
|
||||
WarningsAsErrors: ''
|
||||
HeaderFilterRegex: '.*'
|
||||
AnalyzeTemporaryDtors: false
|
||||
@ -14,8 +14,6 @@ CheckOptions:
|
||||
value: '1'
|
||||
- key: cppcoreguidelines-non-private-member-variables-in-classes.IgnoreClassesWithAllMemberVariablesBeingPublic
|
||||
value: '1'
|
||||
- key: google-readability-braces-around-statements.ShortStatementLines
|
||||
value: '1'
|
||||
- key: google-readability-function-size.StatementThreshold
|
||||
value: '800'
|
||||
- key: google-readability-namespace-comments.ShortNamespaceLines
|
||||
@ -40,5 +38,7 @@ CheckOptions:
|
||||
value: '1'
|
||||
- key: modernize-use-nullptr.NullMacros
|
||||
value: 'NULL'
|
||||
- key: readability-braces-around-statements.ShortStatementLines
|
||||
value: '0'
|
||||
...
|
||||
|
||||
|
@ -46,13 +46,13 @@ public:
|
||||
};
|
||||
|
||||
void Array::_ref(const Array &p_from) const {
|
||||
|
||||
ArrayPrivate *_fp = p_from._p;
|
||||
|
||||
ERR_FAIL_COND(!_fp); // should NOT happen.
|
||||
|
||||
if (_fp == _p)
|
||||
if (_fp == _p) {
|
||||
return; // whatever it is, nothing to do here move along
|
||||
}
|
||||
|
||||
bool success = _fp->refcount.ref();
|
||||
|
||||
@ -64,9 +64,9 @@ void Array::_ref(const Array &p_from) const {
|
||||
}
|
||||
|
||||
void Array::_unref() const {
|
||||
|
||||
if (!_p)
|
||||
if (!_p) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (_p->refcount.unref()) {
|
||||
memdelete(_p);
|
||||
@ -75,46 +75,39 @@ void Array::_unref() const {
|
||||
}
|
||||
|
||||
Variant &Array::operator[](int p_idx) {
|
||||
|
||||
return _p->array.write[p_idx];
|
||||
}
|
||||
|
||||
const Variant &Array::operator[](int p_idx) const {
|
||||
|
||||
return _p->array[p_idx];
|
||||
}
|
||||
|
||||
int Array::size() const {
|
||||
|
||||
return _p->array.size();
|
||||
}
|
||||
bool Array::empty() const {
|
||||
|
||||
bool Array::empty() const {
|
||||
return _p->array.empty();
|
||||
}
|
||||
void Array::clear() {
|
||||
|
||||
void Array::clear() {
|
||||
_p->array.clear();
|
||||
}
|
||||
|
||||
bool Array::operator==(const Array &p_array) const {
|
||||
|
||||
return _p == p_array._p;
|
||||
}
|
||||
|
||||
uint32_t Array::hash() const {
|
||||
|
||||
uint32_t h = hash_djb2_one_32(0);
|
||||
|
||||
for (int i = 0; i < _p->array.size(); i++) {
|
||||
|
||||
h = hash_djb2_one_32(_p->array[i].hash(), h);
|
||||
}
|
||||
return h;
|
||||
}
|
||||
|
||||
void Array::_assign(const Array &p_array) {
|
||||
|
||||
if (_p->typed.type != Variant::OBJECT && _p->typed.type == p_array._p->typed.type) {
|
||||
//same type or untyped, just reference, shuold be fine
|
||||
_ref(p_array);
|
||||
@ -162,25 +155,22 @@ void Array::_assign(const Array &p_array) {
|
||||
void Array::operator=(const Array &p_array) {
|
||||
_assign(p_array);
|
||||
}
|
||||
void Array::push_back(const Variant &p_value) {
|
||||
|
||||
void Array::push_back(const Variant &p_value) {
|
||||
ERR_FAIL_COND(!_p->typed.validate(p_value, "push_back"));
|
||||
_p->array.push_back(p_value);
|
||||
}
|
||||
|
||||
Error Array::resize(int p_new_size) {
|
||||
|
||||
return _p->array.resize(p_new_size);
|
||||
}
|
||||
|
||||
void Array::insert(int p_pos, const Variant &p_value) {
|
||||
|
||||
ERR_FAIL_COND(!_p->typed.validate(p_value, "insert"));
|
||||
_p->array.insert(p_pos, p_value);
|
||||
}
|
||||
|
||||
void Array::erase(const Variant &p_value) {
|
||||
|
||||
ERR_FAIL_COND(!_p->typed.validate(p_value, "erase"));
|
||||
_p->array.erase(p_value);
|
||||
}
|
||||
@ -196,15 +186,14 @@ Variant Array::back() const {
|
||||
}
|
||||
|
||||
int Array::find(const Variant &p_value, int p_from) const {
|
||||
|
||||
ERR_FAIL_COND_V(!_p->typed.validate(p_value, "find"), -1);
|
||||
return _p->array.find(p_value, p_from);
|
||||
}
|
||||
|
||||
int Array::rfind(const Variant &p_value, int p_from) const {
|
||||
|
||||
if (_p->array.size() == 0)
|
||||
if (_p->array.size() == 0) {
|
||||
return -1;
|
||||
}
|
||||
ERR_FAIL_COND_V(!_p->typed.validate(p_value, "rfind"), -1);
|
||||
|
||||
if (p_from < 0) {
|
||||
@ -217,7 +206,6 @@ int Array::rfind(const Variant &p_value, int p_from) const {
|
||||
}
|
||||
|
||||
for (int i = p_from; i >= 0; i--) {
|
||||
|
||||
if (_p->array[i] == p_value) {
|
||||
return i;
|
||||
}
|
||||
@ -227,20 +215,18 @@ int Array::rfind(const Variant &p_value, int p_from) const {
|
||||
}
|
||||
|
||||
int Array::find_last(const Variant &p_value) const {
|
||||
|
||||
ERR_FAIL_COND_V(!_p->typed.validate(p_value, "find_last"), -1);
|
||||
return rfind(p_value);
|
||||
}
|
||||
|
||||
int Array::count(const Variant &p_value) const {
|
||||
|
||||
ERR_FAIL_COND_V(!_p->typed.validate(p_value, "count"), 0);
|
||||
if (_p->array.size() == 0)
|
||||
if (_p->array.size() == 0) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
int amount = 0;
|
||||
for (int i = 0; i < _p->array.size(); i++) {
|
||||
|
||||
if (_p->array[i] == p_value) {
|
||||
amount++;
|
||||
}
|
||||
@ -256,24 +242,20 @@ bool Array::has(const Variant &p_value) const {
|
||||
}
|
||||
|
||||
void Array::remove(int p_pos) {
|
||||
|
||||
_p->array.remove(p_pos);
|
||||
}
|
||||
|
||||
void Array::set(int p_idx, const Variant &p_value) {
|
||||
|
||||
ERR_FAIL_COND(!_p->typed.validate(p_value, "set"));
|
||||
|
||||
operator[](p_idx) = p_value;
|
||||
}
|
||||
|
||||
const Variant &Array::get(int p_idx) const {
|
||||
|
||||
return operator[](p_idx);
|
||||
}
|
||||
|
||||
Array Array::duplicate(bool p_deep) const {
|
||||
|
||||
Array new_arr;
|
||||
int element_count = size();
|
||||
new_arr.resize(element_count);
|
||||
@ -286,7 +268,6 @@ Array Array::duplicate(bool p_deep) const {
|
||||
}
|
||||
|
||||
int Array::_clamp_slice_index(int p_index) const {
|
||||
|
||||
int arr_size = size();
|
||||
int fixed_index = CLAMP(p_index, -arr_size, arr_size - 1);
|
||||
if (fixed_index < 0) {
|
||||
@ -301,15 +282,18 @@ Array Array::slice(int p_begin, int p_end, int p_step, bool p_deep) const { // l
|
||||
|
||||
ERR_FAIL_COND_V_MSG(p_step == 0, new_arr, "Array slice step size cannot be zero.");
|
||||
|
||||
if (empty()) // Don't try to slice empty arrays.
|
||||
if (empty()) { // Don't try to slice empty arrays.
|
||||
return new_arr;
|
||||
}
|
||||
if (p_step > 0) {
|
||||
if (p_begin >= size() || p_end < -size())
|
||||
if (p_begin >= size() || p_end < -size()) {
|
||||
return new_arr;
|
||||
}
|
||||
} else { // p_step < 0
|
||||
if (p_begin < -size() || p_end >= size())
|
||||
if (p_begin < -size() || p_end >= size()) {
|
||||
return new_arr;
|
||||
}
|
||||
}
|
||||
|
||||
int begin = _clamp_slice_index(p_begin);
|
||||
int end = _clamp_slice_index(p_end);
|
||||
@ -335,40 +319,37 @@ Array Array::slice(int p_begin, int p_end, int p_step, bool p_deep) const { // l
|
||||
}
|
||||
|
||||
struct _ArrayVariantSort {
|
||||
|
||||
_FORCE_INLINE_ bool operator()(const Variant &p_l, const Variant &p_r) const {
|
||||
bool valid = false;
|
||||
Variant res;
|
||||
Variant::evaluate(Variant::OP_LESS, p_l, p_r, res, valid);
|
||||
if (!valid)
|
||||
if (!valid) {
|
||||
res = false;
|
||||
}
|
||||
return res;
|
||||
}
|
||||
};
|
||||
|
||||
Array &Array::sort() {
|
||||
|
||||
_p->array.sort_custom<_ArrayVariantSort>();
|
||||
return *this;
|
||||
}
|
||||
|
||||
struct _ArrayVariantSortCustom {
|
||||
|
||||
Object *obj;
|
||||
StringName func;
|
||||
|
||||
_FORCE_INLINE_ bool operator()(const Variant &p_l, const Variant &p_r) const {
|
||||
|
||||
const Variant *args[2] = { &p_l, &p_r };
|
||||
Callable::CallError err;
|
||||
bool res = obj->call(func, args, 2, err);
|
||||
if (err.error != Callable::CallError::CALL_OK)
|
||||
if (err.error != Callable::CallError::CALL_OK) {
|
||||
res = false;
|
||||
}
|
||||
return res;
|
||||
}
|
||||
};
|
||||
Array &Array::sort_custom(Object *p_obj, const StringName &p_function) {
|
||||
|
||||
ERR_FAIL_NULL_V(p_obj, *this);
|
||||
|
||||
SortArray<Variant, _ArrayVariantSortCustom, true> avs;
|
||||
@ -379,10 +360,10 @@ Array &Array::sort_custom(Object *p_obj, const StringName &p_function) {
|
||||
}
|
||||
|
||||
void Array::shuffle() {
|
||||
|
||||
const int n = _p->array.size();
|
||||
if (n < 2)
|
||||
if (n < 2) {
|
||||
return;
|
||||
}
|
||||
Variant *data = _p->array.ptrw();
|
||||
for (int i = n - 1; i >= 1; i--) {
|
||||
const int j = Math::rand() % (i + 1);
|
||||
@ -394,7 +375,6 @@ void Array::shuffle() {
|
||||
|
||||
template <typename Less>
|
||||
_FORCE_INLINE_ int bisect(const Vector<Variant> &p_array, const Variant &p_value, bool p_before, const Less &p_less) {
|
||||
|
||||
int lo = 0;
|
||||
int hi = p_array.size();
|
||||
if (p_before) {
|
||||
@ -420,13 +400,11 @@ _FORCE_INLINE_ int bisect(const Vector<Variant> &p_array, const Variant &p_value
|
||||
}
|
||||
|
||||
int Array::bsearch(const Variant &p_value, bool p_before) {
|
||||
|
||||
ERR_FAIL_COND_V(!_p->typed.validate(p_value, "binary search"), -1);
|
||||
return bisect(_p->array, p_value, p_before, _ArrayVariantSort());
|
||||
}
|
||||
|
||||
int Array::bsearch_custom(const Variant &p_value, Object *p_obj, const StringName &p_function, bool p_before) {
|
||||
|
||||
ERR_FAIL_COND_V(!_p->typed.validate(p_value, "custom binary search"), -1);
|
||||
ERR_FAIL_NULL_V(p_obj, 0);
|
||||
|
||||
@ -438,19 +416,16 @@ int Array::bsearch_custom(const Variant &p_value, Object *p_obj, const StringNam
|
||||
}
|
||||
|
||||
Array &Array::invert() {
|
||||
|
||||
_p->array.invert();
|
||||
return *this;
|
||||
}
|
||||
|
||||
void Array::push_front(const Variant &p_value) {
|
||||
|
||||
ERR_FAIL_COND(!_p->typed.validate(p_value, "push_front"));
|
||||
_p->array.insert(0, p_value);
|
||||
}
|
||||
|
||||
Variant Array::pop_back() {
|
||||
|
||||
if (!_p->array.empty()) {
|
||||
int n = _p->array.size() - 1;
|
||||
Variant ret = _p->array.get(n);
|
||||
@ -461,7 +436,6 @@ Variant Array::pop_back() {
|
||||
}
|
||||
|
||||
Variant Array::pop_front() {
|
||||
|
||||
if (!_p->array.empty()) {
|
||||
Variant ret = _p->array.get(0);
|
||||
_p->array.remove(0);
|
||||
@ -471,7 +445,6 @@ Variant Array::pop_front() {
|
||||
}
|
||||
|
||||
Variant Array::min() const {
|
||||
|
||||
Variant minval;
|
||||
for (int i = 0; i < size(); i++) {
|
||||
if (i == 0) {
|
||||
@ -494,7 +467,6 @@ Variant Array::min() const {
|
||||
}
|
||||
|
||||
Variant Array::max() const {
|
||||
|
||||
Variant maxval;
|
||||
for (int i = 0; i < size(); i++) {
|
||||
if (i == 0) {
|
||||
@ -542,17 +514,15 @@ void Array::set_typed(uint32_t p_type, const StringName &p_class_name, const Var
|
||||
}
|
||||
|
||||
Array::Array(const Array &p_from) {
|
||||
|
||||
_p = nullptr;
|
||||
_ref(p_from);
|
||||
}
|
||||
|
||||
Array::Array() {
|
||||
|
||||
_p = memnew(ArrayPrivate);
|
||||
_p->refcount.init();
|
||||
}
|
||||
Array::~Array() {
|
||||
|
||||
Array::~Array() {
|
||||
_unref();
|
||||
}
|
||||
|
@ -39,7 +39,6 @@ class Object;
|
||||
class StringName;
|
||||
|
||||
class Array {
|
||||
|
||||
mutable ArrayPrivate *_p;
|
||||
void _ref(const Array &p_from) const;
|
||||
void _unref() const;
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -254,7 +254,6 @@ VARIANT_ENUM_CAST(_OS::Month);
|
||||
VARIANT_ENUM_CAST(_OS::SystemDir);
|
||||
|
||||
class _Geometry : public Object {
|
||||
|
||||
GDCLASS(_Geometry, Object);
|
||||
|
||||
static _Geometry *singleton;
|
||||
@ -437,7 +436,6 @@ VARIANT_ENUM_CAST(_File::ModeFlags);
|
||||
VARIANT_ENUM_CAST(_File::CompressionMode);
|
||||
|
||||
class _Directory : public Reference {
|
||||
|
||||
GDCLASS(_Directory, Reference);
|
||||
DirAccess *d;
|
||||
|
||||
@ -481,7 +479,6 @@ private:
|
||||
};
|
||||
|
||||
class _Marshalls : public Object {
|
||||
|
||||
GDCLASS(_Marshalls, Object);
|
||||
|
||||
static _Marshalls *singleton;
|
||||
@ -506,7 +503,6 @@ public:
|
||||
};
|
||||
|
||||
class _Mutex : public Reference {
|
||||
|
||||
GDCLASS(_Mutex, Reference);
|
||||
Mutex mutex;
|
||||
|
||||
@ -519,7 +515,6 @@ public:
|
||||
};
|
||||
|
||||
class _Semaphore : public Reference {
|
||||
|
||||
GDCLASS(_Semaphore, Reference);
|
||||
Semaphore semaphore;
|
||||
|
||||
@ -532,7 +527,6 @@ public:
|
||||
};
|
||||
|
||||
class _Thread : public Reference {
|
||||
|
||||
GDCLASS(_Thread, Reference);
|
||||
|
||||
protected:
|
||||
@ -566,7 +560,6 @@ public:
|
||||
VARIANT_ENUM_CAST(_Thread::Priority);
|
||||
|
||||
class _ClassDB : public Object {
|
||||
|
||||
GDCLASS(_ClassDB, Object);
|
||||
|
||||
protected:
|
||||
|
@ -40,7 +40,6 @@ void Callable::call_deferred(const Variant **p_arguments, int p_argcount) const
|
||||
}
|
||||
|
||||
void Callable::call(const Variant **p_arguments, int p_argcount, Variant &r_return_value, CallError &r_call_error) const {
|
||||
|
||||
if (is_null()) {
|
||||
r_call_error.error = CallError::CALL_ERROR_INSTANCE_IS_NULL;
|
||||
r_call_error.argument = 0;
|
||||
@ -73,6 +72,7 @@ ObjectID Callable::get_object_id() const {
|
||||
return ObjectID(object);
|
||||
}
|
||||
}
|
||||
|
||||
StringName Callable::get_method() const {
|
||||
ERR_FAIL_COND_V_MSG(is_custom(), StringName(),
|
||||
vformat("Can't get method on CallableCustom \"%s\".", operator String()));
|
||||
@ -118,9 +118,11 @@ bool Callable::operator==(const Callable &p_callable) const {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
bool Callable::operator!=(const Callable &p_callable) const {
|
||||
return !(*this == p_callable);
|
||||
}
|
||||
|
||||
bool Callable::operator<(const Callable &p_callable) const {
|
||||
bool custom_a = is_custom();
|
||||
bool custom_b = p_callable.is_custom();
|
||||
@ -179,7 +181,6 @@ void Callable::operator=(const Callable &p_callable) {
|
||||
}
|
||||
|
||||
Callable::operator String() const {
|
||||
|
||||
if (is_custom()) {
|
||||
return custom->get_as_text();
|
||||
} else {
|
||||
@ -192,7 +193,6 @@ Callable::operator String() const {
|
||||
String class_name = base->get_class();
|
||||
Ref<Script> script = base->get_script();
|
||||
if (script.is_valid() && script->get_path().is_resource_file()) {
|
||||
|
||||
class_name += "(" + script->get_path().get_file() + ")";
|
||||
}
|
||||
return class_name + "::" + String(method);
|
||||
@ -225,6 +225,7 @@ Callable::Callable(ObjectID p_object, const StringName &p_method) {
|
||||
object = p_object;
|
||||
method = p_method;
|
||||
}
|
||||
|
||||
Callable::Callable(CallableCustom *p_custom) {
|
||||
if (p_custom->referenced) {
|
||||
object = 0;
|
||||
@ -234,6 +235,7 @@ Callable::Callable(CallableCustom *p_custom) {
|
||||
object = 0; //ensure object is all zero, since pointer may be 32 bits
|
||||
custom = p_custom;
|
||||
}
|
||||
|
||||
Callable::Callable(const Callable &p_callable) {
|
||||
if (p_callable.is_custom()) {
|
||||
if (!p_callable.custom->ref_count.ref()) {
|
||||
@ -265,9 +267,11 @@ CallableCustom::CallableCustom() {
|
||||
Object *Signal::get_object() const {
|
||||
return ObjectDB::get_instance(object);
|
||||
}
|
||||
|
||||
ObjectID Signal::get_object_id() const {
|
||||
return object;
|
||||
}
|
||||
|
||||
StringName Signal::get_name() const {
|
||||
return name;
|
||||
}
|
||||
@ -294,7 +298,6 @@ Signal::operator String() const {
|
||||
String class_name = base->get_class();
|
||||
Ref<Script> script = base->get_script();
|
||||
if (script.is_valid() && script->get_path().is_resource_file()) {
|
||||
|
||||
class_name += "(" + script->get_path().get_file() + ")";
|
||||
}
|
||||
return class_name + "::[signal]" + String(name);
|
||||
@ -311,18 +314,20 @@ Error Signal::emit(const Variant **p_arguments, int p_argcount) const {
|
||||
|
||||
return obj->emit_signal(name, p_arguments, p_argcount);
|
||||
}
|
||||
Error Signal::connect(const Callable &p_callable, const Vector<Variant> &p_binds, uint32_t p_flags) {
|
||||
|
||||
Error Signal::connect(const Callable &p_callable, const Vector<Variant> &p_binds, uint32_t p_flags) {
|
||||
Object *object = get_object();
|
||||
ERR_FAIL_COND_V(!object, ERR_UNCONFIGURED);
|
||||
|
||||
return object->connect(name, p_callable, p_binds, p_flags);
|
||||
}
|
||||
|
||||
void Signal::disconnect(const Callable &p_callable) {
|
||||
Object *object = get_object();
|
||||
ERR_FAIL_COND(!object);
|
||||
object->disconnect(name, p_callable);
|
||||
}
|
||||
|
||||
bool Signal::is_connected(const Callable &p_callable) const {
|
||||
Object *object = get_object();
|
||||
ERR_FAIL_COND_V(!object, false);
|
||||
@ -347,7 +352,6 @@ Array Signal::get_connections() const {
|
||||
}
|
||||
|
||||
Signal::Signal(const Object *p_object, const StringName &p_name) {
|
||||
|
||||
ERR_FAIL_COND_MSG(p_object == nullptr, "Object argument to Signal constructor must be non-null");
|
||||
|
||||
object = p_object->get_instance_id();
|
||||
@ -355,7 +359,6 @@ Signal::Signal(const Object *p_object, const StringName &p_name) {
|
||||
}
|
||||
|
||||
Signal::Signal(ObjectID p_object, const StringName &p_name) {
|
||||
|
||||
object = p_object;
|
||||
name = p_name;
|
||||
}
|
||||
|
@ -45,7 +45,6 @@ class CallableCustom;
|
||||
// but can be optimized or customized.
|
||||
|
||||
class Callable {
|
||||
|
||||
//needs to be max 16 bytes in 64 bits
|
||||
StringName method;
|
||||
union {
|
||||
|
@ -48,7 +48,6 @@ bool CallableCustomMethodPointerBase::compare_equal(const CallableCustom *p_a, c
|
||||
}
|
||||
|
||||
bool CallableCustomMethodPointerBase::compare_less(const CallableCustom *p_a, const CallableCustom *p_b) {
|
||||
|
||||
const CallableCustomMethodPointerBase *a = static_cast<const CallableCustomMethodPointerBase *>(p_a);
|
||||
const CallableCustomMethodPointerBase *b = static_cast<const CallableCustomMethodPointerBase *>(p_b);
|
||||
|
||||
|
@ -38,7 +38,6 @@
|
||||
#include "core/simple_type.h"
|
||||
|
||||
class CallableCustomMethodPointerBase : public CallableCustom {
|
||||
|
||||
uint32_t *comp_ptr;
|
||||
uint32_t comp_size;
|
||||
uint32_t h;
|
||||
@ -74,7 +73,6 @@ public:
|
||||
|
||||
template <class T>
|
||||
struct VariantCasterAndValidate {
|
||||
|
||||
static _FORCE_INLINE_ T cast(const Variant **p_args, uint32_t p_arg_idx, Callable::CallError &r_error) {
|
||||
Variant::Type argtype = GetTypeInfo<T>::VARIANT_TYPE;
|
||||
if (!Variant::can_convert_strict(p_args[p_arg_idx]->get_type(), argtype)) {
|
||||
@ -89,7 +87,6 @@ struct VariantCasterAndValidate {
|
||||
|
||||
template <class T>
|
||||
struct VariantCasterAndValidate<T &> {
|
||||
|
||||
static _FORCE_INLINE_ T cast(const Variant **p_args, uint32_t p_arg_idx, Callable::CallError &r_error) {
|
||||
Variant::Type argtype = GetTypeInfo<T>::VARIANT_TYPE;
|
||||
if (!Variant::can_convert_strict(p_args[p_arg_idx]->get_type(), argtype)) {
|
||||
@ -104,7 +101,6 @@ struct VariantCasterAndValidate<T &> {
|
||||
|
||||
template <class T>
|
||||
struct VariantCasterAndValidate<const T &> {
|
||||
|
||||
static _FORCE_INLINE_ T cast(const Variant **p_args, uint32_t p_arg_idx, Callable::CallError &r_error) {
|
||||
Variant::Type argtype = GetTypeInfo<T>::VARIANT_TYPE;
|
||||
if (!Variant::can_convert_strict(p_args[p_arg_idx]->get_type(), argtype)) {
|
||||
@ -163,7 +159,6 @@ void call_with_variant_args(T *p_instance, void (T::*p_method)(P...), const Vari
|
||||
|
||||
template <class T, class... P>
|
||||
class CallableCustomMethodPointer : public CallableCustomMethodPointerBase {
|
||||
|
||||
struct Data {
|
||||
T *instance;
|
||||
void (T::*method)(P...);
|
||||
@ -173,7 +168,6 @@ public:
|
||||
virtual ObjectID get_object() const { return data.instance->get_instance_id(); }
|
||||
|
||||
virtual void call(const Variant **p_arguments, int p_argcount, Variant &r_return_value, Callable::CallError &r_call_error) const {
|
||||
|
||||
call_with_variant_args(data.instance, data.method, p_arguments, p_argcount, r_call_error);
|
||||
}
|
||||
|
||||
@ -246,7 +240,6 @@ void call_with_variant_args_ret(T *p_instance, R (T::*p_method)(P...), const Var
|
||||
|
||||
template <class T, class R, class... P>
|
||||
class CallableCustomMethodPointerRet : public CallableCustomMethodPointerBase {
|
||||
|
||||
struct Data {
|
||||
T *instance;
|
||||
R(T::*method)
|
||||
@ -257,7 +250,6 @@ public:
|
||||
virtual ObjectID get_object() const { return data.instance->get_instance_id(); }
|
||||
|
||||
virtual void call(const Variant **p_arguments, int p_argcount, Variant &r_return_value, Callable::CallError &r_call_error) const {
|
||||
|
||||
call_with_variant_args_ret(data.instance, data.method, p_arguments, p_argcount, r_return_value, r_call_error);
|
||||
}
|
||||
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -48,7 +48,6 @@
|
||||
#ifdef DEBUG_METHODS_ENABLED
|
||||
|
||||
struct MethodDefinition {
|
||||
|
||||
StringName name;
|
||||
Vector<StringName> args;
|
||||
MethodDefinition() {}
|
||||
@ -103,7 +102,6 @@ public:
|
||||
|
||||
public:
|
||||
struct PropertySetGet {
|
||||
|
||||
int index;
|
||||
StringName setter;
|
||||
StringName getter;
|
||||
@ -113,7 +111,6 @@ public:
|
||||
};
|
||||
|
||||
struct ClassInfo {
|
||||
|
||||
APIType api = API_NONE;
|
||||
ClassInfo *inherits_ptr = nullptr;
|
||||
void *class_ptr = nullptr;
|
||||
@ -169,13 +166,11 @@ public:
|
||||
// DO NOT USE THIS!!!!!! NEEDS TO BE PUBLIC BUT DO NOT USE NO MATTER WHAT!!!
|
||||
template <class T>
|
||||
static void _add_class() {
|
||||
|
||||
_add_class2(T::get_class_static(), T::get_parent_class_static());
|
||||
}
|
||||
|
||||
template <class T>
|
||||
static void register_class() {
|
||||
|
||||
GLOBAL_LOCK_FUNCTION;
|
||||
T::initialize_class();
|
||||
ClassInfo *t = classes.getptr(T::get_class_static());
|
||||
@ -188,7 +183,6 @@ public:
|
||||
|
||||
template <class T>
|
||||
static void register_virtual_class() {
|
||||
|
||||
GLOBAL_LOCK_FUNCTION;
|
||||
T::initialize_class();
|
||||
ClassInfo *t = classes.getptr(T::get_class_static());
|
||||
@ -200,13 +194,11 @@ public:
|
||||
|
||||
template <class T>
|
||||
static Object *_create_ptr_func() {
|
||||
|
||||
return T::create();
|
||||
}
|
||||
|
||||
template <class T>
|
||||
static void register_custom_instance_class() {
|
||||
|
||||
GLOBAL_LOCK_FUNCTION;
|
||||
T::initialize_class();
|
||||
ClassInfo *t = classes.getptr(T::get_class_static());
|
||||
@ -233,7 +225,6 @@ public:
|
||||
|
||||
template <class N, class M>
|
||||
static MethodBind *bind_method(N p_method_name, M p_method) {
|
||||
|
||||
MethodBind *bind = create_method_bind(p_method);
|
||||
|
||||
return bind_methodfi(METHOD_FLAGS_DEFAULT, bind, p_method_name, nullptr, 0); //use static function, much smaller binary usage
|
||||
@ -241,7 +232,6 @@ public:
|
||||
|
||||
template <class N, class M>
|
||||
static MethodBind *bind_method(N p_method_name, M p_method, const Variant &p_def1) {
|
||||
|
||||
MethodBind *bind = create_method_bind(p_method);
|
||||
const Variant *ptr[1] = { &p_def1 };
|
||||
|
||||
@ -250,7 +240,6 @@ public:
|
||||
|
||||
template <class N, class M>
|
||||
static MethodBind *bind_method(N p_method_name, M p_method, const Variant &p_def1, const Variant &p_def2) {
|
||||
|
||||
MethodBind *bind = create_method_bind(p_method);
|
||||
const Variant *ptr[2] = { &p_def1, &p_def2 };
|
||||
|
||||
@ -259,7 +248,6 @@ public:
|
||||
|
||||
template <class N, class M>
|
||||
static MethodBind *bind_method(N p_method_name, M p_method, const Variant &p_def1, const Variant &p_def2, const Variant &p_def3) {
|
||||
|
||||
MethodBind *bind = create_method_bind(p_method);
|
||||
const Variant *ptr[3] = { &p_def1, &p_def2, &p_def3 };
|
||||
|
||||
@ -268,7 +256,6 @@ public:
|
||||
|
||||
template <class N, class M>
|
||||
static MethodBind *bind_method(N p_method_name, M p_method, const Variant &p_def1, const Variant &p_def2, const Variant &p_def3, const Variant &p_def4) {
|
||||
|
||||
MethodBind *bind = create_method_bind(p_method);
|
||||
const Variant *ptr[4] = { &p_def1, &p_def2, &p_def3, &p_def4 };
|
||||
|
||||
@ -277,7 +264,6 @@ public:
|
||||
|
||||
template <class N, class M>
|
||||
static MethodBind *bind_method(N p_method_name, M p_method, const Variant &p_def1, const Variant &p_def2, const Variant &p_def3, const Variant &p_def4, const Variant &p_def5) {
|
||||
|
||||
MethodBind *bind = create_method_bind(p_method);
|
||||
const Variant *ptr[5] = { &p_def1, &p_def2, &p_def3, &p_def4, &p_def5 };
|
||||
|
||||
@ -286,7 +272,6 @@ public:
|
||||
|
||||
template <class N, class M>
|
||||
static MethodBind *bind_method(N p_method_name, M p_method, const Variant &p_def1, const Variant &p_def2, const Variant &p_def3, const Variant &p_def4, const Variant &p_def5, const Variant &p_def6) {
|
||||
|
||||
MethodBind *bind = create_method_bind(p_method);
|
||||
const Variant *ptr[6] = { &p_def1, &p_def2, &p_def3, &p_def4, &p_def5, &p_def6 };
|
||||
|
||||
@ -295,7 +280,6 @@ public:
|
||||
|
||||
template <class N, class M>
|
||||
static MethodBind *bind_method(N p_method_name, M p_method, const Variant &p_def1, const Variant &p_def2, const Variant &p_def3, const Variant &p_def4, const Variant &p_def5, const Variant &p_def6, const Variant &p_def7) {
|
||||
|
||||
MethodBind *bind = create_method_bind(p_method);
|
||||
const Variant *ptr[7] = { &p_def1, &p_def2, &p_def3, &p_def4, &p_def5, &p_def6, &p_def7 };
|
||||
|
||||
@ -304,7 +288,6 @@ public:
|
||||
|
||||
template <class N, class M>
|
||||
static MethodBind *bind_method(N p_method_name, M p_method, const Variant &p_def1, const Variant &p_def2, const Variant &p_def3, const Variant &p_def4, const Variant &p_def5, const Variant &p_def6, const Variant &p_def7, const Variant &p_def8) {
|
||||
|
||||
MethodBind *bind = create_method_bind(p_method);
|
||||
const Variant *ptr[8] = { &p_def1, &p_def2, &p_def3, &p_def4, &p_def5, &p_def6, &p_def7, &p_def8 };
|
||||
|
||||
@ -313,7 +296,6 @@ public:
|
||||
|
||||
template <class M>
|
||||
static MethodBind *bind_vararg_method(uint32_t p_flags, StringName p_name, M p_method, const MethodInfo &p_info = MethodInfo(), const Vector<Variant> &p_default_args = Vector<Variant>(), bool p_return_nil_is_variant = true) {
|
||||
|
||||
GLOBAL_LOCK_FUNCTION;
|
||||
|
||||
MethodBind *bind = create_vararg_method_bind(p_method, p_info, p_return_nil_is_variant);
|
||||
|
@ -36,7 +36,6 @@
|
||||
#include "core/print_string.h"
|
||||
|
||||
uint32_t Color::to_argb32() const {
|
||||
|
||||
uint32_t c = (uint8_t)Math::round(a * 255);
|
||||
c <<= 8;
|
||||
c |= (uint8_t)Math::round(r * 255);
|
||||
@ -49,7 +48,6 @@ uint32_t Color::to_argb32() const {
|
||||
}
|
||||
|
||||
uint32_t Color::to_abgr32() const {
|
||||
|
||||
uint32_t c = (uint8_t)Math::round(a * 255);
|
||||
c <<= 8;
|
||||
c |= (uint8_t)Math::round(b * 255);
|
||||
@ -62,7 +60,6 @@ uint32_t Color::to_abgr32() const {
|
||||
}
|
||||
|
||||
uint32_t Color::to_rgba32() const {
|
||||
|
||||
uint32_t c = (uint8_t)Math::round(r * 255);
|
||||
c <<= 8;
|
||||
c |= (uint8_t)Math::round(g * 255);
|
||||
@ -75,7 +72,6 @@ uint32_t Color::to_rgba32() const {
|
||||
}
|
||||
|
||||
uint64_t Color::to_abgr64() const {
|
||||
|
||||
uint64_t c = (uint16_t)Math::round(a * 65535);
|
||||
c <<= 16;
|
||||
c |= (uint16_t)Math::round(b * 65535);
|
||||
@ -88,7 +84,6 @@ uint64_t Color::to_abgr64() const {
|
||||
}
|
||||
|
||||
uint64_t Color::to_argb64() const {
|
||||
|
||||
uint64_t c = (uint16_t)Math::round(a * 65535);
|
||||
c <<= 16;
|
||||
c |= (uint16_t)Math::round(r * 65535);
|
||||
@ -101,7 +96,6 @@ uint64_t Color::to_argb64() const {
|
||||
}
|
||||
|
||||
uint64_t Color::to_rgba64() const {
|
||||
|
||||
uint64_t c = (uint16_t)Math::round(r * 65535);
|
||||
c <<= 16;
|
||||
c |= (uint16_t)Math::round(g * 65535);
|
||||
@ -114,7 +108,6 @@ uint64_t Color::to_rgba64() const {
|
||||
}
|
||||
|
||||
float Color::get_h() const {
|
||||
|
||||
float min = MIN(r, g);
|
||||
min = MIN(min, b);
|
||||
float max = MAX(r, g);
|
||||
@ -122,26 +115,28 @@ float Color::get_h() const {
|
||||
|
||||
float delta = max - min;
|
||||
|
||||
if (delta == 0)
|
||||
if (delta == 0) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
float h;
|
||||
if (r == max)
|
||||
if (r == max) {
|
||||
h = (g - b) / delta; // between yellow & magenta
|
||||
else if (g == max)
|
||||
} else if (g == max) {
|
||||
h = 2 + (b - r) / delta; // between cyan & yellow
|
||||
else
|
||||
} else {
|
||||
h = 4 + (r - g) / delta; // between magenta & cyan
|
||||
}
|
||||
|
||||
h /= 6.0;
|
||||
if (h < 0)
|
||||
if (h < 0) {
|
||||
h += 1.0;
|
||||
}
|
||||
|
||||
return h;
|
||||
}
|
||||
|
||||
float Color::get_s() const {
|
||||
|
||||
float min = MIN(r, g);
|
||||
min = MIN(min, b);
|
||||
float max = MAX(r, g);
|
||||
@ -153,14 +148,12 @@ float Color::get_s() const {
|
||||
}
|
||||
|
||||
float Color::get_v() const {
|
||||
|
||||
float max = MAX(r, g);
|
||||
max = MAX(max, b);
|
||||
return max;
|
||||
}
|
||||
|
||||
void Color::set_hsv(float p_h, float p_s, float p_v, float p_alpha) {
|
||||
|
||||
int i;
|
||||
float f, p, q, t;
|
||||
a = p_alpha;
|
||||
@ -215,25 +208,22 @@ void Color::set_hsv(float p_h, float p_s, float p_v, float p_alpha) {
|
||||
}
|
||||
|
||||
bool Color::is_equal_approx(const Color &p_color) const {
|
||||
|
||||
return Math::is_equal_approx(r, p_color.r) && Math::is_equal_approx(g, p_color.g) && Math::is_equal_approx(b, p_color.b) && Math::is_equal_approx(a, p_color.a);
|
||||
}
|
||||
|
||||
void Color::invert() {
|
||||
|
||||
r = 1.0 - r;
|
||||
g = 1.0 - g;
|
||||
b = 1.0 - b;
|
||||
}
|
||||
void Color::contrast() {
|
||||
|
||||
void Color::contrast() {
|
||||
r = Math::fmod(r + 0.5, 1.0);
|
||||
g = Math::fmod(g + 0.5, 1.0);
|
||||
b = Math::fmod(b + 0.5, 1.0);
|
||||
}
|
||||
|
||||
Color Color::hex(uint32_t p_hex) {
|
||||
|
||||
float a = (p_hex & 0xFF) / 255.0;
|
||||
p_hex >>= 8;
|
||||
float b = (p_hex & 0xFF) / 255.0;
|
||||
@ -246,7 +236,6 @@ Color Color::hex(uint32_t p_hex) {
|
||||
}
|
||||
|
||||
Color Color::hex64(uint64_t p_hex) {
|
||||
|
||||
float a = (p_hex & 0xFFFF) / 65535.0;
|
||||
p_hex >>= 16;
|
||||
float b = (p_hex & 0xFFFF) / 65535.0;
|
||||
@ -259,7 +248,6 @@ Color Color::hex64(uint64_t p_hex) {
|
||||
}
|
||||
|
||||
Color Color::from_rgbe9995(uint32_t p_rgbe) {
|
||||
|
||||
float r = p_rgbe & 0x1ff;
|
||||
float g = (p_rgbe >> 9) & 0x1ff;
|
||||
float b = (p_rgbe >> 18) & 0x1ff;
|
||||
@ -274,11 +262,9 @@ Color Color::from_rgbe9995(uint32_t p_rgbe) {
|
||||
}
|
||||
|
||||
static float _parse_col(const String &p_str, int p_ofs) {
|
||||
|
||||
int ig = 0;
|
||||
|
||||
for (int i = 0; i < 2; i++) {
|
||||
|
||||
int c = p_str[i + p_ofs];
|
||||
int v = 0;
|
||||
|
||||
@ -294,36 +280,36 @@ static float _parse_col(const String &p_str, int p_ofs) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (i == 0)
|
||||
if (i == 0) {
|
||||
ig += v * 16;
|
||||
else
|
||||
} else {
|
||||
ig += v;
|
||||
}
|
||||
}
|
||||
|
||||
return ig;
|
||||
}
|
||||
|
||||
Color Color::inverted() const {
|
||||
|
||||
Color c = *this;
|
||||
c.invert();
|
||||
return c;
|
||||
}
|
||||
|
||||
Color Color::contrasted() const {
|
||||
|
||||
Color c = *this;
|
||||
c.contrast();
|
||||
return c;
|
||||
}
|
||||
|
||||
Color Color::html(const String &p_color) {
|
||||
|
||||
String color = p_color;
|
||||
if (color.length() == 0)
|
||||
if (color.length() == 0) {
|
||||
return Color();
|
||||
if (color[0] == '#')
|
||||
}
|
||||
if (color[0] == '#') {
|
||||
color = color.substr(1, color.length() - 1);
|
||||
}
|
||||
if (color.length() == 3 || color.length() == 4) {
|
||||
String exp_color;
|
||||
for (int i = 0; i < color.length(); i++) {
|
||||
@ -362,13 +348,14 @@ Color Color::html(const String &p_color) {
|
||||
}
|
||||
|
||||
bool Color::html_is_valid(const String &p_color) {
|
||||
|
||||
String color = p_color;
|
||||
|
||||
if (color.length() == 0)
|
||||
if (color.length() == 0) {
|
||||
return false;
|
||||
if (color[0] == '#')
|
||||
}
|
||||
if (color[0] == '#') {
|
||||
color = color.substr(1, color.length() - 1);
|
||||
}
|
||||
|
||||
bool alpha = false;
|
||||
|
||||
@ -406,8 +393,9 @@ bool Color::html_is_valid(const String &p_color) {
|
||||
}
|
||||
|
||||
Color Color::named(const String &p_name) {
|
||||
if (_named_colors.empty())
|
||||
if (_named_colors.empty()) {
|
||||
_populate_named_colors(); // from color_names.inc
|
||||
}
|
||||
String name = p_name;
|
||||
// Normalize name
|
||||
name = name.replace(" ", "");
|
||||
@ -423,19 +411,18 @@ Color Color::named(const String &p_name) {
|
||||
}
|
||||
|
||||
String _to_hex(float p_val) {
|
||||
|
||||
int v = Math::round(p_val * 255);
|
||||
v = CLAMP(v, 0, 255);
|
||||
String ret;
|
||||
|
||||
for (int i = 0; i < 2; i++) {
|
||||
|
||||
CharType c[2] = { 0, 0 };
|
||||
int lv = v & 0xF;
|
||||
if (lv < 10)
|
||||
if (lv < 10) {
|
||||
c[0] = '0' + lv;
|
||||
else
|
||||
} else {
|
||||
c[0] = 'a' + lv - 10;
|
||||
}
|
||||
|
||||
v >>= 4;
|
||||
String cs = (const CharType *)c;
|
||||
@ -446,21 +433,21 @@ String _to_hex(float p_val) {
|
||||
}
|
||||
|
||||
String Color::to_html(bool p_alpha) const {
|
||||
|
||||
String txt;
|
||||
txt += _to_hex(r);
|
||||
txt += _to_hex(g);
|
||||
txt += _to_hex(b);
|
||||
if (p_alpha)
|
||||
if (p_alpha) {
|
||||
txt = _to_hex(a) + txt;
|
||||
}
|
||||
return txt;
|
||||
}
|
||||
|
||||
Color Color::from_hsv(float p_h, float p_s, float p_v, float p_a) const {
|
||||
|
||||
p_h = Math::fmod(p_h * 360.0f, 360.0f);
|
||||
if (p_h < 0.0)
|
||||
if (p_h < 0.0) {
|
||||
p_h += 360.0f;
|
||||
}
|
||||
|
||||
const float h_ = p_h / 60.0f;
|
||||
const float c = p_v * p_s;
|
||||
@ -510,12 +497,10 @@ Color Color::from_hsv(float p_h, float p_s, float p_v, float p_a) const {
|
||||
}
|
||||
|
||||
Color::operator String() const {
|
||||
|
||||
return rtos(r) + ", " + rtos(g) + ", " + rtos(b) + ", " + rtos(a);
|
||||
}
|
||||
|
||||
Color Color::operator+(const Color &p_color) const {
|
||||
|
||||
return Color(
|
||||
r + p_color.r,
|
||||
g + p_color.g,
|
||||
@ -524,7 +509,6 @@ Color Color::operator+(const Color &p_color) const {
|
||||
}
|
||||
|
||||
Color Color::operator-(const Color &p_color) const {
|
||||
|
||||
return Color(
|
||||
r - p_color.r,
|
||||
g - p_color.g,
|
||||
@ -533,7 +517,6 @@ Color Color::operator-(const Color &p_color) const {
|
||||
}
|
||||
|
||||
void Color::operator-=(const Color &p_color) {
|
||||
|
||||
r = r - p_color.r;
|
||||
g = g - p_color.g;
|
||||
b = b - p_color.b;
|
||||
@ -541,7 +524,6 @@ void Color::operator-=(const Color &p_color) {
|
||||
}
|
||||
|
||||
Color Color::operator*(const Color &p_color) const {
|
||||
|
||||
return Color(
|
||||
r * p_color.r,
|
||||
g * p_color.g,
|
||||
@ -550,7 +532,6 @@ Color Color::operator*(const Color &p_color) const {
|
||||
}
|
||||
|
||||
Color Color::operator*(const real_t &rvalue) const {
|
||||
|
||||
return Color(
|
||||
r * rvalue,
|
||||
g * rvalue,
|
||||
@ -559,7 +540,6 @@ Color Color::operator*(const real_t &rvalue) const {
|
||||
}
|
||||
|
||||
void Color::operator*=(const Color &p_color) {
|
||||
|
||||
r = r * p_color.r;
|
||||
g = g * p_color.g;
|
||||
b = b * p_color.b;
|
||||
@ -567,7 +547,6 @@ void Color::operator*=(const Color &p_color) {
|
||||
}
|
||||
|
||||
void Color::operator*=(const real_t &rvalue) {
|
||||
|
||||
r = r * rvalue;
|
||||
g = g * rvalue;
|
||||
b = b * rvalue;
|
||||
@ -575,7 +554,6 @@ void Color::operator*=(const real_t &rvalue) {
|
||||
}
|
||||
|
||||
Color Color::operator/(const Color &p_color) const {
|
||||
|
||||
return Color(
|
||||
r / p_color.r,
|
||||
g / p_color.g,
|
||||
@ -584,7 +562,6 @@ Color Color::operator/(const Color &p_color) const {
|
||||
}
|
||||
|
||||
Color Color::operator/(const real_t &rvalue) const {
|
||||
|
||||
return Color(
|
||||
r / rvalue,
|
||||
g / rvalue,
|
||||
@ -593,7 +570,6 @@ Color Color::operator/(const real_t &rvalue) const {
|
||||
}
|
||||
|
||||
void Color::operator/=(const Color &p_color) {
|
||||
|
||||
r = r / p_color.r;
|
||||
g = g / p_color.g;
|
||||
b = b / p_color.b;
|
||||
@ -601,7 +577,6 @@ void Color::operator/=(const Color &p_color) {
|
||||
}
|
||||
|
||||
void Color::operator/=(const real_t &rvalue) {
|
||||
|
||||
if (rvalue == 0) {
|
||||
r = 1.0;
|
||||
g = 1.0;
|
||||
@ -616,7 +591,6 @@ void Color::operator/=(const real_t &rvalue) {
|
||||
};
|
||||
|
||||
Color Color::operator-() const {
|
||||
|
||||
return Color(
|
||||
1.0 - r,
|
||||
1.0 - g,
|
||||
|
19
core/color.h
19
core/color.h
@ -35,9 +35,7 @@
|
||||
#include "core/ustring.h"
|
||||
|
||||
struct Color {
|
||||
|
||||
union {
|
||||
|
||||
struct {
|
||||
float r;
|
||||
float g;
|
||||
@ -98,7 +96,6 @@ struct Color {
|
||||
Color contrasted() const;
|
||||
|
||||
_FORCE_INLINE_ Color lerp(const Color &p_b, float p_t) const {
|
||||
|
||||
Color res = *this;
|
||||
|
||||
res.r += (p_t * (p_b.r - r));
|
||||
@ -110,7 +107,6 @@ struct Color {
|
||||
}
|
||||
|
||||
_FORCE_INLINE_ Color darkened(float p_amount) const {
|
||||
|
||||
Color res = *this;
|
||||
res.r = res.r * (1.0f - p_amount);
|
||||
res.g = res.g * (1.0f - p_amount);
|
||||
@ -119,7 +115,6 @@ struct Color {
|
||||
}
|
||||
|
||||
_FORCE_INLINE_ Color lightened(float p_amount) const {
|
||||
|
||||
Color res = *this;
|
||||
res.r = res.r + (1.0f - res.r) * p_amount;
|
||||
res.g = res.g + (1.0f - res.g) * p_amount;
|
||||
@ -128,7 +123,6 @@ struct Color {
|
||||
}
|
||||
|
||||
_FORCE_INLINE_ uint32_t to_rgbe9995() const {
|
||||
|
||||
const float pow2to9 = 512.0f;
|
||||
const float B = 15.0f;
|
||||
//const float Emax = 31.0f;
|
||||
@ -162,7 +156,6 @@ struct Color {
|
||||
}
|
||||
|
||||
_FORCE_INLINE_ Color blend(const Color &p_over) const {
|
||||
|
||||
Color res;
|
||||
float sa = 1.0 - p_over.a;
|
||||
res.a = a * sa + p_over.a;
|
||||
@ -177,7 +170,6 @@ struct Color {
|
||||
}
|
||||
|
||||
_FORCE_INLINE_ Color to_linear() const {
|
||||
|
||||
return Color(
|
||||
r < 0.04045 ? r * (1.0 / 12.92) : Math::pow((r + 0.055) * (1.0 / (1 + 0.055)), 2.4),
|
||||
g < 0.04045 ? g * (1.0 / 12.92) : Math::pow((g + 0.055) * (1.0 / (1 + 0.055)), 2.4),
|
||||
@ -185,7 +177,6 @@ struct Color {
|
||||
a);
|
||||
}
|
||||
_FORCE_INLINE_ Color to_srgb() const {
|
||||
|
||||
return Color(
|
||||
r < 0.0031308 ? 12.92 * r : (1.0 + 0.055) * Math::pow(r, 1.0f / 2.4f) - 0.055,
|
||||
g < 0.0031308 ? 12.92 * g : (1.0 + 0.055) * Math::pow(g, 1.0f / 2.4f) - 0.055,
|
||||
@ -228,17 +219,19 @@ struct Color {
|
||||
};
|
||||
|
||||
bool Color::operator<(const Color &p_color) const {
|
||||
|
||||
if (r == p_color.r) {
|
||||
if (g == p_color.g) {
|
||||
if (b == p_color.b) {
|
||||
return (a < p_color.a);
|
||||
} else
|
||||
} else {
|
||||
return (b < p_color.b);
|
||||
} else
|
||||
}
|
||||
} else {
|
||||
return g < p_color.g;
|
||||
} else
|
||||
}
|
||||
} else {
|
||||
return r < p_color.r;
|
||||
}
|
||||
}
|
||||
|
||||
#endif // COLOR_H
|
||||
|
@ -3,8 +3,9 @@
|
||||
|
||||
static Map<String, Color> _named_colors;
|
||||
static void _populate_named_colors() {
|
||||
if (!_named_colors.empty())
|
||||
if (!_named_colors.empty()) {
|
||||
return;
|
||||
}
|
||||
_named_colors.insert("aliceblue", Color(0.94, 0.97, 1.00));
|
||||
_named_colors.insert("antiquewhite", Color(0.98, 0.92, 0.84));
|
||||
_named_colors.insert("aqua", Color(0.00, 1.00, 1.00));
|
||||
|
@ -33,30 +33,24 @@
|
||||
#include "core/os/os.h"
|
||||
|
||||
void CommandQueueMT::lock() {
|
||||
|
||||
mutex.lock();
|
||||
}
|
||||
|
||||
void CommandQueueMT::unlock() {
|
||||
|
||||
mutex.unlock();
|
||||
}
|
||||
|
||||
void CommandQueueMT::wait_for_flush() {
|
||||
|
||||
// wait one millisecond for a flush to happen
|
||||
OS::get_singleton()->delay_usec(1000);
|
||||
}
|
||||
|
||||
CommandQueueMT::SyncSemaphore *CommandQueueMT::_alloc_sync_sem() {
|
||||
|
||||
int idx = -1;
|
||||
|
||||
while (true) {
|
||||
|
||||
lock();
|
||||
for (int i = 0; i < SYNC_SEMAPHORES; i++) {
|
||||
|
||||
if (!sync_sems[i].in_use) {
|
||||
sync_sems[i].in_use = true;
|
||||
idx = i;
|
||||
@ -100,12 +94,14 @@ tryagain:
|
||||
}
|
||||
|
||||
CommandQueueMT::CommandQueueMT(bool p_sync) {
|
||||
if (p_sync)
|
||||
if (p_sync) {
|
||||
sync = memnew(Semaphore);
|
||||
}
|
||||
}
|
||||
|
||||
CommandQueueMT::~CommandQueueMT() {
|
||||
if (sync)
|
||||
if (sync) {
|
||||
memdelete(sync);
|
||||
}
|
||||
memfree(command_mem);
|
||||
}
|
||||
|
@ -297,22 +297,18 @@
|
||||
#define MAX_CMD_PARAMS 15
|
||||
|
||||
class CommandQueueMT {
|
||||
|
||||
struct SyncSemaphore {
|
||||
|
||||
Semaphore sem;
|
||||
bool in_use = false;
|
||||
};
|
||||
|
||||
struct CommandBase {
|
||||
|
||||
virtual void call() = 0;
|
||||
virtual void post() {}
|
||||
virtual ~CommandBase() {}
|
||||
};
|
||||
|
||||
struct SyncCommand : public CommandBase {
|
||||
|
||||
SyncSemaphore *sync_sem;
|
||||
|
||||
virtual void post() {
|
||||
@ -349,7 +345,6 @@ class CommandQueueMT {
|
||||
|
||||
template <class T>
|
||||
T *allocate() {
|
||||
|
||||
// alloc size is size+T+safeguard
|
||||
uint32_t alloc_size = ((sizeof(T) + 8 - 1) & ~(8 - 1)) + 8;
|
||||
|
||||
@ -358,7 +353,6 @@ class CommandQueueMT {
|
||||
if (write_ptr < dealloc_ptr) {
|
||||
// behind dealloc_ptr, check that there is room
|
||||
if ((dealloc_ptr - write_ptr) <= alloc_size) {
|
||||
|
||||
// There is no more room, try to deallocate something
|
||||
if (dealloc_one()) {
|
||||
goto tryagain;
|
||||
@ -405,12 +399,10 @@ class CommandQueueMT {
|
||||
|
||||
template <class T>
|
||||
T *allocate_and_lock() {
|
||||
|
||||
lock();
|
||||
T *ret;
|
||||
|
||||
while ((ret = allocate<T>()) == nullptr) {
|
||||
|
||||
unlock();
|
||||
// sleep a little until fetch happened and some room is made
|
||||
wait_for_flush();
|
||||
@ -421,14 +413,16 @@ class CommandQueueMT {
|
||||
}
|
||||
|
||||
bool flush_one(bool p_lock = true) {
|
||||
if (p_lock)
|
||||
if (p_lock) {
|
||||
lock();
|
||||
}
|
||||
tryagain:
|
||||
|
||||
// tried to read an empty queue
|
||||
if (read_ptr == write_ptr) {
|
||||
if (p_lock)
|
||||
if (p_lock) {
|
||||
unlock();
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
@ -447,18 +441,21 @@ class CommandQueueMT {
|
||||
|
||||
read_ptr += size;
|
||||
|
||||
if (p_lock)
|
||||
if (p_lock) {
|
||||
unlock();
|
||||
}
|
||||
cmd->call();
|
||||
if (p_lock)
|
||||
if (p_lock) {
|
||||
lock();
|
||||
}
|
||||
|
||||
cmd->post();
|
||||
cmd->~CommandBase();
|
||||
*(uint32_t *)&command_mem[size_ptr] &= ~1;
|
||||
|
||||
if (p_lock)
|
||||
if (p_lock) {
|
||||
unlock();
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
@ -488,11 +485,10 @@ public:
|
||||
}
|
||||
|
||||
void flush_all() {
|
||||
|
||||
//ERR_FAIL_COND(sync);
|
||||
lock();
|
||||
while (flush_one(false))
|
||||
;
|
||||
while (flush_one(false)) {
|
||||
}
|
||||
unlock();
|
||||
}
|
||||
|
||||
|
@ -37,7 +37,6 @@ extern "C" {
|
||||
}
|
||||
|
||||
struct _PHashTranslationCmp {
|
||||
|
||||
int orig_len;
|
||||
CharString compressed;
|
||||
int offset;
|
||||
@ -65,7 +64,6 @@ void PHashTranslation::generate(const Ref<Translation> &p_from) {
|
||||
int total_string_size = 0;
|
||||
|
||||
for (List<StringName>::Element *E = keys.front(); E; E = E->next()) {
|
||||
|
||||
//hash string
|
||||
CharString cs = E->get().operator String().utf8();
|
||||
uint32_t h = hash(0, cs.get_data());
|
||||
@ -108,21 +106,19 @@ void PHashTranslation::generate(const Ref<Translation> &p_from) {
|
||||
int bucket_table_size = 0;
|
||||
|
||||
for (int i = 0; i < size; i++) {
|
||||
|
||||
const Vector<Pair<int, CharString>> &b = buckets[i];
|
||||
Map<uint32_t, int> &t = table.write[i];
|
||||
|
||||
if (b.size() == 0)
|
||||
if (b.size() == 0) {
|
||||
continue;
|
||||
}
|
||||
|
||||
int d = 1;
|
||||
int item = 0;
|
||||
|
||||
while (item < b.size()) {
|
||||
|
||||
uint32_t slot = hash(d, b[item].second.get_data());
|
||||
if (t.has(slot)) {
|
||||
|
||||
item = 0;
|
||||
d++;
|
||||
t.clear();
|
||||
@ -151,7 +147,6 @@ void PHashTranslation::generate(const Ref<Translation> &p_from) {
|
||||
int collisions = 0;
|
||||
|
||||
for (int i = 0; i < size; i++) {
|
||||
|
||||
const Map<uint32_t, int> &t = table[i];
|
||||
if (t.size() == 0) {
|
||||
htw[i] = 0xFFFFFFFF; //nothing
|
||||
@ -165,7 +160,6 @@ void PHashTranslation::generate(const Ref<Translation> &p_from) {
|
||||
btw[btindex++] = hfunc_table[i];
|
||||
|
||||
for (Map<uint32_t, int>::Element *E = t.front(); E; E = E->next()) {
|
||||
|
||||
btw[btindex++] = E->key();
|
||||
btw[btindex++] = compressed[E->get()].offset;
|
||||
btw[btindex++] = compressed[E->get()].compressed.size();
|
||||
@ -187,7 +181,6 @@ void PHashTranslation::generate(const Ref<Translation> &p_from) {
|
||||
}
|
||||
|
||||
bool PHashTranslation::_set(const StringName &p_name, const Variant &p_value) {
|
||||
|
||||
String name = p_name.operator String();
|
||||
if (name == "hash_table") {
|
||||
hash_table = p_value;
|
||||
@ -197,33 +190,34 @@ bool PHashTranslation::_set(const StringName &p_name, const Variant &p_value) {
|
||||
strings = p_value;
|
||||
} else if (name == "load_from") {
|
||||
generate(p_value);
|
||||
} else
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool PHashTranslation::_get(const StringName &p_name, Variant &r_ret) const {
|
||||
|
||||
String name = p_name.operator String();
|
||||
if (name == "hash_table")
|
||||
if (name == "hash_table") {
|
||||
r_ret = hash_table;
|
||||
else if (name == "bucket_table")
|
||||
} else if (name == "bucket_table") {
|
||||
r_ret = bucket_table;
|
||||
else if (name == "strings")
|
||||
} else if (name == "strings") {
|
||||
r_ret = strings;
|
||||
else
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
StringName PHashTranslation::get_message(const StringName &p_src_text) const {
|
||||
|
||||
int htsize = hash_table.size();
|
||||
|
||||
if (htsize == 0)
|
||||
if (htsize == 0) {
|
||||
return StringName();
|
||||
}
|
||||
|
||||
CharString str = p_src_text.operator String().utf8();
|
||||
uint32_t h = hash(0, str.get_data());
|
||||
@ -248,9 +242,7 @@ StringName PHashTranslation::get_message(const StringName &p_src_text) const {
|
||||
int idx = -1;
|
||||
|
||||
for (int i = 0; i < bucket.size; i++) {
|
||||
|
||||
if (bucket.elem[i].key == h) {
|
||||
|
||||
idx = i;
|
||||
break;
|
||||
}
|
||||
@ -261,13 +253,11 @@ StringName PHashTranslation::get_message(const StringName &p_src_text) const {
|
||||
}
|
||||
|
||||
if (bucket.elem[idx].comp_size == bucket.elem[idx].uncomp_size) {
|
||||
|
||||
String rstr;
|
||||
rstr.parse_utf8(&sptr[bucket.elem[idx].str_offset], bucket.elem[idx].uncomp_size);
|
||||
|
||||
return rstr;
|
||||
} else {
|
||||
|
||||
CharString uncomp;
|
||||
uncomp.resize(bucket.elem[idx].uncomp_size + 1);
|
||||
smaz_decompress(&sptr[bucket.elem[idx].str_offset], bucket.elem[idx].comp_size, uncomp.ptrw(), bucket.elem[idx].uncomp_size);
|
||||
@ -278,13 +268,12 @@ StringName PHashTranslation::get_message(const StringName &p_src_text) const {
|
||||
}
|
||||
|
||||
void PHashTranslation::_get_property_list(List<PropertyInfo> *p_list) const {
|
||||
|
||||
p_list->push_back(PropertyInfo(Variant::PACKED_INT32_ARRAY, "hash_table"));
|
||||
p_list->push_back(PropertyInfo(Variant::PACKED_INT32_ARRAY, "bucket_table"));
|
||||
p_list->push_back(PropertyInfo(Variant::PACKED_BYTE_ARRAY, "strings"));
|
||||
p_list->push_back(PropertyInfo(Variant::OBJECT, "load_from", PROPERTY_HINT_RESOURCE_TYPE, "Translation", PROPERTY_USAGE_EDITOR));
|
||||
}
|
||||
void PHashTranslation::_bind_methods() {
|
||||
|
||||
void PHashTranslation::_bind_methods() {
|
||||
ClassDB::bind_method(D_METHOD("generate", "from"), &PHashTranslation::generate);
|
||||
}
|
||||
|
@ -34,7 +34,6 @@
|
||||
#include "core/translation.h"
|
||||
|
||||
class PHashTranslation : public Translation {
|
||||
|
||||
GDCLASS(PHashTranslation, Translation);
|
||||
|
||||
//this translation uses a sort of modified perfect hash algorithm
|
||||
@ -48,12 +47,10 @@ class PHashTranslation : public Translation {
|
||||
Vector<uint8_t> strings;
|
||||
|
||||
struct Bucket {
|
||||
|
||||
int size;
|
||||
uint32_t func;
|
||||
|
||||
struct Elem {
|
||||
|
||||
uint32_t key;
|
||||
uint32_t str_offset;
|
||||
uint32_t comp_size;
|
||||
@ -64,11 +61,10 @@ class PHashTranslation : public Translation {
|
||||
};
|
||||
|
||||
_FORCE_INLINE_ uint32_t hash(uint32_t d, const char *p_str) const {
|
||||
|
||||
if (d == 0)
|
||||
if (d == 0) {
|
||||
d = 0x1000193;
|
||||
}
|
||||
while (*p_str) {
|
||||
|
||||
d = (d * 0x1000193) ^ uint32_t(*p_str);
|
||||
p_str++;
|
||||
}
|
||||
|
@ -35,7 +35,6 @@
|
||||
#include "core/variant.h"
|
||||
|
||||
struct ContainerTypeValidate {
|
||||
|
||||
Variant::Type type = Variant::NIL;
|
||||
StringName class_name;
|
||||
Ref<Script> script;
|
||||
@ -76,7 +75,6 @@ struct ContainerTypeValidate {
|
||||
}
|
||||
|
||||
_FORCE_INLINE_ bool validate(const Variant &p_variant, const char *p_operation = "use") {
|
||||
|
||||
if (type == Variant::NIL) {
|
||||
return true;
|
||||
}
|
||||
|
@ -34,7 +34,6 @@
|
||||
#include "core/string_name.h"
|
||||
|
||||
class CoreStringNames {
|
||||
|
||||
friend void register_core_types();
|
||||
friend void unregister_core_types();
|
||||
|
||||
|
@ -59,25 +59,25 @@ private:
|
||||
// internal helpers
|
||||
|
||||
_FORCE_INLINE_ uint32_t *_get_refcount() const {
|
||||
|
||||
if (!_ptr)
|
||||
if (!_ptr) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
return reinterpret_cast<uint32_t *>(_ptr) - 2;
|
||||
}
|
||||
|
||||
_FORCE_INLINE_ uint32_t *_get_size() const {
|
||||
|
||||
if (!_ptr)
|
||||
if (!_ptr) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
return reinterpret_cast<uint32_t *>(_ptr) - 1;
|
||||
}
|
||||
|
||||
_FORCE_INLINE_ T *_get_data() const {
|
||||
|
||||
if (!_ptr)
|
||||
if (!_ptr) {
|
||||
return nullptr;
|
||||
}
|
||||
return reinterpret_cast<T *>(_ptr);
|
||||
}
|
||||
|
||||
@ -125,31 +125,29 @@ public:
|
||||
|
||||
_FORCE_INLINE_ int size() const {
|
||||
uint32_t *size = (uint32_t *)_get_size();
|
||||
if (size)
|
||||
if (size) {
|
||||
return *size;
|
||||
else
|
||||
} else {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
_FORCE_INLINE_ void clear() { resize(0); }
|
||||
_FORCE_INLINE_ bool empty() const { return _ptr == nullptr; }
|
||||
|
||||
_FORCE_INLINE_ void set(int p_index, const T &p_elem) {
|
||||
|
||||
CRASH_BAD_INDEX(p_index, size());
|
||||
_copy_on_write();
|
||||
_get_data()[p_index] = p_elem;
|
||||
}
|
||||
|
||||
_FORCE_INLINE_ T &get_m(int p_index) {
|
||||
|
||||
CRASH_BAD_INDEX(p_index, size());
|
||||
_copy_on_write();
|
||||
return _get_data()[p_index];
|
||||
}
|
||||
|
||||
_FORCE_INLINE_ const T &get(int p_index) const {
|
||||
|
||||
CRASH_BAD_INDEX(p_index, size());
|
||||
|
||||
return _get_data()[p_index];
|
||||
@ -158,12 +156,10 @@ public:
|
||||
Error resize(int p_size);
|
||||
|
||||
_FORCE_INLINE_ void remove(int p_index) {
|
||||
|
||||
ERR_FAIL_INDEX(p_index, size());
|
||||
T *p = ptrw();
|
||||
int len = size();
|
||||
for (int i = p_index; i < len - 1; i++) {
|
||||
|
||||
p[i] = p[i + 1];
|
||||
};
|
||||
|
||||
@ -171,11 +167,11 @@ public:
|
||||
};
|
||||
|
||||
Error insert(int p_pos, const T &p_val) {
|
||||
|
||||
ERR_FAIL_INDEX_V(p_pos, size() + 1, ERR_INVALID_PARAMETER);
|
||||
resize(size() + 1);
|
||||
for (int i = (size() - 1); i > p_pos; i--)
|
||||
for (int i = (size() - 1); i > p_pos; i--) {
|
||||
set(i, get(i - 1));
|
||||
}
|
||||
set(p_pos, p_val);
|
||||
|
||||
return OK;
|
||||
@ -190,14 +186,15 @@ public:
|
||||
|
||||
template <class T>
|
||||
void CowData<T>::_unref(void *p_data) {
|
||||
|
||||
if (!p_data)
|
||||
if (!p_data) {
|
||||
return;
|
||||
}
|
||||
|
||||
uint32_t *refc = _get_refcount();
|
||||
|
||||
if (atomic_decrement(refc) > 0)
|
||||
if (atomic_decrement(refc) > 0) {
|
||||
return; // still in use
|
||||
}
|
||||
// clean up
|
||||
|
||||
if (!__has_trivial_destructor(T)) {
|
||||
@ -216,9 +213,9 @@ void CowData<T>::_unref(void *p_data) {
|
||||
|
||||
template <class T>
|
||||
void CowData<T>::_copy_on_write() {
|
||||
|
||||
if (!_ptr)
|
||||
if (!_ptr) {
|
||||
return;
|
||||
}
|
||||
|
||||
uint32_t *refc = _get_refcount();
|
||||
|
||||
@ -250,13 +247,13 @@ void CowData<T>::_copy_on_write() {
|
||||
|
||||
template <class T>
|
||||
Error CowData<T>::resize(int p_size) {
|
||||
|
||||
ERR_FAIL_COND_V(p_size < 0, ERR_INVALID_PARAMETER);
|
||||
|
||||
int current_size = size();
|
||||
|
||||
if (p_size == current_size)
|
||||
if (p_size == current_size) {
|
||||
return OK;
|
||||
}
|
||||
|
||||
if (p_size == 0) {
|
||||
// wants to clean up
|
||||
@ -273,7 +270,6 @@ Error CowData<T>::resize(int p_size) {
|
||||
ERR_FAIL_COND_V(!_get_alloc_size_checked(p_size, &alloc_size), ERR_OUT_OF_MEMORY);
|
||||
|
||||
if (p_size > current_size) {
|
||||
|
||||
if (alloc_size != current_alloc_size) {
|
||||
if (current_size == 0) {
|
||||
// alloc from scratch
|
||||
@ -304,7 +300,6 @@ Error CowData<T>::resize(int p_size) {
|
||||
*_get_size() = p_size;
|
||||
|
||||
} else if (p_size < current_size) {
|
||||
|
||||
if (!__has_trivial_destructor(T)) {
|
||||
// deinitialize no longer needed elements
|
||||
for (uint32_t i = p_size; i < *_get_size(); i++) {
|
||||
@ -351,15 +346,16 @@ void CowData<T>::_ref(const CowData *p_from) {
|
||||
|
||||
template <class T>
|
||||
void CowData<T>::_ref(const CowData &p_from) {
|
||||
|
||||
if (_ptr == p_from._ptr)
|
||||
if (_ptr == p_from._ptr) {
|
||||
return; // self assign, do nothing.
|
||||
}
|
||||
|
||||
_unref(_ptr);
|
||||
_ptr = nullptr;
|
||||
|
||||
if (!p_from._ptr)
|
||||
if (!p_from._ptr) {
|
||||
return; //nothing to do
|
||||
}
|
||||
|
||||
if (atomic_conditional_increment(p_from._get_refcount()) > 0) { // could reference
|
||||
_ptr = p_from._ptr;
|
||||
@ -368,7 +364,6 @@ void CowData<T>::_ref(const CowData &p_from) {
|
||||
|
||||
template <class T>
|
||||
CowData<T>::~CowData() {
|
||||
|
||||
_unref(_ptr);
|
||||
}
|
||||
|
||||
|
@ -38,8 +38,9 @@
|
||||
|
||||
CryptoKey *(*CryptoKey::_create)() = nullptr;
|
||||
CryptoKey *CryptoKey::create() {
|
||||
if (_create)
|
||||
if (_create) {
|
||||
return _create();
|
||||
}
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
@ -50,8 +51,9 @@ void CryptoKey::_bind_methods() {
|
||||
|
||||
X509Certificate *(*X509Certificate::_create)() = nullptr;
|
||||
X509Certificate *X509Certificate::create() {
|
||||
if (_create)
|
||||
if (_create) {
|
||||
return _create();
|
||||
}
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
@ -65,16 +67,17 @@ void X509Certificate::_bind_methods() {
|
||||
void (*Crypto::_load_default_certificates)(String p_path) = nullptr;
|
||||
Crypto *(*Crypto::_create)() = nullptr;
|
||||
Crypto *Crypto::create() {
|
||||
if (_create)
|
||||
if (_create) {
|
||||
return _create();
|
||||
}
|
||||
return memnew(Crypto);
|
||||
}
|
||||
|
||||
void Crypto::load_default_certificates(String p_path) {
|
||||
|
||||
if (_load_default_certificates)
|
||||
if (_load_default_certificates) {
|
||||
_load_default_certificates(p_path);
|
||||
}
|
||||
}
|
||||
|
||||
void Crypto::_bind_methods() {
|
||||
ClassDB::bind_method(D_METHOD("generate_random_bytes", "size"), &Crypto::generate_random_bytes);
|
||||
@ -97,45 +100,43 @@ Ref<X509Certificate> Crypto::generate_self_signed_certificate(Ref<CryptoKey> p_k
|
||||
/// Resource loader/saver
|
||||
|
||||
RES ResourceFormatLoaderCrypto::load(const String &p_path, const String &p_original_path, Error *r_error, bool p_use_sub_threads, float *r_progress, bool p_no_cache) {
|
||||
|
||||
String el = p_path.get_extension().to_lower();
|
||||
if (el == "crt") {
|
||||
X509Certificate *cert = X509Certificate::create();
|
||||
if (cert)
|
||||
if (cert) {
|
||||
cert->load(p_path);
|
||||
}
|
||||
return cert;
|
||||
} else if (el == "key") {
|
||||
CryptoKey *key = CryptoKey::create();
|
||||
if (key)
|
||||
if (key) {
|
||||
key->load(p_path);
|
||||
}
|
||||
return key;
|
||||
}
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
void ResourceFormatLoaderCrypto::get_recognized_extensions(List<String> *p_extensions) const {
|
||||
|
||||
p_extensions->push_back("crt");
|
||||
p_extensions->push_back("key");
|
||||
}
|
||||
|
||||
bool ResourceFormatLoaderCrypto::handles_type(const String &p_type) const {
|
||||
|
||||
return p_type == "X509Certificate" || p_type == "CryptoKey";
|
||||
}
|
||||
|
||||
String ResourceFormatLoaderCrypto::get_resource_type(const String &p_path) const {
|
||||
|
||||
String el = p_path.get_extension().to_lower();
|
||||
if (el == "crt")
|
||||
if (el == "crt") {
|
||||
return "X509Certificate";
|
||||
else if (el == "key")
|
||||
} else if (el == "key") {
|
||||
return "CryptoKey";
|
||||
}
|
||||
return "";
|
||||
}
|
||||
|
||||
Error ResourceFormatSaverCrypto::save(const String &p_path, const RES &p_resource, uint32_t p_flags) {
|
||||
|
||||
Error err;
|
||||
Ref<X509Certificate> cert = p_resource;
|
||||
Ref<CryptoKey> key = p_resource;
|
||||
@ -151,7 +152,6 @@ Error ResourceFormatSaverCrypto::save(const String &p_path, const RES &p_resourc
|
||||
}
|
||||
|
||||
void ResourceFormatSaverCrypto::get_recognized_extensions(const RES &p_resource, List<String> *p_extensions) const {
|
||||
|
||||
const X509Certificate *cert = Object::cast_to<X509Certificate>(*p_resource);
|
||||
const CryptoKey *key = Object::cast_to<CryptoKey>(*p_resource);
|
||||
if (cert) {
|
||||
@ -161,7 +161,7 @@ void ResourceFormatSaverCrypto::get_recognized_extensions(const RES &p_resource,
|
||||
p_extensions->push_back("key");
|
||||
}
|
||||
}
|
||||
bool ResourceFormatSaverCrypto::recognize(const RES &p_resource) const {
|
||||
|
||||
bool ResourceFormatSaverCrypto::recognize(const RES &p_resource) const {
|
||||
return Object::cast_to<X509Certificate>(*p_resource) || Object::cast_to<CryptoKey>(*p_resource);
|
||||
}
|
||||
|
@ -34,10 +34,8 @@
|
||||
#include "core/reference.h"
|
||||
|
||||
class CryptoCore {
|
||||
|
||||
public:
|
||||
class MD5Context {
|
||||
|
||||
private:
|
||||
void *ctx; // To include, or not to include...
|
||||
|
||||
@ -51,7 +49,6 @@ public:
|
||||
};
|
||||
|
||||
class SHA1Context {
|
||||
|
||||
private:
|
||||
void *ctx; // To include, or not to include...
|
||||
|
||||
@ -65,7 +62,6 @@ public:
|
||||
};
|
||||
|
||||
class SHA256Context {
|
||||
|
||||
private:
|
||||
void *ctx; // To include, or not to include...
|
||||
|
||||
@ -79,7 +75,6 @@ public:
|
||||
};
|
||||
|
||||
class AESContext {
|
||||
|
||||
private:
|
||||
void *ctx; // To include, or not to include...
|
||||
|
||||
|
@ -104,7 +104,6 @@ void HashingContext::_create_ctx(HashType p_type) {
|
||||
}
|
||||
|
||||
void HashingContext::_delete_ctx() {
|
||||
|
||||
switch (type) {
|
||||
case HASH_MD5:
|
||||
memdelete((CryptoCore::MD5Context *)ctx);
|
||||
@ -129,6 +128,7 @@ void HashingContext::_bind_methods() {
|
||||
}
|
||||
|
||||
HashingContext::~HashingContext() {
|
||||
if (ctx != nullptr)
|
||||
if (ctx != nullptr) {
|
||||
_delete_ctx();
|
||||
}
|
||||
}
|
||||
|
@ -228,8 +228,9 @@ Array DebuggerMarshalls::ScriptStackVariable::serialize(int max_size) {
|
||||
|
||||
int len = 0;
|
||||
Error err = encode_variant(var, nullptr, len, true);
|
||||
if (err != OK)
|
||||
if (err != OK) {
|
||||
ERR_PRINT("Failed to encode variant.");
|
||||
}
|
||||
|
||||
if (len > max_size) {
|
||||
arr.push_back(Variant());
|
||||
|
@ -35,7 +35,6 @@
|
||||
#include "servers/rendering_server.h"
|
||||
|
||||
struct DebuggerMarshalls {
|
||||
|
||||
// Memory usage
|
||||
struct ResourceInfo {
|
||||
String path;
|
||||
|
@ -111,8 +111,9 @@ Error EngineDebugger::capture_parse(const StringName &p_name, const String &p_ms
|
||||
|
||||
void EngineDebugger::line_poll() {
|
||||
// The purpose of this is just processing events every now and then when the script might get too busy otherwise bugs like infinite loops can't be caught
|
||||
if (poll_every % 2048 == 0)
|
||||
if (poll_every % 2048 == 0) {
|
||||
poll_events(false);
|
||||
}
|
||||
poll_every++;
|
||||
}
|
||||
|
||||
@ -124,8 +125,9 @@ void EngineDebugger::iteration(uint64_t p_frame_ticks, uint64_t p_idle_ticks, ui
|
||||
// Notify tick to running profilers
|
||||
for (Map<StringName, Profiler>::Element *E = profilers.front(); E; E = E->next()) {
|
||||
Profiler &p = E->get();
|
||||
if (!p.active || !p.tick)
|
||||
if (!p.active || !p.tick) {
|
||||
continue;
|
||||
}
|
||||
p.tick(p.data, frame_time, idle_time, physics_time, physics_frame_time);
|
||||
}
|
||||
singleton->poll_events(true);
|
||||
@ -133,8 +135,9 @@ void EngineDebugger::iteration(uint64_t p_frame_ticks, uint64_t p_idle_ticks, ui
|
||||
|
||||
void EngineDebugger::initialize(const String &p_uri, bool p_skip_breakpoints, Vector<String> p_breakpoints) {
|
||||
register_uri_handler("tcp://", RemoteDebuggerPeerTCP::create); // TCP is the default protocol. Platforms/modules can add more.
|
||||
if (p_uri.empty())
|
||||
if (p_uri.empty()) {
|
||||
return;
|
||||
}
|
||||
if (p_uri == "local://") {
|
||||
singleton = memnew(LocalDebugger);
|
||||
script_debugger = memnew(ScriptDebugger);
|
||||
@ -142,11 +145,13 @@ void EngineDebugger::initialize(const String &p_uri, bool p_skip_breakpoints, Ve
|
||||
OS::get_singleton()->initialize_debugging();
|
||||
} else if (p_uri.find("://") >= 0) {
|
||||
const String proto = p_uri.substr(0, p_uri.find("://") + 3);
|
||||
if (!protocols.has(proto))
|
||||
if (!protocols.has(proto)) {
|
||||
return;
|
||||
}
|
||||
RemoteDebuggerPeer *peer = protocols[proto](p_uri);
|
||||
if (!peer)
|
||||
if (!peer) {
|
||||
return;
|
||||
}
|
||||
singleton = memnew(RemoteDebugger(Ref<RemoteDebuggerPeer>(peer)));
|
||||
script_debugger = memnew(ScriptDebugger);
|
||||
// Notify editor of our pid (to allow focus stealing).
|
||||
@ -154,15 +159,15 @@ void EngineDebugger::initialize(const String &p_uri, bool p_skip_breakpoints, Ve
|
||||
msg.push_back(OS::get_singleton()->get_process_id());
|
||||
singleton->send_message("set_pid", msg);
|
||||
}
|
||||
if (!singleton)
|
||||
if (!singleton) {
|
||||
return;
|
||||
}
|
||||
|
||||
// There is a debugger, parse breakpoints.
|
||||
ScriptDebugger *singleton_script_debugger = singleton->get_script_debugger();
|
||||
singleton_script_debugger->set_skip_breakpoints(p_skip_breakpoints);
|
||||
|
||||
for (int i = 0; i < p_breakpoints.size(); i++) {
|
||||
|
||||
String bp = p_breakpoints[i];
|
||||
int sp = bp.find_last(":");
|
||||
ERR_CONTINUE_MSG(sp == -1, "Invalid breakpoint: '" + bp + "', expected file:line format.");
|
||||
@ -175,9 +180,10 @@ void EngineDebugger::deinitialize() {
|
||||
if (singleton) {
|
||||
// Stop all profilers
|
||||
for (Map<StringName, Profiler>::Element *E = profilers.front(); E; E = E->next()) {
|
||||
if (E->get().active)
|
||||
if (E->get().active) {
|
||||
singleton->profiler_enable(E->key(), false);
|
||||
}
|
||||
}
|
||||
|
||||
// Flush any remaining message
|
||||
singleton->poll_events(false);
|
||||
@ -193,8 +199,9 @@ void EngineDebugger::deinitialize() {
|
||||
}
|
||||
|
||||
EngineDebugger::~EngineDebugger() {
|
||||
if (script_debugger)
|
||||
if (script_debugger) {
|
||||
memdelete(script_debugger);
|
||||
}
|
||||
script_debugger = nullptr;
|
||||
singleton = nullptr;
|
||||
}
|
||||
|
@ -36,7 +36,6 @@
|
||||
|
||||
struct LocalDebugger::ScriptsProfiler {
|
||||
struct ProfileInfoSort {
|
||||
|
||||
bool operator()(const ScriptLanguage::ProfilingInfo &A, const ScriptLanguage::ProfilingInfo &B) const {
|
||||
return A.total_time > B.total_time;
|
||||
}
|
||||
@ -70,18 +69,20 @@ struct LocalDebugger::ScriptsProfiler {
|
||||
void _print_frame_data(bool p_accumulated) {
|
||||
uint64_t diff = OS::get_singleton()->get_ticks_usec() - idle_accum;
|
||||
|
||||
if (!p_accumulated && diff < 1000000) //show every one second
|
||||
if (!p_accumulated && diff < 1000000) { //show every one second
|
||||
return;
|
||||
}
|
||||
|
||||
idle_accum = OS::get_singleton()->get_ticks_usec();
|
||||
|
||||
int ofs = 0;
|
||||
for (int i = 0; i < ScriptServer::get_language_count(); i++) {
|
||||
if (p_accumulated)
|
||||
if (p_accumulated) {
|
||||
ofs += ScriptServer::get_language(i)->profiling_get_accumulated_data(&pinfo.write[ofs], pinfo.size() - ofs);
|
||||
else
|
||||
} else {
|
||||
ofs += ScriptServer::get_language(i)->profiling_get_frame_data(&pinfo.write[ofs], pinfo.size() - ofs);
|
||||
}
|
||||
}
|
||||
|
||||
SortArray<ScriptLanguage::ProfilingInfo, ProfileInfoSort> sort;
|
||||
sort.sort(pinfo.ptrw(), ofs);
|
||||
@ -89,7 +90,6 @@ struct LocalDebugger::ScriptsProfiler {
|
||||
// compute total script frame time
|
||||
uint64_t script_time_us = 0;
|
||||
for (int i = 0; i < ofs; i++) {
|
||||
|
||||
script_time_us += pinfo[i].self_time;
|
||||
}
|
||||
float script_time = USEC_TO_SEC(script_time_us);
|
||||
@ -102,7 +102,6 @@ struct LocalDebugger::ScriptsProfiler {
|
||||
}
|
||||
|
||||
for (int i = 0; i < ofs; i++) {
|
||||
|
||||
print_line(itos(i) + ":" + pinfo[i].signature);
|
||||
float tt = USEC_TO_SEC(pinfo[i].total_time);
|
||||
float st = USEC_TO_SEC(pinfo[i].self_time);
|
||||
@ -116,7 +115,6 @@ struct LocalDebugger::ScriptsProfiler {
|
||||
};
|
||||
|
||||
void LocalDebugger::debug(bool p_can_continue, bool p_is_error_breakpoint) {
|
||||
|
||||
ScriptLanguage *script_lang = script_debugger->get_break_language();
|
||||
|
||||
if (!target_function.empty()) {
|
||||
@ -135,7 +133,6 @@ void LocalDebugger::debug(bool p_can_continue, bool p_is_error_breakpoint) {
|
||||
int current_frame = 0;
|
||||
int total_frames = script_lang->debug_get_stack_level_count();
|
||||
while (true) {
|
||||
|
||||
OS::get_singleton()->print("debug> ");
|
||||
String line = OS::get_singleton()->get_stdin_string().strip_edges();
|
||||
|
||||
@ -146,18 +143,15 @@ void LocalDebugger::debug(bool p_can_continue, bool p_is_error_breakpoint) {
|
||||
print_line("\nDebugger Break, Reason: '" + script_lang->debug_get_error() + "'");
|
||||
print_line("*Frame " + itos(current_frame) + " - " + script_lang->debug_get_stack_level_source(current_frame) + ":" + itos(script_lang->debug_get_stack_level_line(current_frame)) + " in function '" + script_lang->debug_get_stack_level_function(current_frame) + "'");
|
||||
print_line("Enter \"help\" for assistance.");
|
||||
} else if (line == "c" || line == "continue")
|
||||
} else if (line == "c" || line == "continue") {
|
||||
break;
|
||||
else if (line == "bt" || line == "breakpoint") {
|
||||
|
||||
} else if (line == "bt" || line == "breakpoint") {
|
||||
for (int i = 0; i < total_frames; i++) {
|
||||
|
||||
String cfi = (current_frame == i) ? "*" : " "; //current frame indicator
|
||||
print_line(cfi + "Frame " + itos(i) + " - " + script_lang->debug_get_stack_level_source(i) + ":" + itos(script_lang->debug_get_stack_level_line(i)) + " in function '" + script_lang->debug_get_stack_level_function(i) + "'");
|
||||
}
|
||||
|
||||
} else if (line.begins_with("fr") || line.begins_with("frame")) {
|
||||
|
||||
if (line.get_slice_count(" ") == 1) {
|
||||
print_line("*Frame " + itos(current_frame) + " - " + script_lang->debug_get_stack_level_source(current_frame) + ":" + itos(script_lang->debug_get_stack_level_line(current_frame)) + " in function '" + script_lang->debug_get_stack_level_function(current_frame) + "'");
|
||||
} else {
|
||||
@ -171,9 +165,7 @@ void LocalDebugger::debug(bool p_can_continue, bool p_is_error_breakpoint) {
|
||||
}
|
||||
|
||||
} else if (line.begins_with("set")) {
|
||||
|
||||
if (line.get_slice_count(" ") == 1) {
|
||||
|
||||
for (Map<String, String>::Element *E = options.front(); E; E = E->next()) {
|
||||
print_line("\t" + E->key() + "=" + E->value());
|
||||
}
|
||||
@ -185,13 +177,11 @@ void LocalDebugger::debug(bool p_can_continue, bool p_is_error_breakpoint) {
|
||||
if (value_pos < 0) {
|
||||
print_line("Error: Invalid set format. Use: set key=value");
|
||||
} else {
|
||||
|
||||
String key = key_value.left(value_pos);
|
||||
|
||||
if (!options.has(key)) {
|
||||
print_line("Error: Unknown option " + key);
|
||||
} else {
|
||||
|
||||
// Allow explicit tab character
|
||||
String value = key_value.right(value_pos + 1).replace("\\t", "\t");
|
||||
|
||||
@ -201,49 +191,41 @@ void LocalDebugger::debug(bool p_can_continue, bool p_is_error_breakpoint) {
|
||||
}
|
||||
|
||||
} else if (line == "lv" || line == "locals") {
|
||||
|
||||
List<String> locals;
|
||||
List<Variant> values;
|
||||
script_lang->debug_get_stack_level_locals(current_frame, &locals, &values);
|
||||
print_variables(locals, values, variable_prefix);
|
||||
|
||||
} else if (line == "gv" || line == "globals") {
|
||||
|
||||
List<String> globals;
|
||||
List<Variant> values;
|
||||
script_lang->debug_get_globals(&globals, &values);
|
||||
print_variables(globals, values, variable_prefix);
|
||||
|
||||
} else if (line == "mv" || line == "members") {
|
||||
|
||||
List<String> members;
|
||||
List<Variant> values;
|
||||
script_lang->debug_get_stack_level_members(current_frame, &members, &values);
|
||||
print_variables(members, values, variable_prefix);
|
||||
|
||||
} else if (line.begins_with("p") || line.begins_with("print")) {
|
||||
|
||||
if (line.get_slice_count(" ") <= 1) {
|
||||
print_line("Usage: print <expre>");
|
||||
} else {
|
||||
|
||||
String expr = line.get_slicec(' ', 2);
|
||||
String res = script_lang->debug_parse_stack_level_expression(current_frame, expr);
|
||||
print_line(res);
|
||||
}
|
||||
|
||||
} else if (line == "s" || line == "step") {
|
||||
|
||||
script_debugger->set_depth(-1);
|
||||
script_debugger->set_lines_left(1);
|
||||
break;
|
||||
} else if (line == "n" || line == "next") {
|
||||
|
||||
script_debugger->set_depth(0);
|
||||
script_debugger->set_lines_left(1);
|
||||
break;
|
||||
} else if (line == "fin" || line == "finish") {
|
||||
|
||||
String current_function = script_lang->debug_get_stack_level_function(0);
|
||||
|
||||
for (int i = 0; i < total_frames; i++) {
|
||||
@ -259,9 +241,7 @@ void LocalDebugger::debug(bool p_can_continue, bool p_is_error_breakpoint) {
|
||||
target_function = "";
|
||||
|
||||
} else if (line.begins_with("br") || line.begins_with("break")) {
|
||||
|
||||
if (line.get_slice_count(" ") <= 1) {
|
||||
|
||||
const Map<int, Set<StringName>> &breakpoints = script_debugger->get_breakpoints();
|
||||
if (breakpoints.size() == 0) {
|
||||
print_line("No Breakpoints.");
|
||||
@ -274,14 +254,14 @@ void LocalDebugger::debug(bool p_can_continue, bool p_is_error_breakpoint) {
|
||||
}
|
||||
|
||||
} else {
|
||||
|
||||
Pair<String, int> breakpoint = to_breakpoint(line);
|
||||
|
||||
String source = breakpoint.first;
|
||||
int linenr = breakpoint.second;
|
||||
|
||||
if (source.empty())
|
||||
if (source.empty()) {
|
||||
continue;
|
||||
}
|
||||
|
||||
script_debugger->insert_breakpoint(linenr, source);
|
||||
|
||||
@ -289,7 +269,6 @@ void LocalDebugger::debug(bool p_can_continue, bool p_is_error_breakpoint) {
|
||||
}
|
||||
|
||||
} else if (line == "q" || line == "quit") {
|
||||
|
||||
// Do not stop again on quit
|
||||
script_debugger->clear_breakpoints();
|
||||
script_debugger->set_depth(-1);
|
||||
@ -298,18 +277,17 @@ void LocalDebugger::debug(bool p_can_continue, bool p_is_error_breakpoint) {
|
||||
SceneTree::get_singleton()->quit();
|
||||
break;
|
||||
} else if (line.begins_with("delete")) {
|
||||
|
||||
if (line.get_slice_count(" ") <= 1) {
|
||||
script_debugger->clear_breakpoints();
|
||||
} else {
|
||||
|
||||
Pair<String, int> breakpoint = to_breakpoint(line);
|
||||
|
||||
String source = breakpoint.first;
|
||||
int linenr = breakpoint.second;
|
||||
|
||||
if (source.empty())
|
||||
if (source.empty()) {
|
||||
continue;
|
||||
}
|
||||
|
||||
script_debugger->remove_breakpoint(linenr, source);
|
||||
|
||||
@ -317,7 +295,6 @@ void LocalDebugger::debug(bool p_can_continue, bool p_is_error_breakpoint) {
|
||||
}
|
||||
|
||||
} else if (line == "h" || line == "help") {
|
||||
|
||||
print_line("Built-In Debugger command list:\n");
|
||||
print_line("\tc,continue\t\t Continue execution.");
|
||||
print_line("\tbt,backtrace\t\t Show stack trace (frames).");
|
||||
@ -340,18 +317,15 @@ void LocalDebugger::debug(bool p_can_continue, bool p_is_error_breakpoint) {
|
||||
}
|
||||
|
||||
void LocalDebugger::print_variables(const List<String> &names, const List<Variant> &values, const String &variable_prefix) {
|
||||
|
||||
String value;
|
||||
Vector<String> value_lines;
|
||||
const List<Variant>::Element *V = values.front();
|
||||
for (const List<String>::Element *E = names.front(); E; E = E->next()) {
|
||||
|
||||
value = String(V->get());
|
||||
|
||||
if (variable_prefix.empty()) {
|
||||
print_line(E->get() + ": " + String(V->get()));
|
||||
} else {
|
||||
|
||||
print_line(E->get() + ":");
|
||||
value_lines = value.split("\n");
|
||||
for (int i = 0; i < value_lines.size(); ++i) {
|
||||
@ -364,7 +338,6 @@ void LocalDebugger::print_variables(const List<String> &names, const List<Varian
|
||||
}
|
||||
|
||||
Pair<String, int> LocalDebugger::to_breakpoint(const String &p_line) {
|
||||
|
||||
String breakpoint_part = p_line.get_slicec(' ', 1);
|
||||
Pair<String, int> breakpoint;
|
||||
|
||||
@ -381,18 +354,15 @@ Pair<String, int> LocalDebugger::to_breakpoint(const String &p_line) {
|
||||
}
|
||||
|
||||
void LocalDebugger::send_message(const String &p_message, const Array &p_args) {
|
||||
|
||||
// This needs to be cleaned up entirely.
|
||||
// print_line("MESSAGE: '" + p_message + "' - " + String(Variant(p_args)));
|
||||
}
|
||||
|
||||
void LocalDebugger::send_error(const String &p_func, const String &p_file, int p_line, const String &p_err, const String &p_descr, ErrorHandlerType p_type) {
|
||||
|
||||
print_line("ERROR: '" + (p_descr.empty() ? p_err : p_descr) + "'");
|
||||
}
|
||||
|
||||
LocalDebugger::LocalDebugger() {
|
||||
|
||||
options["variable_prefix"] = "";
|
||||
|
||||
// Bind scripts profiler.
|
||||
@ -411,6 +381,7 @@ LocalDebugger::LocalDebugger() {
|
||||
|
||||
LocalDebugger::~LocalDebugger() {
|
||||
unregister_profiler("scripts");
|
||||
if (scripts_profiler)
|
||||
if (scripts_profiler) {
|
||||
memdelete(scripts_profiler);
|
||||
}
|
||||
}
|
||||
|
@ -36,7 +36,6 @@
|
||||
#include "core/script_language.h"
|
||||
|
||||
class LocalDebugger : public EngineDebugger {
|
||||
|
||||
private:
|
||||
struct ScriptsProfiler;
|
||||
|
||||
|
@ -57,7 +57,6 @@ void RemoteDebugger::_bind_profiler(const String &p_name, T *p_prof) {
|
||||
}
|
||||
|
||||
struct RemoteDebugger::NetworkProfiler {
|
||||
|
||||
public:
|
||||
typedef DebuggerMarshalls::MultiplayerNodeInfo NodeInfo;
|
||||
struct BandwidthFrame {
|
||||
@ -97,8 +96,9 @@ public:
|
||||
}
|
||||
|
||||
void init_node(const ObjectID p_node) {
|
||||
if (multiplayer_node_data.has(p_node))
|
||||
if (multiplayer_node_data.has(p_node)) {
|
||||
return;
|
||||
}
|
||||
multiplayer_node_data.insert(p_node, DebuggerMarshalls::MultiplayerNodeInfo());
|
||||
multiplayer_node_data[p_node].node = p_node;
|
||||
multiplayer_node_data[p_node].node_path = Object::cast_to<Node>(ObjectDB::get_instance(p_node))->get_path();
|
||||
@ -191,7 +191,6 @@ struct RemoteDebugger::ScriptsProfiler {
|
||||
typedef DebuggerMarshalls::ScriptFunctionSignature FunctionSignature;
|
||||
typedef DebuggerMarshalls::ScriptFunctionInfo FunctionInfo;
|
||||
struct ProfileInfoSort {
|
||||
|
||||
bool operator()(ScriptLanguage::ProfilingInfo *A, ScriptLanguage::ProfilingInfo *B) const {
|
||||
return A->total_time < B->total_time;
|
||||
}
|
||||
@ -220,11 +219,12 @@ struct RemoteDebugger::ScriptsProfiler {
|
||||
void write_frame_data(Vector<FunctionInfo> &r_funcs, uint64_t &r_total, bool p_accumulated) {
|
||||
int ofs = 0;
|
||||
for (int i = 0; i < ScriptServer::get_language_count(); i++) {
|
||||
if (p_accumulated)
|
||||
if (p_accumulated) {
|
||||
ofs += ScriptServer::get_language(i)->profiling_get_accumulated_data(&info.write[ofs], info.size() - ofs);
|
||||
else
|
||||
} else {
|
||||
ofs += ScriptServer::get_language(i)->profiling_get_frame_data(&info.write[ofs], info.size() - ofs);
|
||||
}
|
||||
}
|
||||
|
||||
for (int i = 0; i < ofs; i++) {
|
||||
ptrs.write[i] = &info.write[i];
|
||||
@ -270,7 +270,6 @@ struct RemoteDebugger::ScriptsProfiler {
|
||||
};
|
||||
|
||||
struct RemoteDebugger::ServersProfiler {
|
||||
|
||||
bool skip_profile_frame = false;
|
||||
typedef DebuggerMarshalls::ServerInfo ServerInfo;
|
||||
typedef DebuggerMarshalls::ServerFunctionInfo ServerFunctionInfo;
|
||||
@ -347,7 +346,6 @@ struct RemoteDebugger::ServersProfiler {
|
||||
};
|
||||
|
||||
struct RemoteDebugger::VisualProfiler {
|
||||
|
||||
typedef DebuggerMarshalls::ServerInfo ServerInfo;
|
||||
typedef DebuggerMarshalls::ServerFunctionInfo ServerFunctionInfo;
|
||||
|
||||
@ -362,8 +360,9 @@ struct RemoteDebugger::VisualProfiler {
|
||||
void tick(float p_frame_time, float p_idle_time, float p_physics_time, float p_physics_frame_time) {
|
||||
Vector<RS::FrameProfileArea> profile_areas = RS::get_singleton()->get_frame_profile();
|
||||
DebuggerMarshalls::VisualProfilerFrame frame;
|
||||
if (!profile_areas.size())
|
||||
if (!profile_areas.size()) {
|
||||
return;
|
||||
}
|
||||
|
||||
frame.frame_number = RS::get_singleton()->get_frame_profile_frame();
|
||||
frame.areas.append_array(profile_areas);
|
||||
@ -372,19 +371,20 @@ struct RemoteDebugger::VisualProfiler {
|
||||
};
|
||||
|
||||
struct RemoteDebugger::PerformanceProfiler {
|
||||
|
||||
Object *performance = nullptr;
|
||||
int last_perf_time = 0;
|
||||
|
||||
void toggle(bool p_enable, const Array &p_opts) {}
|
||||
void add(const Array &p_data) {}
|
||||
void tick(float p_frame_time, float p_idle_time, float p_physics_time, float p_physics_frame_time) {
|
||||
if (!performance)
|
||||
if (!performance) {
|
||||
return;
|
||||
}
|
||||
|
||||
uint64_t pt = OS::get_singleton()->get_ticks_msec();
|
||||
if (pt - last_perf_time < 1000)
|
||||
if (pt - last_perf_time < 1000) {
|
||||
return;
|
||||
}
|
||||
last_perf_time = pt;
|
||||
int max = performance->get("MONITOR_MAX");
|
||||
Array arr;
|
||||
@ -401,14 +401,12 @@ struct RemoteDebugger::PerformanceProfiler {
|
||||
};
|
||||
|
||||
void RemoteDebugger::_send_resource_usage() {
|
||||
|
||||
DebuggerMarshalls::ResourceUsage usage;
|
||||
|
||||
List<RS::TextureInfo> tinfo;
|
||||
RS::get_singleton()->texture_debug_usage(&tinfo);
|
||||
|
||||
for (List<RS::TextureInfo>::Element *E = tinfo.front(); E; E = E->next()) {
|
||||
|
||||
DebuggerMarshalls::ResourceInfo info;
|
||||
info.path = E->get().path;
|
||||
info.vram = E->get().bytes;
|
||||
@ -430,44 +428,48 @@ Error RemoteDebugger::_put_msg(String p_message, Array p_data) {
|
||||
msg.push_back(p_message);
|
||||
msg.push_back(p_data);
|
||||
Error err = peer->put_message(msg);
|
||||
if (err != OK)
|
||||
if (err != OK) {
|
||||
n_messages_dropped++;
|
||||
}
|
||||
return err;
|
||||
}
|
||||
|
||||
void RemoteDebugger::_err_handler(void *p_this, const char *p_func, const char *p_file, int p_line, const char *p_err, const char *p_descr, ErrorHandlerType p_type) {
|
||||
|
||||
if (p_type == ERR_HANDLER_SCRIPT)
|
||||
if (p_type == ERR_HANDLER_SCRIPT) {
|
||||
return; //ignore script errors, those go through debugger
|
||||
}
|
||||
|
||||
RemoteDebugger *rd = (RemoteDebugger *)p_this;
|
||||
if (rd->flushing && Thread::get_caller_id() == rd->flush_thread) // Can't handle recursive errors during flush.
|
||||
if (rd->flushing && Thread::get_caller_id() == rd->flush_thread) { // Can't handle recursive errors during flush.
|
||||
return;
|
||||
}
|
||||
|
||||
Vector<ScriptLanguage::StackInfo> si;
|
||||
|
||||
for (int i = 0; i < ScriptServer::get_language_count(); i++) {
|
||||
si = ScriptServer::get_language(i)->debug_get_current_stack_info();
|
||||
if (si.size())
|
||||
if (si.size()) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// send_error will lock internally.
|
||||
rd->script_debugger->send_error(p_func, p_file, p_line, p_err, p_descr, p_type, si);
|
||||
}
|
||||
|
||||
void RemoteDebugger::_print_handler(void *p_this, const String &p_string, bool p_error) {
|
||||
|
||||
RemoteDebugger *rd = (RemoteDebugger *)p_this;
|
||||
|
||||
if (rd->flushing && Thread::get_caller_id() == rd->flush_thread) // Can't handle recursive prints during flush.
|
||||
if (rd->flushing && Thread::get_caller_id() == rd->flush_thread) { // Can't handle recursive prints during flush.
|
||||
return;
|
||||
}
|
||||
|
||||
String s = p_string;
|
||||
int allowed_chars = MIN(MAX(rd->max_chars_per_second - rd->char_count, 0), s.length());
|
||||
|
||||
if (allowed_chars == 0 && s.length() > 0)
|
||||
if (allowed_chars == 0 && s.length() > 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (allowed_chars < s.length()) {
|
||||
s = s.substr(0, allowed_chars);
|
||||
@ -478,8 +480,9 @@ void RemoteDebugger::_print_handler(void *p_this, const String &p_string, bool p
|
||||
rd->char_count += allowed_chars;
|
||||
bool overflowed = rd->char_count >= rd->max_chars_per_second;
|
||||
if (rd->is_peer_connected()) {
|
||||
if (overflowed)
|
||||
if (overflowed) {
|
||||
s += "[...]";
|
||||
}
|
||||
|
||||
OutputString output_string;
|
||||
output_string.message = s;
|
||||
@ -511,17 +514,18 @@ void RemoteDebugger::flush_output() {
|
||||
flush_thread = Thread::get_caller_id();
|
||||
flushing = true;
|
||||
MutexLock lock(mutex);
|
||||
if (!is_peer_connected())
|
||||
if (!is_peer_connected()) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (n_messages_dropped > 0) {
|
||||
ErrorMessage err_msg = _create_overflow_error("TOO_MANY_MESSAGES", "Too many messages! " + String::num_int64(n_messages_dropped) + " messages were dropped. Profiling might misbheave, try raising 'network/limits/debugger/max_queued_messages' in project setting.");
|
||||
if (_put_msg("error", err_msg.serialize()) == OK)
|
||||
if (_put_msg("error", err_msg.serialize()) == OK) {
|
||||
n_messages_dropped = 0;
|
||||
}
|
||||
}
|
||||
|
||||
if (output_strings.size()) {
|
||||
|
||||
// Join output strings so we generate less messages.
|
||||
Vector<String> joined_log_strings;
|
||||
Vector<String> strings;
|
||||
@ -574,7 +578,6 @@ void RemoteDebugger::flush_output() {
|
||||
}
|
||||
|
||||
void RemoteDebugger::send_message(const String &p_message, const Array &p_args) {
|
||||
|
||||
MutexLock lock(mutex);
|
||||
if (is_peer_connected()) {
|
||||
_put_msg(p_message, p_args);
|
||||
@ -582,7 +585,6 @@ void RemoteDebugger::send_message(const String &p_message, const Array &p_args)
|
||||
}
|
||||
|
||||
void RemoteDebugger::send_error(const String &p_func, const String &p_file, int p_line, const String &p_err, const String &p_descr, ErrorHandlerType p_type) {
|
||||
|
||||
ErrorMessage oe;
|
||||
oe.error = p_err;
|
||||
oe.error_descr = p_descr;
|
||||
@ -597,8 +599,9 @@ void RemoteDebugger::send_error(const String &p_func, const String &p_file, int
|
||||
oe.msec = time % 1000;
|
||||
oe.callstack.append_array(script_debugger->get_error_stack_info());
|
||||
|
||||
if (flushing && Thread::get_caller_id() == flush_thread) // Can't handle recursive errors during flush.
|
||||
if (flushing && Thread::get_caller_id() == flush_thread) { // Can't handle recursive errors during flush.
|
||||
return;
|
||||
}
|
||||
|
||||
MutexLock lock(mutex);
|
||||
|
||||
@ -609,7 +612,6 @@ void RemoteDebugger::send_error(const String &p_func, const String &p_file, int
|
||||
}
|
||||
|
||||
if (is_peer_connected()) {
|
||||
|
||||
if (oe.warning) {
|
||||
if (warn_count > max_warnings_per_second) {
|
||||
n_warnings_dropped++;
|
||||
@ -657,24 +659,26 @@ Error RemoteDebugger::_try_capture(const String &p_msg, const Array &p_data, boo
|
||||
return OK;
|
||||
}
|
||||
const String cap = p_msg.substr(0, idx);
|
||||
if (!has_capture(cap))
|
||||
if (!has_capture(cap)) {
|
||||
return ERR_UNAVAILABLE; // Unknown message...
|
||||
}
|
||||
const String msg = p_msg.substr(idx + 1);
|
||||
return capture_parse(cap, msg, p_data, r_captured);
|
||||
}
|
||||
|
||||
void RemoteDebugger::debug(bool p_can_continue, bool p_is_error_breakpoint) {
|
||||
|
||||
//this function is called when there is a debugger break (bug on script)
|
||||
//or when execution is paused from editor
|
||||
|
||||
if (script_debugger->is_skipping_breakpoints() && !p_is_error_breakpoint)
|
||||
if (script_debugger->is_skipping_breakpoints() && !p_is_error_breakpoint) {
|
||||
return;
|
||||
}
|
||||
|
||||
ERR_FAIL_COND_MSG(!is_peer_connected(), "Script Debugger failed to connect, but being used anyway.");
|
||||
|
||||
if (!peer->can_block())
|
||||
if (!peer->can_block()) {
|
||||
return; // Peer does not support blocking IO. We could at least send the error though.
|
||||
}
|
||||
|
||||
ScriptLanguage *script_lang = script_debugger->get_break_language();
|
||||
const String error_str = script_lang ? script_lang->debug_get_error() : "";
|
||||
@ -686,8 +690,9 @@ void RemoteDebugger::debug(bool p_can_continue, bool p_is_error_breakpoint) {
|
||||
servers_profiler->skip_profile_frame = true; // Avoid frame time spike in debug.
|
||||
|
||||
Input::MouseMode mouse_mode = Input::get_singleton()->get_mouse_mode();
|
||||
if (mouse_mode != Input::MOUSE_MODE_VISIBLE)
|
||||
if (mouse_mode != Input::MOUSE_MODE_VISIBLE) {
|
||||
Input::get_singleton()->set_mouse_mode(Input::MOUSE_MODE_VISIBLE);
|
||||
}
|
||||
|
||||
uint64_t loop_begin_usec = 0;
|
||||
uint64_t loop_time_sec = 0;
|
||||
@ -698,7 +703,6 @@ void RemoteDebugger::debug(bool p_can_continue, bool p_is_error_breakpoint) {
|
||||
peer->poll();
|
||||
|
||||
if (peer->has_message()) {
|
||||
|
||||
Array cmd = peer->get_message();
|
||||
|
||||
ERR_CONTINUE(cmd.size() != 2);
|
||||
@ -776,10 +780,11 @@ void RemoteDebugger::debug(bool p_can_continue, bool p_is_error_breakpoint) {
|
||||
} else if (command == "breakpoint") {
|
||||
ERR_FAIL_COND(data.size() < 3);
|
||||
bool set = data[2];
|
||||
if (set)
|
||||
if (set) {
|
||||
script_debugger->insert_breakpoint(data[1], data[0]);
|
||||
else
|
||||
} else {
|
||||
script_debugger->remove_breakpoint(data[1], data[0]);
|
||||
}
|
||||
|
||||
} else if (command == "set_skip_breakpoints") {
|
||||
ERR_FAIL_COND(data.size() < 1);
|
||||
@ -787,9 +792,10 @@ void RemoteDebugger::debug(bool p_can_continue, bool p_is_error_breakpoint) {
|
||||
} else {
|
||||
bool captured = false;
|
||||
ERR_CONTINUE(_try_capture(command, data, captured) != OK);
|
||||
if (!captured)
|
||||
if (!captured) {
|
||||
WARN_PRINT("Unknown message received from debugger: " + command);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
OS::get_singleton()->delay_usec(10000);
|
||||
OS::get_singleton()->process_and_drop_events();
|
||||
@ -805,18 +811,19 @@ void RemoteDebugger::debug(bool p_can_continue, bool p_is_error_breakpoint) {
|
||||
|
||||
send_message("debug_exit", Array());
|
||||
|
||||
if (mouse_mode != Input::MOUSE_MODE_VISIBLE)
|
||||
if (mouse_mode != Input::MOUSE_MODE_VISIBLE) {
|
||||
Input::get_singleton()->set_mouse_mode(mouse_mode);
|
||||
}
|
||||
}
|
||||
|
||||
void RemoteDebugger::poll_events(bool p_is_idle) {
|
||||
if (peer.is_null())
|
||||
if (peer.is_null()) {
|
||||
return;
|
||||
}
|
||||
|
||||
flush_output();
|
||||
peer->poll();
|
||||
while (peer->has_message()) {
|
||||
|
||||
Array arr = peer->get_message();
|
||||
|
||||
ERR_CONTINUE(arr.size() != 2);
|
||||
@ -832,8 +839,9 @@ void RemoteDebugger::poll_events(bool p_is_idle) {
|
||||
}
|
||||
|
||||
const String cap = cmd.substr(0, idx);
|
||||
if (!has_capture(cap))
|
||||
if (!has_capture(cap)) {
|
||||
continue; // Unknown message...
|
||||
}
|
||||
|
||||
const String msg = cmd.substr(idx + 1);
|
||||
capture_parse(cap, msg, arr[1], parsed);
|
||||
@ -856,10 +864,11 @@ Error RemoteDebugger::_core_capture(const String &p_cmd, const Array &p_data, bo
|
||||
} else if (p_cmd == "breakpoint") {
|
||||
ERR_FAIL_COND_V(p_data.size() < 3, ERR_INVALID_DATA);
|
||||
bool set = p_data[2];
|
||||
if (set)
|
||||
if (set) {
|
||||
script_debugger->insert_breakpoint(p_data[1], p_data[0]);
|
||||
else
|
||||
} else {
|
||||
script_debugger->remove_breakpoint(p_data[1], p_data[0]);
|
||||
}
|
||||
|
||||
} else if (p_cmd == "set_skip_breakpoints") {
|
||||
ERR_FAIL_COND_V(p_data.size() < 1, ERR_INVALID_DATA);
|
||||
@ -950,6 +959,7 @@ RemoteDebugger::~RemoteDebugger() {
|
||||
memdelete(servers_profiler);
|
||||
memdelete(network_profiler);
|
||||
memdelete(visual_profiler);
|
||||
if (performance_profiler)
|
||||
if (performance_profiler) {
|
||||
memdelete(performance_profiler);
|
||||
}
|
||||
}
|
||||
|
@ -52,8 +52,9 @@ Array RemoteDebuggerPeerTCP::get_message() {
|
||||
|
||||
Error RemoteDebuggerPeerTCP::put_message(const Array &p_arr) {
|
||||
MutexLock lock(mutex);
|
||||
if (out_queue.size() >= max_queued_messages)
|
||||
if (out_queue.size() >= max_queued_messages) {
|
||||
return ERR_OUT_OF_MEMORY;
|
||||
}
|
||||
|
||||
out_queue.push_back(p_arr);
|
||||
return OK;
|
||||
@ -99,8 +100,9 @@ void RemoteDebuggerPeerTCP::_write_out() {
|
||||
while (tcp_client->poll(NetSocket::POLL_TYPE_OUT) == OK) {
|
||||
uint8_t *buf = out_buf.ptrw();
|
||||
if (out_left <= 0) {
|
||||
if (out_queue.size() == 0)
|
||||
if (out_queue.size() == 0) {
|
||||
break; // Nothing left to send
|
||||
}
|
||||
mutex.lock();
|
||||
Variant var = out_queue[0];
|
||||
out_queue.pop_front();
|
||||
@ -154,12 +156,12 @@ void RemoteDebuggerPeerTCP::_read_in() {
|
||||
}
|
||||
|
||||
Error RemoteDebuggerPeerTCP::connect_to_host(const String &p_host, uint16_t p_port) {
|
||||
|
||||
IP_Address ip;
|
||||
if (p_host.is_valid_ip_address())
|
||||
if (p_host.is_valid_ip_address()) {
|
||||
ip = p_host;
|
||||
else
|
||||
} else {
|
||||
ip = IP::get_singleton()->resolve_hostname(p_host);
|
||||
}
|
||||
|
||||
int port = p_port;
|
||||
|
||||
@ -169,12 +171,10 @@ Error RemoteDebuggerPeerTCP::connect_to_host(const String &p_host, uint16_t p_po
|
||||
tcp_client->connect_to_host(ip, port);
|
||||
|
||||
for (int i = 0; i < tries; i++) {
|
||||
|
||||
if (tcp_client->get_status() == StreamPeerTCP::STATUS_CONNECTED) {
|
||||
print_verbose("Remote Debugger: Connected!");
|
||||
break;
|
||||
} else {
|
||||
|
||||
const int ms = waits[i];
|
||||
OS::get_singleton()->delay_usec(ms * 1000);
|
||||
print_verbose("Remote Debugger: Connection failed with status: '" + String::num(tcp_client->get_status()) + "', retrying in " + String::num(ms) + " msec.");
|
||||
@ -182,7 +182,6 @@ Error RemoteDebuggerPeerTCP::connect_to_host(const String &p_host, uint16_t p_po
|
||||
};
|
||||
|
||||
if (tcp_client->get_status() != StreamPeerTCP::STATUS_CONNECTED) {
|
||||
|
||||
ERR_PRINT("Remote Debugger: Unable to connect. Status: " + String::num(tcp_client->get_status()) + ".");
|
||||
return FAILED;
|
||||
};
|
||||
@ -198,8 +197,9 @@ void RemoteDebuggerPeerTCP::_thread_func(void *p_ud) {
|
||||
RemoteDebuggerPeerTCP *peer = (RemoteDebuggerPeerTCP *)p_ud;
|
||||
while (peer->running && peer->is_peer_connected()) {
|
||||
peer->_poll();
|
||||
if (!peer->is_peer_connected())
|
||||
if (!peer->is_peer_connected()) {
|
||||
break;
|
||||
}
|
||||
peer->tcp_client->poll(NetSocket::POLL_TYPE_IN_OUT, 1);
|
||||
}
|
||||
}
|
||||
|
@ -33,69 +33,63 @@
|
||||
#include "core/debugger/engine_debugger.h"
|
||||
|
||||
void ScriptDebugger::set_lines_left(int p_left) {
|
||||
|
||||
lines_left = p_left;
|
||||
}
|
||||
|
||||
int ScriptDebugger::get_lines_left() const {
|
||||
|
||||
return lines_left;
|
||||
}
|
||||
|
||||
void ScriptDebugger::set_depth(int p_depth) {
|
||||
|
||||
depth = p_depth;
|
||||
}
|
||||
|
||||
int ScriptDebugger::get_depth() const {
|
||||
|
||||
return depth;
|
||||
}
|
||||
|
||||
void ScriptDebugger::insert_breakpoint(int p_line, const StringName &p_source) {
|
||||
|
||||
if (!breakpoints.has(p_line))
|
||||
if (!breakpoints.has(p_line)) {
|
||||
breakpoints[p_line] = Set<StringName>();
|
||||
}
|
||||
breakpoints[p_line].insert(p_source);
|
||||
}
|
||||
|
||||
void ScriptDebugger::remove_breakpoint(int p_line, const StringName &p_source) {
|
||||
|
||||
if (!breakpoints.has(p_line))
|
||||
if (!breakpoints.has(p_line)) {
|
||||
return;
|
||||
}
|
||||
|
||||
breakpoints[p_line].erase(p_source);
|
||||
if (breakpoints[p_line].size() == 0)
|
||||
if (breakpoints[p_line].size() == 0) {
|
||||
breakpoints.erase(p_line);
|
||||
}
|
||||
bool ScriptDebugger::is_breakpoint(int p_line, const StringName &p_source) const {
|
||||
}
|
||||
|
||||
if (!breakpoints.has(p_line))
|
||||
bool ScriptDebugger::is_breakpoint(int p_line, const StringName &p_source) const {
|
||||
if (!breakpoints.has(p_line)) {
|
||||
return false;
|
||||
}
|
||||
return breakpoints[p_line].has(p_source);
|
||||
}
|
||||
bool ScriptDebugger::is_breakpoint_line(int p_line) const {
|
||||
|
||||
bool ScriptDebugger::is_breakpoint_line(int p_line) const {
|
||||
return breakpoints.has(p_line);
|
||||
}
|
||||
|
||||
String ScriptDebugger::breakpoint_find_source(const String &p_source) const {
|
||||
|
||||
return p_source;
|
||||
}
|
||||
|
||||
void ScriptDebugger::clear_breakpoints() {
|
||||
|
||||
breakpoints.clear();
|
||||
}
|
||||
|
||||
void ScriptDebugger::set_skip_breakpoints(bool p_skip_breakpoints) {
|
||||
|
||||
skip_breakpoints = p_skip_breakpoints;
|
||||
}
|
||||
|
||||
bool ScriptDebugger::is_skipping_breakpoints() {
|
||||
|
||||
return skip_breakpoints;
|
||||
}
|
||||
|
||||
@ -118,6 +112,5 @@ Vector<ScriptLanguage::StackInfo> ScriptDebugger::get_error_stack_info() const {
|
||||
}
|
||||
|
||||
ScriptLanguage *ScriptDebugger::get_break_language() const {
|
||||
|
||||
return break_lang;
|
||||
}
|
||||
|
@ -38,7 +38,6 @@
|
||||
#include "core/vector.h"
|
||||
|
||||
class ScriptDebugger {
|
||||
|
||||
typedef ScriptLanguage::StackInfo StackInfo;
|
||||
|
||||
int lines_left = -1;
|
||||
|
@ -35,15 +35,14 @@
|
||||
#include "core/variant.h"
|
||||
|
||||
struct DictionaryPrivate {
|
||||
|
||||
SafeRefCount refcount;
|
||||
OrderedHashMap<Variant, Variant, VariantHasher, VariantComparator> variant_map;
|
||||
};
|
||||
|
||||
void Dictionary::get_key_list(List<Variant> *p_keys) const {
|
||||
|
||||
if (_p->variant_map.empty())
|
||||
if (_p->variant_map.empty()) {
|
||||
return;
|
||||
}
|
||||
|
||||
for (OrderedHashMap<Variant, Variant, VariantHasher, VariantComparator>::Element E = _p->variant_map.front(); E; E = E.next()) {
|
||||
p_keys->push_back(E.key());
|
||||
@ -51,7 +50,6 @@ void Dictionary::get_key_list(List<Variant> *p_keys) const {
|
||||
}
|
||||
|
||||
Variant Dictionary::get_key_at_index(int p_index) const {
|
||||
|
||||
int index = 0;
|
||||
for (OrderedHashMap<Variant, Variant, VariantHasher, VariantComparator>::Element E = _p->variant_map.front(); E; E = E.next()) {
|
||||
if (index == p_index) {
|
||||
@ -64,7 +62,6 @@ Variant Dictionary::get_key_at_index(int p_index) const {
|
||||
}
|
||||
|
||||
Variant Dictionary::get_value_at_index(int p_index) const {
|
||||
|
||||
int index = 0;
|
||||
for (OrderedHashMap<Variant, Variant, VariantHasher, VariantComparator>::Element E = _p->variant_map.front(); E; E = E.next()) {
|
||||
if (index == p_index) {
|
||||
@ -77,38 +74,37 @@ Variant Dictionary::get_value_at_index(int p_index) const {
|
||||
}
|
||||
|
||||
Variant &Dictionary::operator[](const Variant &p_key) {
|
||||
|
||||
return _p->variant_map[p_key];
|
||||
}
|
||||
|
||||
const Variant &Dictionary::operator[](const Variant &p_key) const {
|
||||
|
||||
return _p->variant_map[p_key];
|
||||
}
|
||||
const Variant *Dictionary::getptr(const Variant &p_key) const {
|
||||
|
||||
const Variant *Dictionary::getptr(const Variant &p_key) const {
|
||||
OrderedHashMap<Variant, Variant, VariantHasher, VariantComparator>::ConstElement E = ((const OrderedHashMap<Variant, Variant, VariantHasher, VariantComparator> *)&_p->variant_map)->find(p_key);
|
||||
|
||||
if (!E)
|
||||
if (!E) {
|
||||
return nullptr;
|
||||
}
|
||||
return &E.get();
|
||||
}
|
||||
|
||||
Variant *Dictionary::getptr(const Variant &p_key) {
|
||||
|
||||
OrderedHashMap<Variant, Variant, VariantHasher, VariantComparator>::Element E = _p->variant_map.find(p_key);
|
||||
|
||||
if (!E)
|
||||
if (!E) {
|
||||
return nullptr;
|
||||
}
|
||||
return &E.get();
|
||||
}
|
||||
|
||||
Variant Dictionary::get_valid(const Variant &p_key) const {
|
||||
|
||||
OrderedHashMap<Variant, Variant, VariantHasher, VariantComparator>::ConstElement E = ((const OrderedHashMap<Variant, Variant, VariantHasher, VariantComparator> *)&_p->variant_map)->find(p_key);
|
||||
|
||||
if (!E)
|
||||
if (!E) {
|
||||
return Variant();
|
||||
}
|
||||
return E.get();
|
||||
}
|
||||
|
||||
@ -122,16 +118,14 @@ Variant Dictionary::get(const Variant &p_key, const Variant &p_default) const {
|
||||
}
|
||||
|
||||
int Dictionary::size() const {
|
||||
|
||||
return _p->variant_map.size();
|
||||
}
|
||||
bool Dictionary::empty() const {
|
||||
|
||||
bool Dictionary::empty() const {
|
||||
return !_p->variant_map.size();
|
||||
}
|
||||
|
||||
bool Dictionary::has(const Variant &p_key) const {
|
||||
|
||||
return _p->variant_map.has(p_key);
|
||||
}
|
||||
|
||||
@ -145,51 +139,47 @@ bool Dictionary::has_all(const Array &p_keys) const {
|
||||
}
|
||||
|
||||
bool Dictionary::erase(const Variant &p_key) {
|
||||
|
||||
return _p->variant_map.erase(p_key);
|
||||
}
|
||||
|
||||
bool Dictionary::operator==(const Dictionary &p_dictionary) const {
|
||||
|
||||
return _p == p_dictionary._p;
|
||||
}
|
||||
|
||||
bool Dictionary::operator!=(const Dictionary &p_dictionary) const {
|
||||
|
||||
return _p != p_dictionary._p;
|
||||
}
|
||||
|
||||
void Dictionary::_ref(const Dictionary &p_from) const {
|
||||
|
||||
//make a copy first (thread safe)
|
||||
if (!p_from._p->refcount.ref())
|
||||
if (!p_from._p->refcount.ref()) {
|
||||
return; // couldn't copy
|
||||
}
|
||||
|
||||
//if this is the same, unreference the other one
|
||||
if (p_from._p == _p) {
|
||||
_p->refcount.unref();
|
||||
return;
|
||||
}
|
||||
if (_p)
|
||||
if (_p) {
|
||||
_unref();
|
||||
}
|
||||
_p = p_from._p;
|
||||
}
|
||||
|
||||
void Dictionary::clear() {
|
||||
|
||||
_p->variant_map.clear();
|
||||
}
|
||||
|
||||
void Dictionary::_unref() const {
|
||||
|
||||
ERR_FAIL_COND(!_p);
|
||||
if (_p->refcount.unref()) {
|
||||
memdelete(_p);
|
||||
}
|
||||
_p = nullptr;
|
||||
}
|
||||
uint32_t Dictionary::hash() const {
|
||||
|
||||
uint32_t Dictionary::hash() const {
|
||||
uint32_t h = hash_djb2_one_32(Variant::DICTIONARY);
|
||||
|
||||
for (OrderedHashMap<Variant, Variant, VariantHasher, VariantComparator>::Element E = _p->variant_map.front(); E; E = E.next()) {
|
||||
@ -201,10 +191,10 @@ uint32_t Dictionary::hash() const {
|
||||
}
|
||||
|
||||
Array Dictionary::keys() const {
|
||||
|
||||
Array varr;
|
||||
if (_p->variant_map.empty())
|
||||
if (_p->variant_map.empty()) {
|
||||
return varr;
|
||||
}
|
||||
|
||||
varr.resize(size());
|
||||
|
||||
@ -218,10 +208,10 @@ Array Dictionary::keys() const {
|
||||
}
|
||||
|
||||
Array Dictionary::values() const {
|
||||
|
||||
Array varr;
|
||||
if (_p->variant_map.empty())
|
||||
if (_p->variant_map.empty()) {
|
||||
return varr;
|
||||
}
|
||||
|
||||
varr.resize(size());
|
||||
|
||||
@ -235,22 +225,22 @@ Array Dictionary::values() const {
|
||||
}
|
||||
|
||||
const Variant *Dictionary::next(const Variant *p_key) const {
|
||||
|
||||
if (p_key == nullptr) {
|
||||
// caller wants to get the first element
|
||||
if (_p->variant_map.front())
|
||||
if (_p->variant_map.front()) {
|
||||
return &_p->variant_map.front().key();
|
||||
}
|
||||
return nullptr;
|
||||
}
|
||||
OrderedHashMap<Variant, Variant, VariantHasher, VariantComparator>::Element E = _p->variant_map.find(*p_key);
|
||||
|
||||
if (E && E.next())
|
||||
if (E && E.next()) {
|
||||
return &E.next().key();
|
||||
}
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
Dictionary Dictionary::duplicate(bool p_deep) const {
|
||||
|
||||
Dictionary n;
|
||||
|
||||
for (OrderedHashMap<Variant, Variant, VariantHasher, VariantComparator>::Element E = _p->variant_map.front(); E; E = E.next()) {
|
||||
@ -261,7 +251,6 @@ Dictionary Dictionary::duplicate(bool p_deep) const {
|
||||
}
|
||||
|
||||
void Dictionary::operator=(const Dictionary &p_dictionary) {
|
||||
|
||||
_ref(p_dictionary);
|
||||
}
|
||||
|
||||
@ -275,11 +264,10 @@ Dictionary::Dictionary(const Dictionary &p_from) {
|
||||
}
|
||||
|
||||
Dictionary::Dictionary() {
|
||||
|
||||
_p = memnew(DictionaryPrivate);
|
||||
_p->refcount.init();
|
||||
}
|
||||
Dictionary::~Dictionary() {
|
||||
|
||||
Dictionary::~Dictionary() {
|
||||
_unref();
|
||||
}
|
||||
|
@ -40,7 +40,6 @@ class Variant;
|
||||
struct DictionaryPrivate;
|
||||
|
||||
class Dictionary {
|
||||
|
||||
mutable DictionaryPrivate *_p;
|
||||
|
||||
void _ref(const Dictionary &p_from) const;
|
||||
|
@ -37,18 +37,18 @@
|
||||
#include "core/version_hash.gen.h"
|
||||
|
||||
void Engine::set_iterations_per_second(int p_ips) {
|
||||
|
||||
ERR_FAIL_COND_MSG(p_ips <= 0, "Engine iterations per second must be greater than 0.");
|
||||
ips = p_ips;
|
||||
}
|
||||
int Engine::get_iterations_per_second() const {
|
||||
|
||||
int Engine::get_iterations_per_second() const {
|
||||
return ips;
|
||||
}
|
||||
|
||||
void Engine::set_physics_jitter_fix(float p_threshold) {
|
||||
if (p_threshold < 0)
|
||||
if (p_threshold < 0) {
|
||||
p_threshold = 0;
|
||||
}
|
||||
physics_jitter_fix = p_threshold;
|
||||
}
|
||||
|
||||
@ -65,32 +65,26 @@ int Engine::get_target_fps() const {
|
||||
}
|
||||
|
||||
uint64_t Engine::get_frames_drawn() {
|
||||
|
||||
return frames_drawn;
|
||||
}
|
||||
|
||||
void Engine::set_frame_delay(uint32_t p_msec) {
|
||||
|
||||
_frame_delay = p_msec;
|
||||
}
|
||||
|
||||
uint32_t Engine::get_frame_delay() const {
|
||||
|
||||
return _frame_delay;
|
||||
}
|
||||
|
||||
void Engine::set_time_scale(float p_scale) {
|
||||
|
||||
_time_scale = p_scale;
|
||||
}
|
||||
|
||||
float Engine::get_time_scale() const {
|
||||
|
||||
return _time_scale;
|
||||
}
|
||||
|
||||
Dictionary Engine::get_version_info() const {
|
||||
|
||||
Dictionary dict;
|
||||
dict["major"] = VERSION_MAJOR;
|
||||
dict["minor"] = VERSION_MINOR;
|
||||
@ -104,8 +98,9 @@ Dictionary Engine::get_version_info() const {
|
||||
dict["hash"] = hash.length() == 0 ? String("unknown") : hash;
|
||||
|
||||
String stringver = String(dict["major"]) + "." + String(dict["minor"]);
|
||||
if ((int)dict["patch"] != 0)
|
||||
if ((int)dict["patch"] != 0) {
|
||||
stringver += "." + String(dict["patch"]);
|
||||
}
|
||||
stringver += "-" + String(dict["status"]) + " (" + String(dict["build"]) + ")";
|
||||
dict["string"] = stringver;
|
||||
|
||||
@ -185,28 +180,25 @@ String Engine::get_license_text() const {
|
||||
}
|
||||
|
||||
void Engine::add_singleton(const Singleton &p_singleton) {
|
||||
|
||||
singletons.push_back(p_singleton);
|
||||
singleton_ptrs[p_singleton.name] = p_singleton.ptr;
|
||||
}
|
||||
|
||||
Object *Engine::get_singleton_object(const String &p_name) const {
|
||||
|
||||
const Map<StringName, Object *>::Element *E = singleton_ptrs.find(p_name);
|
||||
ERR_FAIL_COND_V_MSG(!E, nullptr, "Failed to retrieve non-existent singleton '" + p_name + "'.");
|
||||
return E->get();
|
||||
};
|
||||
|
||||
bool Engine::has_singleton(const String &p_name) const {
|
||||
|
||||
return singleton_ptrs.has(p_name);
|
||||
};
|
||||
|
||||
void Engine::get_singletons(List<Singleton> *p_singletons) {
|
||||
|
||||
for (List<Singleton>::Element *E = singletons.front(); E; E = E->next())
|
||||
for (List<Singleton>::Element *E = singletons.front(); E; E = E->next()) {
|
||||
p_singletons->push_back(E->get());
|
||||
}
|
||||
}
|
||||
|
||||
Engine *Engine::singleton = nullptr;
|
||||
|
||||
|
@ -37,7 +37,6 @@
|
||||
#include "core/vector.h"
|
||||
|
||||
class Engine {
|
||||
|
||||
public:
|
||||
struct Singleton {
|
||||
StringName name;
|
||||
|
@ -37,7 +37,6 @@
|
||||
static ErrorHandlerList *error_handler_list = nullptr;
|
||||
|
||||
void add_error_handler(ErrorHandlerList *p_handler) {
|
||||
|
||||
_global_lock();
|
||||
p_handler->next = error_handler_list;
|
||||
error_handler_list = p_handler;
|
||||
@ -45,20 +44,18 @@ void add_error_handler(ErrorHandlerList *p_handler) {
|
||||
}
|
||||
|
||||
void remove_error_handler(ErrorHandlerList *p_handler) {
|
||||
|
||||
_global_lock();
|
||||
|
||||
ErrorHandlerList *prev = nullptr;
|
||||
ErrorHandlerList *l = error_handler_list;
|
||||
|
||||
while (l) {
|
||||
|
||||
if (l == p_handler) {
|
||||
|
||||
if (prev)
|
||||
if (prev) {
|
||||
prev->next = l->next;
|
||||
else
|
||||
} else {
|
||||
error_handler_list = l->next;
|
||||
}
|
||||
break;
|
||||
}
|
||||
prev = l;
|
||||
@ -77,13 +74,11 @@ void _err_print_error(const char *p_function, const char *p_file, int p_line, co
|
||||
}
|
||||
|
||||
void _err_print_error(const char *p_function, const char *p_file, int p_line, const char *p_error, const char *p_message, ErrorHandlerType p_type) {
|
||||
|
||||
OS::get_singleton()->print_error(p_function, p_file, p_line, p_error, p_message, (Logger::ErrorType)p_type);
|
||||
|
||||
_global_lock();
|
||||
ErrorHandlerList *l = error_handler_list;
|
||||
while (l) {
|
||||
|
||||
l->errfunc(l->userdata, p_function, p_file, p_line, p_error, p_message, p_type);
|
||||
l = l->next;
|
||||
}
|
||||
@ -104,7 +99,6 @@ void _err_print_error(const char *p_function, const char *p_file, int p_line, co
|
||||
}
|
||||
|
||||
void _err_print_index_error(const char *p_function, const char *p_file, int p_line, int64_t p_index, int64_t p_size, const char *p_index_str, const char *p_size_str, const char *p_message, bool fatal) {
|
||||
|
||||
String fstr(fatal ? "FATAL: " : "");
|
||||
String err(fstr + "Index " + p_index_str + " = " + itos(p_index) + " is out of bounds (" + p_size_str + " = " + itos(p_size) + ").");
|
||||
_err_print_error(p_function, p_file, p_line, err.utf8().get_data(), p_message);
|
||||
|
@ -47,7 +47,6 @@ enum ErrorHandlerType {
|
||||
typedef void (*ErrorHandlerFunc)(void *, const char *, const char *, int p_line, const char *, const char *, ErrorHandlerType p_type);
|
||||
|
||||
struct ErrorHandlerList {
|
||||
|
||||
ErrorHandlerFunc errfunc = nullptr;
|
||||
void *userdata = nullptr;
|
||||
|
||||
|
@ -31,7 +31,6 @@
|
||||
#include "func_ref.h"
|
||||
|
||||
Variant FuncRef::call_func(const Variant **p_args, int p_argcount, Callable::CallError &r_error) {
|
||||
|
||||
if (id.is_null()) {
|
||||
r_error.error = Callable::CallError::CALL_ERROR_INSTANCE_IS_NULL;
|
||||
return Variant();
|
||||
@ -47,7 +46,6 @@ Variant FuncRef::call_func(const Variant **p_args, int p_argcount, Callable::Cal
|
||||
}
|
||||
|
||||
Variant FuncRef::call_funcv(const Array &p_args) {
|
||||
|
||||
ERR_FAIL_COND_V(id.is_null(), Variant());
|
||||
|
||||
Object *obj = ObjectDB::get_instance(id);
|
||||
@ -58,29 +56,28 @@ Variant FuncRef::call_funcv(const Array &p_args) {
|
||||
}
|
||||
|
||||
void FuncRef::set_instance(Object *p_obj) {
|
||||
|
||||
ERR_FAIL_NULL(p_obj);
|
||||
id = p_obj->get_instance_id();
|
||||
}
|
||||
|
||||
void FuncRef::set_function(const StringName &p_func) {
|
||||
|
||||
function = p_func;
|
||||
}
|
||||
|
||||
bool FuncRef::is_valid() const {
|
||||
if (id.is_null())
|
||||
if (id.is_null()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
Object *obj = ObjectDB::get_instance(id);
|
||||
if (!obj)
|
||||
if (!obj) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return obj->has_method(function);
|
||||
}
|
||||
|
||||
void FuncRef::_bind_methods() {
|
||||
|
||||
{
|
||||
MethodInfo mi;
|
||||
mi.name = "call_func";
|
||||
|
@ -34,7 +34,6 @@
|
||||
#include "core/reference.h"
|
||||
|
||||
class FuncRef : public Reference {
|
||||
|
||||
GDCLASS(FuncRef, Reference);
|
||||
ObjectID id;
|
||||
StringName function;
|
||||
|
@ -36,7 +36,6 @@
|
||||
#include "core/variant.h"
|
||||
|
||||
struct _GlobalConstant {
|
||||
|
||||
#ifdef DEBUG_METHODS_ENABLED
|
||||
StringName enum_name;
|
||||
#endif
|
||||
@ -638,33 +637,27 @@ void register_global_constants() {
|
||||
}
|
||||
|
||||
void unregister_global_constants() {
|
||||
|
||||
_global_constants.clear();
|
||||
}
|
||||
|
||||
int GlobalConstants::get_global_constant_count() {
|
||||
|
||||
return _global_constants.size();
|
||||
}
|
||||
|
||||
#ifdef DEBUG_METHODS_ENABLED
|
||||
StringName GlobalConstants::get_global_constant_enum(int p_idx) {
|
||||
|
||||
return _global_constants[p_idx].enum_name;
|
||||
}
|
||||
#else
|
||||
StringName GlobalConstants::get_global_constant_enum(int p_idx) {
|
||||
|
||||
return StringName();
|
||||
}
|
||||
#endif
|
||||
|
||||
const char *GlobalConstants::get_global_constant_name(int p_idx) {
|
||||
|
||||
return _global_constants[p_idx].name;
|
||||
}
|
||||
|
||||
int GlobalConstants::get_global_constant_value(int p_idx) {
|
||||
|
||||
return _global_constants[p_idx].value;
|
||||
}
|
||||
|
109
core/hash_map.h
109
core/hash_map.h
@ -59,7 +59,6 @@ template <class TKey, class TData, class Hasher = HashMapHasherDefault, class Co
|
||||
class HashMap {
|
||||
public:
|
||||
struct Pair {
|
||||
|
||||
TKey key;
|
||||
TData data;
|
||||
|
||||
@ -99,19 +98,18 @@ private:
|
||||
uint32_t elements = 0;
|
||||
|
||||
void make_hash_table() {
|
||||
|
||||
ERR_FAIL_COND(hash_table);
|
||||
|
||||
hash_table = memnew_arr(Element *, (1 << MIN_HASH_TABLE_POWER));
|
||||
|
||||
hash_table_power = MIN_HASH_TABLE_POWER;
|
||||
elements = 0;
|
||||
for (int i = 0; i < (1 << MIN_HASH_TABLE_POWER); i++)
|
||||
for (int i = 0; i < (1 << MIN_HASH_TABLE_POWER); i++) {
|
||||
hash_table[i] = nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
void erase_hash_table() {
|
||||
|
||||
ERR_FAIL_COND_MSG(elements, "Cannot erase hash table if there are still elements inside.");
|
||||
|
||||
memdelete_arr(hash_table);
|
||||
@ -121,7 +119,6 @@ private:
|
||||
}
|
||||
|
||||
void check_hash_table() {
|
||||
|
||||
int new_hash_table_power = -1;
|
||||
|
||||
if ((int)elements > ((1 << hash_table_power) * RELATIONSHIP)) {
|
||||
@ -129,40 +126,36 @@ private:
|
||||
new_hash_table_power = hash_table_power + 1;
|
||||
|
||||
while ((int)elements > ((1 << new_hash_table_power) * RELATIONSHIP)) {
|
||||
|
||||
new_hash_table_power++;
|
||||
}
|
||||
|
||||
} else if ((hash_table_power > (int)MIN_HASH_TABLE_POWER) && ((int)elements < ((1 << (hash_table_power - 1)) * RELATIONSHIP))) {
|
||||
|
||||
/* rehash down */
|
||||
new_hash_table_power = hash_table_power - 1;
|
||||
|
||||
while ((int)elements < ((1 << (new_hash_table_power - 1)) * RELATIONSHIP)) {
|
||||
|
||||
new_hash_table_power--;
|
||||
}
|
||||
|
||||
if (new_hash_table_power < (int)MIN_HASH_TABLE_POWER)
|
||||
if (new_hash_table_power < (int)MIN_HASH_TABLE_POWER) {
|
||||
new_hash_table_power = MIN_HASH_TABLE_POWER;
|
||||
}
|
||||
}
|
||||
|
||||
if (new_hash_table_power == -1)
|
||||
if (new_hash_table_power == -1) {
|
||||
return;
|
||||
}
|
||||
|
||||
Element **new_hash_table = memnew_arr(Element *, ((uint64_t)1 << new_hash_table_power));
|
||||
ERR_FAIL_COND_MSG(!new_hash_table, "Out of memory.");
|
||||
|
||||
for (int i = 0; i < (1 << new_hash_table_power); i++) {
|
||||
|
||||
new_hash_table[i] = nullptr;
|
||||
}
|
||||
|
||||
if (hash_table) {
|
||||
for (int i = 0; i < (1 << hash_table_power); i++) {
|
||||
|
||||
while (hash_table[i]) {
|
||||
|
||||
Element *se = hash_table[i];
|
||||
hash_table[i] = se->next;
|
||||
int new_pos = se->hash & ((1 << new_hash_table_power) - 1);
|
||||
@ -179,17 +172,14 @@ private:
|
||||
|
||||
/* I want to have only one function.. */
|
||||
_FORCE_INLINE_ const Element *get_element(const TKey &p_key) const {
|
||||
|
||||
uint32_t hash = Hasher::hash(p_key);
|
||||
uint32_t index = hash & ((1 << hash_table_power) - 1);
|
||||
|
||||
Element *e = hash_table[index];
|
||||
|
||||
while (e) {
|
||||
|
||||
/* checking hash first avoids comparing key, which may take longer */
|
||||
if (e->hash == hash && Comparator::compare(e->pair.key, p_key)) {
|
||||
|
||||
/* the pair exists in this hashtable, so just update data */
|
||||
return e;
|
||||
}
|
||||
@ -201,7 +191,6 @@ private:
|
||||
}
|
||||
|
||||
Element *create_element(const TKey &p_key) {
|
||||
|
||||
/* if element doesn't exist, create it */
|
||||
Element *e = memnew(Element);
|
||||
ERR_FAIL_COND_V_MSG(!e, nullptr, "Out of memory.");
|
||||
@ -219,27 +208,26 @@ private:
|
||||
}
|
||||
|
||||
void copy_from(const HashMap &p_t) {
|
||||
|
||||
if (&p_t == this)
|
||||
if (&p_t == this) {
|
||||
return; /* much less bother with that */
|
||||
}
|
||||
|
||||
clear();
|
||||
|
||||
if (!p_t.hash_table || p_t.hash_table_power == 0)
|
||||
if (!p_t.hash_table || p_t.hash_table_power == 0) {
|
||||
return; /* not copying from empty table */
|
||||
}
|
||||
|
||||
hash_table = memnew_arr(Element *, (uint64_t)1 << p_t.hash_table_power);
|
||||
hash_table_power = p_t.hash_table_power;
|
||||
elements = p_t.elements;
|
||||
|
||||
for (int i = 0; i < (1 << p_t.hash_table_power); i++) {
|
||||
|
||||
hash_table[i] = nullptr;
|
||||
|
||||
const Element *e = p_t.hash_table[i];
|
||||
|
||||
while (e) {
|
||||
|
||||
Element *le = memnew(Element); /* local element */
|
||||
|
||||
*le = *e; /* copy data */
|
||||
@ -259,20 +247,20 @@ public:
|
||||
}
|
||||
|
||||
Element *set(const Pair &p_pair) {
|
||||
|
||||
Element *e = nullptr;
|
||||
if (!hash_table)
|
||||
if (!hash_table) {
|
||||
make_hash_table(); // if no table, make one
|
||||
else
|
||||
} else {
|
||||
e = const_cast<Element *>(get_element(p_pair.key));
|
||||
}
|
||||
|
||||
/* if we made it up to here, the pair doesn't exist, create and assign */
|
||||
|
||||
if (!e) {
|
||||
|
||||
e = create_element(p_pair.key);
|
||||
if (!e)
|
||||
if (!e) {
|
||||
return nullptr;
|
||||
}
|
||||
check_hash_table(); // perform mantenience routine
|
||||
}
|
||||
|
||||
@ -281,7 +269,6 @@ public:
|
||||
}
|
||||
|
||||
bool has(const TKey &p_key) const {
|
||||
|
||||
return getptr(p_key) != nullptr;
|
||||
}
|
||||
|
||||
@ -292,14 +279,12 @@ public:
|
||||
*/
|
||||
|
||||
const TData &get(const TKey &p_key) const {
|
||||
|
||||
const TData *res = getptr(p_key);
|
||||
ERR_FAIL_COND_V(!res, *res);
|
||||
return *res;
|
||||
}
|
||||
|
||||
TData &get(const TKey &p_key) {
|
||||
|
||||
TData *res = getptr(p_key);
|
||||
ERR_FAIL_COND_V(!res, *res);
|
||||
return *res;
|
||||
@ -311,27 +296,29 @@ public:
|
||||
*/
|
||||
|
||||
_FORCE_INLINE_ TData *getptr(const TKey &p_key) {
|
||||
|
||||
if (unlikely(!hash_table))
|
||||
if (unlikely(!hash_table)) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
Element *e = const_cast<Element *>(get_element(p_key));
|
||||
|
||||
if (e)
|
||||
if (e) {
|
||||
return &e->pair.data;
|
||||
}
|
||||
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
_FORCE_INLINE_ const TData *getptr(const TKey &p_key) const {
|
||||
|
||||
if (unlikely(!hash_table))
|
||||
if (unlikely(!hash_table)) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
const Element *e = const_cast<Element *>(get_element(p_key));
|
||||
|
||||
if (e)
|
||||
if (e) {
|
||||
return &e->pair.data;
|
||||
}
|
||||
|
||||
return nullptr;
|
||||
}
|
||||
@ -343,9 +330,9 @@ public:
|
||||
|
||||
template <class C>
|
||||
_FORCE_INLINE_ TData *custom_getptr(C p_custom_key, uint32_t p_custom_hash) {
|
||||
|
||||
if (unlikely(!hash_table))
|
||||
if (unlikely(!hash_table)) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
uint32_t hash = p_custom_hash;
|
||||
uint32_t index = hash & ((1 << hash_table_power) - 1);
|
||||
@ -353,10 +340,8 @@ public:
|
||||
Element *e = hash_table[index];
|
||||
|
||||
while (e) {
|
||||
|
||||
/* checking hash first avoids comparing key, which may take longer */
|
||||
if (e->hash == hash && Comparator::compare(e->pair.key, p_custom_key)) {
|
||||
|
||||
/* the pair exists in this hashtable, so just update data */
|
||||
return &e->pair.data;
|
||||
}
|
||||
@ -369,9 +354,9 @@ public:
|
||||
|
||||
template <class C>
|
||||
_FORCE_INLINE_ const TData *custom_getptr(C p_custom_key, uint32_t p_custom_hash) const {
|
||||
|
||||
if (unlikely(!hash_table))
|
||||
if (unlikely(!hash_table)) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
uint32_t hash = p_custom_hash;
|
||||
uint32_t index = hash & ((1 << hash_table_power) - 1);
|
||||
@ -379,10 +364,8 @@ public:
|
||||
const Element *e = hash_table[index];
|
||||
|
||||
while (e) {
|
||||
|
||||
/* checking hash first avoids comparing key, which may take longer */
|
||||
if (e->hash == hash && Comparator::compare(e->pair.key, p_custom_key)) {
|
||||
|
||||
/* the pair exists in this hashtable, so just update data */
|
||||
return &e->pair.data;
|
||||
}
|
||||
@ -398,9 +381,9 @@ public:
|
||||
*/
|
||||
|
||||
bool erase(const TKey &p_key) {
|
||||
|
||||
if (unlikely(!hash_table))
|
||||
if (unlikely(!hash_table)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
uint32_t hash = Hasher::hash(p_key);
|
||||
uint32_t index = hash & ((1 << hash_table_power) - 1);
|
||||
@ -408,12 +391,9 @@ public:
|
||||
Element *e = hash_table[index];
|
||||
Element *p = nullptr;
|
||||
while (e) {
|
||||
|
||||
/* checking hash first avoids comparing key, which may take longer */
|
||||
if (e->hash == hash && Comparator::compare(e->pair.key, p_key)) {
|
||||
|
||||
if (p) {
|
||||
|
||||
p->next = e->next;
|
||||
} else {
|
||||
//begin of list
|
||||
@ -423,10 +403,11 @@ public:
|
||||
memdelete(e);
|
||||
elements--;
|
||||
|
||||
if (elements == 0)
|
||||
if (elements == 0) {
|
||||
erase_hash_table();
|
||||
else
|
||||
} else {
|
||||
check_hash_table();
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
@ -444,14 +425,14 @@ public:
|
||||
inline TData &operator[](const TKey &p_key) { //assignment
|
||||
|
||||
Element *e = nullptr;
|
||||
if (!hash_table)
|
||||
if (!hash_table) {
|
||||
make_hash_table(); // if no table, make one
|
||||
else
|
||||
} else {
|
||||
e = const_cast<Element *>(get_element(p_key));
|
||||
}
|
||||
|
||||
/* if we made it up to here, the pair doesn't exist, create */
|
||||
if (!e) {
|
||||
|
||||
e = create_element(p_key);
|
||||
CRASH_COND(!e);
|
||||
check_hash_table(); // perform mantenience routine
|
||||
@ -476,14 +457,13 @@ public:
|
||||
*
|
||||
*/
|
||||
const TKey *next(const TKey *p_key) const {
|
||||
|
||||
if (unlikely(!hash_table))
|
||||
if (unlikely(!hash_table)) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
if (!p_key) { /* get the first key */
|
||||
|
||||
for (int i = 0; i < (1 << hash_table_power); i++) {
|
||||
|
||||
if (hash_table[i]) {
|
||||
return &hash_table[i]->pair.key;
|
||||
}
|
||||
@ -501,7 +481,6 @@ public:
|
||||
uint32_t index = e->hash & ((1 << hash_table_power) - 1);
|
||||
index++;
|
||||
for (int i = index; i < (1 << hash_table_power); i++) {
|
||||
|
||||
if (hash_table[i]) {
|
||||
return &hash_table[i]->pair.key;
|
||||
}
|
||||
@ -515,23 +494,18 @@ public:
|
||||
}
|
||||
|
||||
inline unsigned int size() const {
|
||||
|
||||
return elements;
|
||||
}
|
||||
|
||||
inline bool empty() const {
|
||||
|
||||
return elements == 0;
|
||||
}
|
||||
|
||||
void clear() {
|
||||
|
||||
/* clean up */
|
||||
if (hash_table) {
|
||||
for (int i = 0; i < (1 << hash_table_power); i++) {
|
||||
|
||||
while (hash_table[i]) {
|
||||
|
||||
Element *e = hash_table[i];
|
||||
hash_table[i] = e->next;
|
||||
memdelete(e);
|
||||
@ -547,15 +521,14 @@ public:
|
||||
}
|
||||
|
||||
void operator=(const HashMap &p_table) {
|
||||
|
||||
copy_from(p_table);
|
||||
}
|
||||
|
||||
void get_key_value_ptr_array(const Pair **p_pairs) const {
|
||||
if (unlikely(!hash_table))
|
||||
if (unlikely(!hash_table)) {
|
||||
return;
|
||||
}
|
||||
for (int i = 0; i < (1 << hash_table_power); i++) {
|
||||
|
||||
Element *e = hash_table[i];
|
||||
while (e) {
|
||||
*p_pairs = &e->pair;
|
||||
@ -566,10 +539,10 @@ public:
|
||||
}
|
||||
|
||||
void get_key_list(List<TKey> *p_keys) const {
|
||||
if (unlikely(!hash_table))
|
||||
if (unlikely(!hash_table)) {
|
||||
return;
|
||||
}
|
||||
for (int i = 0; i < (1 << hash_table_power); i++) {
|
||||
|
||||
Element *e = hash_table[i];
|
||||
while (e) {
|
||||
p_keys->push_back(e->pair.key);
|
||||
|
@ -49,29 +49,28 @@
|
||||
* @return 32-bits hashcode
|
||||
*/
|
||||
static inline uint32_t hash_djb2(const char *p_cstr) {
|
||||
|
||||
const unsigned char *chr = (const unsigned char *)p_cstr;
|
||||
uint32_t hash = 5381;
|
||||
uint32_t c;
|
||||
|
||||
while ((c = *chr++))
|
||||
while ((c = *chr++)) {
|
||||
hash = ((hash << 5) + hash) + c; /* hash * 33 + c */
|
||||
}
|
||||
|
||||
return hash;
|
||||
}
|
||||
|
||||
static inline uint32_t hash_djb2_buffer(const uint8_t *p_buff, int p_len, uint32_t p_prev = 5381) {
|
||||
|
||||
uint32_t hash = p_prev;
|
||||
|
||||
for (int i = 0; i < p_len; i++)
|
||||
for (int i = 0; i < p_len; i++) {
|
||||
hash = ((hash << 5) + hash) + p_buff[i]; /* hash * 33 + c */
|
||||
}
|
||||
|
||||
return hash;
|
||||
}
|
||||
|
||||
static inline uint32_t hash_djb2_one_32(uint32_t p_in, uint32_t p_prev = 5381) {
|
||||
|
||||
return ((p_prev << 5) + p_prev) + p_in;
|
||||
}
|
||||
|
||||
@ -93,19 +92,19 @@ static inline uint32_t hash_djb2_one_float(double p_in, uint32_t p_prev = 5381)
|
||||
} u;
|
||||
|
||||
// Normalize +/- 0.0 and NaN values so they hash the same.
|
||||
if (p_in == 0.0f)
|
||||
if (p_in == 0.0f) {
|
||||
u.d = 0.0;
|
||||
else if (Math::is_nan(p_in))
|
||||
} else if (Math::is_nan(p_in)) {
|
||||
u.d = Math_NAN;
|
||||
else
|
||||
} else {
|
||||
u.d = p_in;
|
||||
}
|
||||
|
||||
return ((p_prev << 5) + p_prev) + hash_one_uint64(u.i);
|
||||
}
|
||||
|
||||
template <class T>
|
||||
static inline uint32_t make_uint32_t(T p_in) {
|
||||
|
||||
union {
|
||||
T t;
|
||||
uint32_t _u32;
|
||||
@ -116,13 +115,11 @@ static inline uint32_t make_uint32_t(T p_in) {
|
||||
}
|
||||
|
||||
static inline uint64_t hash_djb2_one_64(uint64_t p_in, uint64_t p_prev = 5381) {
|
||||
|
||||
return ((p_prev << 5) + p_prev) + p_in;
|
||||
}
|
||||
|
||||
template <class T>
|
||||
static inline uint64_t make_uint64_t(T p_in) {
|
||||
|
||||
union {
|
||||
T t;
|
||||
uint64_t _u64;
|
||||
@ -134,7 +131,6 @@ static inline uint64_t make_uint64_t(T p_in) {
|
||||
}
|
||||
|
||||
struct HashMapHasherDefault {
|
||||
|
||||
static _FORCE_INLINE_ uint32_t hash(const String &p_string) { return p_string.hash(); }
|
||||
static _FORCE_INLINE_ uint32_t hash(const char *p_cstr) { return hash_djb2(p_cstr); }
|
||||
static _FORCE_INLINE_ uint32_t hash(const uint64_t p_int) { return hash_one_uint64(p_int); }
|
||||
|
526
core/image.cpp
526
core/image.cpp
File diff suppressed because it is too large
Load Diff
@ -129,7 +129,6 @@ Input::CursorShape (*Input::get_current_cursor_shape_func)() = nullptr;
|
||||
void (*Input::set_custom_mouse_cursor_func)(const RES &, Input::CursorShape, const Vector2 &) = nullptr;
|
||||
|
||||
Input *Input::get_singleton() {
|
||||
|
||||
return singleton;
|
||||
}
|
||||
|
||||
@ -139,12 +138,10 @@ void Input::set_mouse_mode(MouseMode p_mode) {
|
||||
}
|
||||
|
||||
Input::MouseMode Input::get_mouse_mode() const {
|
||||
|
||||
return get_mouse_mode_func();
|
||||
}
|
||||
|
||||
void Input::_bind_methods() {
|
||||
|
||||
ClassDB::bind_method(D_METHOD("is_key_pressed", "keycode"), &Input::is_key_pressed);
|
||||
ClassDB::bind_method(D_METHOD("is_mouse_button_pressed", "button"), &Input::is_mouse_button_pressed);
|
||||
ClassDB::bind_method(D_METHOD("is_joy_button_pressed", "device", "button"), &Input::is_joy_button_pressed);
|
||||
@ -219,15 +216,15 @@ void Input::get_argument_options(const StringName &p_function, int p_idx, List<S
|
||||
|
||||
String pf = p_function;
|
||||
if (p_idx == 0 && (pf == "is_action_pressed" || pf == "action_press" || pf == "action_release" || pf == "is_action_just_pressed" || pf == "is_action_just_released" || pf == "get_action_strength")) {
|
||||
|
||||
List<PropertyInfo> pinfo;
|
||||
ProjectSettings::get_singleton()->get_property_list(&pinfo);
|
||||
|
||||
for (List<PropertyInfo>::Element *E = pinfo.front(); E; E = E->next()) {
|
||||
const PropertyInfo &pi = E->get();
|
||||
|
||||
if (!pi.name.begins_with("input/"))
|
||||
if (!pi.name.begins_with("input/")) {
|
||||
continue;
|
||||
}
|
||||
|
||||
String name = pi.name.substr(pi.name.find("/") + 1, pi.name.length());
|
||||
r_options->push_back(quote_style + name + quote_style);
|
||||
@ -237,7 +234,6 @@ void Input::get_argument_options(const StringName &p_function, int p_idx, List<S
|
||||
}
|
||||
|
||||
void Input::SpeedTrack::update(const Vector2 &p_delta_p) {
|
||||
|
||||
uint64_t tick = OS::get_singleton()->get_ticks_usec();
|
||||
uint32_t tdiff = tick - last_tick;
|
||||
float delta_t = tdiff / 1000000.0;
|
||||
@ -246,11 +242,11 @@ void Input::SpeedTrack::update(const Vector2 &p_delta_p) {
|
||||
accum += p_delta_p;
|
||||
accum_t += delta_t;
|
||||
|
||||
if (accum_t > max_ref_frame * 10)
|
||||
if (accum_t > max_ref_frame * 10) {
|
||||
accum_t = max_ref_frame * 10;
|
||||
}
|
||||
|
||||
while (accum_t >= min_ref_frame) {
|
||||
|
||||
float slice_t = min_ref_frame / accum_t;
|
||||
Vector2 slice = accum * slice_t;
|
||||
accum = accum - slice;
|
||||
@ -267,45 +263,39 @@ void Input::SpeedTrack::reset() {
|
||||
}
|
||||
|
||||
Input::SpeedTrack::SpeedTrack() {
|
||||
|
||||
min_ref_frame = 0.1;
|
||||
max_ref_frame = 0.3;
|
||||
reset();
|
||||
}
|
||||
|
||||
bool Input::is_key_pressed(int p_keycode) const {
|
||||
|
||||
_THREAD_SAFE_METHOD_
|
||||
return keys_pressed.has(p_keycode);
|
||||
}
|
||||
|
||||
bool Input::is_mouse_button_pressed(int p_button) const {
|
||||
|
||||
_THREAD_SAFE_METHOD_
|
||||
return (mouse_button_mask & (1 << (p_button - 1))) != 0;
|
||||
}
|
||||
|
||||
static int _combine_device(int p_value, int p_device) {
|
||||
|
||||
return p_value | (p_device << 20);
|
||||
}
|
||||
|
||||
bool Input::is_joy_button_pressed(int p_device, int p_button) const {
|
||||
|
||||
_THREAD_SAFE_METHOD_
|
||||
return joy_buttons_pressed.has(_combine_device(p_button, p_device));
|
||||
}
|
||||
|
||||
bool Input::is_action_pressed(const StringName &p_action) const {
|
||||
|
||||
return action_state.has(p_action) && action_state[p_action].pressed;
|
||||
}
|
||||
|
||||
bool Input::is_action_just_pressed(const StringName &p_action) const {
|
||||
|
||||
const Map<StringName, Action>::Element *E = action_state.find(p_action);
|
||||
if (!E)
|
||||
if (!E) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (Engine::get_singleton()->is_in_physics_frame()) {
|
||||
return E->get().pressed && E->get().physics_frame == Engine::get_singleton()->get_physics_frames();
|
||||
@ -315,10 +305,10 @@ bool Input::is_action_just_pressed(const StringName &p_action) const {
|
||||
}
|
||||
|
||||
bool Input::is_action_just_released(const StringName &p_action) const {
|
||||
|
||||
const Map<StringName, Action>::Element *E = action_state.find(p_action);
|
||||
if (!E)
|
||||
if (!E) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (Engine::get_singleton()->is_in_physics_frame()) {
|
||||
return !E->get().pressed && E->get().physics_frame == Engine::get_singleton()->get_physics_frames();
|
||||
@ -329,14 +319,14 @@ bool Input::is_action_just_released(const StringName &p_action) const {
|
||||
|
||||
float Input::get_action_strength(const StringName &p_action) const {
|
||||
const Map<StringName, Action>::Element *E = action_state.find(p_action);
|
||||
if (!E)
|
||||
if (!E) {
|
||||
return 0.0f;
|
||||
}
|
||||
|
||||
return E->get().strength;
|
||||
}
|
||||
|
||||
float Input::get_joy_axis(int p_device, int p_axis) const {
|
||||
|
||||
_THREAD_SAFE_METHOD_
|
||||
int c = _combine_device(p_axis, p_device);
|
||||
if (_joy_axis.has(c)) {
|
||||
@ -347,7 +337,6 @@ float Input::get_joy_axis(int p_device, int p_axis) const {
|
||||
}
|
||||
|
||||
String Input::get_joy_name(int p_idx) {
|
||||
|
||||
_THREAD_SAFE_METHOD_
|
||||
return joy_names[p_idx].name;
|
||||
};
|
||||
@ -377,7 +366,6 @@ float Input::get_joy_vibration_duration(int p_device) {
|
||||
}
|
||||
|
||||
static String _hex_str(uint8_t p_byte) {
|
||||
|
||||
static const char *dict = "0123456789abcdef";
|
||||
char ret[3];
|
||||
ret[2] = 0;
|
||||
@ -389,14 +377,12 @@ static String _hex_str(uint8_t p_byte) {
|
||||
};
|
||||
|
||||
void Input::joy_connection_changed(int p_idx, bool p_connected, String p_name, String p_guid) {
|
||||
|
||||
_THREAD_SAFE_METHOD_
|
||||
Joypad js;
|
||||
js.name = p_connected ? p_name : "";
|
||||
js.uid = p_connected ? p_guid : "";
|
||||
|
||||
if (p_connected) {
|
||||
|
||||
String uidname = p_guid;
|
||||
if (p_guid == "") {
|
||||
int uidlen = MIN(p_name.length(), 16);
|
||||
@ -430,36 +416,30 @@ void Input::joy_connection_changed(int p_idx, bool p_connected, String p_name, S
|
||||
};
|
||||
|
||||
Vector3 Input::get_gravity() const {
|
||||
|
||||
_THREAD_SAFE_METHOD_
|
||||
return gravity;
|
||||
}
|
||||
|
||||
Vector3 Input::get_accelerometer() const {
|
||||
|
||||
_THREAD_SAFE_METHOD_
|
||||
return accelerometer;
|
||||
}
|
||||
|
||||
Vector3 Input::get_magnetometer() const {
|
||||
|
||||
_THREAD_SAFE_METHOD_
|
||||
return magnetometer;
|
||||
}
|
||||
|
||||
Vector3 Input::get_gyroscope() const {
|
||||
|
||||
_THREAD_SAFE_METHOD_
|
||||
return gyroscope;
|
||||
}
|
||||
|
||||
void Input::parse_input_event(const Ref<InputEvent> &p_event) {
|
||||
|
||||
_parse_input_event_impl(p_event, false);
|
||||
}
|
||||
|
||||
void Input::_parse_input_event_impl(const Ref<InputEvent> &p_event, bool p_is_emulated) {
|
||||
|
||||
// Notes on mouse-touch emulation:
|
||||
// - Emulated mouse events are parsed, that is, re-routed to this method, so they make the same effects
|
||||
// as true mouse events. The only difference is the situation is flagged as emulated so they are not
|
||||
@ -471,16 +451,16 @@ void Input::_parse_input_event_impl(const Ref<InputEvent> &p_event, bool p_is_em
|
||||
|
||||
Ref<InputEventKey> k = p_event;
|
||||
if (k.is_valid() && !k->is_echo() && k->get_keycode() != 0) {
|
||||
if (k->is_pressed())
|
||||
if (k->is_pressed()) {
|
||||
keys_pressed.insert(k->get_keycode());
|
||||
else
|
||||
} else {
|
||||
keys_pressed.erase(k->get_keycode());
|
||||
}
|
||||
}
|
||||
|
||||
Ref<InputEventMouseButton> mb = p_event;
|
||||
|
||||
if (mb.is_valid()) {
|
||||
|
||||
if (mb->is_pressed()) {
|
||||
mouse_button_mask |= (1 << (mb->get_button_index() - 1));
|
||||
} else {
|
||||
@ -504,7 +484,6 @@ void Input::_parse_input_event_impl(const Ref<InputEvent> &p_event, bool p_is_em
|
||||
Ref<InputEventMouseMotion> mm = p_event;
|
||||
|
||||
if (mm.is_valid()) {
|
||||
|
||||
Point2 pos = mm->get_global_position();
|
||||
if (mouse_pos != pos) {
|
||||
set_mouse_position(pos);
|
||||
@ -525,7 +504,6 @@ void Input::_parse_input_event_impl(const Ref<InputEvent> &p_event, bool p_is_em
|
||||
Ref<InputEventScreenTouch> st = p_event;
|
||||
|
||||
if (st.is_valid()) {
|
||||
|
||||
if (st->is_pressed()) {
|
||||
SpeedTrack &track = touch_speed_track[st->get_index()];
|
||||
track.reset();
|
||||
@ -536,7 +514,6 @@ void Input::_parse_input_event_impl(const Ref<InputEvent> &p_event, bool p_is_em
|
||||
}
|
||||
|
||||
if (emulate_mouse_from_touch) {
|
||||
|
||||
bool translate = false;
|
||||
if (st->is_pressed()) {
|
||||
if (mouse_from_touch_index == -1) {
|
||||
@ -573,13 +550,11 @@ void Input::_parse_input_event_impl(const Ref<InputEvent> &p_event, bool p_is_em
|
||||
Ref<InputEventScreenDrag> sd = p_event;
|
||||
|
||||
if (sd.is_valid()) {
|
||||
|
||||
SpeedTrack &track = touch_speed_track[sd->get_index()];
|
||||
track.update(sd->get_relative());
|
||||
sd->set_speed(track.speed);
|
||||
|
||||
if (emulate_mouse_from_touch && sd->get_index() == mouse_from_touch_index) {
|
||||
|
||||
Ref<InputEventMouseMotion> motion_event;
|
||||
motion_event.instance();
|
||||
|
||||
@ -597,14 +572,14 @@ void Input::_parse_input_event_impl(const Ref<InputEvent> &p_event, bool p_is_em
|
||||
Ref<InputEventJoypadButton> jb = p_event;
|
||||
|
||||
if (jb.is_valid()) {
|
||||
|
||||
int c = _combine_device(jb->get_button_index(), jb->get_device());
|
||||
|
||||
if (jb->is_pressed())
|
||||
if (jb->is_pressed()) {
|
||||
joy_buttons_pressed.insert(c);
|
||||
else
|
||||
} else {
|
||||
joy_buttons_pressed.erase(c);
|
||||
}
|
||||
}
|
||||
|
||||
Ref<InputEventJoypadMotion> jm = p_event;
|
||||
|
||||
@ -615,7 +590,6 @@ void Input::_parse_input_event_impl(const Ref<InputEvent> &p_event, bool p_is_em
|
||||
Ref<InputEventGesture> ge = p_event;
|
||||
|
||||
if (ge.is_valid()) {
|
||||
|
||||
if (event_dispatch_function) {
|
||||
event_dispatch_function(ge);
|
||||
}
|
||||
@ -623,7 +597,6 @@ void Input::_parse_input_event_impl(const Ref<InputEvent> &p_event, bool p_is_em
|
||||
|
||||
for (const Map<StringName, InputMap::Action>::Element *E = InputMap::get_singleton()->get_action_map().front(); E; E = E->next()) {
|
||||
if (InputMap::get_singleton()->event_is_action(p_event, E->key())) {
|
||||
|
||||
// Save the action's state
|
||||
if (!p_event->is_echo() && is_action_pressed(E->key()) != p_event->is_action_pressed(E->key())) {
|
||||
Action action;
|
||||
@ -637,12 +610,12 @@ void Input::_parse_input_event_impl(const Ref<InputEvent> &p_event, bool p_is_em
|
||||
}
|
||||
}
|
||||
|
||||
if (event_dispatch_function)
|
||||
if (event_dispatch_function) {
|
||||
event_dispatch_function(p_event);
|
||||
}
|
||||
}
|
||||
|
||||
void Input::set_joy_axis(int p_device, int p_axis, float p_value) {
|
||||
|
||||
_THREAD_SAFE_METHOD_
|
||||
int c = _combine_device(p_axis, p_device);
|
||||
_joy_axis[c] = p_value;
|
||||
@ -676,50 +649,43 @@ void Input::vibrate_handheld(int p_duration_ms) {
|
||||
}
|
||||
|
||||
void Input::set_gravity(const Vector3 &p_gravity) {
|
||||
|
||||
_THREAD_SAFE_METHOD_
|
||||
|
||||
gravity = p_gravity;
|
||||
}
|
||||
|
||||
void Input::set_accelerometer(const Vector3 &p_accel) {
|
||||
|
||||
_THREAD_SAFE_METHOD_
|
||||
|
||||
accelerometer = p_accel;
|
||||
}
|
||||
|
||||
void Input::set_magnetometer(const Vector3 &p_magnetometer) {
|
||||
|
||||
_THREAD_SAFE_METHOD_
|
||||
|
||||
magnetometer = p_magnetometer;
|
||||
}
|
||||
|
||||
void Input::set_gyroscope(const Vector3 &p_gyroscope) {
|
||||
|
||||
_THREAD_SAFE_METHOD_
|
||||
|
||||
gyroscope = p_gyroscope;
|
||||
}
|
||||
|
||||
void Input::set_mouse_position(const Point2 &p_posf) {
|
||||
|
||||
mouse_speed_track.update(p_posf - mouse_pos);
|
||||
mouse_pos = p_posf;
|
||||
}
|
||||
|
||||
Point2 Input::get_mouse_position() const {
|
||||
|
||||
return mouse_pos;
|
||||
}
|
||||
Point2 Input::get_last_mouse_speed() const {
|
||||
|
||||
Point2 Input::get_last_mouse_speed() const {
|
||||
return mouse_speed_track.speed;
|
||||
}
|
||||
|
||||
int Input::get_mouse_button_mask() const {
|
||||
|
||||
return mouse_button_mask; // do not trust OS implementation, should remove it - OS::get_singleton()->get_mouse_button_state();
|
||||
}
|
||||
|
||||
@ -728,7 +694,6 @@ void Input::warp_mouse_position(const Vector2 &p_to) {
|
||||
}
|
||||
|
||||
Point2i Input::warp_mouse_motion(const Ref<InputEventMouseMotion> &p_motion, const Rect2 &p_rect) {
|
||||
|
||||
// The relative distance reported for the next event after a warp is in the boundaries of the
|
||||
// size of the rect on that axis, but it may be greater, in which case there's not problem as fmod()
|
||||
// will warp it, but if the pointer has moved in the opposite direction between the pointer relocation
|
||||
@ -757,7 +722,6 @@ void Input::iteration(float p_step) {
|
||||
}
|
||||
|
||||
void Input::action_press(const StringName &p_action, float p_strength) {
|
||||
|
||||
Action action;
|
||||
|
||||
action.physics_frame = Engine::get_singleton()->get_physics_frames();
|
||||
@ -769,7 +733,6 @@ void Input::action_press(const StringName &p_action, float p_strength) {
|
||||
}
|
||||
|
||||
void Input::action_release(const StringName &p_action) {
|
||||
|
||||
Action action;
|
||||
|
||||
action.physics_frame = Engine::get_singleton()->get_physics_frames();
|
||||
@ -781,19 +744,16 @@ void Input::action_release(const StringName &p_action) {
|
||||
}
|
||||
|
||||
void Input::set_emulate_touch_from_mouse(bool p_emulate) {
|
||||
|
||||
emulate_touch_from_mouse = p_emulate;
|
||||
}
|
||||
|
||||
bool Input::is_emulating_touch_from_mouse() const {
|
||||
|
||||
return emulate_touch_from_mouse;
|
||||
}
|
||||
|
||||
// Calling this whenever the game window is focused helps unstucking the "touch mouse"
|
||||
// if the OS or its abstraction class hasn't properly reported that touch pointers raised
|
||||
void Input::ensure_touch_mouse_raised() {
|
||||
|
||||
if (mouse_from_touch_index != -1) {
|
||||
mouse_from_touch_index = -1;
|
||||
|
||||
@ -812,24 +772,21 @@ void Input::ensure_touch_mouse_raised() {
|
||||
}
|
||||
|
||||
void Input::set_emulate_mouse_from_touch(bool p_emulate) {
|
||||
|
||||
emulate_mouse_from_touch = p_emulate;
|
||||
}
|
||||
|
||||
bool Input::is_emulating_mouse_from_touch() const {
|
||||
|
||||
return emulate_mouse_from_touch;
|
||||
}
|
||||
|
||||
Input::CursorShape Input::get_default_cursor_shape() const {
|
||||
|
||||
return default_shape;
|
||||
}
|
||||
|
||||
void Input::set_default_cursor_shape(CursorShape p_shape) {
|
||||
|
||||
if (default_shape == p_shape)
|
||||
if (default_shape == p_shape) {
|
||||
return;
|
||||
}
|
||||
|
||||
default_shape = p_shape;
|
||||
// The default shape is set in Viewport::_gui_input_event. To instantly
|
||||
@ -842,13 +799,13 @@ void Input::set_default_cursor_shape(CursorShape p_shape) {
|
||||
}
|
||||
|
||||
Input::CursorShape Input::get_current_cursor_shape() const {
|
||||
|
||||
return get_current_cursor_shape_func();
|
||||
}
|
||||
|
||||
void Input::set_custom_mouse_cursor(const RES &p_cursor, CursorShape p_shape, const Vector2 &p_hotspot) {
|
||||
if (Engine::get_singleton()->is_editor_hint())
|
||||
if (Engine::get_singleton()->is_editor_hint()) {
|
||||
return;
|
||||
}
|
||||
|
||||
set_custom_mouse_cursor_func(p_cursor, p_shape, p_hotspot);
|
||||
}
|
||||
@ -866,8 +823,8 @@ void Input::accumulate_input_event(const Ref<InputEvent> &p_event) {
|
||||
|
||||
accumulated_events.push_back(p_event);
|
||||
}
|
||||
void Input::flush_accumulated_events() {
|
||||
|
||||
void Input::flush_accumulated_events() {
|
||||
while (accumulated_events.front()) {
|
||||
parse_input_event(accumulated_events.front()->get());
|
||||
accumulated_events.pop_front();
|
||||
@ -875,12 +832,10 @@ void Input::flush_accumulated_events() {
|
||||
}
|
||||
|
||||
void Input::set_use_accumulated_input(bool p_enable) {
|
||||
|
||||
use_accumulated_input = p_enable;
|
||||
}
|
||||
|
||||
void Input::release_pressed_events() {
|
||||
|
||||
flush_accumulated_events(); // this is needed to release actions strengths
|
||||
|
||||
keys_pressed.clear();
|
||||
@ -888,17 +843,17 @@ void Input::release_pressed_events() {
|
||||
_joy_axis.clear();
|
||||
|
||||
for (Map<StringName, Input::Action>::Element *E = action_state.front(); E; E = E->next()) {
|
||||
if (E->get().pressed)
|
||||
if (E->get().pressed) {
|
||||
action_release(E->key());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void Input::set_event_dispatch_function(EventDispatchFunc p_function) {
|
||||
event_dispatch_function = p_function;
|
||||
}
|
||||
|
||||
void Input::joy_button(int p_device, int p_button, bool p_pressed) {
|
||||
|
||||
_THREAD_SAFE_METHOD_;
|
||||
Joypad &joy = joy_names[p_device];
|
||||
//printf("got button %i, mapping is %i\n", p_button, joy.mapping);
|
||||
@ -925,7 +880,6 @@ void Input::joy_button(int p_device, int p_button, bool p_pressed) {
|
||||
}
|
||||
|
||||
void Input::joy_axis(int p_device, int p_axis, const JoyAxis &p_value) {
|
||||
|
||||
_THREAD_SAFE_METHOD_;
|
||||
|
||||
ERR_FAIL_INDEX(p_axis, JOY_AXIS_MAX);
|
||||
@ -937,13 +891,10 @@ void Input::joy_axis(int p_device, int p_axis, const JoyAxis &p_value) {
|
||||
}
|
||||
|
||||
if (p_value.value > joy.last_axis[p_axis]) {
|
||||
|
||||
if (p_value.value < joy.last_axis[p_axis] + joy.filter) {
|
||||
|
||||
return;
|
||||
}
|
||||
} else if (p_value.value > joy.last_axis[p_axis] - joy.filter) {
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
@ -972,7 +923,6 @@ void Input::joy_axis(int p_device, int p_axis, const JoyAxis &p_value) {
|
||||
JoyEvent map = _get_mapped_axis_event(map_db[joy.mapping], p_axis, p_value);
|
||||
|
||||
if (map.type == TYPE_BUTTON) {
|
||||
|
||||
if (map.index == JOY_BUTTON_DPAD_UP || map.index == JOY_BUTTON_DPAD_DOWN) {
|
||||
bool pressed = p_value.value != 0.0f;
|
||||
int button = p_value.value < 0 ? JOY_BUTTON_DPAD_UP : JOY_BUTTON_DPAD_DOWN;
|
||||
@ -1023,7 +973,6 @@ void Input::joy_axis(int p_device, int p_axis, const JoyAxis &p_value) {
|
||||
}
|
||||
|
||||
if (map.type == TYPE_AXIS) {
|
||||
|
||||
_axis_event(p_device, map.index, map.value);
|
||||
return;
|
||||
}
|
||||
@ -1031,7 +980,6 @@ void Input::joy_axis(int p_device, int p_axis, const JoyAxis &p_value) {
|
||||
}
|
||||
|
||||
void Input::joy_hat(int p_device, int p_val) {
|
||||
|
||||
_THREAD_SAFE_METHOD_;
|
||||
const Joypad &joy = joy_names[p_device];
|
||||
|
||||
@ -1077,7 +1025,6 @@ void Input::joy_hat(int p_device, int p_val) {
|
||||
}
|
||||
|
||||
void Input::_button_event(int p_device, int p_index, bool p_pressed) {
|
||||
|
||||
Ref<InputEventJoypadButton> ievent;
|
||||
ievent.instance();
|
||||
ievent->set_device(p_device);
|
||||
@ -1088,7 +1035,6 @@ void Input::_button_event(int p_device, int p_index, bool p_pressed) {
|
||||
}
|
||||
|
||||
void Input::_axis_event(int p_device, int p_axis, float p_value) {
|
||||
|
||||
Ref<InputEventJoypadMotion> ievent;
|
||||
ievent.instance();
|
||||
ievent->set_device(p_device);
|
||||
@ -1099,7 +1045,6 @@ void Input::_axis_event(int p_device, int p_axis, float p_value) {
|
||||
};
|
||||
|
||||
Input::JoyEvent Input::_get_mapped_button_event(const JoyDeviceMapping &mapping, int p_button) {
|
||||
|
||||
JoyEvent event;
|
||||
event.type = TYPE_MAX;
|
||||
|
||||
@ -1123,7 +1068,6 @@ Input::JoyEvent Input::_get_mapped_button_event(const JoyDeviceMapping &mapping,
|
||||
}
|
||||
|
||||
Input::JoyEvent Input::_get_mapped_axis_event(const JoyDeviceMapping &mapping, int p_axis, const JoyAxis &p_value) {
|
||||
|
||||
JoyEvent event;
|
||||
event.type = TYPE_MAX;
|
||||
|
||||
@ -1131,8 +1075,9 @@ Input::JoyEvent Input::_get_mapped_axis_event(const JoyDeviceMapping &mapping, i
|
||||
const JoyBinding binding = mapping.bindings[i];
|
||||
if (binding.inputType == TYPE_AXIS && binding.input.axis.axis == p_axis) {
|
||||
float value = p_value.value;
|
||||
if (binding.input.axis.invert)
|
||||
if (binding.input.axis.invert) {
|
||||
value = -value;
|
||||
}
|
||||
if (binding.input.axis.range == FULL_AXIS ||
|
||||
(binding.input.axis.range == POSITIVE_HALF_AXIS && value > 0) ||
|
||||
(binding.input.axis.range == NEGATIVE_HALF_AXIS && value < 0)) {
|
||||
@ -1180,11 +1125,9 @@ Input::JoyEvent Input::_get_mapped_axis_event(const JoyDeviceMapping &mapping, i
|
||||
}
|
||||
|
||||
void Input::_get_mapped_hat_events(const JoyDeviceMapping &mapping, int p_hat, JoyEvent r_events[]) {
|
||||
|
||||
for (int i = 0; i < mapping.bindings.size(); i++) {
|
||||
const JoyBinding binding = mapping.bindings[i];
|
||||
if (binding.inputType == TYPE_HAT && binding.input.hat.hat == p_hat) {
|
||||
|
||||
int index;
|
||||
switch (binding.input.hat.hat_mask) {
|
||||
case HAT_MASK_UP:
|
||||
@ -1220,25 +1163,24 @@ void Input::_get_mapped_hat_events(const JoyDeviceMapping &mapping, int p_hat, J
|
||||
}
|
||||
|
||||
JoyButtonList Input::_get_output_button(String output) {
|
||||
|
||||
for (int i = 0; _joy_buttons[i]; i++) {
|
||||
if (output == _joy_buttons[i])
|
||||
if (output == _joy_buttons[i]) {
|
||||
return JoyButtonList(i);
|
||||
}
|
||||
}
|
||||
return JoyButtonList::JOY_INVALID_BUTTON;
|
||||
}
|
||||
|
||||
JoyAxisList Input::_get_output_axis(String output) {
|
||||
|
||||
for (int i = 0; _joy_axes[i]; i++) {
|
||||
if (output == _joy_axes[i])
|
||||
if (output == _joy_axes[i]) {
|
||||
return JoyAxisList(i);
|
||||
}
|
||||
}
|
||||
return JoyAxisList::JOY_INVALID_AXIS;
|
||||
}
|
||||
|
||||
void Input::parse_mapping(String p_mapping) {
|
||||
|
||||
_THREAD_SAFE_METHOD_;
|
||||
JoyDeviceMapping mapping;
|
||||
|
||||
@ -1255,27 +1197,29 @@ void Input::parse_mapping(String p_mapping) {
|
||||
|
||||
int idx = 1;
|
||||
while (++idx < entry.size()) {
|
||||
|
||||
if (entry[idx] == "")
|
||||
if (entry[idx] == "") {
|
||||
continue;
|
||||
}
|
||||
|
||||
String output = entry[idx].get_slice(":", 0).replace(" ", "");
|
||||
String input = entry[idx].get_slice(":", 1).replace(" ", "");
|
||||
ERR_CONTINUE_MSG(output.length() < 1 || input.length() < 2,
|
||||
String(entry[idx] + "\nInvalid device mapping entry: " + entry[idx]));
|
||||
|
||||
if (output == "platform")
|
||||
if (output == "platform") {
|
||||
continue;
|
||||
}
|
||||
|
||||
JoyAxisRange output_range = FULL_AXIS;
|
||||
if (output[0] == '+' || output[0] == '-') {
|
||||
ERR_CONTINUE_MSG(output.length() < 2, String(entry[idx] + "\nInvalid output: " + entry[idx]));
|
||||
output = output.right(1);
|
||||
if (output[0] == '+')
|
||||
if (output[0] == '+') {
|
||||
output_range = POSITIVE_HALF_AXIS;
|
||||
else if (output[0] == '-')
|
||||
} else if (output[0] == '-') {
|
||||
output_range = NEGATIVE_HALF_AXIS;
|
||||
}
|
||||
}
|
||||
|
||||
JoyAxisRange input_range = FULL_AXIS;
|
||||
if (input[0] == '+') {
|
||||
@ -1286,8 +1230,9 @@ void Input::parse_mapping(String p_mapping) {
|
||||
input = input.right(1);
|
||||
}
|
||||
bool invert_axis = false;
|
||||
if (input[input.length() - 1] == '~')
|
||||
if (input[input.length() - 1] == '~') {
|
||||
invert_axis = true;
|
||||
}
|
||||
|
||||
JoyButtonList output_button = _get_output_button(output);
|
||||
JoyAxisList output_axis = _get_output_axis(output);
|
||||
@ -1361,7 +1306,6 @@ void Input::remove_joy_mapping(String p_guid) {
|
||||
}
|
||||
|
||||
void Input::set_fallback_mapping(String p_guid) {
|
||||
|
||||
for (int i = 0; i < map_db.size(); i++) {
|
||||
if (map_db[i].uid == p_guid) {
|
||||
fallback_mapping = i;
|
||||
@ -1431,7 +1375,6 @@ int Input::get_joy_axis_index_from_string(String p_axis) {
|
||||
}
|
||||
|
||||
Input::Input() {
|
||||
|
||||
singleton = this;
|
||||
|
||||
// Parse default mappings.
|
||||
@ -1447,8 +1390,9 @@ Input::Input() {
|
||||
if (env_mapping != "") {
|
||||
Vector<String> entries = env_mapping.split("\n");
|
||||
for (int i = 0; i < entries.size(); i++) {
|
||||
if (entries[i] == "")
|
||||
if (entries[i] == "") {
|
||||
continue;
|
||||
}
|
||||
parse_mapping(entries[i]);
|
||||
}
|
||||
}
|
||||
|
@ -128,7 +128,6 @@ private:
|
||||
int mouse_from_touch_index = -1;
|
||||
|
||||
struct SpeedTrack {
|
||||
|
||||
uint64_t last_tick;
|
||||
Vector2 speed;
|
||||
Vector2 accum;
|
||||
|
@ -45,26 +45,22 @@ int InputEvent::get_device() const {
|
||||
}
|
||||
|
||||
bool InputEvent::is_action(const StringName &p_action) const {
|
||||
|
||||
return InputMap::get_singleton()->event_is_action(Ref<InputEvent>((InputEvent *)this), p_action);
|
||||
}
|
||||
|
||||
bool InputEvent::is_action_pressed(const StringName &p_action, bool p_allow_echo) const {
|
||||
|
||||
bool pressed;
|
||||
bool valid = InputMap::get_singleton()->event_get_action_status(Ref<InputEvent>((InputEvent *)this), p_action, &pressed);
|
||||
return valid && pressed && (p_allow_echo || !is_echo());
|
||||
}
|
||||
|
||||
bool InputEvent::is_action_released(const StringName &p_action) const {
|
||||
|
||||
bool pressed;
|
||||
bool valid = InputMap::get_singleton()->event_get_action_status(Ref<InputEvent>((InputEvent *)this), p_action, &pressed);
|
||||
return valid && !pressed;
|
||||
}
|
||||
|
||||
float InputEvent::get_action_strength(const StringName &p_action) const {
|
||||
|
||||
bool pressed;
|
||||
float strength;
|
||||
bool valid = InputMap::get_singleton()->event_get_action_status(Ref<InputEvent>((InputEvent *)this), p_action, &pressed, &strength);
|
||||
@ -72,42 +68,34 @@ float InputEvent::get_action_strength(const StringName &p_action) const {
|
||||
}
|
||||
|
||||
bool InputEvent::is_pressed() const {
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
bool InputEvent::is_echo() const {
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
Ref<InputEvent> InputEvent::xformed_by(const Transform2D &p_xform, const Vector2 &p_local_ofs) const {
|
||||
|
||||
return Ref<InputEvent>((InputEvent *)this);
|
||||
}
|
||||
|
||||
String InputEvent::as_text() const {
|
||||
|
||||
return String();
|
||||
}
|
||||
|
||||
bool InputEvent::action_match(const Ref<InputEvent> &p_event, bool *p_pressed, float *p_strength, float p_deadzone) const {
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
bool InputEvent::shortcut_match(const Ref<InputEvent> &p_event) const {
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
bool InputEvent::is_action_type() const {
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
void InputEvent::_bind_methods() {
|
||||
|
||||
ClassDB::bind_method(D_METHOD("set_device", "device"), &InputEvent::set_device);
|
||||
ClassDB::bind_method(D_METHOD("get_device"), &InputEvent::get_device);
|
||||
|
||||
@ -135,7 +123,6 @@ void InputEvent::_bind_methods() {
|
||||
///////////////////////////////////
|
||||
|
||||
void InputEventFromWindow::_bind_methods() {
|
||||
|
||||
ClassDB::bind_method(D_METHOD("set_window_id", "id"), &InputEventFromWindow::set_window_id);
|
||||
ClassDB::bind_method(D_METHOD("get_window_id"), &InputEventFromWindow::get_window_id);
|
||||
ADD_PROPERTY(PropertyInfo(Variant::INT, "window_id"), "set_window_id", "get_window_id");
|
||||
@ -144,6 +131,7 @@ void InputEventFromWindow::_bind_methods() {
|
||||
void InputEventFromWindow::set_window_id(int64_t p_id) {
|
||||
window_id = p_id;
|
||||
}
|
||||
|
||||
int64_t InputEventFromWindow::get_window_id() const {
|
||||
return window_id;
|
||||
}
|
||||
@ -151,53 +139,46 @@ int64_t InputEventFromWindow::get_window_id() const {
|
||||
///////////////////////////////////
|
||||
|
||||
void InputEventWithModifiers::set_shift(bool p_enabled) {
|
||||
|
||||
shift = p_enabled;
|
||||
}
|
||||
|
||||
bool InputEventWithModifiers::get_shift() const {
|
||||
|
||||
return shift;
|
||||
}
|
||||
|
||||
void InputEventWithModifiers::set_alt(bool p_enabled) {
|
||||
|
||||
alt = p_enabled;
|
||||
}
|
||||
bool InputEventWithModifiers::get_alt() const {
|
||||
|
||||
bool InputEventWithModifiers::get_alt() const {
|
||||
return alt;
|
||||
}
|
||||
|
||||
void InputEventWithModifiers::set_control(bool p_enabled) {
|
||||
|
||||
control = p_enabled;
|
||||
}
|
||||
bool InputEventWithModifiers::get_control() const {
|
||||
|
||||
bool InputEventWithModifiers::get_control() const {
|
||||
return control;
|
||||
}
|
||||
|
||||
void InputEventWithModifiers::set_metakey(bool p_enabled) {
|
||||
|
||||
meta = p_enabled;
|
||||
}
|
||||
bool InputEventWithModifiers::get_metakey() const {
|
||||
|
||||
bool InputEventWithModifiers::get_metakey() const {
|
||||
return meta;
|
||||
}
|
||||
|
||||
void InputEventWithModifiers::set_command(bool p_enabled) {
|
||||
|
||||
command = p_enabled;
|
||||
}
|
||||
bool InputEventWithModifiers::get_command() const {
|
||||
|
||||
bool InputEventWithModifiers::get_command() const {
|
||||
return command;
|
||||
}
|
||||
|
||||
void InputEventWithModifiers::set_modifiers_from_event(const InputEventWithModifiers *event) {
|
||||
|
||||
set_alt(event->get_alt());
|
||||
set_shift(event->get_shift());
|
||||
set_control(event->get_control());
|
||||
@ -205,7 +186,6 @@ void InputEventWithModifiers::set_modifiers_from_event(const InputEventWithModif
|
||||
}
|
||||
|
||||
void InputEventWithModifiers::_bind_methods() {
|
||||
|
||||
ClassDB::bind_method(D_METHOD("set_alt", "enable"), &InputEventWithModifiers::set_alt);
|
||||
ClassDB::bind_method(D_METHOD("get_alt"), &InputEventWithModifiers::get_alt);
|
||||
|
||||
@ -231,90 +211,86 @@ void InputEventWithModifiers::_bind_methods() {
|
||||
///////////////////////////////////
|
||||
|
||||
void InputEventKey::set_pressed(bool p_pressed) {
|
||||
|
||||
pressed = p_pressed;
|
||||
}
|
||||
|
||||
bool InputEventKey::is_pressed() const {
|
||||
|
||||
return pressed;
|
||||
}
|
||||
|
||||
void InputEventKey::set_keycode(uint32_t p_keycode) {
|
||||
|
||||
keycode = p_keycode;
|
||||
}
|
||||
|
||||
uint32_t InputEventKey::get_keycode() const {
|
||||
|
||||
return keycode;
|
||||
}
|
||||
|
||||
void InputEventKey::set_physical_keycode(uint32_t p_keycode) {
|
||||
|
||||
physical_keycode = p_keycode;
|
||||
}
|
||||
|
||||
uint32_t InputEventKey::get_physical_keycode() const {
|
||||
|
||||
return physical_keycode;
|
||||
}
|
||||
|
||||
void InputEventKey::set_unicode(uint32_t p_unicode) {
|
||||
|
||||
unicode = p_unicode;
|
||||
}
|
||||
|
||||
uint32_t InputEventKey::get_unicode() const {
|
||||
|
||||
return unicode;
|
||||
}
|
||||
|
||||
void InputEventKey::set_echo(bool p_enable) {
|
||||
|
||||
echo = p_enable;
|
||||
}
|
||||
|
||||
bool InputEventKey::is_echo() const {
|
||||
|
||||
return echo;
|
||||
}
|
||||
|
||||
uint32_t InputEventKey::get_keycode_with_modifiers() const {
|
||||
|
||||
uint32_t sc = keycode;
|
||||
if (get_control())
|
||||
if (get_control()) {
|
||||
sc |= KEY_MASK_CTRL;
|
||||
if (get_alt())
|
||||
}
|
||||
if (get_alt()) {
|
||||
sc |= KEY_MASK_ALT;
|
||||
if (get_shift())
|
||||
}
|
||||
if (get_shift()) {
|
||||
sc |= KEY_MASK_SHIFT;
|
||||
if (get_metakey())
|
||||
}
|
||||
if (get_metakey()) {
|
||||
sc |= KEY_MASK_META;
|
||||
}
|
||||
|
||||
return sc;
|
||||
}
|
||||
|
||||
uint32_t InputEventKey::get_physical_keycode_with_modifiers() const {
|
||||
|
||||
uint32_t sc = physical_keycode;
|
||||
if (get_control())
|
||||
if (get_control()) {
|
||||
sc |= KEY_MASK_CTRL;
|
||||
if (get_alt())
|
||||
}
|
||||
if (get_alt()) {
|
||||
sc |= KEY_MASK_ALT;
|
||||
if (get_shift())
|
||||
}
|
||||
if (get_shift()) {
|
||||
sc |= KEY_MASK_SHIFT;
|
||||
if (get_metakey())
|
||||
}
|
||||
if (get_metakey()) {
|
||||
sc |= KEY_MASK_META;
|
||||
}
|
||||
|
||||
return sc;
|
||||
}
|
||||
|
||||
String InputEventKey::as_text() const {
|
||||
|
||||
String kc = keycode_get_string(keycode);
|
||||
if (kc == String())
|
||||
if (kc == String()) {
|
||||
return kc;
|
||||
}
|
||||
|
||||
if (get_metakey()) {
|
||||
kc = find_keycode_name(KEY_META) + ("+" + kc);
|
||||
@ -332,10 +308,10 @@ String InputEventKey::as_text() const {
|
||||
}
|
||||
|
||||
bool InputEventKey::action_match(const Ref<InputEvent> &p_event, bool *p_pressed, float *p_strength, float p_deadzone) const {
|
||||
|
||||
Ref<InputEventKey> key = p_event;
|
||||
if (key.is_null())
|
||||
if (key.is_null()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
bool match = false;
|
||||
if (get_keycode() == 0) {
|
||||
@ -350,19 +326,21 @@ bool InputEventKey::action_match(const Ref<InputEvent> &p_event, bool *p_pressed
|
||||
match = get_keycode() == key->get_keycode() && (!key->is_pressed() || (code & event_code) == code);
|
||||
}
|
||||
if (match) {
|
||||
if (p_pressed != nullptr)
|
||||
if (p_pressed != nullptr) {
|
||||
*p_pressed = key->is_pressed();
|
||||
if (p_strength != nullptr)
|
||||
}
|
||||
if (p_strength != nullptr) {
|
||||
*p_strength = (p_pressed != nullptr && *p_pressed) ? 1.0f : 0.0f;
|
||||
}
|
||||
}
|
||||
return match;
|
||||
}
|
||||
|
||||
bool InputEventKey::shortcut_match(const Ref<InputEvent> &p_event) const {
|
||||
|
||||
Ref<InputEventKey> key = p_event;
|
||||
if (key.is_null())
|
||||
if (key.is_null()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
uint32_t code = get_keycode_with_modifiers();
|
||||
uint32_t event_code = key->get_keycode_with_modifiers();
|
||||
@ -371,7 +349,6 @@ bool InputEventKey::shortcut_match(const Ref<InputEvent> &p_event) const {
|
||||
}
|
||||
|
||||
void InputEventKey::_bind_methods() {
|
||||
|
||||
ClassDB::bind_method(D_METHOD("set_pressed", "pressed"), &InputEventKey::set_pressed);
|
||||
|
||||
ClassDB::bind_method(D_METHOD("set_keycode", "keycode"), &InputEventKey::set_keycode);
|
||||
@ -398,34 +375,30 @@ void InputEventKey::_bind_methods() {
|
||||
///////////////////////////////////
|
||||
|
||||
void InputEventMouse::set_button_mask(int p_mask) {
|
||||
|
||||
button_mask = p_mask;
|
||||
}
|
||||
int InputEventMouse::get_button_mask() const {
|
||||
|
||||
int InputEventMouse::get_button_mask() const {
|
||||
return button_mask;
|
||||
}
|
||||
|
||||
void InputEventMouse::set_position(const Vector2 &p_pos) {
|
||||
|
||||
pos = p_pos;
|
||||
}
|
||||
Vector2 InputEventMouse::get_position() const {
|
||||
|
||||
Vector2 InputEventMouse::get_position() const {
|
||||
return pos;
|
||||
}
|
||||
|
||||
void InputEventMouse::set_global_position(const Vector2 &p_global_pos) {
|
||||
|
||||
global_pos = p_global_pos;
|
||||
}
|
||||
Vector2 InputEventMouse::get_global_position() const {
|
||||
|
||||
Vector2 InputEventMouse::get_global_position() const {
|
||||
return global_pos;
|
||||
}
|
||||
|
||||
void InputEventMouse::_bind_methods() {
|
||||
|
||||
ClassDB::bind_method(D_METHOD("set_button_mask", "button_mask"), &InputEventMouse::set_button_mask);
|
||||
ClassDB::bind_method(D_METHOD("get_button_mask"), &InputEventMouse::get_button_mask);
|
||||
|
||||
@ -443,44 +416,38 @@ void InputEventMouse::_bind_methods() {
|
||||
///////////////////////////////////
|
||||
|
||||
void InputEventMouseButton::set_factor(float p_factor) {
|
||||
|
||||
factor = p_factor;
|
||||
}
|
||||
|
||||
float InputEventMouseButton::get_factor() const {
|
||||
|
||||
return factor;
|
||||
}
|
||||
|
||||
void InputEventMouseButton::set_button_index(int p_index) {
|
||||
|
||||
button_index = p_index;
|
||||
}
|
||||
int InputEventMouseButton::get_button_index() const {
|
||||
|
||||
int InputEventMouseButton::get_button_index() const {
|
||||
return button_index;
|
||||
}
|
||||
|
||||
void InputEventMouseButton::set_pressed(bool p_pressed) {
|
||||
|
||||
pressed = p_pressed;
|
||||
}
|
||||
bool InputEventMouseButton::is_pressed() const {
|
||||
|
||||
bool InputEventMouseButton::is_pressed() const {
|
||||
return pressed;
|
||||
}
|
||||
|
||||
void InputEventMouseButton::set_doubleclick(bool p_doubleclick) {
|
||||
|
||||
doubleclick = p_doubleclick;
|
||||
}
|
||||
bool InputEventMouseButton::is_doubleclick() const {
|
||||
|
||||
bool InputEventMouseButton::is_doubleclick() const {
|
||||
return doubleclick;
|
||||
}
|
||||
|
||||
Ref<InputEvent> InputEventMouseButton::xformed_by(const Transform2D &p_xform, const Vector2 &p_local_ofs) const {
|
||||
|
||||
Vector2 g = get_global_position();
|
||||
Vector2 l = p_xform.xform(get_position() + p_local_ofs);
|
||||
|
||||
@ -504,24 +471,25 @@ Ref<InputEvent> InputEventMouseButton::xformed_by(const Transform2D &p_xform, co
|
||||
}
|
||||
|
||||
bool InputEventMouseButton::action_match(const Ref<InputEvent> &p_event, bool *p_pressed, float *p_strength, float p_deadzone) const {
|
||||
|
||||
Ref<InputEventMouseButton> mb = p_event;
|
||||
if (mb.is_null())
|
||||
if (mb.is_null()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
bool match = mb->button_index == button_index;
|
||||
if (match) {
|
||||
if (p_pressed != nullptr)
|
||||
if (p_pressed != nullptr) {
|
||||
*p_pressed = mb->is_pressed();
|
||||
if (p_strength != nullptr)
|
||||
}
|
||||
if (p_strength != nullptr) {
|
||||
*p_strength = (p_pressed != nullptr && *p_pressed) ? 1.0f : 0.0f;
|
||||
}
|
||||
}
|
||||
|
||||
return match;
|
||||
}
|
||||
|
||||
String InputEventMouseButton::as_text() const {
|
||||
|
||||
String button_index_string = "";
|
||||
switch (get_button_index()) {
|
||||
case BUTTON_LEFT:
|
||||
@ -559,7 +527,6 @@ String InputEventMouseButton::as_text() const {
|
||||
}
|
||||
|
||||
void InputEventMouseButton::_bind_methods() {
|
||||
|
||||
ClassDB::bind_method(D_METHOD("set_factor", "factor"), &InputEventMouseButton::set_factor);
|
||||
ClassDB::bind_method(D_METHOD("get_factor"), &InputEventMouseButton::get_factor);
|
||||
|
||||
@ -581,47 +548,38 @@ void InputEventMouseButton::_bind_methods() {
|
||||
///////////////////////////////////
|
||||
|
||||
void InputEventMouseMotion::set_tilt(const Vector2 &p_tilt) {
|
||||
|
||||
tilt = p_tilt;
|
||||
}
|
||||
|
||||
Vector2 InputEventMouseMotion::get_tilt() const {
|
||||
|
||||
return tilt;
|
||||
}
|
||||
|
||||
void InputEventMouseMotion::set_pressure(float p_pressure) {
|
||||
|
||||
pressure = p_pressure;
|
||||
}
|
||||
|
||||
float InputEventMouseMotion::get_pressure() const {
|
||||
|
||||
return pressure;
|
||||
}
|
||||
|
||||
void InputEventMouseMotion::set_relative(const Vector2 &p_relative) {
|
||||
|
||||
relative = p_relative;
|
||||
}
|
||||
|
||||
Vector2 InputEventMouseMotion::get_relative() const {
|
||||
|
||||
return relative;
|
||||
}
|
||||
|
||||
void InputEventMouseMotion::set_speed(const Vector2 &p_speed) {
|
||||
|
||||
speed = p_speed;
|
||||
}
|
||||
|
||||
Vector2 InputEventMouseMotion::get_speed() const {
|
||||
|
||||
return speed;
|
||||
}
|
||||
|
||||
Ref<InputEvent> InputEventMouseMotion::xformed_by(const Transform2D &p_xform, const Vector2 &p_local_ofs) const {
|
||||
|
||||
Vector2 g = get_global_position();
|
||||
Vector2 l = p_xform.xform(get_position() + p_local_ofs);
|
||||
Vector2 r = p_xform.basis_xform(get_relative());
|
||||
@ -648,7 +606,6 @@ Ref<InputEvent> InputEventMouseMotion::xformed_by(const Transform2D &p_xform, co
|
||||
}
|
||||
|
||||
String InputEventMouseMotion::as_text() const {
|
||||
|
||||
String button_mask_string = "";
|
||||
switch (get_button_mask()) {
|
||||
case BUTTON_MASK_LEFT:
|
||||
@ -674,10 +631,10 @@ String InputEventMouseMotion::as_text() const {
|
||||
}
|
||||
|
||||
bool InputEventMouseMotion::accumulate(const Ref<InputEvent> &p_event) {
|
||||
|
||||
Ref<InputEventMouseMotion> motion = p_event;
|
||||
if (motion.is_null())
|
||||
if (motion.is_null()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (get_window_id() != motion->get_window_id()) {
|
||||
return false;
|
||||
@ -716,7 +673,6 @@ bool InputEventMouseMotion::accumulate(const Ref<InputEvent> &p_event) {
|
||||
}
|
||||
|
||||
void InputEventMouseMotion::_bind_methods() {
|
||||
|
||||
ClassDB::bind_method(D_METHOD("set_tilt", "tilt"), &InputEventMouseMotion::set_tilt);
|
||||
ClassDB::bind_method(D_METHOD("get_tilt"), &InputEventMouseMotion::get_tilt);
|
||||
|
||||
@ -738,42 +694,38 @@ void InputEventMouseMotion::_bind_methods() {
|
||||
///////////////////////////////////
|
||||
|
||||
void InputEventJoypadMotion::set_axis(int p_axis) {
|
||||
|
||||
axis = p_axis;
|
||||
}
|
||||
|
||||
int InputEventJoypadMotion::get_axis() const {
|
||||
|
||||
return axis;
|
||||
}
|
||||
|
||||
void InputEventJoypadMotion::set_axis_value(float p_value) {
|
||||
|
||||
axis_value = p_value;
|
||||
}
|
||||
|
||||
float InputEventJoypadMotion::get_axis_value() const {
|
||||
|
||||
return axis_value;
|
||||
}
|
||||
|
||||
bool InputEventJoypadMotion::is_pressed() const {
|
||||
|
||||
return Math::abs(axis_value) >= 0.5f;
|
||||
}
|
||||
|
||||
bool InputEventJoypadMotion::action_match(const Ref<InputEvent> &p_event, bool *p_pressed, float *p_strength, float p_deadzone) const {
|
||||
|
||||
Ref<InputEventJoypadMotion> jm = p_event;
|
||||
if (jm.is_null())
|
||||
if (jm.is_null()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
bool match = (axis == jm->axis); // Matches even if not in the same direction, but returns a "not pressed" event.
|
||||
if (match) {
|
||||
bool same_direction = (((axis_value < 0) == (jm->axis_value < 0)) || jm->axis_value == 0);
|
||||
bool pressed = same_direction ? Math::abs(jm->get_axis_value()) >= p_deadzone : false;
|
||||
if (p_pressed != nullptr)
|
||||
if (p_pressed != nullptr) {
|
||||
*p_pressed = pressed;
|
||||
}
|
||||
if (p_strength != nullptr) {
|
||||
if (pressed) {
|
||||
if (p_deadzone == 1.0f) {
|
||||
@ -790,12 +742,10 @@ bool InputEventJoypadMotion::action_match(const Ref<InputEvent> &p_event, bool *
|
||||
}
|
||||
|
||||
String InputEventJoypadMotion::as_text() const {
|
||||
|
||||
return "InputEventJoypadMotion : axis=" + itos(axis) + ", axis_value=" + String(Variant(axis_value));
|
||||
}
|
||||
|
||||
void InputEventJoypadMotion::_bind_methods() {
|
||||
|
||||
ClassDB::bind_method(D_METHOD("set_axis", "axis"), &InputEventJoypadMotion::set_axis);
|
||||
ClassDB::bind_method(D_METHOD("get_axis"), &InputEventJoypadMotion::get_axis);
|
||||
|
||||
@ -809,66 +759,62 @@ void InputEventJoypadMotion::_bind_methods() {
|
||||
///////////////////////////////////
|
||||
|
||||
void InputEventJoypadButton::set_button_index(int p_index) {
|
||||
|
||||
button_index = p_index;
|
||||
}
|
||||
|
||||
int InputEventJoypadButton::get_button_index() const {
|
||||
|
||||
return button_index;
|
||||
}
|
||||
|
||||
void InputEventJoypadButton::set_pressed(bool p_pressed) {
|
||||
|
||||
pressed = p_pressed;
|
||||
}
|
||||
bool InputEventJoypadButton::is_pressed() const {
|
||||
|
||||
bool InputEventJoypadButton::is_pressed() const {
|
||||
return pressed;
|
||||
}
|
||||
|
||||
void InputEventJoypadButton::set_pressure(float p_pressure) {
|
||||
|
||||
pressure = p_pressure;
|
||||
}
|
||||
float InputEventJoypadButton::get_pressure() const {
|
||||
|
||||
float InputEventJoypadButton::get_pressure() const {
|
||||
return pressure;
|
||||
}
|
||||
|
||||
bool InputEventJoypadButton::action_match(const Ref<InputEvent> &p_event, bool *p_pressed, float *p_strength, float p_deadzone) const {
|
||||
|
||||
Ref<InputEventJoypadButton> jb = p_event;
|
||||
if (jb.is_null())
|
||||
if (jb.is_null()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
bool match = button_index == jb->button_index;
|
||||
if (match) {
|
||||
if (p_pressed != nullptr)
|
||||
if (p_pressed != nullptr) {
|
||||
*p_pressed = jb->is_pressed();
|
||||
if (p_strength != nullptr)
|
||||
}
|
||||
if (p_strength != nullptr) {
|
||||
*p_strength = (p_pressed != nullptr && *p_pressed) ? 1.0f : 0.0f;
|
||||
}
|
||||
}
|
||||
|
||||
return match;
|
||||
}
|
||||
|
||||
bool InputEventJoypadButton::shortcut_match(const Ref<InputEvent> &p_event) const {
|
||||
|
||||
Ref<InputEventJoypadButton> button = p_event;
|
||||
if (button.is_null())
|
||||
if (button.is_null()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return button_index == button->button_index;
|
||||
}
|
||||
|
||||
String InputEventJoypadButton::as_text() const {
|
||||
|
||||
return "InputEventJoypadButton : button_index=" + itos(button_index) + ", pressed=" + (pressed ? "true" : "false") + ", pressure=" + String(Variant(pressure));
|
||||
}
|
||||
|
||||
void InputEventJoypadButton::_bind_methods() {
|
||||
|
||||
ClassDB::bind_method(D_METHOD("set_button_index", "button_index"), &InputEventJoypadButton::set_button_index);
|
||||
ClassDB::bind_method(D_METHOD("get_button_index"), &InputEventJoypadButton::get_button_index);
|
||||
|
||||
@ -886,34 +832,30 @@ void InputEventJoypadButton::_bind_methods() {
|
||||
///////////////////////////////////
|
||||
|
||||
void InputEventScreenTouch::set_index(int p_index) {
|
||||
|
||||
index = p_index;
|
||||
}
|
||||
int InputEventScreenTouch::get_index() const {
|
||||
|
||||
int InputEventScreenTouch::get_index() const {
|
||||
return index;
|
||||
}
|
||||
|
||||
void InputEventScreenTouch::set_position(const Vector2 &p_pos) {
|
||||
|
||||
pos = p_pos;
|
||||
}
|
||||
Vector2 InputEventScreenTouch::get_position() const {
|
||||
|
||||
Vector2 InputEventScreenTouch::get_position() const {
|
||||
return pos;
|
||||
}
|
||||
|
||||
void InputEventScreenTouch::set_pressed(bool p_pressed) {
|
||||
|
||||
pressed = p_pressed;
|
||||
}
|
||||
bool InputEventScreenTouch::is_pressed() const {
|
||||
|
||||
bool InputEventScreenTouch::is_pressed() const {
|
||||
return pressed;
|
||||
}
|
||||
|
||||
Ref<InputEvent> InputEventScreenTouch::xformed_by(const Transform2D &p_xform, const Vector2 &p_local_ofs) const {
|
||||
|
||||
Ref<InputEventScreenTouch> st;
|
||||
st.instance();
|
||||
st->set_device(get_device());
|
||||
@ -926,12 +868,10 @@ Ref<InputEvent> InputEventScreenTouch::xformed_by(const Transform2D &p_xform, co
|
||||
}
|
||||
|
||||
String InputEventScreenTouch::as_text() const {
|
||||
|
||||
return "InputEventScreenTouch : index=" + itos(index) + ", pressed=" + (pressed ? "true" : "false") + ", position=(" + String(get_position()) + ")";
|
||||
}
|
||||
|
||||
void InputEventScreenTouch::_bind_methods() {
|
||||
|
||||
ClassDB::bind_method(D_METHOD("set_index", "index"), &InputEventScreenTouch::set_index);
|
||||
ClassDB::bind_method(D_METHOD("get_index"), &InputEventScreenTouch::get_index);
|
||||
|
||||
@ -949,44 +889,38 @@ void InputEventScreenTouch::_bind_methods() {
|
||||
///////////////////////////////////
|
||||
|
||||
void InputEventScreenDrag::set_index(int p_index) {
|
||||
|
||||
index = p_index;
|
||||
}
|
||||
|
||||
int InputEventScreenDrag::get_index() const {
|
||||
|
||||
return index;
|
||||
}
|
||||
|
||||
void InputEventScreenDrag::set_position(const Vector2 &p_pos) {
|
||||
|
||||
pos = p_pos;
|
||||
}
|
||||
Vector2 InputEventScreenDrag::get_position() const {
|
||||
|
||||
Vector2 InputEventScreenDrag::get_position() const {
|
||||
return pos;
|
||||
}
|
||||
|
||||
void InputEventScreenDrag::set_relative(const Vector2 &p_relative) {
|
||||
|
||||
relative = p_relative;
|
||||
}
|
||||
Vector2 InputEventScreenDrag::get_relative() const {
|
||||
|
||||
Vector2 InputEventScreenDrag::get_relative() const {
|
||||
return relative;
|
||||
}
|
||||
|
||||
void InputEventScreenDrag::set_speed(const Vector2 &p_speed) {
|
||||
|
||||
speed = p_speed;
|
||||
}
|
||||
Vector2 InputEventScreenDrag::get_speed() const {
|
||||
|
||||
Vector2 InputEventScreenDrag::get_speed() const {
|
||||
return speed;
|
||||
}
|
||||
|
||||
Ref<InputEvent> InputEventScreenDrag::xformed_by(const Transform2D &p_xform, const Vector2 &p_local_ofs) const {
|
||||
|
||||
Ref<InputEventScreenDrag> sd;
|
||||
|
||||
sd.instance();
|
||||
@ -1003,12 +937,10 @@ Ref<InputEvent> InputEventScreenDrag::xformed_by(const Transform2D &p_xform, con
|
||||
}
|
||||
|
||||
String InputEventScreenDrag::as_text() const {
|
||||
|
||||
return "InputEventScreenDrag : index=" + itos(index) + ", position=(" + String(get_position()) + "), relative=(" + String(get_relative()) + "), speed=(" + String(get_speed()) + ")";
|
||||
}
|
||||
|
||||
void InputEventScreenDrag::_bind_methods() {
|
||||
|
||||
ClassDB::bind_method(D_METHOD("set_index", "index"), &InputEventScreenDrag::set_index);
|
||||
ClassDB::bind_method(D_METHOD("get_index"), &InputEventScreenDrag::get_index);
|
||||
|
||||
@ -1030,20 +962,18 @@ void InputEventScreenDrag::_bind_methods() {
|
||||
///////////////////////////////////
|
||||
|
||||
void InputEventAction::set_action(const StringName &p_action) {
|
||||
|
||||
action = p_action;
|
||||
}
|
||||
StringName InputEventAction::get_action() const {
|
||||
|
||||
StringName InputEventAction::get_action() const {
|
||||
return action;
|
||||
}
|
||||
|
||||
void InputEventAction::set_pressed(bool p_pressed) {
|
||||
|
||||
pressed = p_pressed;
|
||||
}
|
||||
bool InputEventAction::is_pressed() const {
|
||||
|
||||
bool InputEventAction::is_pressed() const {
|
||||
return pressed;
|
||||
}
|
||||
|
||||
@ -1056,40 +986,40 @@ float InputEventAction::get_strength() const {
|
||||
}
|
||||
|
||||
bool InputEventAction::shortcut_match(const Ref<InputEvent> &p_event) const {
|
||||
if (p_event.is_null())
|
||||
if (p_event.is_null()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return p_event->is_action(action);
|
||||
}
|
||||
|
||||
bool InputEventAction::is_action(const StringName &p_action) const {
|
||||
|
||||
return action == p_action;
|
||||
}
|
||||
|
||||
bool InputEventAction::action_match(const Ref<InputEvent> &p_event, bool *p_pressed, float *p_strength, float p_deadzone) const {
|
||||
|
||||
Ref<InputEventAction> act = p_event;
|
||||
if (act.is_null())
|
||||
if (act.is_null()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
bool match = action == act->action;
|
||||
if (match) {
|
||||
if (p_pressed != nullptr)
|
||||
if (p_pressed != nullptr) {
|
||||
*p_pressed = act->pressed;
|
||||
if (p_strength != nullptr)
|
||||
}
|
||||
if (p_strength != nullptr) {
|
||||
*p_strength = (p_pressed != nullptr && *p_pressed) ? 1.0f : 0.0f;
|
||||
}
|
||||
}
|
||||
return match;
|
||||
}
|
||||
|
||||
String InputEventAction::as_text() const {
|
||||
|
||||
return "InputEventAction : action=" + action + ", pressed=(" + (pressed ? "true" : "false");
|
||||
}
|
||||
|
||||
void InputEventAction::_bind_methods() {
|
||||
|
||||
ClassDB::bind_method(D_METHOD("set_action", "action"), &InputEventAction::set_action);
|
||||
ClassDB::bind_method(D_METHOD("get_action"), &InputEventAction::get_action);
|
||||
|
||||
@ -1109,12 +1039,10 @@ void InputEventAction::_bind_methods() {
|
||||
///////////////////////////////////
|
||||
|
||||
void InputEventGesture::set_position(const Vector2 &p_pos) {
|
||||
|
||||
pos = p_pos;
|
||||
}
|
||||
|
||||
void InputEventGesture::_bind_methods() {
|
||||
|
||||
ClassDB::bind_method(D_METHOD("set_position", "position"), &InputEventGesture::set_position);
|
||||
ClassDB::bind_method(D_METHOD("get_position"), &InputEventGesture::get_position);
|
||||
|
||||
@ -1122,24 +1050,20 @@ void InputEventGesture::_bind_methods() {
|
||||
}
|
||||
|
||||
Vector2 InputEventGesture::get_position() const {
|
||||
|
||||
return pos;
|
||||
}
|
||||
|
||||
///////////////////////////////////
|
||||
|
||||
void InputEventMagnifyGesture::set_factor(real_t p_factor) {
|
||||
|
||||
factor = p_factor;
|
||||
}
|
||||
|
||||
real_t InputEventMagnifyGesture::get_factor() const {
|
||||
|
||||
return factor;
|
||||
}
|
||||
|
||||
Ref<InputEvent> InputEventMagnifyGesture::xformed_by(const Transform2D &p_xform, const Vector2 &p_local_ofs) const {
|
||||
|
||||
Ref<InputEventMagnifyGesture> ev;
|
||||
ev.instance();
|
||||
|
||||
@ -1155,12 +1079,10 @@ Ref<InputEvent> InputEventMagnifyGesture::xformed_by(const Transform2D &p_xform,
|
||||
}
|
||||
|
||||
String InputEventMagnifyGesture::as_text() const {
|
||||
|
||||
return "InputEventMagnifyGesture : factor=" + rtos(get_factor()) + ", position=(" + String(get_position()) + ")";
|
||||
}
|
||||
|
||||
void InputEventMagnifyGesture::_bind_methods() {
|
||||
|
||||
ClassDB::bind_method(D_METHOD("set_factor", "factor"), &InputEventMagnifyGesture::set_factor);
|
||||
ClassDB::bind_method(D_METHOD("get_factor"), &InputEventMagnifyGesture::get_factor);
|
||||
|
||||
@ -1170,7 +1092,6 @@ void InputEventMagnifyGesture::_bind_methods() {
|
||||
///////////////////////////////////
|
||||
|
||||
void InputEventPanGesture::set_delta(const Vector2 &p_delta) {
|
||||
|
||||
delta = p_delta;
|
||||
}
|
||||
|
||||
@ -1179,7 +1100,6 @@ Vector2 InputEventPanGesture::get_delta() const {
|
||||
}
|
||||
|
||||
Ref<InputEvent> InputEventPanGesture::xformed_by(const Transform2D &p_xform, const Vector2 &p_local_ofs) const {
|
||||
|
||||
Ref<InputEventPanGesture> ev;
|
||||
ev.instance();
|
||||
|
||||
@ -1195,12 +1115,10 @@ Ref<InputEvent> InputEventPanGesture::xformed_by(const Transform2D &p_xform, con
|
||||
}
|
||||
|
||||
String InputEventPanGesture::as_text() const {
|
||||
|
||||
return "InputEventPanGesture : delta=(" + String(get_delta()) + "), position=(" + String(get_position()) + ")";
|
||||
}
|
||||
|
||||
void InputEventPanGesture::_bind_methods() {
|
||||
|
||||
ClassDB::bind_method(D_METHOD("set_delta", "delta"), &InputEventPanGesture::set_delta);
|
||||
ClassDB::bind_method(D_METHOD("get_delta"), &InputEventPanGesture::get_delta);
|
||||
|
||||
@ -1210,7 +1128,6 @@ void InputEventPanGesture::_bind_methods() {
|
||||
///////////////////////////////////
|
||||
|
||||
void InputEventMIDI::set_channel(const int p_channel) {
|
||||
|
||||
channel = p_channel;
|
||||
}
|
||||
|
||||
@ -1219,7 +1136,6 @@ int InputEventMIDI::get_channel() const {
|
||||
}
|
||||
|
||||
void InputEventMIDI::set_message(const int p_message) {
|
||||
|
||||
message = p_message;
|
||||
}
|
||||
|
||||
@ -1228,7 +1144,6 @@ int InputEventMIDI::get_message() const {
|
||||
}
|
||||
|
||||
void InputEventMIDI::set_pitch(const int p_pitch) {
|
||||
|
||||
pitch = p_pitch;
|
||||
}
|
||||
|
||||
@ -1237,7 +1152,6 @@ int InputEventMIDI::get_pitch() const {
|
||||
}
|
||||
|
||||
void InputEventMIDI::set_velocity(const int p_velocity) {
|
||||
|
||||
velocity = p_velocity;
|
||||
}
|
||||
|
||||
@ -1246,7 +1160,6 @@ int InputEventMIDI::get_velocity() const {
|
||||
}
|
||||
|
||||
void InputEventMIDI::set_instrument(const int p_instrument) {
|
||||
|
||||
instrument = p_instrument;
|
||||
}
|
||||
|
||||
@ -1255,7 +1168,6 @@ int InputEventMIDI::get_instrument() const {
|
||||
}
|
||||
|
||||
void InputEventMIDI::set_pressure(const int p_pressure) {
|
||||
|
||||
pressure = p_pressure;
|
||||
}
|
||||
|
||||
@ -1264,7 +1176,6 @@ int InputEventMIDI::get_pressure() const {
|
||||
}
|
||||
|
||||
void InputEventMIDI::set_controller_number(const int p_controller_number) {
|
||||
|
||||
controller_number = p_controller_number;
|
||||
}
|
||||
|
||||
@ -1273,7 +1184,6 @@ int InputEventMIDI::get_controller_number() const {
|
||||
}
|
||||
|
||||
void InputEventMIDI::set_controller_value(const int p_controller_value) {
|
||||
|
||||
controller_value = p_controller_value;
|
||||
}
|
||||
|
||||
@ -1282,12 +1192,10 @@ int InputEventMIDI::get_controller_value() const {
|
||||
}
|
||||
|
||||
String InputEventMIDI::as_text() const {
|
||||
|
||||
return "InputEventMIDI : channel=(" + itos(get_channel()) + "), message=(" + itos(get_message()) + ")";
|
||||
}
|
||||
|
||||
void InputEventMIDI::_bind_methods() {
|
||||
|
||||
ClassDB::bind_method(D_METHOD("set_channel", "channel"), &InputEventMIDI::set_channel);
|
||||
ClassDB::bind_method(D_METHOD("get_channel"), &InputEventMIDI::get_channel);
|
||||
ClassDB::bind_method(D_METHOD("set_message", "message"), &InputEventMIDI::set_message);
|
||||
|
@ -192,7 +192,6 @@ public:
|
||||
};
|
||||
|
||||
class InputEventFromWindow : public InputEvent {
|
||||
|
||||
GDCLASS(InputEventFromWindow, InputEvent);
|
||||
|
||||
int64_t window_id = 0;
|
||||
@ -252,7 +251,6 @@ public:
|
||||
};
|
||||
|
||||
class InputEventKey : public InputEventWithModifiers {
|
||||
|
||||
GDCLASS(InputEventKey, InputEventWithModifiers);
|
||||
|
||||
bool pressed = false; /// otherwise release
|
||||
@ -296,7 +294,6 @@ public:
|
||||
};
|
||||
|
||||
class InputEventMouse : public InputEventWithModifiers {
|
||||
|
||||
GDCLASS(InputEventMouse, InputEventWithModifiers);
|
||||
|
||||
int button_mask = 0;
|
||||
@ -321,7 +318,6 @@ public:
|
||||
};
|
||||
|
||||
class InputEventMouseButton : public InputEventMouse {
|
||||
|
||||
GDCLASS(InputEventMouseButton, InputEventMouse);
|
||||
|
||||
float factor = 1;
|
||||
@ -355,7 +351,6 @@ public:
|
||||
};
|
||||
|
||||
class InputEventMouseMotion : public InputEventMouse {
|
||||
|
||||
GDCLASS(InputEventMouseMotion, InputEventMouse);
|
||||
|
||||
Vector2 tilt;
|
||||
@ -388,7 +383,6 @@ public:
|
||||
};
|
||||
|
||||
class InputEventJoypadMotion : public InputEvent {
|
||||
|
||||
GDCLASS(InputEventJoypadMotion, InputEvent);
|
||||
int axis = 0; ///< Joypad axis
|
||||
float axis_value = 0; ///< -1 to 1
|
||||
@ -467,7 +461,6 @@ public:
|
||||
};
|
||||
|
||||
class InputEventScreenDrag : public InputEventFromWindow {
|
||||
|
||||
GDCLASS(InputEventScreenDrag, InputEventFromWindow);
|
||||
int index = 0;
|
||||
Vector2 pos;
|
||||
@ -497,7 +490,6 @@ public:
|
||||
};
|
||||
|
||||
class InputEventAction : public InputEvent {
|
||||
|
||||
GDCLASS(InputEventAction, InputEvent);
|
||||
|
||||
StringName action;
|
||||
@ -529,7 +521,6 @@ public:
|
||||
};
|
||||
|
||||
class InputEventGesture : public InputEventWithModifiers {
|
||||
|
||||
GDCLASS(InputEventGesture, InputEventWithModifiers);
|
||||
|
||||
Vector2 pos;
|
||||
@ -543,7 +534,6 @@ public:
|
||||
};
|
||||
|
||||
class InputEventMagnifyGesture : public InputEventGesture {
|
||||
|
||||
GDCLASS(InputEventMagnifyGesture, InputEventGesture);
|
||||
real_t factor = 1.0;
|
||||
|
||||
@ -561,7 +551,6 @@ public:
|
||||
};
|
||||
|
||||
class InputEventPanGesture : public InputEventGesture {
|
||||
|
||||
GDCLASS(InputEventPanGesture, InputEventGesture);
|
||||
Vector2 delta;
|
||||
|
||||
|
@ -38,7 +38,6 @@ InputMap *InputMap::singleton = nullptr;
|
||||
int InputMap::ALL_DEVICES = -1;
|
||||
|
||||
void InputMap::_bind_methods() {
|
||||
|
||||
ClassDB::bind_method(D_METHOD("has_action", "action"), &InputMap::has_action);
|
||||
ClassDB::bind_method(D_METHOD("get_actions"), &InputMap::_get_actions);
|
||||
ClassDB::bind_method(D_METHOD("add_action", "action", "deadzone"), &InputMap::add_action, DEFVAL(0.5f));
|
||||
@ -55,7 +54,6 @@ void InputMap::_bind_methods() {
|
||||
}
|
||||
|
||||
void InputMap::add_action(const StringName &p_action, float p_deadzone) {
|
||||
|
||||
ERR_FAIL_COND_MSG(input_map.has(p_action), "InputMap already has action '" + String(p_action) + "'.");
|
||||
input_map[p_action] = Action();
|
||||
static int last_id = 1;
|
||||
@ -65,20 +63,18 @@ void InputMap::add_action(const StringName &p_action, float p_deadzone) {
|
||||
}
|
||||
|
||||
void InputMap::erase_action(const StringName &p_action) {
|
||||
|
||||
ERR_FAIL_COND_MSG(!input_map.has(p_action), "Request for nonexistent InputMap action '" + String(p_action) + "'.");
|
||||
input_map.erase(p_action);
|
||||
}
|
||||
|
||||
Array InputMap::_get_actions() {
|
||||
|
||||
Array ret;
|
||||
List<StringName> actions = get_actions();
|
||||
if (actions.empty())
|
||||
if (actions.empty()) {
|
||||
return ret;
|
||||
}
|
||||
|
||||
for (const List<StringName>::Element *E = actions.front(); E; E = E->next()) {
|
||||
|
||||
ret.push_back(E->get());
|
||||
}
|
||||
|
||||
@ -86,7 +82,6 @@ Array InputMap::_get_actions() {
|
||||
}
|
||||
|
||||
List<StringName> InputMap::get_actions() const {
|
||||
|
||||
List<StringName> actions = List<StringName>();
|
||||
if (input_map.empty()) {
|
||||
return actions;
|
||||
@ -100,9 +95,7 @@ List<StringName> InputMap::get_actions() const {
|
||||
}
|
||||
|
||||
List<Ref<InputEvent>>::Element *InputMap::_find_event(Action &p_action, const Ref<InputEvent> &p_event, bool *p_pressed, float *p_strength) const {
|
||||
|
||||
for (List<Ref<InputEvent>>::Element *E = p_action.inputs.front(); E; E = E->next()) {
|
||||
|
||||
const Ref<InputEvent> e = E->get();
|
||||
|
||||
//if (e.type != Ref<InputEvent>::KEY && e.device != p_event.device) -- unsure about the KEY comparison, why is this here?
|
||||
@ -120,56 +113,50 @@ List<Ref<InputEvent>>::Element *InputMap::_find_event(Action &p_action, const Re
|
||||
}
|
||||
|
||||
bool InputMap::has_action(const StringName &p_action) const {
|
||||
|
||||
return input_map.has(p_action);
|
||||
}
|
||||
|
||||
void InputMap::action_set_deadzone(const StringName &p_action, float p_deadzone) {
|
||||
|
||||
ERR_FAIL_COND_MSG(!input_map.has(p_action), "Request for nonexistent InputMap action '" + String(p_action) + "'.");
|
||||
|
||||
input_map[p_action].deadzone = p_deadzone;
|
||||
}
|
||||
|
||||
void InputMap::action_add_event(const StringName &p_action, const Ref<InputEvent> &p_event) {
|
||||
|
||||
ERR_FAIL_COND_MSG(p_event.is_null(), "It's not a reference to a valid InputEvent object.");
|
||||
ERR_FAIL_COND_MSG(!input_map.has(p_action), "Request for nonexistent InputMap action '" + String(p_action) + "'.");
|
||||
if (_find_event(input_map[p_action], p_event))
|
||||
if (_find_event(input_map[p_action], p_event)) {
|
||||
return; //already gots
|
||||
}
|
||||
|
||||
input_map[p_action].inputs.push_back(p_event);
|
||||
}
|
||||
|
||||
bool InputMap::action_has_event(const StringName &p_action, const Ref<InputEvent> &p_event) {
|
||||
|
||||
ERR_FAIL_COND_V_MSG(!input_map.has(p_action), false, "Request for nonexistent InputMap action '" + String(p_action) + "'.");
|
||||
return (_find_event(input_map[p_action], p_event) != nullptr);
|
||||
}
|
||||
|
||||
void InputMap::action_erase_event(const StringName &p_action, const Ref<InputEvent> &p_event) {
|
||||
|
||||
ERR_FAIL_COND_MSG(!input_map.has(p_action), "Request for nonexistent InputMap action '" + String(p_action) + "'.");
|
||||
|
||||
List<Ref<InputEvent>>::Element *E = _find_event(input_map[p_action], p_event);
|
||||
if (E)
|
||||
if (E) {
|
||||
input_map[p_action].inputs.erase(E);
|
||||
}
|
||||
}
|
||||
|
||||
void InputMap::action_erase_events(const StringName &p_action) {
|
||||
|
||||
ERR_FAIL_COND_MSG(!input_map.has(p_action), "Request for nonexistent InputMap action '" + String(p_action) + "'.");
|
||||
|
||||
input_map[p_action].inputs.clear();
|
||||
}
|
||||
|
||||
Array InputMap::_get_action_list(const StringName &p_action) {
|
||||
|
||||
Array ret;
|
||||
const List<Ref<InputEvent>> *al = get_action_list(p_action);
|
||||
if (al) {
|
||||
for (const List<Ref<InputEvent>>::Element *E = al->front(); E; E = E->next()) {
|
||||
|
||||
ret.push_back(E->get());
|
||||
}
|
||||
}
|
||||
@ -178,10 +165,10 @@ Array InputMap::_get_action_list(const StringName &p_action) {
|
||||
}
|
||||
|
||||
const List<Ref<InputEvent>> *InputMap::get_action_list(const StringName &p_action) {
|
||||
|
||||
const Map<StringName, Action>::Element *E = input_map.find(p_action);
|
||||
if (!E)
|
||||
if (!E) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
return &E->get().inputs;
|
||||
}
|
||||
@ -196,10 +183,12 @@ bool InputMap::event_get_action_status(const Ref<InputEvent> &p_event, const Str
|
||||
|
||||
Ref<InputEventAction> input_event_action = p_event;
|
||||
if (input_event_action.is_valid()) {
|
||||
if (p_pressed != nullptr)
|
||||
if (p_pressed != nullptr) {
|
||||
*p_pressed = input_event_action->is_pressed();
|
||||
if (p_strength != nullptr)
|
||||
}
|
||||
if (p_strength != nullptr) {
|
||||
*p_strength = (p_pressed != nullptr && *p_pressed) ? input_event_action->get_strength() : 0.0f;
|
||||
}
|
||||
return input_event_action->get_action() == p_action;
|
||||
}
|
||||
|
||||
@ -207,10 +196,12 @@ bool InputMap::event_get_action_status(const Ref<InputEvent> &p_event, const Str
|
||||
float strength;
|
||||
List<Ref<InputEvent>>::Element *event = _find_event(E->get(), p_event, &pressed, &strength);
|
||||
if (event != nullptr) {
|
||||
if (p_pressed != nullptr)
|
||||
if (p_pressed != nullptr) {
|
||||
*p_pressed = pressed;
|
||||
if (p_strength != nullptr)
|
||||
}
|
||||
if (p_strength != nullptr) {
|
||||
*p_strength = strength;
|
||||
}
|
||||
return true;
|
||||
} else {
|
||||
return false;
|
||||
@ -222,7 +213,6 @@ const Map<StringName, InputMap::Action> &InputMap::get_action_map() const {
|
||||
}
|
||||
|
||||
void InputMap::load_from_globals() {
|
||||
|
||||
input_map.clear();
|
||||
|
||||
List<PropertyInfo> pinfo;
|
||||
@ -231,8 +221,9 @@ void InputMap::load_from_globals() {
|
||||
for (List<PropertyInfo>::Element *E = pinfo.front(); E; E = E->next()) {
|
||||
const PropertyInfo &pi = E->get();
|
||||
|
||||
if (!pi.name.begins_with("input/"))
|
||||
if (!pi.name.begins_with("input/")) {
|
||||
continue;
|
||||
}
|
||||
|
||||
String name = pi.name.substr(pi.name.find("/") + 1, pi.name.length());
|
||||
|
||||
@ -243,15 +234,15 @@ void InputMap::load_from_globals() {
|
||||
add_action(name, deadzone);
|
||||
for (int i = 0; i < events.size(); i++) {
|
||||
Ref<InputEvent> event = events[i];
|
||||
if (event.is_null())
|
||||
if (event.is_null()) {
|
||||
continue;
|
||||
}
|
||||
action_add_event(name, event);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void InputMap::load_default() {
|
||||
|
||||
Ref<InputEventKey> key;
|
||||
|
||||
add_action("ui_accept");
|
||||
@ -332,7 +323,6 @@ void InputMap::load_default() {
|
||||
}
|
||||
|
||||
InputMap::InputMap() {
|
||||
|
||||
ERR_FAIL_COND_MSG(singleton, "Singleton in InputMap already exist.");
|
||||
singleton = this;
|
||||
}
|
||||
|
@ -35,7 +35,6 @@
|
||||
#include "core/object.h"
|
||||
|
||||
class InputMap : public Object {
|
||||
|
||||
GDCLASS(InputMap, Object);
|
||||
|
||||
public:
|
||||
|
@ -40,10 +40,8 @@
|
||||
#include <zstd.h>
|
||||
|
||||
int Compression::compress(uint8_t *p_dst, const uint8_t *p_src, int p_src_size, Mode p_mode) {
|
||||
|
||||
switch (p_mode) {
|
||||
case MODE_FASTLZ: {
|
||||
|
||||
if (p_src_size < 16) {
|
||||
uint8_t src[16];
|
||||
zeromem(&src[p_src_size], 16 - p_src_size);
|
||||
@ -56,7 +54,6 @@ int Compression::compress(uint8_t *p_dst, const uint8_t *p_src, int p_src_size,
|
||||
} break;
|
||||
case MODE_DEFLATE:
|
||||
case MODE_GZIP: {
|
||||
|
||||
int window_bits = p_mode == MODE_DEFLATE ? 15 : 15 + 16;
|
||||
|
||||
z_stream strm;
|
||||
@ -65,8 +62,9 @@ int Compression::compress(uint8_t *p_dst, const uint8_t *p_src, int p_src_size,
|
||||
strm.opaque = Z_NULL;
|
||||
int level = p_mode == MODE_DEFLATE ? zlib_level : gzip_level;
|
||||
int err = deflateInit2(&strm, level, Z_DEFLATED, window_bits, 8, Z_DEFAULT_STRATEGY);
|
||||
if (err != Z_OK)
|
||||
if (err != Z_OK) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
strm.avail_in = p_src_size;
|
||||
int aout = deflateBound(&strm, p_src_size);
|
||||
@ -97,19 +95,17 @@ int Compression::compress(uint8_t *p_dst, const uint8_t *p_src, int p_src_size,
|
||||
}
|
||||
|
||||
int Compression::get_max_compressed_buffer_size(int p_src_size, Mode p_mode) {
|
||||
|
||||
switch (p_mode) {
|
||||
case MODE_FASTLZ: {
|
||||
|
||||
int ss = p_src_size + p_src_size * 6 / 100;
|
||||
if (ss < 66)
|
||||
if (ss < 66) {
|
||||
ss = 66;
|
||||
}
|
||||
return ss;
|
||||
|
||||
} break;
|
||||
case MODE_DEFLATE:
|
||||
case MODE_GZIP: {
|
||||
|
||||
int window_bits = p_mode == MODE_DEFLATE ? 15 : 15 + 16;
|
||||
|
||||
z_stream strm;
|
||||
@ -117,14 +113,14 @@ int Compression::get_max_compressed_buffer_size(int p_src_size, Mode p_mode) {
|
||||
strm.zfree = zipio_free;
|
||||
strm.opaque = Z_NULL;
|
||||
int err = deflateInit2(&strm, Z_DEFAULT_COMPRESSION, Z_DEFLATED, window_bits, 8, Z_DEFAULT_STRATEGY);
|
||||
if (err != Z_OK)
|
||||
if (err != Z_OK) {
|
||||
return -1;
|
||||
}
|
||||
int aout = deflateBound(&strm, p_src_size);
|
||||
deflateEnd(&strm);
|
||||
return aout;
|
||||
} break;
|
||||
case MODE_ZSTD: {
|
||||
|
||||
return ZSTD_compressBound(p_src_size);
|
||||
} break;
|
||||
}
|
||||
@ -133,10 +129,8 @@ int Compression::get_max_compressed_buffer_size(int p_src_size, Mode p_mode) {
|
||||
}
|
||||
|
||||
int Compression::decompress(uint8_t *p_dst, int p_dst_max_size, const uint8_t *p_src, int p_src_size, Mode p_mode) {
|
||||
|
||||
switch (p_mode) {
|
||||
case MODE_FASTLZ: {
|
||||
|
||||
int ret_size = 0;
|
||||
|
||||
if (p_dst_max_size < 16) {
|
||||
@ -150,7 +144,6 @@ int Compression::decompress(uint8_t *p_dst, int p_dst_max_size, const uint8_t *p
|
||||
} break;
|
||||
case MODE_DEFLATE:
|
||||
case MODE_GZIP: {
|
||||
|
||||
int window_bits = p_mode == MODE_DEFLATE ? 15 : 15 + 16;
|
||||
|
||||
z_stream strm;
|
||||
|
@ -34,7 +34,6 @@
|
||||
#include "core/typedefs.h"
|
||||
|
||||
class Compression {
|
||||
|
||||
public:
|
||||
static int zlib_level;
|
||||
static int gzip_level;
|
||||
|
@ -35,14 +35,12 @@
|
||||
#include "core/variant_parser.h"
|
||||
|
||||
PackedStringArray ConfigFile::_get_sections() const {
|
||||
|
||||
List<String> s;
|
||||
get_sections(&s);
|
||||
PackedStringArray arr;
|
||||
arr.resize(s.size());
|
||||
int idx = 0;
|
||||
for (const List<String>::Element *E = s.front(); E; E = E->next()) {
|
||||
|
||||
arr.set(idx++, E->get());
|
||||
}
|
||||
|
||||
@ -50,14 +48,12 @@ PackedStringArray ConfigFile::_get_sections() const {
|
||||
}
|
||||
|
||||
PackedStringArray ConfigFile::_get_section_keys(const String &p_section) const {
|
||||
|
||||
List<String> s;
|
||||
get_section_keys(p_section, &s);
|
||||
PackedStringArray arr;
|
||||
arr.resize(s.size());
|
||||
int idx = 0;
|
||||
for (const List<String>::Element *E = s.front(); E; E = E->next()) {
|
||||
|
||||
arr.set(idx++, E->get());
|
||||
}
|
||||
|
||||
@ -65,11 +61,11 @@ PackedStringArray ConfigFile::_get_section_keys(const String &p_section) const {
|
||||
}
|
||||
|
||||
void ConfigFile::set_value(const String &p_section, const String &p_key, const Variant &p_value) {
|
||||
|
||||
if (p_value.get_type() == Variant::NIL) {
|
||||
//erase
|
||||
if (!values.has(p_section))
|
||||
if (!values.has(p_section)) {
|
||||
return; // ?
|
||||
}
|
||||
values[p_section].erase(p_key);
|
||||
if (values[p_section].empty()) {
|
||||
values.erase(p_section);
|
||||
@ -83,8 +79,8 @@ void ConfigFile::set_value(const String &p_section, const String &p_key, const V
|
||||
values[p_section][p_key] = p_value;
|
||||
}
|
||||
}
|
||||
Variant ConfigFile::get_value(const String &p_section, const String &p_key, Variant p_default) const {
|
||||
|
||||
Variant ConfigFile::get_value(const String &p_section, const String &p_key, Variant p_default) const {
|
||||
if (!values.has(p_section) || !values[p_section].has(p_key)) {
|
||||
ERR_FAIL_COND_V_MSG(p_default.get_type() == Variant::NIL, Variant(),
|
||||
vformat("Couldn't find the given section \"%s\" and key \"%s\", and no default was given.", p_section, p_key));
|
||||
@ -95,24 +91,23 @@ Variant ConfigFile::get_value(const String &p_section, const String &p_key, Vari
|
||||
}
|
||||
|
||||
bool ConfigFile::has_section(const String &p_section) const {
|
||||
|
||||
return values.has(p_section);
|
||||
}
|
||||
bool ConfigFile::has_section_key(const String &p_section, const String &p_key) const {
|
||||
|
||||
if (!values.has(p_section))
|
||||
bool ConfigFile::has_section_key(const String &p_section, const String &p_key) const {
|
||||
if (!values.has(p_section)) {
|
||||
return false;
|
||||
}
|
||||
return values[p_section].has(p_key);
|
||||
}
|
||||
|
||||
void ConfigFile::get_sections(List<String> *r_sections) const {
|
||||
|
||||
for (OrderedHashMap<String, OrderedHashMap<String, Variant>>::ConstElement E = values.front(); E; E = E.next()) {
|
||||
r_sections->push_back(E.key());
|
||||
}
|
||||
}
|
||||
void ConfigFile::get_section_keys(const String &p_section, List<String> *r_keys) const {
|
||||
|
||||
void ConfigFile::get_section_keys(const String &p_section, List<String> *r_keys) const {
|
||||
ERR_FAIL_COND_MSG(!values.has(p_section), vformat("Cannot get keys from nonexistent section \"%s\".", p_section));
|
||||
|
||||
for (OrderedHashMap<String, Variant>::ConstElement E = values[p_section].front(); E; E = E.next()) {
|
||||
@ -121,13 +116,11 @@ void ConfigFile::get_section_keys(const String &p_section, List<String> *r_keys)
|
||||
}
|
||||
|
||||
void ConfigFile::erase_section(const String &p_section) {
|
||||
|
||||
ERR_FAIL_COND_MSG(!values.has(p_section), vformat("Cannot erase nonexistent section \"%s\".", p_section));
|
||||
values.erase(p_section);
|
||||
}
|
||||
|
||||
void ConfigFile::erase_section_key(const String &p_section, const String &p_key) {
|
||||
|
||||
ERR_FAIL_COND_MSG(!values.has(p_section), vformat("Cannot erase key \"%s\" from nonexistent section \"%s\".", p_key, p_section));
|
||||
ERR_FAIL_COND_MSG(!values[p_section].has(p_key), vformat("Cannot erase nonexistent key \"%s\" from section \"%s\".", p_key, p_section));
|
||||
|
||||
@ -135,13 +128,13 @@ void ConfigFile::erase_section_key(const String &p_section, const String &p_key)
|
||||
}
|
||||
|
||||
Error ConfigFile::save(const String &p_path) {
|
||||
|
||||
Error err;
|
||||
FileAccess *file = FileAccess::open(p_path, FileAccess::WRITE, &err);
|
||||
|
||||
if (err) {
|
||||
if (file)
|
||||
if (file) {
|
||||
memdelete(file);
|
||||
}
|
||||
return err;
|
||||
}
|
||||
|
||||
@ -149,12 +142,12 @@ Error ConfigFile::save(const String &p_path) {
|
||||
}
|
||||
|
||||
Error ConfigFile::save_encrypted(const String &p_path, const Vector<uint8_t> &p_key) {
|
||||
|
||||
Error err;
|
||||
FileAccess *f = FileAccess::open(p_path, FileAccess::WRITE, &err);
|
||||
|
||||
if (err)
|
||||
if (err) {
|
||||
return err;
|
||||
}
|
||||
|
||||
FileAccessEncrypted *fae = memnew(FileAccessEncrypted);
|
||||
err = fae->open_and_parse(f, p_key, FileAccessEncrypted::MODE_WRITE_AES256);
|
||||
@ -167,12 +160,12 @@ Error ConfigFile::save_encrypted(const String &p_path, const Vector<uint8_t> &p_
|
||||
}
|
||||
|
||||
Error ConfigFile::save_encrypted_pass(const String &p_path, const String &p_pass) {
|
||||
|
||||
Error err;
|
||||
FileAccess *f = FileAccess::open(p_path, FileAccess::WRITE, &err);
|
||||
|
||||
if (err)
|
||||
if (err) {
|
||||
return err;
|
||||
}
|
||||
|
||||
FileAccessEncrypted *fae = memnew(FileAccessEncrypted);
|
||||
err = fae->open_and_parse_password(f, p_pass, FileAccessEncrypted::MODE_WRITE_AES256);
|
||||
@ -186,15 +179,13 @@ Error ConfigFile::save_encrypted_pass(const String &p_path, const String &p_pass
|
||||
}
|
||||
|
||||
Error ConfigFile::_internal_save(FileAccess *file) {
|
||||
|
||||
for (OrderedHashMap<String, OrderedHashMap<String, Variant>>::Element E = values.front(); E; E = E.next()) {
|
||||
|
||||
if (E != values.front())
|
||||
if (E != values.front()) {
|
||||
file->store_string("\n");
|
||||
}
|
||||
file->store_string("[" + E.key() + "]\n\n");
|
||||
|
||||
for (OrderedHashMap<String, Variant>::Element F = E.get().front(); F; F = F.next()) {
|
||||
|
||||
String vstr;
|
||||
VariantWriter::write_to_string(F.get(), vstr);
|
||||
file->store_string(F.key() + "=" + vstr + "\n");
|
||||
@ -207,23 +198,23 @@ Error ConfigFile::_internal_save(FileAccess *file) {
|
||||
}
|
||||
|
||||
Error ConfigFile::load(const String &p_path) {
|
||||
|
||||
Error err;
|
||||
FileAccess *f = FileAccess::open(p_path, FileAccess::READ, &err);
|
||||
|
||||
if (!f)
|
||||
if (!f) {
|
||||
return err;
|
||||
}
|
||||
|
||||
return _internal_load(p_path, f);
|
||||
}
|
||||
|
||||
Error ConfigFile::load_encrypted(const String &p_path, const Vector<uint8_t> &p_key) {
|
||||
|
||||
Error err;
|
||||
FileAccess *f = FileAccess::open(p_path, FileAccess::READ, &err);
|
||||
|
||||
if (err)
|
||||
if (err) {
|
||||
return err;
|
||||
}
|
||||
|
||||
FileAccessEncrypted *fae = memnew(FileAccessEncrypted);
|
||||
err = fae->open_and_parse(f, p_key, FileAccessEncrypted::MODE_READ);
|
||||
@ -236,12 +227,12 @@ Error ConfigFile::load_encrypted(const String &p_path, const Vector<uint8_t> &p_
|
||||
}
|
||||
|
||||
Error ConfigFile::load_encrypted_pass(const String &p_path, const String &p_pass) {
|
||||
|
||||
Error err;
|
||||
FileAccess *f = FileAccess::open(p_path, FileAccess::READ, &err);
|
||||
|
||||
if (err)
|
||||
if (err) {
|
||||
return err;
|
||||
}
|
||||
|
||||
FileAccessEncrypted *fae = memnew(FileAccessEncrypted);
|
||||
err = fae->open_and_parse_password(f, p_pass, FileAccessEncrypted::MODE_READ);
|
||||
@ -255,7 +246,6 @@ Error ConfigFile::load_encrypted_pass(const String &p_path, const String &p_pass
|
||||
}
|
||||
|
||||
Error ConfigFile::_internal_load(const String &p_path, FileAccess *f) {
|
||||
|
||||
VariantParser::StreamFile stream;
|
||||
stream.f = f;
|
||||
|
||||
@ -267,14 +257,12 @@ Error ConfigFile::_internal_load(const String &p_path, FileAccess *f) {
|
||||
}
|
||||
|
||||
Error ConfigFile::parse(const String &p_data) {
|
||||
|
||||
VariantParser::StreamString stream;
|
||||
stream.s = p_data;
|
||||
return _parse("<string>", &stream);
|
||||
}
|
||||
|
||||
Error ConfigFile::_parse(const String &p_path, VariantParser::Stream *p_stream) {
|
||||
|
||||
String assign;
|
||||
Variant value;
|
||||
VariantParser::Tag next_tag;
|
||||
@ -285,7 +273,6 @@ Error ConfigFile::_parse(const String &p_path, VariantParser::Stream *p_stream)
|
||||
String section;
|
||||
|
||||
while (true) {
|
||||
|
||||
assign = Variant();
|
||||
next_tag.fields.clear();
|
||||
next_tag.name = String();
|
||||
@ -309,7 +296,6 @@ Error ConfigFile::_parse(const String &p_path, VariantParser::Stream *p_stream)
|
||||
}
|
||||
|
||||
void ConfigFile::_bind_methods() {
|
||||
|
||||
ClassDB::bind_method(D_METHOD("set_value", "section", "key", "value"), &ConfigFile::set_value);
|
||||
ClassDB::bind_method(D_METHOD("get_value", "section", "key", "default"), &ConfigFile::get_value, DEFVAL(Variant()));
|
||||
|
||||
|
@ -37,7 +37,6 @@
|
||||
#include "core/variant_parser.h"
|
||||
|
||||
class ConfigFile : public Reference {
|
||||
|
||||
GDCLASS(ConfigFile, Reference);
|
||||
|
||||
OrderedHashMap<String, OrderedHashMap<String, Variant>> values;
|
||||
|
@ -37,7 +37,6 @@ DTLSServer *(*DTLSServer::_create)() = nullptr;
|
||||
bool DTLSServer::available = false;
|
||||
|
||||
DTLSServer *DTLSServer::create() {
|
||||
|
||||
return _create();
|
||||
}
|
||||
|
||||
@ -46,7 +45,6 @@ bool DTLSServer::is_available() {
|
||||
}
|
||||
|
||||
void DTLSServer::_bind_methods() {
|
||||
|
||||
ClassDB::bind_method(D_METHOD("setup", "key", "certificate", "chain"), &DTLSServer::setup, DEFVAL(Ref<X509Certificate>()));
|
||||
ClassDB::bind_method(D_METHOD("take_connection", "udp_peer"), &DTLSServer::take_connection);
|
||||
}
|
||||
|
@ -33,28 +33,23 @@
|
||||
#include "core/error_macros.h"
|
||||
|
||||
Error FileAccessBuffered::set_error(Error p_error) const {
|
||||
|
||||
return (last_error = p_error);
|
||||
}
|
||||
|
||||
void FileAccessBuffered::set_cache_size(int p_size) {
|
||||
|
||||
cache_size = p_size;
|
||||
}
|
||||
|
||||
int FileAccessBuffered::get_cache_size() {
|
||||
|
||||
return cache_size;
|
||||
}
|
||||
|
||||
int FileAccessBuffered::cache_data_left() const {
|
||||
|
||||
if (file.offset >= file.size) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (cache.offset == -1 || file.offset < cache.offset || file.offset >= cache.offset + cache.buffer.size()) {
|
||||
|
||||
return read_data_block(file.offset, cache_size);
|
||||
}
|
||||
|
||||
@ -62,37 +57,30 @@ int FileAccessBuffered::cache_data_left() const {
|
||||
}
|
||||
|
||||
void FileAccessBuffered::seek(size_t p_position) {
|
||||
|
||||
file.offset = p_position;
|
||||
}
|
||||
|
||||
void FileAccessBuffered::seek_end(int64_t p_position) {
|
||||
|
||||
file.offset = file.size + p_position;
|
||||
}
|
||||
|
||||
size_t FileAccessBuffered::get_position() const {
|
||||
|
||||
return file.offset;
|
||||
}
|
||||
|
||||
size_t FileAccessBuffered::get_len() const {
|
||||
|
||||
return file.size;
|
||||
}
|
||||
|
||||
bool FileAccessBuffered::eof_reached() const {
|
||||
|
||||
return file.offset > file.size;
|
||||
}
|
||||
|
||||
uint8_t FileAccessBuffered::get_8() const {
|
||||
|
||||
ERR_FAIL_COND_V_MSG(!file.open, 0, "Can't get data, when file is not opened.");
|
||||
|
||||
uint8_t byte = 0;
|
||||
if (cache_data_left() >= 1) {
|
||||
|
||||
byte = cache.buffer[file.offset - cache.offset];
|
||||
}
|
||||
|
||||
@ -102,15 +90,12 @@ uint8_t FileAccessBuffered::get_8() const {
|
||||
}
|
||||
|
||||
int FileAccessBuffered::get_buffer(uint8_t *p_dest, int p_length) const {
|
||||
|
||||
ERR_FAIL_COND_V_MSG(!file.open, -1, "Can't get buffer, when file is not opened.");
|
||||
|
||||
if (p_length > cache_size) {
|
||||
|
||||
int total_read = 0;
|
||||
|
||||
if (!(cache.offset == -1 || file.offset < cache.offset || file.offset >= cache.offset + cache.buffer.size())) {
|
||||
|
||||
int size = (cache.buffer.size() - (file.offset - cache.offset));
|
||||
size = size - (size % 4);
|
||||
//const uint8_t* read = cache.buffer.ptr();
|
||||
@ -134,7 +119,6 @@ int FileAccessBuffered::get_buffer(uint8_t *p_dest, int p_length) const {
|
||||
int to_read = p_length;
|
||||
int total_read = 0;
|
||||
while (to_read > 0) {
|
||||
|
||||
int left = cache_data_left();
|
||||
if (left == 0) {
|
||||
file.offset += to_read;
|
||||
@ -158,11 +142,9 @@ int FileAccessBuffered::get_buffer(uint8_t *p_dest, int p_length) const {
|
||||
}
|
||||
|
||||
bool FileAccessBuffered::is_open() const {
|
||||
|
||||
return file.open;
|
||||
}
|
||||
|
||||
Error FileAccessBuffered::get_error() const {
|
||||
|
||||
return last_error;
|
||||
}
|
||||
|
@ -36,7 +36,6 @@
|
||||
#include "core/ustring.h"
|
||||
|
||||
class FileAccessBuffered : public FileAccess {
|
||||
|
||||
public:
|
||||
enum {
|
||||
DEFAULT_CACHE_SIZE = 128 * 1024,
|
||||
@ -52,7 +51,6 @@ protected:
|
||||
Error set_error(Error p_error) const;
|
||||
|
||||
mutable struct File {
|
||||
|
||||
bool open;
|
||||
int size;
|
||||
int offset;
|
||||
@ -61,7 +59,6 @@ protected:
|
||||
} file;
|
||||
|
||||
mutable struct Cache {
|
||||
|
||||
Vector<uint8_t> buffer;
|
||||
int offset;
|
||||
} cache;
|
||||
|
@ -35,22 +35,18 @@
|
||||
|
||||
template <class T>
|
||||
class FileAccessBufferedFA : public FileAccessBuffered {
|
||||
|
||||
T f;
|
||||
|
||||
int read_data_block(int p_offset, int p_size, uint8_t *p_dest = 0) const {
|
||||
|
||||
ERR_FAIL_COND_V_MSG(!f.is_open(), -1, "Can't read data block when file is not opened.");
|
||||
|
||||
((T *)&f)->seek(p_offset);
|
||||
|
||||
if (p_dest) {
|
||||
|
||||
f.get_buffer(p_dest, p_size);
|
||||
return p_size;
|
||||
|
||||
} else {
|
||||
|
||||
cache.offset = p_offset;
|
||||
cache.buffer.resize(p_size);
|
||||
|
||||
@ -66,7 +62,6 @@ class FileAccessBufferedFA : public FileAccessBuffered {
|
||||
};
|
||||
|
||||
static FileAccess *create() {
|
||||
|
||||
return memnew(FileAccessBufferedFA<T>());
|
||||
};
|
||||
|
||||
@ -78,27 +73,22 @@ protected:
|
||||
|
||||
public:
|
||||
void flush() {
|
||||
|
||||
f.flush();
|
||||
};
|
||||
|
||||
void store_8(uint8_t p_dest) {
|
||||
|
||||
f.store_8(p_dest);
|
||||
};
|
||||
|
||||
void store_buffer(const uint8_t *p_src, int p_length) {
|
||||
|
||||
f.store_buffer(p_src, p_length);
|
||||
};
|
||||
|
||||
bool file_exists(const String &p_name) {
|
||||
|
||||
return f.file_exists(p_name);
|
||||
};
|
||||
|
||||
Error _open(const String &p_path, int p_mode_flags) {
|
||||
|
||||
close();
|
||||
|
||||
Error ret = f._open(p_path, p_mode_flags);
|
||||
@ -119,7 +109,6 @@ public:
|
||||
};
|
||||
|
||||
void close() {
|
||||
|
||||
f.close();
|
||||
|
||||
file.offset = 0;
|
||||
@ -133,7 +122,6 @@ public:
|
||||
};
|
||||
|
||||
virtual uint64_t _get_modified_time(const String &p_file) {
|
||||
|
||||
return f._get_modified_time(p_file);
|
||||
}
|
||||
|
||||
|
@ -33,14 +33,14 @@
|
||||
#include "core/print_string.h"
|
||||
|
||||
void FileAccessCompressed::configure(const String &p_magic, Compression::Mode p_mode, int p_block_size) {
|
||||
|
||||
magic = p_magic.ascii().get_data();
|
||||
if (magic.length() > 4)
|
||||
if (magic.length() > 4) {
|
||||
magic = magic.substr(0, 4);
|
||||
else {
|
||||
while (magic.length() < 4)
|
||||
} else {
|
||||
while (magic.length() < 4) {
|
||||
magic += " ";
|
||||
}
|
||||
}
|
||||
|
||||
cmode = p_mode;
|
||||
block_size = p_block_size;
|
||||
@ -59,7 +59,6 @@ void FileAccessCompressed::configure(const String &p_magic, Compression::Mode p_
|
||||
}
|
||||
|
||||
Error FileAccessCompressed::open_after_magic(FileAccess *p_base) {
|
||||
|
||||
f = p_base;
|
||||
cmode = (Compression::Mode)f->get_32();
|
||||
block_size = f->get_32();
|
||||
@ -72,7 +71,6 @@ Error FileAccessCompressed::open_after_magic(FileAccess *p_base) {
|
||||
int acc_ofs = f->get_position() + bc * 4;
|
||||
int max_bs = 0;
|
||||
for (int i = 0; i < bc; i++) {
|
||||
|
||||
ReadBlock rb;
|
||||
rb.offset = acc_ofs;
|
||||
rb.csize = f->get_32();
|
||||
@ -98,11 +96,11 @@ Error FileAccessCompressed::open_after_magic(FileAccess *p_base) {
|
||||
}
|
||||
|
||||
Error FileAccessCompressed::_open(const String &p_path, int p_mode_flags) {
|
||||
|
||||
ERR_FAIL_COND_V(p_mode_flags == READ_WRITE, ERR_UNAVAILABLE);
|
||||
|
||||
if (f)
|
||||
if (f) {
|
||||
close();
|
||||
}
|
||||
|
||||
Error err;
|
||||
f = FileAccess::open(p_path, p_mode_flags, &err);
|
||||
@ -114,7 +112,6 @@ Error FileAccessCompressed::_open(const String &p_path, int p_mode_flags) {
|
||||
}
|
||||
|
||||
if (p_mode_flags & WRITE) {
|
||||
|
||||
buffer.clear();
|
||||
writing = true;
|
||||
write_pos = 0;
|
||||
@ -125,7 +122,6 @@ Error FileAccessCompressed::_open(const String &p_path, int p_mode_flags) {
|
||||
|
||||
//don't store anything else unless it's done saving!
|
||||
} else {
|
||||
|
||||
char rmagic[5];
|
||||
f->get_buffer((uint8_t *)rmagic, 4);
|
||||
rmagic[4] = 0;
|
||||
@ -138,10 +134,11 @@ Error FileAccessCompressed::_open(const String &p_path, int p_mode_flags) {
|
||||
|
||||
return OK;
|
||||
}
|
||||
void FileAccessCompressed::close() {
|
||||
|
||||
if (!f)
|
||||
void FileAccessCompressed::close() {
|
||||
if (!f) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (writing) {
|
||||
//save block table and all compressed blocks
|
||||
@ -159,7 +156,6 @@ void FileAccessCompressed::close() {
|
||||
|
||||
Vector<int> block_sizes;
|
||||
for (int i = 0; i < bc; i++) {
|
||||
|
||||
int bl = i == (bc - 1) ? write_max % block_size : block_size;
|
||||
uint8_t *bp = &write_ptr[i * block_size];
|
||||
|
||||
@ -172,15 +168,15 @@ void FileAccessCompressed::close() {
|
||||
}
|
||||
|
||||
f->seek(16); //ok write block sizes
|
||||
for (int i = 0; i < bc; i++)
|
||||
for (int i = 0; i < bc; i++) {
|
||||
f->store_32(block_sizes[i]);
|
||||
}
|
||||
f->seek_end();
|
||||
f->store_buffer((const uint8_t *)mgc.get_data(), mgc.length()); //magic at the end too
|
||||
|
||||
buffer.clear();
|
||||
|
||||
} else {
|
||||
|
||||
comp_buffer.clear();
|
||||
buffer.clear();
|
||||
read_blocks.clear();
|
||||
@ -191,21 +187,17 @@ void FileAccessCompressed::close() {
|
||||
}
|
||||
|
||||
bool FileAccessCompressed::is_open() const {
|
||||
|
||||
return f != nullptr;
|
||||
}
|
||||
|
||||
void FileAccessCompressed::seek(size_t p_position) {
|
||||
|
||||
ERR_FAIL_COND_MSG(!f, "File must be opened before use.");
|
||||
if (writing) {
|
||||
|
||||
ERR_FAIL_COND(p_position > write_max);
|
||||
|
||||
write_pos = p_position;
|
||||
|
||||
} else {
|
||||
|
||||
ERR_FAIL_COND(p_position > read_total);
|
||||
if (p_position == read_total) {
|
||||
at_end = true;
|
||||
@ -214,7 +206,6 @@ void FileAccessCompressed::seek(size_t p_position) {
|
||||
read_eof = false;
|
||||
int block_idx = p_position / block_size;
|
||||
if (block_idx != read_block) {
|
||||
|
||||
read_block = block_idx;
|
||||
f->seek(read_blocks[read_block].offset);
|
||||
f->get_buffer(comp_buffer.ptrw(), read_blocks[read_block].csize);
|
||||
@ -228,32 +219,26 @@ void FileAccessCompressed::seek(size_t p_position) {
|
||||
}
|
||||
|
||||
void FileAccessCompressed::seek_end(int64_t p_position) {
|
||||
|
||||
ERR_FAIL_COND_MSG(!f, "File must be opened before use.");
|
||||
if (writing) {
|
||||
|
||||
seek(write_max + p_position);
|
||||
} else {
|
||||
|
||||
seek(read_total + p_position);
|
||||
}
|
||||
}
|
||||
size_t FileAccessCompressed::get_position() const {
|
||||
|
||||
size_t FileAccessCompressed::get_position() const {
|
||||
ERR_FAIL_COND_V_MSG(!f, 0, "File must be opened before use.");
|
||||
if (writing) {
|
||||
|
||||
return write_pos;
|
||||
} else {
|
||||
|
||||
return read_block * block_size + read_pos;
|
||||
}
|
||||
}
|
||||
size_t FileAccessCompressed::get_len() const {
|
||||
|
||||
size_t FileAccessCompressed::get_len() const {
|
||||
ERR_FAIL_COND_V_MSG(!f, 0, "File must be opened before use.");
|
||||
if (writing) {
|
||||
|
||||
return write_max;
|
||||
} else {
|
||||
return read_total;
|
||||
@ -261,7 +246,6 @@ size_t FileAccessCompressed::get_len() const {
|
||||
}
|
||||
|
||||
bool FileAccessCompressed::eof_reached() const {
|
||||
|
||||
ERR_FAIL_COND_V_MSG(!f, false, "File must be opened before use.");
|
||||
if (writing) {
|
||||
return false;
|
||||
@ -271,7 +255,6 @@ bool FileAccessCompressed::eof_reached() const {
|
||||
}
|
||||
|
||||
uint8_t FileAccessCompressed::get_8() const {
|
||||
|
||||
ERR_FAIL_COND_V_MSG(!f, 0, "File must be opened before use.");
|
||||
ERR_FAIL_COND_V_MSG(writing, 0, "File has not been opened in read mode.");
|
||||
|
||||
@ -301,8 +284,8 @@ uint8_t FileAccessCompressed::get_8() const {
|
||||
|
||||
return ret;
|
||||
}
|
||||
int FileAccessCompressed::get_buffer(uint8_t *p_dst, int p_length) const {
|
||||
|
||||
int FileAccessCompressed::get_buffer(uint8_t *p_dst, int p_length) const {
|
||||
ERR_FAIL_COND_V_MSG(!f, 0, "File must be opened before use.");
|
||||
ERR_FAIL_COND_V_MSG(writing, 0, "File has not been opened in read mode.");
|
||||
|
||||
@ -312,7 +295,6 @@ int FileAccessCompressed::get_buffer(uint8_t *p_dst, int p_length) const {
|
||||
}
|
||||
|
||||
for (int i = 0; i < p_length; i++) {
|
||||
|
||||
p_dst[i] = read_ptr[read_pos];
|
||||
read_pos++;
|
||||
if (read_pos >= read_block_size) {
|
||||
@ -328,8 +310,9 @@ int FileAccessCompressed::get_buffer(uint8_t *p_dst, int p_length) const {
|
||||
} else {
|
||||
read_block--;
|
||||
at_end = true;
|
||||
if (i < p_length - 1)
|
||||
if (i < p_length - 1) {
|
||||
read_eof = true;
|
||||
}
|
||||
return i;
|
||||
}
|
||||
}
|
||||
@ -339,7 +322,6 @@ int FileAccessCompressed::get_buffer(uint8_t *p_dst, int p_length) const {
|
||||
}
|
||||
|
||||
Error FileAccessCompressed::get_error() const {
|
||||
|
||||
return read_eof ? ERR_FILE_EOF : OK;
|
||||
}
|
||||
|
||||
@ -351,7 +333,6 @@ void FileAccessCompressed::flush() {
|
||||
}
|
||||
|
||||
void FileAccessCompressed::store_8(uint8_t p_dest) {
|
||||
|
||||
ERR_FAIL_COND_MSG(!f, "File must be opened before use.");
|
||||
ERR_FAIL_COND_MSG(!writing, "File has not been opened in read mode.");
|
||||
|
||||
@ -360,25 +341,26 @@ void FileAccessCompressed::store_8(uint8_t p_dest) {
|
||||
}
|
||||
|
||||
bool FileAccessCompressed::file_exists(const String &p_name) {
|
||||
|
||||
FileAccess *fa = FileAccess::open(p_name, FileAccess::READ);
|
||||
if (!fa)
|
||||
if (!fa) {
|
||||
return false;
|
||||
}
|
||||
memdelete(fa);
|
||||
return true;
|
||||
}
|
||||
|
||||
uint64_t FileAccessCompressed::_get_modified_time(const String &p_file) {
|
||||
|
||||
if (f)
|
||||
if (f) {
|
||||
return f->get_modified_time(p_file);
|
||||
else
|
||||
} else {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
uint32_t FileAccessCompressed::_get_unix_permissions(const String &p_file) {
|
||||
if (f)
|
||||
if (f) {
|
||||
return f->_get_unix_permissions(p_file);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -390,7 +372,7 @@ Error FileAccessCompressed::_set_unix_permissions(const String &p_file, uint32_t
|
||||
}
|
||||
|
||||
FileAccessCompressed::~FileAccessCompressed() {
|
||||
|
||||
if (f)
|
||||
if (f) {
|
||||
close();
|
||||
}
|
||||
}
|
||||
|
@ -35,7 +35,6 @@
|
||||
#include "core/os/file_access.h"
|
||||
|
||||
class FileAccessCompressed : public FileAccess {
|
||||
|
||||
Compression::Mode cmode = Compression::MODE_ZSTD;
|
||||
bool writing = false;
|
||||
uint32_t write_pos = 0;
|
||||
|
@ -40,7 +40,6 @@
|
||||
#define COMP_MAGIC 0x43454447
|
||||
|
||||
Error FileAccessEncrypted::open_and_parse(FileAccess *p_base, const Vector<uint8_t> &p_key, Mode p_mode) {
|
||||
|
||||
ERR_FAIL_COND_V_MSG(file != nullptr, ERR_ALREADY_IN_USE, "Can't open file while another file from path '" + file->get_path_absolute() + "' is open.");
|
||||
ERR_FAIL_COND_V(p_key.size() != 32, ERR_INVALID_PARAMETER);
|
||||
|
||||
@ -48,7 +47,6 @@ Error FileAccessEncrypted::open_and_parse(FileAccess *p_base, const Vector<uint8
|
||||
eofed = false;
|
||||
|
||||
if (p_mode == MODE_WRITE_AES256) {
|
||||
|
||||
data.clear();
|
||||
writing = true;
|
||||
file = p_base;
|
||||
@ -56,7 +54,6 @@ Error FileAccessEncrypted::open_and_parse(FileAccess *p_base, const Vector<uint8
|
||||
key = p_key;
|
||||
|
||||
} else if (p_mode == MODE_READ) {
|
||||
|
||||
writing = false;
|
||||
key = p_key;
|
||||
uint32_t magic = p_base->get_32();
|
||||
@ -85,7 +82,6 @@ Error FileAccessEncrypted::open_and_parse(FileAccess *p_base, const Vector<uint8
|
||||
ctx.set_decode_key(key.ptrw(), 256);
|
||||
|
||||
for (size_t i = 0; i < ds; i += 16) {
|
||||
|
||||
ctx.decrypt_ecb(&data.write[i], &data.write[i]);
|
||||
}
|
||||
|
||||
@ -103,13 +99,11 @@ Error FileAccessEncrypted::open_and_parse(FileAccess *p_base, const Vector<uint8
|
||||
}
|
||||
|
||||
Error FileAccessEncrypted::open_and_parse_password(FileAccess *p_base, const String &p_key, Mode p_mode) {
|
||||
|
||||
String cs = p_key.md5_text();
|
||||
ERR_FAIL_COND_V(cs.length() != 32, ERR_INVALID_PARAMETER);
|
||||
Vector<uint8_t> key;
|
||||
key.resize(32);
|
||||
for (int i = 0; i < 32; i++) {
|
||||
|
||||
key.write[i] = cs[i];
|
||||
}
|
||||
|
||||
@ -117,16 +111,15 @@ Error FileAccessEncrypted::open_and_parse_password(FileAccess *p_base, const Str
|
||||
}
|
||||
|
||||
Error FileAccessEncrypted::_open(const String &p_path, int p_mode_flags) {
|
||||
|
||||
return OK;
|
||||
}
|
||||
void FileAccessEncrypted::close() {
|
||||
|
||||
if (!file)
|
||||
void FileAccessEncrypted::close() {
|
||||
if (!file) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (writing) {
|
||||
|
||||
Vector<uint8_t> compressed;
|
||||
size_t len = data.size();
|
||||
if (len % 16) {
|
||||
@ -146,7 +139,6 @@ void FileAccessEncrypted::close() {
|
||||
ctx.set_encode_key(key.ptrw(), 256);
|
||||
|
||||
for (size_t i = 0; i < len; i += 16) {
|
||||
|
||||
ctx.encrypt_ecb(&compressed.write[i], &compressed.write[i]);
|
||||
}
|
||||
|
||||
@ -163,7 +155,6 @@ void FileAccessEncrypted::close() {
|
||||
data.clear();
|
||||
|
||||
} else {
|
||||
|
||||
file->close();
|
||||
memdelete(file);
|
||||
data.clear();
|
||||
@ -172,55 +163,51 @@ void FileAccessEncrypted::close() {
|
||||
}
|
||||
|
||||
bool FileAccessEncrypted::is_open() const {
|
||||
|
||||
return file != nullptr;
|
||||
}
|
||||
|
||||
String FileAccessEncrypted::get_path() const {
|
||||
|
||||
if (file)
|
||||
if (file) {
|
||||
return file->get_path();
|
||||
else
|
||||
} else {
|
||||
return "";
|
||||
}
|
||||
}
|
||||
|
||||
String FileAccessEncrypted::get_path_absolute() const {
|
||||
|
||||
if (file)
|
||||
if (file) {
|
||||
return file->get_path_absolute();
|
||||
else
|
||||
} else {
|
||||
return "";
|
||||
}
|
||||
}
|
||||
|
||||
void FileAccessEncrypted::seek(size_t p_position) {
|
||||
|
||||
if (p_position > (size_t)data.size())
|
||||
if (p_position > (size_t)data.size()) {
|
||||
p_position = data.size();
|
||||
}
|
||||
|
||||
pos = p_position;
|
||||
eofed = false;
|
||||
}
|
||||
|
||||
void FileAccessEncrypted::seek_end(int64_t p_position) {
|
||||
|
||||
seek(data.size() + p_position);
|
||||
}
|
||||
size_t FileAccessEncrypted::get_position() const {
|
||||
|
||||
size_t FileAccessEncrypted::get_position() const {
|
||||
return pos;
|
||||
}
|
||||
size_t FileAccessEncrypted::get_len() const {
|
||||
|
||||
size_t FileAccessEncrypted::get_len() const {
|
||||
return data.size();
|
||||
}
|
||||
|
||||
bool FileAccessEncrypted::eof_reached() const {
|
||||
|
||||
return eofed;
|
||||
}
|
||||
|
||||
uint8_t FileAccessEncrypted::get_8() const {
|
||||
|
||||
ERR_FAIL_COND_V_MSG(writing, 0, "File has not been opened in read mode.");
|
||||
if (pos >= data.size()) {
|
||||
eofed = true;
|
||||
@ -231,13 +218,12 @@ uint8_t FileAccessEncrypted::get_8() const {
|
||||
pos++;
|
||||
return b;
|
||||
}
|
||||
int FileAccessEncrypted::get_buffer(uint8_t *p_dst, int p_length) const {
|
||||
|
||||
int FileAccessEncrypted::get_buffer(uint8_t *p_dst, int p_length) const {
|
||||
ERR_FAIL_COND_V_MSG(writing, 0, "File has not been opened in read mode.");
|
||||
|
||||
int to_copy = MIN(p_length, data.size() - pos);
|
||||
for (int i = 0; i < to_copy; i++) {
|
||||
|
||||
p_dst[i] = data[pos++];
|
||||
}
|
||||
|
||||
@ -249,25 +235,19 @@ int FileAccessEncrypted::get_buffer(uint8_t *p_dst, int p_length) const {
|
||||
}
|
||||
|
||||
Error FileAccessEncrypted::get_error() const {
|
||||
|
||||
return eofed ? ERR_FILE_EOF : OK;
|
||||
}
|
||||
|
||||
void FileAccessEncrypted::store_buffer(const uint8_t *p_src, int p_length) {
|
||||
|
||||
ERR_FAIL_COND_MSG(!writing, "File has not been opened in read mode.");
|
||||
|
||||
if (pos < data.size()) {
|
||||
|
||||
for (int i = 0; i < p_length; i++) {
|
||||
|
||||
store_8(p_src[i]);
|
||||
}
|
||||
} else if (pos == data.size()) {
|
||||
|
||||
data.resize(pos + p_length);
|
||||
for (int i = 0; i < p_length; i++) {
|
||||
|
||||
data.write[pos + i] = p_src[i];
|
||||
}
|
||||
pos += p_length;
|
||||
@ -281,7 +261,6 @@ void FileAccessEncrypted::flush() {
|
||||
}
|
||||
|
||||
void FileAccessEncrypted::store_8(uint8_t p_dest) {
|
||||
|
||||
ERR_FAIL_COND_MSG(!writing, "File has not been opened in read mode.");
|
||||
|
||||
if (pos < data.size()) {
|
||||
@ -294,21 +273,19 @@ void FileAccessEncrypted::store_8(uint8_t p_dest) {
|
||||
}
|
||||
|
||||
bool FileAccessEncrypted::file_exists(const String &p_name) {
|
||||
|
||||
FileAccess *fa = FileAccess::open(p_name, FileAccess::READ);
|
||||
if (!fa)
|
||||
if (!fa) {
|
||||
return false;
|
||||
}
|
||||
memdelete(fa);
|
||||
return true;
|
||||
}
|
||||
|
||||
uint64_t FileAccessEncrypted::_get_modified_time(const String &p_file) {
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
uint32_t FileAccessEncrypted::_get_unix_permissions(const String &p_file) {
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -318,7 +295,7 @@ Error FileAccessEncrypted::_set_unix_permissions(const String &p_file, uint32_t
|
||||
}
|
||||
|
||||
FileAccessEncrypted::~FileAccessEncrypted() {
|
||||
|
||||
if (file)
|
||||
if (file) {
|
||||
close();
|
||||
}
|
||||
}
|
||||
|
@ -38,36 +38,34 @@
|
||||
static Map<String, Vector<uint8_t>> *files = nullptr;
|
||||
|
||||
void FileAccessMemory::register_file(String p_name, Vector<uint8_t> p_data) {
|
||||
|
||||
if (!files) {
|
||||
files = memnew((Map<String, Vector<uint8_t>>));
|
||||
}
|
||||
|
||||
String name;
|
||||
if (ProjectSettings::get_singleton())
|
||||
if (ProjectSettings::get_singleton()) {
|
||||
name = ProjectSettings::get_singleton()->globalize_path(p_name);
|
||||
else
|
||||
} else {
|
||||
name = p_name;
|
||||
}
|
||||
//name = DirAccess::normalize_path(name);
|
||||
|
||||
(*files)[name] = p_data;
|
||||
}
|
||||
|
||||
void FileAccessMemory::cleanup() {
|
||||
|
||||
if (!files)
|
||||
if (!files) {
|
||||
return;
|
||||
}
|
||||
|
||||
memdelete(files);
|
||||
}
|
||||
|
||||
FileAccess *FileAccessMemory::create() {
|
||||
|
||||
return memnew(FileAccessMemory);
|
||||
}
|
||||
|
||||
bool FileAccessMemory::file_exists(const String &p_name) {
|
||||
|
||||
String name = fix_path(p_name);
|
||||
//name = DirAccess::normalize_path(name);
|
||||
|
||||
@ -75,7 +73,6 @@ bool FileAccessMemory::file_exists(const String &p_name) {
|
||||
}
|
||||
|
||||
Error FileAccessMemory::open_custom(const uint8_t *p_data, int p_len) {
|
||||
|
||||
data = (uint8_t *)p_data;
|
||||
length = p_len;
|
||||
pos = 0;
|
||||
@ -83,7 +80,6 @@ Error FileAccessMemory::open_custom(const uint8_t *p_data, int p_len) {
|
||||
}
|
||||
|
||||
Error FileAccessMemory::_open(const String &p_path, int p_mode_flags) {
|
||||
|
||||
ERR_FAIL_COND_V(!files, ERR_FILE_NOT_FOUND);
|
||||
|
||||
String name = fix_path(p_path);
|
||||
@ -100,46 +96,38 @@ Error FileAccessMemory::_open(const String &p_path, int p_mode_flags) {
|
||||
}
|
||||
|
||||
void FileAccessMemory::close() {
|
||||
|
||||
data = nullptr;
|
||||
}
|
||||
|
||||
bool FileAccessMemory::is_open() const {
|
||||
|
||||
return data != nullptr;
|
||||
}
|
||||
|
||||
void FileAccessMemory::seek(size_t p_position) {
|
||||
|
||||
ERR_FAIL_COND(!data);
|
||||
pos = p_position;
|
||||
}
|
||||
|
||||
void FileAccessMemory::seek_end(int64_t p_position) {
|
||||
|
||||
ERR_FAIL_COND(!data);
|
||||
pos = length + p_position;
|
||||
}
|
||||
|
||||
size_t FileAccessMemory::get_position() const {
|
||||
|
||||
ERR_FAIL_COND_V(!data, 0);
|
||||
return pos;
|
||||
}
|
||||
|
||||
size_t FileAccessMemory::get_len() const {
|
||||
|
||||
ERR_FAIL_COND_V(!data, 0);
|
||||
return length;
|
||||
}
|
||||
|
||||
bool FileAccessMemory::eof_reached() const {
|
||||
|
||||
return pos > length;
|
||||
}
|
||||
|
||||
uint8_t FileAccessMemory::get_8() const {
|
||||
|
||||
uint8_t ret = 0;
|
||||
if (pos < length) {
|
||||
ret = data[pos];
|
||||
@ -150,7 +138,6 @@ uint8_t FileAccessMemory::get_8() const {
|
||||
}
|
||||
|
||||
int FileAccessMemory::get_buffer(uint8_t *p_dst, int p_length) const {
|
||||
|
||||
ERR_FAIL_COND_V(!data, -1);
|
||||
|
||||
int left = length - pos;
|
||||
@ -167,7 +154,6 @@ int FileAccessMemory::get_buffer(uint8_t *p_dst, int p_length) const {
|
||||
}
|
||||
|
||||
Error FileAccessMemory::get_error() const {
|
||||
|
||||
return pos >= length ? ERR_FILE_EOF : OK;
|
||||
}
|
||||
|
||||
@ -176,14 +162,12 @@ void FileAccessMemory::flush() {
|
||||
}
|
||||
|
||||
void FileAccessMemory::store_8(uint8_t p_byte) {
|
||||
|
||||
ERR_FAIL_COND(!data);
|
||||
ERR_FAIL_COND(pos >= length);
|
||||
data[pos++] = p_byte;
|
||||
}
|
||||
|
||||
void FileAccessMemory::store_buffer(const uint8_t *p_src, int p_length) {
|
||||
|
||||
int left = length - pos;
|
||||
int write = MIN(p_length, left);
|
||||
if (write < p_length) {
|
||||
|
@ -34,7 +34,6 @@
|
||||
#include "core/os/file_access.h"
|
||||
|
||||
class FileAccessMemory : public FileAccess {
|
||||
|
||||
uint8_t *data = nullptr;
|
||||
int length;
|
||||
mutable int pos;
|
||||
|
@ -41,19 +41,16 @@
|
||||
#define DEBUG_TIME(m_what)
|
||||
|
||||
void FileAccessNetworkClient::lock_mutex() {
|
||||
|
||||
mutex.lock();
|
||||
lockcount++;
|
||||
}
|
||||
|
||||
void FileAccessNetworkClient::unlock_mutex() {
|
||||
|
||||
lockcount--;
|
||||
mutex.unlock();
|
||||
}
|
||||
|
||||
void FileAccessNetworkClient::put_32(int p_32) {
|
||||
|
||||
uint8_t buf[4];
|
||||
encode_uint32(p_32, buf);
|
||||
client->put_data(buf, 4);
|
||||
@ -61,7 +58,6 @@ void FileAccessNetworkClient::put_32(int p_32) {
|
||||
}
|
||||
|
||||
void FileAccessNetworkClient::put_64(int64_t p_64) {
|
||||
|
||||
uint8_t buf[8];
|
||||
encode_uint64(p_64, buf);
|
||||
client->put_data(buf, 8);
|
||||
@ -69,24 +65,20 @@ void FileAccessNetworkClient::put_64(int64_t p_64) {
|
||||
}
|
||||
|
||||
int FileAccessNetworkClient::get_32() {
|
||||
|
||||
uint8_t buf[4];
|
||||
client->get_data(buf, 4);
|
||||
return decode_uint32(buf);
|
||||
}
|
||||
|
||||
int64_t FileAccessNetworkClient::get_64() {
|
||||
|
||||
uint8_t buf[8];
|
||||
client->get_data(buf, 8);
|
||||
return decode_uint64(buf);
|
||||
}
|
||||
|
||||
void FileAccessNetworkClient::_thread_func() {
|
||||
|
||||
client->set_no_delay(true);
|
||||
while (!quit) {
|
||||
|
||||
DEBUG_PRINT("SEM WAIT - " + itos(sem->get()));
|
||||
sem.wait();
|
||||
DEBUG_TIME("sem_unlock");
|
||||
@ -123,13 +115,12 @@ void FileAccessNetworkClient::_thread_func() {
|
||||
}
|
||||
}
|
||||
|
||||
if (accesses.has(id))
|
||||
if (accesses.has(id)) {
|
||||
fa = accesses[id];
|
||||
}
|
||||
|
||||
switch (response) {
|
||||
|
||||
case FileAccessNetwork::RESPONSE_OPEN: {
|
||||
|
||||
DEBUG_TIME("sem_open");
|
||||
int status = get_32();
|
||||
if (status != OK) {
|
||||
@ -143,7 +134,6 @@ void FileAccessNetworkClient::_thread_func() {
|
||||
|
||||
} break;
|
||||
case FileAccessNetwork::RESPONSE_DATA: {
|
||||
|
||||
int64_t offset = get_64();
|
||||
uint32_t len = get_32();
|
||||
|
||||
@ -151,19 +141,18 @@ void FileAccessNetworkClient::_thread_func() {
|
||||
block.resize(len);
|
||||
client->get_data(block.ptrw(), len);
|
||||
|
||||
if (fa) //may have been queued
|
||||
if (fa) { //may have been queued
|
||||
fa->_set_block(offset, block);
|
||||
}
|
||||
|
||||
} break;
|
||||
case FileAccessNetwork::RESPONSE_FILE_EXISTS: {
|
||||
|
||||
int status = get_32();
|
||||
fa->exists_modtime = status != 0;
|
||||
fa->sem.post();
|
||||
|
||||
} break;
|
||||
case FileAccessNetwork::RESPONSE_GET_MODTIME: {
|
||||
|
||||
uint64_t status = get_64();
|
||||
fa->exists_modtime = status;
|
||||
fa->sem.post();
|
||||
@ -176,14 +165,12 @@ void FileAccessNetworkClient::_thread_func() {
|
||||
}
|
||||
|
||||
void FileAccessNetworkClient::_thread_func(void *s) {
|
||||
|
||||
FileAccessNetworkClient *self = (FileAccessNetworkClient *)s;
|
||||
|
||||
self->_thread_func();
|
||||
}
|
||||
|
||||
Error FileAccessNetworkClient::connect(const String &p_host, int p_port, const String &p_password) {
|
||||
|
||||
IP_Address ip;
|
||||
|
||||
if (p_host.is_valid_ip_address()) {
|
||||
@ -236,7 +223,6 @@ FileAccessNetworkClient::~FileAccessNetworkClient() {
|
||||
}
|
||||
|
||||
void FileAccessNetwork::_set_block(int p_offset, const Vector<uint8_t> &p_block) {
|
||||
|
||||
int page = p_offset / page_size;
|
||||
ERR_FAIL_INDEX(page, pages.size());
|
||||
if (page < pages.size() - 1) {
|
||||
@ -258,11 +244,11 @@ void FileAccessNetwork::_set_block(int p_offset, const Vector<uint8_t> &p_block)
|
||||
}
|
||||
|
||||
void FileAccessNetwork::_respond(size_t p_len, Error p_status) {
|
||||
|
||||
DEBUG_PRINT("GOT RESPONSE - len: " + itos(p_len) + " status: " + itos(p_status));
|
||||
response = p_status;
|
||||
if (response != OK)
|
||||
if (response != OK) {
|
||||
return;
|
||||
}
|
||||
opened = true;
|
||||
total_size = p_len;
|
||||
int pc = ((total_size - 1) / page_size) + 1;
|
||||
@ -270,10 +256,10 @@ void FileAccessNetwork::_respond(size_t p_len, Error p_status) {
|
||||
}
|
||||
|
||||
Error FileAccessNetwork::_open(const String &p_path, int p_mode_flags) {
|
||||
|
||||
ERR_FAIL_COND_V(p_mode_flags != READ, ERR_UNAVAILABLE);
|
||||
if (opened)
|
||||
if (opened) {
|
||||
close();
|
||||
}
|
||||
FileAccessNetworkClient *nc = FileAccessNetworkClient::singleton;
|
||||
DEBUG_PRINT("open: " + p_path);
|
||||
|
||||
@ -305,9 +291,9 @@ Error FileAccessNetwork::_open(const String &p_path, int p_mode_flags) {
|
||||
}
|
||||
|
||||
void FileAccessNetwork::close() {
|
||||
|
||||
if (!opened)
|
||||
if (!opened) {
|
||||
return;
|
||||
}
|
||||
|
||||
FileAccessNetworkClient *nc = FileAccessNetworkClient::singleton;
|
||||
|
||||
@ -319,13 +305,12 @@ void FileAccessNetwork::close() {
|
||||
opened = false;
|
||||
nc->unlock_mutex();
|
||||
}
|
||||
bool FileAccessNetwork::is_open() const {
|
||||
|
||||
bool FileAccessNetwork::is_open() const {
|
||||
return opened;
|
||||
}
|
||||
|
||||
void FileAccessNetwork::seek(size_t p_position) {
|
||||
|
||||
ERR_FAIL_COND_MSG(!opened, "File must be opened before use.");
|
||||
eof_flag = p_position > total_size;
|
||||
|
||||
@ -337,39 +322,35 @@ void FileAccessNetwork::seek(size_t p_position) {
|
||||
}
|
||||
|
||||
void FileAccessNetwork::seek_end(int64_t p_position) {
|
||||
|
||||
seek(total_size + p_position);
|
||||
}
|
||||
size_t FileAccessNetwork::get_position() const {
|
||||
|
||||
size_t FileAccessNetwork::get_position() const {
|
||||
ERR_FAIL_COND_V_MSG(!opened, 0, "File must be opened before use.");
|
||||
return pos;
|
||||
}
|
||||
size_t FileAccessNetwork::get_len() const {
|
||||
|
||||
size_t FileAccessNetwork::get_len() const {
|
||||
ERR_FAIL_COND_V_MSG(!opened, 0, "File must be opened before use.");
|
||||
return total_size;
|
||||
}
|
||||
|
||||
bool FileAccessNetwork::eof_reached() const {
|
||||
|
||||
ERR_FAIL_COND_V_MSG(!opened, false, "File must be opened before use.");
|
||||
return eof_flag;
|
||||
}
|
||||
|
||||
uint8_t FileAccessNetwork::get_8() const {
|
||||
|
||||
uint8_t v;
|
||||
get_buffer(&v, 1);
|
||||
return v;
|
||||
}
|
||||
|
||||
void FileAccessNetwork::_queue_page(int p_page) const {
|
||||
|
||||
if (p_page >= pages.size())
|
||||
if (p_page >= pages.size()) {
|
||||
return;
|
||||
}
|
||||
if (pages[p_page].buffer.empty() && !pages[p_page].queued) {
|
||||
|
||||
FileAccessNetworkClient *nc = FileAccessNetworkClient::singleton;
|
||||
{
|
||||
MutexLock lock(nc->blockrequest_mutex);
|
||||
@ -388,7 +369,6 @@ void FileAccessNetwork::_queue_page(int p_page) const {
|
||||
}
|
||||
|
||||
int FileAccessNetwork::get_buffer(uint8_t *p_dst, int p_length) const {
|
||||
|
||||
//bool eof=false;
|
||||
if (pos + p_length > total_size) {
|
||||
eof_flag = true;
|
||||
@ -402,7 +382,6 @@ int FileAccessNetwork::get_buffer(uint8_t *p_dst, int p_length) const {
|
||||
uint8_t *buff = last_page_buff;
|
||||
|
||||
for (int i = 0; i < p_length; i++) {
|
||||
|
||||
int page = pos / page_size;
|
||||
|
||||
if (page != last_page) {
|
||||
@ -410,7 +389,6 @@ int FileAccessNetwork::get_buffer(uint8_t *p_dst, int p_length) const {
|
||||
if (pages[page].buffer.empty()) {
|
||||
waiting_on_page = page;
|
||||
for (int j = 0; j < read_ahead; j++) {
|
||||
|
||||
_queue_page(page + j);
|
||||
}
|
||||
buffer_mutex.unlock();
|
||||
@ -418,9 +396,7 @@ int FileAccessNetwork::get_buffer(uint8_t *p_dst, int p_length) const {
|
||||
page_sem.wait();
|
||||
DEBUG_PRINT("done");
|
||||
} else {
|
||||
|
||||
for (int j = 0; j < read_ahead; j++) {
|
||||
|
||||
_queue_page(page + j);
|
||||
}
|
||||
//queue pages
|
||||
@ -440,7 +416,6 @@ int FileAccessNetwork::get_buffer(uint8_t *p_dst, int p_length) const {
|
||||
}
|
||||
|
||||
Error FileAccessNetwork::get_error() const {
|
||||
|
||||
return pos == total_size ? ERR_FILE_EOF : OK;
|
||||
}
|
||||
|
||||
@ -449,12 +424,10 @@ void FileAccessNetwork::flush() {
|
||||
}
|
||||
|
||||
void FileAccessNetwork::store_8(uint8_t p_dest) {
|
||||
|
||||
ERR_FAIL();
|
||||
}
|
||||
|
||||
bool FileAccessNetwork::file_exists(const String &p_path) {
|
||||
|
||||
FileAccessNetworkClient *nc = FileAccessNetworkClient::singleton;
|
||||
nc->lock_mutex();
|
||||
nc->put_32(id);
|
||||
@ -471,7 +444,6 @@ bool FileAccessNetwork::file_exists(const String &p_path) {
|
||||
}
|
||||
|
||||
uint64_t FileAccessNetwork::_get_modified_time(const String &p_file) {
|
||||
|
||||
FileAccessNetworkClient *nc = FileAccessNetworkClient::singleton;
|
||||
nc->lock_mutex();
|
||||
nc->put_32(id);
|
||||
@ -498,7 +470,6 @@ Error FileAccessNetwork::_set_unix_permissions(const String &p_file, uint32_t p_
|
||||
}
|
||||
|
||||
void FileAccessNetwork::configure() {
|
||||
|
||||
GLOBAL_DEF("network/remote_fs/page_size", 65536);
|
||||
ProjectSettings::get_singleton()->set_custom_property_info("network/remote_fs/page_size", PropertyInfo(Variant::INT, "network/remote_fs/page_size", PROPERTY_HINT_RANGE, "1,65536,1,or_greater")); //is used as denominator and can't be zero
|
||||
GLOBAL_DEF("network/remote_fs/page_read_ahead", 4);
|
||||
@ -506,7 +477,6 @@ void FileAccessNetwork::configure() {
|
||||
}
|
||||
|
||||
FileAccessNetwork::FileAccessNetwork() {
|
||||
|
||||
FileAccessNetworkClient *nc = FileAccessNetworkClient::singleton;
|
||||
nc->lock_mutex();
|
||||
id = nc->last_id++;
|
||||
@ -517,7 +487,6 @@ FileAccessNetwork::FileAccessNetwork() {
|
||||
}
|
||||
|
||||
FileAccessNetwork::~FileAccessNetwork() {
|
||||
|
||||
close();
|
||||
|
||||
FileAccessNetworkClient *nc = FileAccessNetworkClient::singleton;
|
||||
|
@ -39,9 +39,7 @@
|
||||
class FileAccessNetwork;
|
||||
|
||||
class FileAccessNetworkClient {
|
||||
|
||||
struct BlockRequest {
|
||||
|
||||
int id;
|
||||
uint64_t offset;
|
||||
int size;
|
||||
@ -84,7 +82,6 @@ public:
|
||||
};
|
||||
|
||||
class FileAccessNetwork : public FileAccess {
|
||||
|
||||
Semaphore sem;
|
||||
Semaphore page_sem;
|
||||
Mutex buffer_mutex;
|
||||
|
@ -35,11 +35,8 @@
|
||||
#include <stdio.h>
|
||||
|
||||
Error PackedData::add_pack(const String &p_path, bool p_replace_files) {
|
||||
|
||||
for (int i = 0; i < sources.size(); i++) {
|
||||
|
||||
if (sources[i]->try_open_pack(p_path, p_replace_files)) {
|
||||
|
||||
return OK;
|
||||
};
|
||||
};
|
||||
@ -48,7 +45,6 @@ Error PackedData::add_pack(const String &p_path, bool p_replace_files) {
|
||||
};
|
||||
|
||||
void PackedData::add_path(const String &pkg_path, const String &path, uint64_t ofs, uint64_t size, const uint8_t *p_md5, PackSource *p_src, bool p_replace_files) {
|
||||
|
||||
PathMD5 pmd5(path.md5_buffer());
|
||||
//printf("adding path %ls, %lli, %lli\n", path.c_str(), pmd5.a, pmd5.b);
|
||||
|
||||
@ -58,12 +54,14 @@ void PackedData::add_path(const String &pkg_path, const String &path, uint64_t o
|
||||
pf.pack = pkg_path;
|
||||
pf.offset = ofs;
|
||||
pf.size = size;
|
||||
for (int i = 0; i < 16; i++)
|
||||
for (int i = 0; i < 16; i++) {
|
||||
pf.md5[i] = p_md5[i];
|
||||
}
|
||||
pf.src = p_src;
|
||||
|
||||
if (!exists || p_replace_files)
|
||||
if (!exists || p_replace_files) {
|
||||
files[pmd5] = pf;
|
||||
}
|
||||
|
||||
if (!exists) {
|
||||
//search for dir
|
||||
@ -75,9 +73,7 @@ void PackedData::add_path(const String &pkg_path, const String &path, uint64_t o
|
||||
Vector<String> ds = p.get_base_dir().split("/");
|
||||
|
||||
for (int j = 0; j < ds.size(); j++) {
|
||||
|
||||
if (!cd->subdirs.has(ds[j])) {
|
||||
|
||||
PackedDir *pd = memnew(PackedDir);
|
||||
pd->name = ds[j];
|
||||
pd->parent = cd;
|
||||
@ -97,7 +93,6 @@ void PackedData::add_path(const String &pkg_path, const String &path, uint64_t o
|
||||
}
|
||||
|
||||
void PackedData::add_pack_source(PackSource *p_source) {
|
||||
|
||||
if (p_source != nullptr) {
|
||||
sources.push_back(p_source);
|
||||
}
|
||||
@ -106,7 +101,6 @@ void PackedData::add_pack_source(PackSource *p_source) {
|
||||
PackedData *PackedData::singleton = nullptr;
|
||||
|
||||
PackedData::PackedData() {
|
||||
|
||||
singleton = this;
|
||||
root = memnew(PackedDir);
|
||||
|
||||
@ -114,14 +108,13 @@ PackedData::PackedData() {
|
||||
}
|
||||
|
||||
void PackedData::_free_packed_dirs(PackedDir *p_dir) {
|
||||
|
||||
for (Map<String, PackedDir *>::Element *E = p_dir->subdirs.front(); E; E = E->next())
|
||||
for (Map<String, PackedDir *>::Element *E = p_dir->subdirs.front(); E; E = E->next()) {
|
||||
_free_packed_dirs(E->get());
|
||||
}
|
||||
memdelete(p_dir);
|
||||
}
|
||||
|
||||
PackedData::~PackedData() {
|
||||
|
||||
for (int i = 0; i < sources.size(); i++) {
|
||||
memdelete(sources[i]);
|
||||
}
|
||||
@ -131,10 +124,10 @@ PackedData::~PackedData() {
|
||||
//////////////////////////////////////////////////////////////////
|
||||
|
||||
bool PackedSourcePCK::try_open_pack(const String &p_path, bool p_replace_files) {
|
||||
|
||||
FileAccess *f = FileAccess::open(p_path, FileAccess::READ);
|
||||
if (!f)
|
||||
if (!f) {
|
||||
return false;
|
||||
}
|
||||
|
||||
uint32_t magic = f->get_32();
|
||||
|
||||
@ -144,7 +137,6 @@ bool PackedSourcePCK::try_open_pack(const String &p_path, bool p_replace_files)
|
||||
f->seek(f->get_position() - 4);
|
||||
magic = f->get_32();
|
||||
if (magic != PACK_HEADER_MAGIC) {
|
||||
|
||||
f->close();
|
||||
memdelete(f);
|
||||
return false;
|
||||
@ -156,7 +148,6 @@ bool PackedSourcePCK::try_open_pack(const String &p_path, bool p_replace_files)
|
||||
|
||||
magic = f->get_32();
|
||||
if (magic != PACK_HEADER_MAGIC) {
|
||||
|
||||
f->close();
|
||||
memdelete(f);
|
||||
return false;
|
||||
@ -187,7 +178,6 @@ bool PackedSourcePCK::try_open_pack(const String &p_path, bool p_replace_files)
|
||||
int file_count = f->get_32();
|
||||
|
||||
for (int i = 0; i < file_count; i++) {
|
||||
|
||||
uint32_t sl = f->get_32();
|
||||
CharString cs;
|
||||
cs.resize(sl + 1);
|
||||
@ -210,30 +200,25 @@ bool PackedSourcePCK::try_open_pack(const String &p_path, bool p_replace_files)
|
||||
};
|
||||
|
||||
FileAccess *PackedSourcePCK::get_file(const String &p_path, PackedData::PackedFile *p_file) {
|
||||
|
||||
return memnew(FileAccessPack(p_path, *p_file));
|
||||
};
|
||||
|
||||
//////////////////////////////////////////////////////////////////
|
||||
|
||||
Error FileAccessPack::_open(const String &p_path, int p_mode_flags) {
|
||||
|
||||
ERR_FAIL_V(ERR_UNAVAILABLE);
|
||||
return ERR_UNAVAILABLE;
|
||||
}
|
||||
|
||||
void FileAccessPack::close() {
|
||||
|
||||
f->close();
|
||||
}
|
||||
|
||||
bool FileAccessPack::is_open() const {
|
||||
|
||||
return f->is_open();
|
||||
}
|
||||
|
||||
void FileAccessPack::seek(size_t p_position) {
|
||||
|
||||
if (p_position > pf.size) {
|
||||
eof = true;
|
||||
} else {
|
||||
@ -243,26 +228,24 @@ void FileAccessPack::seek(size_t p_position) {
|
||||
f->seek(pf.offset + p_position);
|
||||
pos = p_position;
|
||||
}
|
||||
void FileAccessPack::seek_end(int64_t p_position) {
|
||||
|
||||
void FileAccessPack::seek_end(int64_t p_position) {
|
||||
seek(pf.size + p_position);
|
||||
}
|
||||
size_t FileAccessPack::get_position() const {
|
||||
|
||||
size_t FileAccessPack::get_position() const {
|
||||
return pos;
|
||||
}
|
||||
size_t FileAccessPack::get_len() const {
|
||||
|
||||
size_t FileAccessPack::get_len() const {
|
||||
return pf.size;
|
||||
}
|
||||
|
||||
bool FileAccessPack::eof_reached() const {
|
||||
|
||||
return eof;
|
||||
}
|
||||
|
||||
uint8_t FileAccessPack::get_8() const {
|
||||
|
||||
if (pos >= pf.size) {
|
||||
eof = true;
|
||||
return 0;
|
||||
@ -273,9 +256,9 @@ uint8_t FileAccessPack::get_8() const {
|
||||
}
|
||||
|
||||
int FileAccessPack::get_buffer(uint8_t *p_dst, int p_length) const {
|
||||
|
||||
if (eof)
|
||||
if (eof) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
uint64_t to_read = p_length;
|
||||
if (to_read + pos > pf.size) {
|
||||
@ -285,8 +268,9 @@ int FileAccessPack::get_buffer(uint8_t *p_dst, int p_length) const {
|
||||
|
||||
pos += p_length;
|
||||
|
||||
if (to_read <= 0)
|
||||
if (to_read <= 0) {
|
||||
return 0;
|
||||
}
|
||||
f->get_buffer(p_dst, to_read);
|
||||
|
||||
return to_read;
|
||||
@ -298,36 +282,31 @@ void FileAccessPack::set_endian_swap(bool p_swap) {
|
||||
}
|
||||
|
||||
Error FileAccessPack::get_error() const {
|
||||
|
||||
if (eof)
|
||||
if (eof) {
|
||||
return ERR_FILE_EOF;
|
||||
}
|
||||
return OK;
|
||||
}
|
||||
|
||||
void FileAccessPack::flush() {
|
||||
|
||||
ERR_FAIL();
|
||||
}
|
||||
|
||||
void FileAccessPack::store_8(uint8_t p_dest) {
|
||||
|
||||
ERR_FAIL();
|
||||
}
|
||||
|
||||
void FileAccessPack::store_buffer(const uint8_t *p_src, int p_length) {
|
||||
|
||||
ERR_FAIL();
|
||||
}
|
||||
|
||||
bool FileAccessPack::file_exists(const String &p_name) {
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
FileAccessPack::FileAccessPack(const String &p_path, const PackedData::PackedFile &p_file) :
|
||||
pf(p_file),
|
||||
f(FileAccess::open(pf.pack, FileAccess::READ)) {
|
||||
|
||||
ERR_FAIL_COND_MSG(!f, "Can't open pack-referenced file '" + String(pf.pack) + "'.");
|
||||
|
||||
f->seek(pf.offset);
|
||||
@ -336,26 +315,24 @@ FileAccessPack::FileAccessPack(const String &p_path, const PackedData::PackedFil
|
||||
}
|
||||
|
||||
FileAccessPack::~FileAccessPack() {
|
||||
if (f)
|
||||
if (f) {
|
||||
memdelete(f);
|
||||
}
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////////
|
||||
// DIR ACCESS
|
||||
//////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
Error DirAccessPack::list_dir_begin() {
|
||||
|
||||
list_dirs.clear();
|
||||
list_files.clear();
|
||||
|
||||
for (Map<String, PackedData::PackedDir *>::Element *E = current->subdirs.front(); E; E = E->next()) {
|
||||
|
||||
list_dirs.push_back(E->key());
|
||||
}
|
||||
|
||||
for (Set<String>::Element *E = current->files.front(); E; E = E->next()) {
|
||||
|
||||
list_files.push_back(E->get());
|
||||
}
|
||||
|
||||
@ -363,7 +340,6 @@ Error DirAccessPack::list_dir_begin() {
|
||||
}
|
||||
|
||||
String DirAccessPack::get_next() {
|
||||
|
||||
if (list_dirs.size()) {
|
||||
cdir = true;
|
||||
String d = list_dirs.front()->get();
|
||||
@ -378,31 +354,29 @@ String DirAccessPack::get_next() {
|
||||
return String();
|
||||
}
|
||||
}
|
||||
bool DirAccessPack::current_is_dir() const {
|
||||
|
||||
bool DirAccessPack::current_is_dir() const {
|
||||
return cdir;
|
||||
}
|
||||
bool DirAccessPack::current_is_hidden() const {
|
||||
|
||||
bool DirAccessPack::current_is_hidden() const {
|
||||
return false;
|
||||
}
|
||||
void DirAccessPack::list_dir_end() {
|
||||
|
||||
void DirAccessPack::list_dir_end() {
|
||||
list_dirs.clear();
|
||||
list_files.clear();
|
||||
}
|
||||
|
||||
int DirAccessPack::get_drive_count() {
|
||||
|
||||
return 0;
|
||||
}
|
||||
String DirAccessPack::get_drive(int p_drive) {
|
||||
|
||||
String DirAccessPack::get_drive(int p_drive) {
|
||||
return "";
|
||||
}
|
||||
|
||||
Error DirAccessPack::change_dir(String p_dir) {
|
||||
|
||||
String nd = p_dir.replace("\\", "/");
|
||||
bool absolute = false;
|
||||
if (nd.begins_with("res://")) {
|
||||
@ -412,8 +386,9 @@ Error DirAccessPack::change_dir(String p_dir) {
|
||||
|
||||
nd = nd.simplify_path();
|
||||
|
||||
if (nd == "")
|
||||
if (nd == "") {
|
||||
nd = ".";
|
||||
}
|
||||
|
||||
if (nd.begins_with("/")) {
|
||||
nd = nd.replace_first("/", "");
|
||||
@ -424,13 +399,13 @@ Error DirAccessPack::change_dir(String p_dir) {
|
||||
|
||||
PackedData::PackedDir *pd;
|
||||
|
||||
if (absolute)
|
||||
if (absolute) {
|
||||
pd = PackedData::get_singleton()->root;
|
||||
else
|
||||
} else {
|
||||
pd = current;
|
||||
}
|
||||
|
||||
for (int i = 0; i < paths.size(); i++) {
|
||||
|
||||
String p = paths[i];
|
||||
if (p == ".") {
|
||||
continue;
|
||||
@ -439,11 +414,9 @@ Error DirAccessPack::change_dir(String p_dir) {
|
||||
pd = pd->parent;
|
||||
}
|
||||
} else if (pd->subdirs.has(p)) {
|
||||
|
||||
pd = pd->subdirs[p];
|
||||
|
||||
} else {
|
||||
|
||||
return ERR_INVALID_PARAMETER;
|
||||
}
|
||||
}
|
||||
@ -454,7 +427,6 @@ Error DirAccessPack::change_dir(String p_dir) {
|
||||
}
|
||||
|
||||
String DirAccessPack::get_current_dir(bool p_include_drive) {
|
||||
|
||||
PackedData::PackedDir *pd = current;
|
||||
String p = current->name;
|
||||
|
||||
@ -467,35 +439,30 @@ String DirAccessPack::get_current_dir(bool p_include_drive) {
|
||||
}
|
||||
|
||||
bool DirAccessPack::file_exists(String p_file) {
|
||||
|
||||
p_file = fix_path(p_file);
|
||||
|
||||
return current->files.has(p_file);
|
||||
}
|
||||
|
||||
bool DirAccessPack::dir_exists(String p_dir) {
|
||||
|
||||
p_dir = fix_path(p_dir);
|
||||
|
||||
return current->subdirs.has(p_dir);
|
||||
}
|
||||
|
||||
Error DirAccessPack::make_dir(String p_dir) {
|
||||
|
||||
return ERR_UNAVAILABLE;
|
||||
}
|
||||
|
||||
Error DirAccessPack::rename(String p_from, String p_to) {
|
||||
|
||||
return ERR_UNAVAILABLE;
|
||||
}
|
||||
Error DirAccessPack::remove(String p_name) {
|
||||
|
||||
Error DirAccessPack::remove(String p_name) {
|
||||
return ERR_UNAVAILABLE;
|
||||
}
|
||||
|
||||
size_t DirAccessPack::get_space_left() {
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -51,7 +51,6 @@ class PackedData {
|
||||
|
||||
public:
|
||||
struct PackedFile {
|
||||
|
||||
String pack;
|
||||
uint64_t offset; //if offset is ZERO, the file was ERASED
|
||||
uint64_t size;
|
||||
@ -71,7 +70,6 @@ private:
|
||||
uint64_t a = 0;
|
||||
uint64_t b = 0;
|
||||
bool operator<(const PathMD5 &p_md5) const {
|
||||
|
||||
if (p_md5.a == a) {
|
||||
return b < p_md5.b;
|
||||
} else {
|
||||
@ -120,7 +118,6 @@ public:
|
||||
};
|
||||
|
||||
class PackSource {
|
||||
|
||||
public:
|
||||
virtual bool try_open_pack(const String &p_path, bool p_replace_files) = 0;
|
||||
virtual FileAccess *get_file(const String &p_path, PackedData::PackedFile *p_file) = 0;
|
||||
@ -128,14 +125,12 @@ public:
|
||||
};
|
||||
|
||||
class PackedSourcePCK : public PackSource {
|
||||
|
||||
public:
|
||||
virtual bool try_open_pack(const String &p_path, bool p_replace_files);
|
||||
virtual FileAccess *get_file(const String &p_path, PackedData::PackedFile *p_file);
|
||||
};
|
||||
|
||||
class FileAccessPack : public FileAccess {
|
||||
|
||||
PackedData::PackedFile pf;
|
||||
|
||||
mutable size_t pos;
|
||||
@ -178,24 +173,23 @@ public:
|
||||
};
|
||||
|
||||
FileAccess *PackedData::try_open_path(const String &p_path) {
|
||||
|
||||
PathMD5 pmd5(p_path.md5_buffer());
|
||||
Map<PathMD5, PackedFile>::Element *E = files.find(pmd5);
|
||||
if (!E)
|
||||
if (!E) {
|
||||
return nullptr; //not found
|
||||
if (E->get().offset == 0)
|
||||
}
|
||||
if (E->get().offset == 0) {
|
||||
return nullptr; //was erased
|
||||
}
|
||||
|
||||
return E->get().src->get_file(p_path, &E->get());
|
||||
}
|
||||
|
||||
bool PackedData::has_path(const String &p_path) {
|
||||
|
||||
return files.has(PathMD5(p_path.md5_buffer()));
|
||||
}
|
||||
|
||||
class DirAccessPack : public DirAccess {
|
||||
|
||||
PackedData::PackedDir *current;
|
||||
|
||||
List<String> list_dirs;
|
||||
|
@ -40,7 +40,6 @@ ZipArchive *ZipArchive::instance = nullptr;
|
||||
extern "C" {
|
||||
|
||||
static void *godot_open(void *data, const char *p_fname, int mode) {
|
||||
|
||||
if (mode & ZLIB_FILEFUNC_MODE_WRITE) {
|
||||
return nullptr;
|
||||
}
|
||||
@ -52,30 +51,25 @@ static void *godot_open(void *data, const char *p_fname, int mode) {
|
||||
}
|
||||
|
||||
static uLong godot_read(void *data, void *fdata, void *buf, uLong size) {
|
||||
|
||||
FileAccess *f = (FileAccess *)data;
|
||||
f->get_buffer((uint8_t *)buf, size);
|
||||
return size;
|
||||
}
|
||||
|
||||
static uLong godot_write(voidpf opaque, voidpf stream, const void *buf, uLong size) {
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static long godot_tell(voidpf opaque, voidpf stream) {
|
||||
|
||||
FileAccess *f = (FileAccess *)opaque;
|
||||
return f->get_position();
|
||||
}
|
||||
|
||||
static long godot_seek(voidpf opaque, voidpf stream, uLong offset, int origin) {
|
||||
|
||||
FileAccess *f = (FileAccess *)opaque;
|
||||
|
||||
int pos = offset;
|
||||
switch (origin) {
|
||||
|
||||
case ZLIB_FILEFUNC_SEEK_CUR:
|
||||
pos = f->get_position() + offset;
|
||||
break;
|
||||
@ -91,32 +85,27 @@ static long godot_seek(voidpf opaque, voidpf stream, uLong offset, int origin) {
|
||||
}
|
||||
|
||||
static int godot_close(voidpf opaque, voidpf stream) {
|
||||
|
||||
FileAccess *f = (FileAccess *)opaque;
|
||||
f->close();
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int godot_testerror(voidpf opaque, voidpf stream) {
|
||||
|
||||
FileAccess *f = (FileAccess *)opaque;
|
||||
return f->get_error() != OK ? 1 : 0;
|
||||
}
|
||||
|
||||
static voidpf godot_alloc(voidpf opaque, uInt items, uInt size) {
|
||||
|
||||
return memalloc(items * size);
|
||||
}
|
||||
|
||||
static void godot_free(voidpf opaque, voidpf address) {
|
||||
|
||||
memfree(address);
|
||||
}
|
||||
|
||||
} // extern "C"
|
||||
|
||||
void ZipArchive::close_handle(unzFile p_file) const {
|
||||
|
||||
ERR_FAIL_COND_MSG(!p_file, "Cannot close a file if none is open.");
|
||||
FileAccess *f = (FileAccess *)unzGetOpaque(p_file);
|
||||
unzCloseCurrentFile(p_file);
|
||||
@ -125,7 +114,6 @@ void ZipArchive::close_handle(unzFile p_file) const {
|
||||
}
|
||||
|
||||
unzFile ZipArchive::get_file_handle(String p_file) const {
|
||||
|
||||
ERR_FAIL_COND_V_MSG(!file_exists(p_file), nullptr, "File '" + p_file + " doesn't exist.");
|
||||
File file = files[p_file];
|
||||
|
||||
@ -152,7 +140,6 @@ unzFile ZipArchive::get_file_handle(String p_file) const {
|
||||
ERR_FAIL_COND_V(!pkg, nullptr);
|
||||
int unz_err = unzGoToFilePos(pkg, &file.file_pos);
|
||||
if (unz_err != UNZ_OK || unzOpenCurrentFile(pkg) != UNZ_OK) {
|
||||
|
||||
unzClose(pkg);
|
||||
ERR_FAIL_V(nullptr);
|
||||
}
|
||||
@ -161,16 +148,17 @@ unzFile ZipArchive::get_file_handle(String p_file) const {
|
||||
}
|
||||
|
||||
bool ZipArchive::try_open_pack(const String &p_path, bool p_replace_files) {
|
||||
|
||||
//printf("opening zip pack %ls, %i, %i\n", p_name.c_str(), p_name.extension().nocasecmp_to("zip"), p_name.extension().nocasecmp_to("pcz"));
|
||||
if (p_path.get_extension().nocasecmp_to("zip") != 0 && p_path.get_extension().nocasecmp_to("pcz") != 0)
|
||||
if (p_path.get_extension().nocasecmp_to("zip") != 0 && p_path.get_extension().nocasecmp_to("pcz") != 0) {
|
||||
return false;
|
||||
}
|
||||
|
||||
zlib_filefunc_def io;
|
||||
|
||||
FileAccess *fa = FileAccess::open(p_path, FileAccess::READ);
|
||||
if (!fa)
|
||||
if (!fa) {
|
||||
return false;
|
||||
}
|
||||
io.opaque = fa;
|
||||
io.zopen_file = godot_open;
|
||||
io.zread_file = godot_read;
|
||||
@ -195,7 +183,6 @@ bool ZipArchive::try_open_pack(const String &p_path, bool p_replace_files) {
|
||||
int pkg_num = packages.size() - 1;
|
||||
|
||||
for (uint64_t i = 0; i < gi.number_entry; i++) {
|
||||
|
||||
char filename_inzip[256];
|
||||
|
||||
unz_file_info64 file_info;
|
||||
@ -222,17 +209,14 @@ bool ZipArchive::try_open_pack(const String &p_path, bool p_replace_files) {
|
||||
}
|
||||
|
||||
bool ZipArchive::file_exists(String p_name) const {
|
||||
|
||||
return files.has(p_name);
|
||||
}
|
||||
|
||||
FileAccess *ZipArchive::get_file(const String &p_path, PackedData::PackedFile *p_file) {
|
||||
|
||||
return memnew(FileAccessZip(p_path, *p_file));
|
||||
}
|
||||
|
||||
ZipArchive *ZipArchive::get_singleton() {
|
||||
|
||||
if (instance == nullptr) {
|
||||
instance = memnew(ZipArchive);
|
||||
}
|
||||
@ -245,9 +229,7 @@ ZipArchive::ZipArchive() {
|
||||
}
|
||||
|
||||
ZipArchive::~ZipArchive() {
|
||||
|
||||
for (int i = 0; i < packages.size(); i++) {
|
||||
|
||||
FileAccess *f = (FileAccess *)unzGetOpaque(packages[i].zfile);
|
||||
unzClose(packages[i].zfile);
|
||||
memdelete(f);
|
||||
@ -257,7 +239,6 @@ ZipArchive::~ZipArchive() {
|
||||
}
|
||||
|
||||
Error FileAccessZip::_open(const String &p_path, int p_mode_flags) {
|
||||
|
||||
close();
|
||||
|
||||
ERR_FAIL_COND_V(p_mode_flags & FileAccess::WRITE, FAILED);
|
||||
@ -273,9 +254,9 @@ Error FileAccessZip::_open(const String &p_path, int p_mode_flags) {
|
||||
}
|
||||
|
||||
void FileAccessZip::close() {
|
||||
|
||||
if (!zfile)
|
||||
if (!zfile) {
|
||||
return;
|
||||
}
|
||||
|
||||
ZipArchive *arch = ZipArchive::get_singleton();
|
||||
ERR_FAIL_COND(!arch);
|
||||
@ -284,65 +265,57 @@ void FileAccessZip::close() {
|
||||
}
|
||||
|
||||
bool FileAccessZip::is_open() const {
|
||||
|
||||
return zfile != nullptr;
|
||||
}
|
||||
|
||||
void FileAccessZip::seek(size_t p_position) {
|
||||
|
||||
ERR_FAIL_COND(!zfile);
|
||||
unzSeekCurrentFile(zfile, p_position);
|
||||
}
|
||||
|
||||
void FileAccessZip::seek_end(int64_t p_position) {
|
||||
|
||||
ERR_FAIL_COND(!zfile);
|
||||
unzSeekCurrentFile(zfile, get_len() + p_position);
|
||||
}
|
||||
|
||||
size_t FileAccessZip::get_position() const {
|
||||
|
||||
ERR_FAIL_COND_V(!zfile, 0);
|
||||
return unztell(zfile);
|
||||
}
|
||||
|
||||
size_t FileAccessZip::get_len() const {
|
||||
|
||||
ERR_FAIL_COND_V(!zfile, 0);
|
||||
return file_info.uncompressed_size;
|
||||
}
|
||||
|
||||
bool FileAccessZip::eof_reached() const {
|
||||
|
||||
ERR_FAIL_COND_V(!zfile, true);
|
||||
|
||||
return at_eof;
|
||||
}
|
||||
|
||||
uint8_t FileAccessZip::get_8() const {
|
||||
|
||||
uint8_t ret = 0;
|
||||
get_buffer(&ret, 1);
|
||||
return ret;
|
||||
}
|
||||
|
||||
int FileAccessZip::get_buffer(uint8_t *p_dst, int p_length) const {
|
||||
|
||||
ERR_FAIL_COND_V(!zfile, -1);
|
||||
at_eof = unzeof(zfile);
|
||||
if (at_eof)
|
||||
if (at_eof) {
|
||||
return 0;
|
||||
}
|
||||
int read = unzReadCurrentFile(zfile, p_dst, p_length);
|
||||
ERR_FAIL_COND_V(read < 0, read);
|
||||
if (read < p_length)
|
||||
if (read < p_length) {
|
||||
at_eof = true;
|
||||
}
|
||||
return read;
|
||||
}
|
||||
|
||||
Error FileAccessZip::get_error() const {
|
||||
|
||||
if (!zfile) {
|
||||
|
||||
return ERR_UNCONFIGURED;
|
||||
}
|
||||
if (eof_reached()) {
|
||||
@ -353,17 +326,14 @@ Error FileAccessZip::get_error() const {
|
||||
}
|
||||
|
||||
void FileAccessZip::flush() {
|
||||
|
||||
ERR_FAIL();
|
||||
}
|
||||
|
||||
void FileAccessZip::store_8(uint8_t p_dest) {
|
||||
|
||||
ERR_FAIL();
|
||||
}
|
||||
|
||||
bool FileAccessZip::file_exists(const String &p_name) {
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
|
@ -41,10 +41,8 @@
|
||||
#include <stdlib.h>
|
||||
|
||||
class ZipArchive : public PackSource {
|
||||
|
||||
public:
|
||||
struct File {
|
||||
|
||||
int package = -1;
|
||||
unz_file_pos file_pos;
|
||||
File() {}
|
||||
@ -81,7 +79,6 @@ public:
|
||||
};
|
||||
|
||||
class FileAccessZip : public FileAccess {
|
||||
|
||||
unzFile zfile;
|
||||
unz_file_info64 file_info;
|
||||
|
||||
|
@ -47,7 +47,6 @@ const char *HTTPClient::_methods[METHOD_MAX] = {
|
||||
|
||||
#ifndef JAVASCRIPT_ENABLED
|
||||
Error HTTPClient::connect_to_host(const String &p_host, int p_port, bool p_ssl, bool p_verify_host) {
|
||||
|
||||
close();
|
||||
|
||||
conn_port = p_port;
|
||||
@ -58,10 +57,8 @@ Error HTTPClient::connect_to_host(const String &p_host, int p_port, bool p_ssl,
|
||||
|
||||
String host_lower = conn_host.to_lower();
|
||||
if (host_lower.begins_with("http://")) {
|
||||
|
||||
conn_host = conn_host.substr(7, conn_host.length() - 7);
|
||||
} else if (host_lower.begins_with("https://")) {
|
||||
|
||||
ssl = true;
|
||||
conn_host = conn_host.substr(8, conn_host.length() - 8);
|
||||
}
|
||||
@ -97,7 +94,6 @@ Error HTTPClient::connect_to_host(const String &p_host, int p_port, bool p_ssl,
|
||||
}
|
||||
|
||||
void HTTPClient::set_connection(const Ref<StreamPeer> &p_connection) {
|
||||
|
||||
ERR_FAIL_COND_MSG(p_connection.is_null(), "Connection is not a reference to a valid StreamPeer object.");
|
||||
|
||||
close();
|
||||
@ -106,12 +102,10 @@ void HTTPClient::set_connection(const Ref<StreamPeer> &p_connection) {
|
||||
}
|
||||
|
||||
Ref<StreamPeer> HTTPClient::get_connection() const {
|
||||
|
||||
return connection;
|
||||
}
|
||||
|
||||
Error HTTPClient::request_raw(Method p_method, const String &p_url, const Vector<String> &p_headers, const Vector<uint8_t> &p_body) {
|
||||
|
||||
ERR_FAIL_INDEX_V(p_method, METHOD_MAX, ERR_INVALID_PARAMETER);
|
||||
ERR_FAIL_COND_V(!p_url.begins_with("/"), ERR_INVALID_PARAMETER);
|
||||
ERR_FAIL_COND_V(status != STATUS_CONNECTED, ERR_INVALID_PARAMETER);
|
||||
@ -179,7 +173,6 @@ Error HTTPClient::request_raw(Method p_method, const String &p_url, const Vector
|
||||
}
|
||||
|
||||
Error HTTPClient::request(Method p_method, const String &p_url, const Vector<String> &p_headers, const String &p_body) {
|
||||
|
||||
ERR_FAIL_INDEX_V(p_method, METHOD_MAX, ERR_INVALID_PARAMETER);
|
||||
ERR_FAIL_COND_V(!p_url.begins_with("/"), ERR_INVALID_PARAMETER);
|
||||
ERR_FAIL_COND_V(status != STATUS_CONNECTED, ERR_INVALID_PARAMETER);
|
||||
@ -235,27 +228,23 @@ Error HTTPClient::request(Method p_method, const String &p_url, const Vector<Str
|
||||
}
|
||||
|
||||
bool HTTPClient::has_response() const {
|
||||
|
||||
return response_headers.size() != 0;
|
||||
}
|
||||
|
||||
bool HTTPClient::is_response_chunked() const {
|
||||
|
||||
return chunked;
|
||||
}
|
||||
|
||||
int HTTPClient::get_response_code() const {
|
||||
|
||||
return response_num;
|
||||
}
|
||||
|
||||
Error HTTPClient::get_response_headers(List<String> *r_response) {
|
||||
|
||||
if (!response_headers.size())
|
||||
if (!response_headers.size()) {
|
||||
return ERR_INVALID_PARAMETER;
|
||||
}
|
||||
|
||||
for (int i = 0; i < response_headers.size(); i++) {
|
||||
|
||||
r_response->push_back(response_headers[i]);
|
||||
}
|
||||
|
||||
@ -265,15 +254,14 @@ Error HTTPClient::get_response_headers(List<String> *r_response) {
|
||||
}
|
||||
|
||||
void HTTPClient::close() {
|
||||
|
||||
if (tcp_connection->get_status() != StreamPeerTCP::STATUS_NONE)
|
||||
if (tcp_connection->get_status() != StreamPeerTCP::STATUS_NONE) {
|
||||
tcp_connection->disconnect_from_host();
|
||||
}
|
||||
|
||||
connection.unref();
|
||||
status = STATUS_DISCONNECTED;
|
||||
head_request = false;
|
||||
if (resolving != IP::RESOLVER_INVALID_ID) {
|
||||
|
||||
IP::get_singleton()->erase_resolve_item(resolving);
|
||||
resolving = IP::RESOLVER_INVALID_ID;
|
||||
}
|
||||
@ -290,9 +278,7 @@ void HTTPClient::close() {
|
||||
}
|
||||
|
||||
Error HTTPClient::poll() {
|
||||
|
||||
switch (status) {
|
||||
|
||||
case STATUS_RESOLVING: {
|
||||
ERR_FAIL_COND_V(resolving == IP::RESOLVER_INVALID_ID, ERR_BUG);
|
||||
|
||||
@ -302,7 +288,6 @@ Error HTTPClient::poll() {
|
||||
return OK; // Still resolving
|
||||
|
||||
case IP::RESOLVER_STATUS_DONE: {
|
||||
|
||||
IP_Address host = IP::get_singleton()->get_resolve_item_address(resolving);
|
||||
Error err = tcp_connection->connect_to_host(host, conn_port);
|
||||
IP::get_singleton()->erase_resolve_item(resolving);
|
||||
@ -316,7 +301,6 @@ Error HTTPClient::poll() {
|
||||
} break;
|
||||
case IP::RESOLVER_STATUS_NONE:
|
||||
case IP::RESOLVER_STATUS_ERROR: {
|
||||
|
||||
IP::get_singleton()->erase_resolve_item(resolving);
|
||||
resolving = IP::RESOLVER_INVALID_ID;
|
||||
close();
|
||||
@ -326,10 +310,8 @@ Error HTTPClient::poll() {
|
||||
}
|
||||
} break;
|
||||
case STATUS_CONNECTING: {
|
||||
|
||||
StreamPeerTCP::Status s = tcp_connection->get_status();
|
||||
switch (s) {
|
||||
|
||||
case StreamPeerTCP::STATUS_CONNECTING: {
|
||||
return OK;
|
||||
} break;
|
||||
@ -379,7 +361,6 @@ Error HTTPClient::poll() {
|
||||
} break;
|
||||
case StreamPeerTCP::STATUS_ERROR:
|
||||
case StreamPeerTCP::STATUS_NONE: {
|
||||
|
||||
close();
|
||||
status = STATUS_CANT_CONNECT;
|
||||
return ERR_CANT_CONNECT;
|
||||
@ -404,7 +385,6 @@ Error HTTPClient::poll() {
|
||||
return OK;
|
||||
} break;
|
||||
case STATUS_REQUESTING: {
|
||||
|
||||
while (true) {
|
||||
uint8_t byte;
|
||||
int rec = 0;
|
||||
@ -415,15 +395,15 @@ Error HTTPClient::poll() {
|
||||
return ERR_CONNECTION_ERROR;
|
||||
}
|
||||
|
||||
if (rec == 0)
|
||||
if (rec == 0) {
|
||||
return OK; // Still requesting, keep trying!
|
||||
}
|
||||
|
||||
response_str.push_back(byte);
|
||||
int rs = response_str.size();
|
||||
if (
|
||||
(rs >= 2 && response_str[rs - 2] == '\n' && response_str[rs - 1] == '\n') ||
|
||||
(rs >= 4 && response_str[rs - 4] == '\r' && response_str[rs - 3] == '\n' && response_str[rs - 2] == '\r' && response_str[rs - 1] == '\n')) {
|
||||
|
||||
// End of response, parse.
|
||||
response_str.push_back(0);
|
||||
String response;
|
||||
@ -445,11 +425,11 @@ Error HTTPClient::poll() {
|
||||
bool keep_alive = true;
|
||||
|
||||
for (int i = 0; i < responses.size(); i++) {
|
||||
|
||||
String header = responses[i].strip_edges();
|
||||
String s = header.to_lower();
|
||||
if (s.length() == 0)
|
||||
if (s.length() == 0) {
|
||||
continue;
|
||||
}
|
||||
if (s.begins_with("content-length:")) {
|
||||
body_size = s.substr(s.find(":") + 1, s.length()).strip_edges().to_int();
|
||||
body_left = body_size;
|
||||
@ -464,11 +444,9 @@ Error HTTPClient::poll() {
|
||||
}
|
||||
|
||||
if (i == 0 && responses[i].begins_with("HTTP")) {
|
||||
|
||||
String num = responses[i].get_slicec(' ', 1);
|
||||
response_num = num.to_int();
|
||||
} else {
|
||||
|
||||
response_headers.push_back(header);
|
||||
}
|
||||
}
|
||||
@ -480,14 +458,11 @@ Error HTTPClient::poll() {
|
||||
}
|
||||
|
||||
if (body_size != -1 || chunked) {
|
||||
|
||||
status = STATUS_BODY;
|
||||
} else if (!keep_alive) {
|
||||
|
||||
read_until_eof = true;
|
||||
status = STATUS_BODY;
|
||||
} else {
|
||||
|
||||
status = STATUS_CONNECTED;
|
||||
}
|
||||
return OK;
|
||||
@ -513,29 +488,26 @@ Error HTTPClient::poll() {
|
||||
}
|
||||
|
||||
int HTTPClient::get_response_body_length() const {
|
||||
|
||||
return body_size;
|
||||
}
|
||||
|
||||
PackedByteArray HTTPClient::read_response_body_chunk() {
|
||||
|
||||
ERR_FAIL_COND_V(status != STATUS_BODY, PackedByteArray());
|
||||
|
||||
PackedByteArray ret;
|
||||
Error err = OK;
|
||||
|
||||
if (chunked) {
|
||||
|
||||
while (true) {
|
||||
|
||||
if (chunk_trailer_part) {
|
||||
// We need to consume the trailer part too or keep-alive will break
|
||||
uint8_t b;
|
||||
int rec = 0;
|
||||
err = _get_http_data(&b, 1, rec);
|
||||
|
||||
if (rec == 0)
|
||||
if (rec == 0) {
|
||||
break;
|
||||
}
|
||||
|
||||
chunk.push_back(b);
|
||||
int cs = chunk.size();
|
||||
@ -557,8 +529,9 @@ PackedByteArray HTTPClient::read_response_body_chunk() {
|
||||
int rec = 0;
|
||||
err = _get_http_data(&b, 1, rec);
|
||||
|
||||
if (rec == 0)
|
||||
if (rec == 0) {
|
||||
break;
|
||||
}
|
||||
|
||||
chunk.push_back(b);
|
||||
|
||||
@ -569,18 +542,17 @@ PackedByteArray HTTPClient::read_response_body_chunk() {
|
||||
}
|
||||
|
||||
if (chunk.size() > 2 && chunk[chunk.size() - 2] == '\r' && chunk[chunk.size() - 1] == '\n') {
|
||||
|
||||
int len = 0;
|
||||
for (int i = 0; i < chunk.size() - 2; i++) {
|
||||
char c = chunk[i];
|
||||
int v = 0;
|
||||
if (c >= '0' && c <= '9')
|
||||
if (c >= '0' && c <= '9') {
|
||||
v = c - '0';
|
||||
else if (c >= 'a' && c <= 'f')
|
||||
} else if (c >= 'a' && c <= 'f') {
|
||||
v = c - 'a' + 10;
|
||||
else if (c >= 'A' && c <= 'F')
|
||||
} else if (c >= 'A' && c <= 'F') {
|
||||
v = c - 'A' + 10;
|
||||
else {
|
||||
} else {
|
||||
ERR_PRINT("HTTP Chunk len not in hex!!");
|
||||
status = STATUS_CONNECTION_ERROR;
|
||||
break;
|
||||
@ -605,7 +577,6 @@ PackedByteArray HTTPClient::read_response_body_chunk() {
|
||||
chunk.resize(chunk_left);
|
||||
}
|
||||
} else {
|
||||
|
||||
int rec = 0;
|
||||
err = _get_http_data(&chunk.write[chunk.size() - chunk_left], chunk_left, rec);
|
||||
if (rec == 0) {
|
||||
@ -614,7 +585,6 @@ PackedByteArray HTTPClient::read_response_body_chunk() {
|
||||
chunk_left -= rec;
|
||||
|
||||
if (chunk_left == 0) {
|
||||
|
||||
if (chunk[chunk.size() - 2] != '\r' || chunk[chunk.size() - 1] != '\n') {
|
||||
ERR_PRINT("HTTP Invalid chunk terminator (not \\r\\n)");
|
||||
status = STATUS_CONNECTION_ERROR;
|
||||
@ -632,7 +602,6 @@ PackedByteArray HTTPClient::read_response_body_chunk() {
|
||||
}
|
||||
|
||||
} else {
|
||||
|
||||
int to_read = !read_until_eof ? MIN(body_left, read_chunk_size) : read_chunk_size;
|
||||
ret.resize(to_read);
|
||||
int _offset = 0;
|
||||
@ -652,24 +621,21 @@ PackedByteArray HTTPClient::read_response_body_chunk() {
|
||||
body_left -= rec;
|
||||
}
|
||||
}
|
||||
if (err != OK)
|
||||
if (err != OK) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (err != OK) {
|
||||
|
||||
close();
|
||||
|
||||
if (err == ERR_FILE_EOF) {
|
||||
|
||||
status = STATUS_DISCONNECTED; // Server disconnected
|
||||
} else {
|
||||
|
||||
status = STATUS_CONNECTION_ERROR;
|
||||
}
|
||||
} else if (body_left == 0 && !chunked && !read_until_eof) {
|
||||
|
||||
status = STATUS_CONNECTED;
|
||||
}
|
||||
|
||||
@ -677,24 +643,19 @@ PackedByteArray HTTPClient::read_response_body_chunk() {
|
||||
}
|
||||
|
||||
HTTPClient::Status HTTPClient::get_status() const {
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
void HTTPClient::set_blocking_mode(bool p_enable) {
|
||||
|
||||
blocking = p_enable;
|
||||
}
|
||||
|
||||
bool HTTPClient::is_blocking_mode_enabled() const {
|
||||
|
||||
return blocking;
|
||||
}
|
||||
|
||||
Error HTTPClient::_get_http_data(uint8_t *p_buffer, int p_bytes, int &r_received) {
|
||||
|
||||
if (blocking) {
|
||||
|
||||
// We can't use StreamPeer.get_data, since when reaching EOF we will get an
|
||||
// error without knowing how many bytes we received.
|
||||
Error err = ERR_FILE_EOF;
|
||||
@ -767,15 +728,15 @@ String HTTPClient::query_string_from_dict(const Dictionary &p_dict) {
|
||||
}
|
||||
|
||||
Dictionary HTTPClient::_get_response_headers_as_dictionary() {
|
||||
|
||||
List<String> rh;
|
||||
get_response_headers(&rh);
|
||||
Dictionary ret;
|
||||
for (const List<String>::Element *E = rh.front(); E; E = E->next()) {
|
||||
const String &s = E->get();
|
||||
int sp = s.find(":");
|
||||
if (sp == -1)
|
||||
if (sp == -1) {
|
||||
continue;
|
||||
}
|
||||
String key = s.substr(0, sp).strip_edges();
|
||||
String value = s.substr(sp + 1, s.length()).strip_edges();
|
||||
ret[key] = value;
|
||||
@ -785,7 +746,6 @@ Dictionary HTTPClient::_get_response_headers_as_dictionary() {
|
||||
}
|
||||
|
||||
PackedStringArray HTTPClient::_get_response_headers() {
|
||||
|
||||
List<String> rh;
|
||||
get_response_headers(&rh);
|
||||
PackedStringArray ret;
|
||||
@ -799,7 +759,6 @@ PackedStringArray HTTPClient::_get_response_headers() {
|
||||
}
|
||||
|
||||
void HTTPClient::_bind_methods() {
|
||||
|
||||
ClassDB::bind_method(D_METHOD("connect_to_host", "host", "port", "use_ssl", "verify_host"), &HTTPClient::connect_to_host, DEFVAL(-1), DEFVAL(false), DEFVAL(true));
|
||||
ClassDB::bind_method(D_METHOD("set_connection", "connection"), &HTTPClient::set_connection);
|
||||
ClassDB::bind_method(D_METHOD("get_connection"), &HTTPClient::get_connection);
|
||||
|
@ -37,7 +37,6 @@
|
||||
#include "core/reference.h"
|
||||
|
||||
class HTTPClient : public Reference {
|
||||
|
||||
GDCLASS(HTTPClient, Reference);
|
||||
|
||||
public:
|
||||
|
@ -33,14 +33,13 @@
|
||||
#include "core/print_string.h"
|
||||
|
||||
bool ImageFormatLoader::recognize(const String &p_extension) const {
|
||||
|
||||
List<String> extensions;
|
||||
get_recognized_extensions(&extensions);
|
||||
for (List<String>::Element *E = extensions.front(); E; E = E->next()) {
|
||||
|
||||
if (E->get().nocasecmp_to(p_extension) == 0)
|
||||
if (E->get().nocasecmp_to(p_extension) == 0) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
@ -61,44 +60,42 @@ Error ImageLoader::load_image(String p_file, Ref<Image> p_image, FileAccess *p_c
|
||||
String extension = p_file.get_extension();
|
||||
|
||||
for (int i = 0; i < loader.size(); i++) {
|
||||
|
||||
if (!loader[i]->recognize(extension))
|
||||
if (!loader[i]->recognize(extension)) {
|
||||
continue;
|
||||
}
|
||||
Error err = loader[i]->load_image(p_image, f, p_force_linear, p_scale);
|
||||
if (err != OK) {
|
||||
ERR_PRINT("Error loading image: " + p_file);
|
||||
}
|
||||
|
||||
if (err != ERR_FILE_UNRECOGNIZED) {
|
||||
|
||||
if (!p_custom)
|
||||
if (!p_custom) {
|
||||
memdelete(f);
|
||||
}
|
||||
|
||||
return err;
|
||||
}
|
||||
}
|
||||
|
||||
if (!p_custom)
|
||||
if (!p_custom) {
|
||||
memdelete(f);
|
||||
}
|
||||
|
||||
return ERR_FILE_UNRECOGNIZED;
|
||||
}
|
||||
|
||||
void ImageLoader::get_recognized_extensions(List<String> *p_extensions) {
|
||||
|
||||
for (int i = 0; i < loader.size(); i++) {
|
||||
|
||||
loader[i]->get_recognized_extensions(p_extensions);
|
||||
}
|
||||
}
|
||||
|
||||
ImageFormatLoader *ImageLoader::recognize(const String &p_extension) {
|
||||
|
||||
for (int i = 0; i < loader.size(); i++) {
|
||||
|
||||
if (loader[i]->recognize(p_extension))
|
||||
if (loader[i]->recognize(p_extension)) {
|
||||
return loader[i];
|
||||
}
|
||||
}
|
||||
|
||||
return nullptr;
|
||||
}
|
||||
@ -106,22 +103,18 @@ ImageFormatLoader *ImageLoader::recognize(const String &p_extension) {
|
||||
Vector<ImageFormatLoader *> ImageLoader::loader;
|
||||
|
||||
void ImageLoader::add_image_format_loader(ImageFormatLoader *p_loader) {
|
||||
|
||||
loader.push_back(p_loader);
|
||||
}
|
||||
|
||||
void ImageLoader::remove_image_format_loader(ImageFormatLoader *p_loader) {
|
||||
|
||||
loader.erase(p_loader);
|
||||
}
|
||||
|
||||
const Vector<ImageFormatLoader *> &ImageLoader::get_image_format_loaders() {
|
||||
|
||||
return loader;
|
||||
}
|
||||
|
||||
void ImageLoader::cleanup() {
|
||||
|
||||
while (loader.size()) {
|
||||
remove_image_format_loader(loader[0]);
|
||||
}
|
||||
@ -130,7 +123,6 @@ void ImageLoader::cleanup() {
|
||||
/////////////////
|
||||
|
||||
RES ResourceFormatLoaderImage::load(const String &p_path, const String &p_original_path, Error *r_error, bool p_use_sub_threads, float *r_progress, bool p_no_cache) {
|
||||
|
||||
FileAccess *f = FileAccess::open(p_path, FileAccess::READ);
|
||||
if (!f) {
|
||||
if (r_error) {
|
||||
@ -192,16 +184,13 @@ RES ResourceFormatLoaderImage::load(const String &p_path, const String &p_origin
|
||||
}
|
||||
|
||||
void ResourceFormatLoaderImage::get_recognized_extensions(List<String> *p_extensions) const {
|
||||
|
||||
p_extensions->push_back("image");
|
||||
}
|
||||
|
||||
bool ResourceFormatLoaderImage::handles_type(const String &p_type) const {
|
||||
|
||||
return p_type == "Image";
|
||||
}
|
||||
|
||||
String ResourceFormatLoaderImage::get_resource_type(const String &p_path) const {
|
||||
|
||||
return p_path.get_extension().to_lower() == "image" ? "Image" : String();
|
||||
}
|
||||
|
@ -53,7 +53,6 @@ public:
|
||||
};
|
||||
|
||||
class ImageLoader {
|
||||
|
||||
static Vector<ImageFormatLoader *> loader;
|
||||
friend class ResourceFormatLoaderImage;
|
||||
|
||||
|
@ -39,9 +39,7 @@ VARIANT_ENUM_CAST(IP::ResolverStatus);
|
||||
/************* RESOLVER ******************/
|
||||
|
||||
struct _IP_ResolverPrivate {
|
||||
|
||||
struct QueueItem {
|
||||
|
||||
volatile IP::ResolverStatus status;
|
||||
IP_Address response;
|
||||
String hostname;
|
||||
@ -62,11 +60,11 @@ struct _IP_ResolverPrivate {
|
||||
QueueItem queue[IP::RESOLVER_MAX_QUERIES];
|
||||
|
||||
IP::ResolverID find_empty_id() const {
|
||||
|
||||
for (int i = 0; i < IP::RESOLVER_MAX_QUERIES; i++) {
|
||||
if (queue[i].status == IP::RESOLVER_STATUS_NONE)
|
||||
if (queue[i].status == IP::RESOLVER_STATUS_NONE) {
|
||||
return i;
|
||||
}
|
||||
}
|
||||
return IP::RESOLVER_INVALID_ID;
|
||||
}
|
||||
|
||||
@ -78,26 +76,24 @@ struct _IP_ResolverPrivate {
|
||||
bool thread_abort;
|
||||
|
||||
void resolve_queues() {
|
||||
|
||||
for (int i = 0; i < IP::RESOLVER_MAX_QUERIES; i++) {
|
||||
|
||||
if (queue[i].status != IP::RESOLVER_STATUS_WAITING)
|
||||
if (queue[i].status != IP::RESOLVER_STATUS_WAITING) {
|
||||
continue;
|
||||
}
|
||||
queue[i].response = IP::get_singleton()->resolve_hostname(queue[i].hostname, queue[i].type);
|
||||
|
||||
if (!queue[i].response.is_valid())
|
||||
if (!queue[i].response.is_valid()) {
|
||||
queue[i].status = IP::RESOLVER_STATUS_ERROR;
|
||||
else
|
||||
} else {
|
||||
queue[i].status = IP::RESOLVER_STATUS_DONE;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void _thread_function(void *self) {
|
||||
|
||||
_IP_ResolverPrivate *ipr = (_IP_ResolverPrivate *)self;
|
||||
|
||||
while (!ipr->thread_abort) {
|
||||
|
||||
ipr->sem.wait();
|
||||
|
||||
MutexLock lock(ipr->mutex);
|
||||
@ -113,7 +109,6 @@ struct _IP_ResolverPrivate {
|
||||
};
|
||||
|
||||
IP_Address IP::resolve_hostname(const String &p_hostname, IP::Type p_type) {
|
||||
|
||||
MutexLock lock(resolver->mutex);
|
||||
|
||||
String key = _IP_ResolverPrivate::get_cache_key(p_hostname, p_type);
|
||||
@ -128,7 +123,6 @@ IP_Address IP::resolve_hostname(const String &p_hostname, IP::Type p_type) {
|
||||
}
|
||||
|
||||
IP::ResolverID IP::resolve_hostname_queue_item(const String &p_hostname, IP::Type p_type) {
|
||||
|
||||
MutexLock lock(resolver->mutex);
|
||||
|
||||
ResolverID id = resolver->find_empty_id();
|
||||
@ -147,17 +141,17 @@ IP::ResolverID IP::resolve_hostname_queue_item(const String &p_hostname, IP::Typ
|
||||
} else {
|
||||
resolver->queue[id].response = IP_Address();
|
||||
resolver->queue[id].status = IP::RESOLVER_STATUS_WAITING;
|
||||
if (resolver->thread)
|
||||
if (resolver->thread) {
|
||||
resolver->sem.post();
|
||||
else
|
||||
} else {
|
||||
resolver->resolve_queues();
|
||||
}
|
||||
}
|
||||
|
||||
return id;
|
||||
}
|
||||
|
||||
IP::ResolverStatus IP::get_resolve_item_status(ResolverID p_id) const {
|
||||
|
||||
ERR_FAIL_INDEX_V(p_id, IP::RESOLVER_MAX_QUERIES, IP::RESOLVER_STATUS_NONE);
|
||||
|
||||
MutexLock lock(resolver->mutex);
|
||||
@ -171,7 +165,6 @@ IP::ResolverStatus IP::get_resolve_item_status(ResolverID p_id) const {
|
||||
}
|
||||
|
||||
IP_Address IP::get_resolve_item_address(ResolverID p_id) const {
|
||||
|
||||
ERR_FAIL_INDEX_V(p_id, IP::RESOLVER_MAX_QUERIES, IP_Address());
|
||||
|
||||
MutexLock lock(resolver->mutex);
|
||||
@ -186,7 +179,6 @@ IP_Address IP::get_resolve_item_address(ResolverID p_id) const {
|
||||
}
|
||||
|
||||
void IP::erase_resolve_item(ResolverID p_id) {
|
||||
|
||||
ERR_FAIL_INDEX(p_id, IP::RESOLVER_MAX_QUERIES);
|
||||
|
||||
MutexLock lock(resolver->mutex);
|
||||
@ -195,7 +187,6 @@ void IP::erase_resolve_item(ResolverID p_id) {
|
||||
}
|
||||
|
||||
void IP::clear_cache(const String &p_hostname) {
|
||||
|
||||
MutexLock lock(resolver->mutex);
|
||||
|
||||
if (p_hostname.empty()) {
|
||||
@ -209,7 +200,6 @@ void IP::clear_cache(const String &p_hostname) {
|
||||
}
|
||||
|
||||
Array IP::_get_local_addresses() const {
|
||||
|
||||
Array addresses;
|
||||
List<IP_Address> ip_addresses;
|
||||
get_local_addresses(&ip_addresses);
|
||||
@ -221,7 +211,6 @@ Array IP::_get_local_addresses() const {
|
||||
}
|
||||
|
||||
Array IP::_get_local_interfaces() const {
|
||||
|
||||
Array results;
|
||||
Map<String, Interface_Info> interfaces;
|
||||
get_local_interfaces(&interfaces);
|
||||
@ -245,7 +234,6 @@ Array IP::_get_local_interfaces() const {
|
||||
}
|
||||
|
||||
void IP::get_local_addresses(List<IP_Address> *r_addresses) const {
|
||||
|
||||
Map<String, Interface_Info> interfaces;
|
||||
get_local_interfaces(&interfaces);
|
||||
for (Map<String, Interface_Info>::Element *E = interfaces.front(); E; E = E->next()) {
|
||||
@ -256,7 +244,6 @@ void IP::get_local_addresses(List<IP_Address> *r_addresses) const {
|
||||
}
|
||||
|
||||
void IP::_bind_methods() {
|
||||
|
||||
ClassDB::bind_method(D_METHOD("resolve_hostname", "host", "ip_type"), &IP::resolve_hostname, DEFVAL(IP::TYPE_ANY));
|
||||
ClassDB::bind_method(D_METHOD("resolve_hostname_queue_item", "host", "ip_type"), &IP::resolve_hostname_queue_item, DEFVAL(IP::TYPE_ANY));
|
||||
ClassDB::bind_method(D_METHOD("get_resolve_item_status", "id"), &IP::get_resolve_item_status);
|
||||
@ -283,21 +270,18 @@ void IP::_bind_methods() {
|
||||
IP *IP::singleton = nullptr;
|
||||
|
||||
IP *IP::get_singleton() {
|
||||
|
||||
return singleton;
|
||||
}
|
||||
|
||||
IP *(*IP::_create)() = nullptr;
|
||||
|
||||
IP *IP::create() {
|
||||
|
||||
ERR_FAIL_COND_V_MSG(singleton, nullptr, "IP singleton already exist.");
|
||||
ERR_FAIL_COND_V(!_create, nullptr);
|
||||
return _create();
|
||||
}
|
||||
|
||||
IP::IP() {
|
||||
|
||||
singleton = this;
|
||||
resolver = memnew(_IP_ResolverPrivate);
|
||||
|
||||
@ -312,7 +296,6 @@ IP::IP() {
|
||||
}
|
||||
|
||||
IP::~IP() {
|
||||
|
||||
#ifndef NO_THREADS
|
||||
if (resolver->thread) {
|
||||
resolver->thread_abort = true;
|
||||
|
@ -39,20 +39,23 @@ IP_Address::operator Variant() const {
|
||||
#include <string.h>
|
||||
|
||||
IP_Address::operator String() const {
|
||||
|
||||
if (wildcard)
|
||||
if (wildcard) {
|
||||
return "*";
|
||||
}
|
||||
|
||||
if (!valid)
|
||||
if (!valid) {
|
||||
return "";
|
||||
}
|
||||
|
||||
if (is_ipv4())
|
||||
if (is_ipv4()) {
|
||||
// IPv4 address mapped to IPv6
|
||||
return itos(field8[12]) + "." + itos(field8[13]) + "." + itos(field8[14]) + "." + itos(field8[15]);
|
||||
}
|
||||
String ret;
|
||||
for (int i = 0; i < 8; i++) {
|
||||
if (i > 0)
|
||||
if (i > 0) {
|
||||
ret = ret + ":";
|
||||
}
|
||||
uint16_t num = (field8[i * 2] << 8) + field8[i * 2 + 1];
|
||||
ret = ret + String::num_int64(num, 16);
|
||||
};
|
||||
@ -61,10 +64,8 @@ IP_Address::operator String() const {
|
||||
}
|
||||
|
||||
static void _parse_hex(const String &p_string, int p_start, uint8_t *p_dst) {
|
||||
|
||||
uint16_t ret = 0;
|
||||
for (int i = p_start; i < p_start + 4; i++) {
|
||||
|
||||
if (i >= p_string.length()) {
|
||||
break;
|
||||
};
|
||||
@ -72,7 +73,6 @@ static void _parse_hex(const String &p_string, int p_start, uint8_t *p_dst) {
|
||||
int n = 0;
|
||||
CharType c = p_string[i];
|
||||
if (c >= '0' && c <= '9') {
|
||||
|
||||
n = c - '0';
|
||||
} else if (c >= 'a' && c <= 'f') {
|
||||
n = 10 + (c - 'a');
|
||||
@ -92,7 +92,6 @@ static void _parse_hex(const String &p_string, int p_start, uint8_t *p_dst) {
|
||||
};
|
||||
|
||||
void IP_Address::_parse_ipv6(const String &p_string) {
|
||||
|
||||
static const int parts_total = 8;
|
||||
int parts[parts_total] = { 0 };
|
||||
int parts_count = 0;
|
||||
@ -102,10 +101,8 @@ void IP_Address::_parse_ipv6(const String &p_string) {
|
||||
int parts_idx = 0;
|
||||
|
||||
for (int i = 0; i < p_string.length(); i++) {
|
||||
|
||||
CharType c = p_string[i];
|
||||
if (c == ':') {
|
||||
|
||||
if (i == 0) {
|
||||
continue; // next must be a ":"
|
||||
};
|
||||
@ -115,7 +112,6 @@ void IP_Address::_parse_ipv6(const String &p_string) {
|
||||
};
|
||||
part_found = false;
|
||||
} else if (c == '.') {
|
||||
|
||||
part_ipv4 = true;
|
||||
|
||||
} else if ((c >= '0' && c <= '9') || (c >= 'a' && c <= 'f') || (c >= 'A' && c <= 'F')) {
|
||||
@ -136,9 +132,7 @@ void IP_Address::_parse_ipv6(const String &p_string) {
|
||||
|
||||
int idx = 0;
|
||||
for (int i = 0; i < parts_idx; i++) {
|
||||
|
||||
if (parts[i] == -1) {
|
||||
|
||||
for (int j = 0; j < parts_extra; j++) {
|
||||
field16[idx++] = 0;
|
||||
};
|
||||
@ -154,7 +148,6 @@ void IP_Address::_parse_ipv6(const String &p_string) {
|
||||
};
|
||||
|
||||
void IP_Address::_parse_ipv4(const String &p_string, int p_start, uint8_t *p_ret) {
|
||||
|
||||
String ip;
|
||||
if (p_start != 0) {
|
||||
ip = p_string.substr(p_start, p_string.length() - p_start);
|
||||
@ -170,7 +163,6 @@ void IP_Address::_parse_ipv4(const String &p_string, int p_start, uint8_t *p_ret
|
||||
};
|
||||
|
||||
void IP_Address::clear() {
|
||||
|
||||
memset(&field8[0], 0, sizeof(field8));
|
||||
valid = false;
|
||||
wildcard = false;
|
||||
@ -199,12 +191,12 @@ const uint8_t *IP_Address::get_ipv6() const {
|
||||
void IP_Address::set_ipv6(const uint8_t *p_buf) {
|
||||
clear();
|
||||
valid = true;
|
||||
for (int i = 0; i < 16; i++)
|
||||
for (int i = 0; i < 16; i++) {
|
||||
field8[i] = p_buf[i];
|
||||
}
|
||||
}
|
||||
|
||||
IP_Address::IP_Address(const String &p_string) {
|
||||
|
||||
clear();
|
||||
|
||||
if (p_string == "*") {
|
||||
@ -228,7 +220,6 @@ IP_Address::IP_Address(const String &p_string) {
|
||||
}
|
||||
|
||||
_FORCE_INLINE_ static void _32_to_buf(uint8_t *p_dst, uint32_t p_n) {
|
||||
|
||||
p_dst[0] = (p_n >> 24) & 0xff;
|
||||
p_dst[1] = (p_n >> 16) & 0xff;
|
||||
p_dst[2] = (p_n >> 8) & 0xff;
|
||||
@ -236,7 +227,6 @@ _FORCE_INLINE_ static void _32_to_buf(uint8_t *p_dst, uint32_t p_n) {
|
||||
};
|
||||
|
||||
IP_Address::IP_Address(uint32_t p_a, uint32_t p_b, uint32_t p_c, uint32_t p_d, bool is_v6) {
|
||||
|
||||
clear();
|
||||
valid = true;
|
||||
if (!is_v6) {
|
||||
@ -247,7 +237,6 @@ IP_Address::IP_Address(uint32_t p_a, uint32_t p_b, uint32_t p_c, uint32_t p_d, b
|
||||
field8[14] = p_c;
|
||||
field8[15] = p_d;
|
||||
} else {
|
||||
|
||||
_32_to_buf(&field8[0], p_a);
|
||||
_32_to_buf(&field8[4], p_b);
|
||||
_32_to_buf(&field8[8], p_c);
|
||||
|
@ -34,7 +34,6 @@
|
||||
#include "core/ustring.h"
|
||||
|
||||
struct IP_Address {
|
||||
|
||||
private:
|
||||
union {
|
||||
uint8_t field8[16];
|
||||
@ -52,23 +51,32 @@ protected:
|
||||
public:
|
||||
//operator Variant() const;
|
||||
bool operator==(const IP_Address &p_ip) const {
|
||||
if (p_ip.valid != valid)
|
||||
if (p_ip.valid != valid) {
|
||||
return false;
|
||||
if (!valid)
|
||||
}
|
||||
if (!valid) {
|
||||
return false;
|
||||
for (int i = 0; i < 4; i++)
|
||||
if (field32[i] != p_ip.field32[i])
|
||||
}
|
||||
for (int i = 0; i < 4; i++) {
|
||||
if (field32[i] != p_ip.field32[i]) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
bool operator!=(const IP_Address &p_ip) const {
|
||||
if (p_ip.valid != valid)
|
||||
if (p_ip.valid != valid) {
|
||||
return true;
|
||||
if (!valid)
|
||||
}
|
||||
if (!valid) {
|
||||
return true;
|
||||
for (int i = 0; i < 4; i++)
|
||||
if (field32[i] != p_ip.field32[i])
|
||||
}
|
||||
for (int i = 0; i < 4; i++) {
|
||||
if (field32[i] != p_ip.field32[i]) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
|
@ -46,17 +46,16 @@ const char *JSON::tk_name[TK_MAX] = {
|
||||
};
|
||||
|
||||
static String _make_indent(const String &p_indent, int p_size) {
|
||||
|
||||
String indent_text = "";
|
||||
if (!p_indent.empty()) {
|
||||
for (int i = 0; i < p_size; i++)
|
||||
for (int i = 0; i < p_size; i++) {
|
||||
indent_text += p_indent;
|
||||
}
|
||||
}
|
||||
return indent_text;
|
||||
}
|
||||
|
||||
String JSON::_print_var(const Variant &p_var, const String &p_indent, int p_cur_indent, bool p_sort_keys) {
|
||||
|
||||
String colon = ":";
|
||||
String end_statement = "";
|
||||
|
||||
@ -66,7 +65,6 @@ String JSON::_print_var(const Variant &p_var, const String &p_indent, int p_cur_
|
||||
}
|
||||
|
||||
switch (p_var.get_type()) {
|
||||
|
||||
case Variant::NIL:
|
||||
return "null";
|
||||
case Variant::BOOL:
|
||||
@ -81,7 +79,6 @@ String JSON::_print_var(const Variant &p_var, const String &p_indent, int p_cur_
|
||||
case Variant::PACKED_FLOAT64_ARRAY:
|
||||
case Variant::PACKED_STRING_ARRAY:
|
||||
case Variant::ARRAY: {
|
||||
|
||||
String s = "[";
|
||||
s += end_statement;
|
||||
Array a = p_var;
|
||||
@ -96,18 +93,17 @@ String JSON::_print_var(const Variant &p_var, const String &p_indent, int p_cur_
|
||||
return s;
|
||||
};
|
||||
case Variant::DICTIONARY: {
|
||||
|
||||
String s = "{";
|
||||
s += end_statement;
|
||||
Dictionary d = p_var;
|
||||
List<Variant> keys;
|
||||
d.get_key_list(&keys);
|
||||
|
||||
if (p_sort_keys)
|
||||
if (p_sort_keys) {
|
||||
keys.sort();
|
||||
}
|
||||
|
||||
for (List<Variant>::Element *E = keys.front(); E; E = E->next()) {
|
||||
|
||||
if (E != keys.front()) {
|
||||
s += ",";
|
||||
s += end_statement;
|
||||
@ -126,17 +122,13 @@ String JSON::_print_var(const Variant &p_var, const String &p_indent, int p_cur_
|
||||
}
|
||||
|
||||
String JSON::print(const Variant &p_var, const String &p_indent, bool p_sort_keys) {
|
||||
|
||||
return _print_var(p_var, p_indent, 0, p_sort_keys);
|
||||
}
|
||||
|
||||
Error JSON::_get_token(const CharType *p_str, int &index, int p_len, Token &r_token, int &line, String &r_err_str) {
|
||||
|
||||
while (p_len > 0) {
|
||||
switch (p_str[index]) {
|
||||
|
||||
case '\n': {
|
||||
|
||||
line++;
|
||||
index++;
|
||||
break;
|
||||
@ -146,43 +138,36 @@ Error JSON::_get_token(const CharType *p_str, int &index, int p_len, Token &r_to
|
||||
return OK;
|
||||
} break;
|
||||
case '{': {
|
||||
|
||||
r_token.type = TK_CURLY_BRACKET_OPEN;
|
||||
index++;
|
||||
return OK;
|
||||
};
|
||||
case '}': {
|
||||
|
||||
r_token.type = TK_CURLY_BRACKET_CLOSE;
|
||||
index++;
|
||||
return OK;
|
||||
};
|
||||
case '[': {
|
||||
|
||||
r_token.type = TK_BRACKET_OPEN;
|
||||
index++;
|
||||
return OK;
|
||||
};
|
||||
case ']': {
|
||||
|
||||
r_token.type = TK_BRACKET_CLOSE;
|
||||
index++;
|
||||
return OK;
|
||||
};
|
||||
case ':': {
|
||||
|
||||
r_token.type = TK_COLON;
|
||||
index++;
|
||||
return OK;
|
||||
};
|
||||
case ',': {
|
||||
|
||||
r_token.type = TK_COMMA;
|
||||
index++;
|
||||
return OK;
|
||||
};
|
||||
case '"': {
|
||||
|
||||
index++;
|
||||
String str;
|
||||
while (true) {
|
||||
@ -203,7 +188,6 @@ Error JSON::_get_token(const CharType *p_str, int &index, int p_len, Token &r_to
|
||||
CharType res = 0;
|
||||
|
||||
switch (next) {
|
||||
|
||||
case 'b':
|
||||
res = 8;
|
||||
break;
|
||||
@ -228,7 +212,6 @@ Error JSON::_get_token(const CharType *p_str, int &index, int p_len, Token &r_to
|
||||
return ERR_PARSE_ERROR;
|
||||
}
|
||||
if (!((c >= '0' && c <= '9') || (c >= 'a' && c <= 'f') || (c >= 'A' && c <= 'F'))) {
|
||||
|
||||
r_err_str = "Malformed hex constant in string";
|
||||
return ERR_PARSE_ERROR;
|
||||
}
|
||||
@ -260,8 +243,9 @@ Error JSON::_get_token(const CharType *p_str, int &index, int p_len, Token &r_to
|
||||
str += res;
|
||||
|
||||
} else {
|
||||
if (p_str[index] == '\n')
|
||||
if (p_str[index] == '\n') {
|
||||
line++;
|
||||
}
|
||||
str += p_str[index];
|
||||
}
|
||||
index++;
|
||||
@ -273,7 +257,6 @@ Error JSON::_get_token(const CharType *p_str, int &index, int p_len, Token &r_to
|
||||
|
||||
} break;
|
||||
default: {
|
||||
|
||||
if (p_str[index] <= 32) {
|
||||
index++;
|
||||
break;
|
||||
@ -289,11 +272,9 @@ Error JSON::_get_token(const CharType *p_str, int &index, int p_len, Token &r_to
|
||||
return OK;
|
||||
|
||||
} else if ((p_str[index] >= 'A' && p_str[index] <= 'Z') || (p_str[index] >= 'a' && p_str[index] <= 'z')) {
|
||||
|
||||
String id;
|
||||
|
||||
while ((p_str[index] >= 'A' && p_str[index] <= 'Z') || (p_str[index] >= 'a' && p_str[index] <= 'z')) {
|
||||
|
||||
id += p_str[index];
|
||||
index++;
|
||||
}
|
||||
@ -313,45 +294,41 @@ Error JSON::_get_token(const CharType *p_str, int &index, int p_len, Token &r_to
|
||||
}
|
||||
|
||||
Error JSON::_parse_value(Variant &value, Token &token, const CharType *p_str, int &index, int p_len, int &line, String &r_err_str) {
|
||||
|
||||
if (token.type == TK_CURLY_BRACKET_OPEN) {
|
||||
|
||||
Dictionary d;
|
||||
Error err = _parse_object(d, p_str, index, p_len, line, r_err_str);
|
||||
if (err)
|
||||
if (err) {
|
||||
return err;
|
||||
}
|
||||
value = d;
|
||||
return OK;
|
||||
} else if (token.type == TK_BRACKET_OPEN) {
|
||||
|
||||
Array a;
|
||||
Error err = _parse_array(a, p_str, index, p_len, line, r_err_str);
|
||||
if (err)
|
||||
if (err) {
|
||||
return err;
|
||||
}
|
||||
value = a;
|
||||
return OK;
|
||||
|
||||
} else if (token.type == TK_IDENTIFIER) {
|
||||
|
||||
String id = token.value;
|
||||
if (id == "true")
|
||||
if (id == "true") {
|
||||
value = true;
|
||||
else if (id == "false")
|
||||
} else if (id == "false") {
|
||||
value = false;
|
||||
else if (id == "null")
|
||||
} else if (id == "null") {
|
||||
value = Variant();
|
||||
else {
|
||||
} else {
|
||||
r_err_str = "Expected 'true','false' or 'null', got '" + id + "'.";
|
||||
return ERR_PARSE_ERROR;
|
||||
}
|
||||
return OK;
|
||||
|
||||
} else if (token.type == TK_NUMBER) {
|
||||
|
||||
value = token.value;
|
||||
return OK;
|
||||
} else if (token.type == TK_STRING) {
|
||||
|
||||
value = token.value;
|
||||
return OK;
|
||||
} else {
|
||||
@ -361,25 +338,21 @@ Error JSON::_parse_value(Variant &value, Token &token, const CharType *p_str, in
|
||||
}
|
||||
|
||||
Error JSON::_parse_array(Array &array, const CharType *p_str, int &index, int p_len, int &line, String &r_err_str) {
|
||||
|
||||
Token token;
|
||||
bool need_comma = false;
|
||||
|
||||
while (index < p_len) {
|
||||
|
||||
Error err = _get_token(p_str, index, p_len, token, line, r_err_str);
|
||||
if (err != OK)
|
||||
if (err != OK) {
|
||||
return err;
|
||||
}
|
||||
|
||||
if (token.type == TK_BRACKET_CLOSE) {
|
||||
|
||||
return OK;
|
||||
}
|
||||
|
||||
if (need_comma) {
|
||||
|
||||
if (token.type != TK_COMMA) {
|
||||
|
||||
r_err_str = "Expected ','";
|
||||
return ERR_PARSE_ERROR;
|
||||
} else {
|
||||
@ -390,8 +363,9 @@ Error JSON::_parse_array(Array &array, const CharType *p_str, int &index, int p_
|
||||
|
||||
Variant v;
|
||||
err = _parse_value(v, token, p_str, index, p_len, line, r_err_str);
|
||||
if (err)
|
||||
if (err) {
|
||||
return err;
|
||||
}
|
||||
|
||||
array.push_back(v);
|
||||
need_comma = true;
|
||||
@ -401,29 +375,24 @@ Error JSON::_parse_array(Array &array, const CharType *p_str, int &index, int p_
|
||||
}
|
||||
|
||||
Error JSON::_parse_object(Dictionary &object, const CharType *p_str, int &index, int p_len, int &line, String &r_err_str) {
|
||||
|
||||
bool at_key = true;
|
||||
String key;
|
||||
Token token;
|
||||
bool need_comma = false;
|
||||
|
||||
while (index < p_len) {
|
||||
|
||||
if (at_key) {
|
||||
|
||||
Error err = _get_token(p_str, index, p_len, token, line, r_err_str);
|
||||
if (err != OK)
|
||||
if (err != OK) {
|
||||
return err;
|
||||
}
|
||||
|
||||
if (token.type == TK_CURLY_BRACKET_CLOSE) {
|
||||
|
||||
return OK;
|
||||
}
|
||||
|
||||
if (need_comma) {
|
||||
|
||||
if (token.type != TK_COMMA) {
|
||||
|
||||
r_err_str = "Expected '}' or ','";
|
||||
return ERR_PARSE_ERROR;
|
||||
} else {
|
||||
@ -433,31 +402,31 @@ Error JSON::_parse_object(Dictionary &object, const CharType *p_str, int &index,
|
||||
}
|
||||
|
||||
if (token.type != TK_STRING) {
|
||||
|
||||
r_err_str = "Expected key";
|
||||
return ERR_PARSE_ERROR;
|
||||
}
|
||||
|
||||
key = token.value;
|
||||
err = _get_token(p_str, index, p_len, token, line, r_err_str);
|
||||
if (err != OK)
|
||||
if (err != OK) {
|
||||
return err;
|
||||
}
|
||||
if (token.type != TK_COLON) {
|
||||
|
||||
r_err_str = "Expected ':'";
|
||||
return ERR_PARSE_ERROR;
|
||||
}
|
||||
at_key = false;
|
||||
} else {
|
||||
|
||||
Error err = _get_token(p_str, index, p_len, token, line, r_err_str);
|
||||
if (err != OK)
|
||||
if (err != OK) {
|
||||
return err;
|
||||
}
|
||||
|
||||
Variant v;
|
||||
err = _parse_value(v, token, p_str, index, p_len, line, r_err_str);
|
||||
if (err)
|
||||
if (err) {
|
||||
return err;
|
||||
}
|
||||
object[key] = v;
|
||||
need_comma = true;
|
||||
at_key = true;
|
||||
@ -468,7 +437,6 @@ Error JSON::_parse_object(Dictionary &object, const CharType *p_str, int &index,
|
||||
}
|
||||
|
||||
Error JSON::parse(const String &p_json, Variant &r_ret, String &r_err_str, int &r_err_line) {
|
||||
|
||||
const CharType *str = p_json.ptr();
|
||||
int idx = 0;
|
||||
int len = p_json.length();
|
||||
@ -477,8 +445,9 @@ Error JSON::parse(const String &p_json, Variant &r_ret, String &r_err_str, int &
|
||||
String aux_key;
|
||||
|
||||
Error err = _get_token(str, idx, len, token, r_err_line, r_err_str);
|
||||
if (err)
|
||||
if (err) {
|
||||
return err;
|
||||
}
|
||||
|
||||
err = _parse_value(r_ret, token, str, idx, len, r_err_line, r_err_str);
|
||||
|
||||
|
@ -34,7 +34,6 @@
|
||||
#include "core/variant.h"
|
||||
|
||||
class JSON {
|
||||
|
||||
enum TokenType {
|
||||
TK_CURLY_BRACKET_OPEN,
|
||||
TK_CURLY_BRACKET_CLOSE,
|
||||
@ -58,7 +57,6 @@ class JSON {
|
||||
};
|
||||
|
||||
struct Token {
|
||||
|
||||
TokenType type;
|
||||
Variant value;
|
||||
};
|
||||
|
@ -67,10 +67,11 @@ void Logger::log_error(const char *p_function, const char *p_file, int p_line, c
|
||||
}
|
||||
|
||||
const char *err_details;
|
||||
if (p_rationale && *p_rationale)
|
||||
if (p_rationale && *p_rationale) {
|
||||
err_details = p_rationale;
|
||||
else
|
||||
} else {
|
||||
err_details = p_code;
|
||||
}
|
||||
|
||||
logf_error("%s: %s\n", err_type, err_details);
|
||||
logf_error(" at: %s (%s:%i) - %s\n", p_function, p_file, p_line, p_code);
|
||||
|
@ -62,7 +62,6 @@ public:
|
||||
* Writes messages to stdout/stderr.
|
||||
*/
|
||||
class StdLogger : public Logger {
|
||||
|
||||
public:
|
||||
virtual void logv(const char *p_format, va_list p_list, bool p_err) _PRINTF_FORMAT_ATTRIBUTE_2_0;
|
||||
virtual ~StdLogger() {}
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -41,21 +41,17 @@
|
||||
*/
|
||||
|
||||
union MarshallFloat {
|
||||
|
||||
uint32_t i; ///< int
|
||||
float f; ///< float
|
||||
};
|
||||
|
||||
union MarshallDouble {
|
||||
|
||||
uint64_t l; ///< long long
|
||||
double d; ///< double
|
||||
};
|
||||
|
||||
static inline unsigned int encode_uint16(uint16_t p_uint, uint8_t *p_arr) {
|
||||
|
||||
for (int i = 0; i < 2; i++) {
|
||||
|
||||
*p_arr = p_uint & 0xFF;
|
||||
p_arr++;
|
||||
p_uint >>= 8;
|
||||
@ -65,9 +61,7 @@ static inline unsigned int encode_uint16(uint16_t p_uint, uint8_t *p_arr) {
|
||||
}
|
||||
|
||||
static inline unsigned int encode_uint32(uint32_t p_uint, uint8_t *p_arr) {
|
||||
|
||||
for (int i = 0; i < 4; i++) {
|
||||
|
||||
*p_arr = p_uint & 0xFF;
|
||||
p_arr++;
|
||||
p_uint >>= 8;
|
||||
@ -77,7 +71,6 @@ static inline unsigned int encode_uint32(uint32_t p_uint, uint8_t *p_arr) {
|
||||
}
|
||||
|
||||
static inline unsigned int encode_float(float p_float, uint8_t *p_arr) {
|
||||
|
||||
MarshallFloat mf;
|
||||
mf.f = p_float;
|
||||
encode_uint32(mf.i, p_arr);
|
||||
@ -86,9 +79,7 @@ static inline unsigned int encode_float(float p_float, uint8_t *p_arr) {
|
||||
}
|
||||
|
||||
static inline unsigned int encode_uint64(uint64_t p_uint, uint8_t *p_arr) {
|
||||
|
||||
for (int i = 0; i < 8; i++) {
|
||||
|
||||
*p_arr = p_uint & 0xFF;
|
||||
p_arr++;
|
||||
p_uint >>= 8;
|
||||
@ -98,7 +89,6 @@ static inline unsigned int encode_uint64(uint64_t p_uint, uint8_t *p_arr) {
|
||||
}
|
||||
|
||||
static inline unsigned int encode_double(double p_double, uint8_t *p_arr) {
|
||||
|
||||
MarshallDouble md;
|
||||
md.d = p_double;
|
||||
encode_uint64(md.l, p_arr);
|
||||
@ -107,13 +97,10 @@ static inline unsigned int encode_double(double p_double, uint8_t *p_arr) {
|
||||
}
|
||||
|
||||
static inline int encode_cstring(const char *p_string, uint8_t *p_data) {
|
||||
|
||||
int len = 0;
|
||||
|
||||
while (*p_string) {
|
||||
|
||||
if (p_data) {
|
||||
|
||||
*p_data = (uint8_t)*p_string;
|
||||
p_data++;
|
||||
}
|
||||
@ -121,17 +108,16 @@ static inline int encode_cstring(const char *p_string, uint8_t *p_data) {
|
||||
len++;
|
||||
};
|
||||
|
||||
if (p_data)
|
||||
if (p_data) {
|
||||
*p_data = 0;
|
||||
}
|
||||
return len + 1;
|
||||
}
|
||||
|
||||
static inline uint16_t decode_uint16(const uint8_t *p_arr) {
|
||||
|
||||
uint16_t u = 0;
|
||||
|
||||
for (int i = 0; i < 2; i++) {
|
||||
|
||||
uint16_t b = *p_arr;
|
||||
b <<= (i * 8);
|
||||
u |= b;
|
||||
@ -142,11 +128,9 @@ static inline uint16_t decode_uint16(const uint8_t *p_arr) {
|
||||
}
|
||||
|
||||
static inline uint32_t decode_uint32(const uint8_t *p_arr) {
|
||||
|
||||
uint32_t u = 0;
|
||||
|
||||
for (int i = 0; i < 4; i++) {
|
||||
|
||||
uint32_t b = *p_arr;
|
||||
b <<= (i * 8);
|
||||
u |= b;
|
||||
@ -157,18 +141,15 @@ static inline uint32_t decode_uint32(const uint8_t *p_arr) {
|
||||
}
|
||||
|
||||
static inline float decode_float(const uint8_t *p_arr) {
|
||||
|
||||
MarshallFloat mf;
|
||||
mf.i = decode_uint32(p_arr);
|
||||
return mf.f;
|
||||
}
|
||||
|
||||
static inline uint64_t decode_uint64(const uint8_t *p_arr) {
|
||||
|
||||
uint64_t u = 0;
|
||||
|
||||
for (int i = 0; i < 8; i++) {
|
||||
|
||||
uint64_t b = (*p_arr) & 0xFF;
|
||||
b <<= (i * 8);
|
||||
u |= b;
|
||||
@ -179,7 +160,6 @@ static inline uint64_t decode_uint64(const uint8_t *p_arr) {
|
||||
}
|
||||
|
||||
static inline double decode_double(const uint8_t *p_arr) {
|
||||
|
||||
MarshallDouble md;
|
||||
md.l = decode_uint64(p_arr);
|
||||
return md.d;
|
||||
|
@ -45,9 +45,7 @@
|
||||
#endif
|
||||
|
||||
_FORCE_INLINE_ bool _should_call_local(MultiplayerAPI::RPCMode mode, bool is_master, bool &r_skip_rpc) {
|
||||
|
||||
switch (mode) {
|
||||
|
||||
case MultiplayerAPI::RPC_MODE_DISABLED: {
|
||||
// Do nothing.
|
||||
} break;
|
||||
@ -55,8 +53,9 @@ _FORCE_INLINE_ bool _should_call_local(MultiplayerAPI::RPCMode mode, bool is_mas
|
||||
// Do nothing also. Remote cannot produce a local call.
|
||||
} break;
|
||||
case MultiplayerAPI::RPC_MODE_MASTERSYNC: {
|
||||
if (is_master)
|
||||
if (is_master) {
|
||||
r_skip_rpc = true; // I am the master, so skip remote call.
|
||||
}
|
||||
[[fallthrough]];
|
||||
}
|
||||
case MultiplayerAPI::RPC_MODE_REMOTESYNC:
|
||||
@ -65,8 +64,9 @@ _FORCE_INLINE_ bool _should_call_local(MultiplayerAPI::RPCMode mode, bool is_mas
|
||||
return true;
|
||||
} break;
|
||||
case MultiplayerAPI::RPC_MODE_MASTER: {
|
||||
if (is_master)
|
||||
if (is_master) {
|
||||
r_skip_rpc = true; // I am the master, so skip remote call.
|
||||
}
|
||||
return is_master;
|
||||
} break;
|
||||
case MultiplayerAPI::RPC_MODE_PUPPET: {
|
||||
@ -78,7 +78,6 @@ _FORCE_INLINE_ bool _should_call_local(MultiplayerAPI::RPCMode mode, bool is_mas
|
||||
|
||||
_FORCE_INLINE_ bool _can_call_mode(Node *p_node, MultiplayerAPI::RPCMode mode, int p_remote_id) {
|
||||
switch (mode) {
|
||||
|
||||
case MultiplayerAPI::RPC_MODE_DISABLED: {
|
||||
return false;
|
||||
} break;
|
||||
@ -100,17 +99,17 @@ _FORCE_INLINE_ bool _can_call_mode(Node *p_node, MultiplayerAPI::RPCMode mode, i
|
||||
}
|
||||
|
||||
void MultiplayerAPI::poll() {
|
||||
|
||||
if (!network_peer.is_valid() || network_peer->get_connection_status() == NetworkedMultiplayerPeer::CONNECTION_DISCONNECTED)
|
||||
if (!network_peer.is_valid() || network_peer->get_connection_status() == NetworkedMultiplayerPeer::CONNECTION_DISCONNECTED) {
|
||||
return;
|
||||
}
|
||||
|
||||
network_peer->poll();
|
||||
|
||||
if (!network_peer.is_valid()) // It's possible that polling might have resulted in a disconnection, so check here.
|
||||
if (!network_peer.is_valid()) { // It's possible that polling might have resulted in a disconnection, so check here.
|
||||
return;
|
||||
}
|
||||
|
||||
while (network_peer->get_available_packet_count()) {
|
||||
|
||||
int sender = network_peer->get_packet_peer();
|
||||
const uint8_t *packet;
|
||||
int len;
|
||||
@ -144,9 +143,9 @@ void MultiplayerAPI::set_root_node(Node *p_node) {
|
||||
}
|
||||
|
||||
void MultiplayerAPI::set_network_peer(const Ref<NetworkedMultiplayerPeer> &p_peer) {
|
||||
|
||||
if (p_peer == network_peer)
|
||||
if (p_peer == network_peer) {
|
||||
return; // Nothing to do
|
||||
}
|
||||
|
||||
ERR_FAIL_COND_MSG(p_peer.is_valid() && p_peer->get_connection_status() == NetworkedMultiplayerPeer::CONNECTION_DISCONNECTED,
|
||||
"Supplied NetworkedMultiplayerPeer must be connecting or connected.");
|
||||
@ -185,6 +184,7 @@ void _profile_node_data(const String &p_what, ObjectID p_id) {
|
||||
EngineDebugger::profiler_add_frame_data("multiplayer", values);
|
||||
}
|
||||
}
|
||||
|
||||
void _profile_bandwidth_data(const String &p_inout, int p_size) {
|
||||
if (EngineDebugger::is_profiling("multiplayer")) {
|
||||
Array values;
|
||||
@ -208,7 +208,6 @@ int get_packet_len(uint32_t p_node_target, int p_packet_len) {
|
||||
}
|
||||
|
||||
void MultiplayerAPI::_process_packet(int p_from, const uint8_t *p_packet, int p_packet_len) {
|
||||
|
||||
ERR_FAIL_COND_MSG(root_node == nullptr, "Multiplayer root node was not initialized. If you are using custom multiplayer, remember to set the root node via MultiplayerAPI.set_root_node before using it.");
|
||||
ERR_FAIL_COND_MSG(p_packet_len < 1, "Invalid packet received. Size too small.");
|
||||
|
||||
@ -220,20 +219,16 @@ void MultiplayerAPI::_process_packet(int p_from, const uint8_t *p_packet, int p_
|
||||
uint8_t packet_type = p_packet[0] & 7;
|
||||
|
||||
switch (packet_type) {
|
||||
|
||||
case NETWORK_COMMAND_SIMPLIFY_PATH: {
|
||||
|
||||
_process_simplify_path(p_from, p_packet, p_packet_len);
|
||||
} break;
|
||||
|
||||
case NETWORK_COMMAND_CONFIRM_PATH: {
|
||||
|
||||
_process_confirm_path(p_from, p_packet, p_packet_len);
|
||||
} break;
|
||||
|
||||
case NETWORK_COMMAND_REMOTE_CALL:
|
||||
case NETWORK_COMMAND_REMOTE_SET: {
|
||||
|
||||
// Extract packet meta
|
||||
int packet_min_size = 1;
|
||||
int name_id_offset = 1;
|
||||
@ -304,25 +299,21 @@ void MultiplayerAPI::_process_packet(int p_from, const uint8_t *p_packet, int p_
|
||||
|
||||
const int packet_len = get_packet_len(node_target, p_packet_len);
|
||||
if (packet_type == NETWORK_COMMAND_REMOTE_CALL) {
|
||||
|
||||
_process_rpc(node, name_id, p_from, p_packet, packet_len, packet_min_size);
|
||||
|
||||
} else {
|
||||
|
||||
_process_rset(node, name_id, p_from, p_packet, packet_len, packet_min_size);
|
||||
}
|
||||
|
||||
} break;
|
||||
|
||||
case NETWORK_COMMAND_RAW: {
|
||||
|
||||
_process_raw(p_from, p_packet, p_packet_len);
|
||||
} break;
|
||||
}
|
||||
}
|
||||
|
||||
Node *MultiplayerAPI::_process_get_node(int p_from, const uint8_t *p_packet, uint32_t p_node_target, int p_packet_len) {
|
||||
|
||||
Node *node = nullptr;
|
||||
|
||||
if (p_node_target & 0x80000000) {
|
||||
@ -339,8 +330,9 @@ Node *MultiplayerAPI::_process_get_node(int p_from, const uint8_t *p_packet, uin
|
||||
|
||||
node = root_node->get_node(np);
|
||||
|
||||
if (!node)
|
||||
if (!node) {
|
||||
ERR_PRINT("Failed to get path from RPC: " + String(np) + ".");
|
||||
}
|
||||
} else {
|
||||
// Use cached path.
|
||||
int id = p_node_target;
|
||||
@ -355,14 +347,14 @@ Node *MultiplayerAPI::_process_get_node(int p_from, const uint8_t *p_packet, uin
|
||||
// Do proper caching later.
|
||||
|
||||
node = root_node->get_node(ni->path);
|
||||
if (!node)
|
||||
if (!node) {
|
||||
ERR_PRINT("Failed to get cached path from RPC: " + String(ni->path) + ".");
|
||||
}
|
||||
}
|
||||
return node;
|
||||
}
|
||||
|
||||
void MultiplayerAPI::_process_rpc(Node *p_node, const uint16_t p_rpc_method_id, int p_from, const uint8_t *p_packet, int p_packet_len, int p_offset) {
|
||||
|
||||
ERR_FAIL_COND_MSG(p_offset > p_packet_len, "Invalid packet received. Size too small.");
|
||||
|
||||
// Check that remote can call the RPC on this node.
|
||||
@ -415,7 +407,6 @@ void MultiplayerAPI::_process_rpc(Node *p_node, const uint16_t p_rpc_method_id,
|
||||
p_offset += len;
|
||||
} else {
|
||||
for (int i = 0; i < argc; i++) {
|
||||
|
||||
ERR_FAIL_COND_MSG(p_offset >= p_packet_len, "Invalid packet received. Size too small.");
|
||||
|
||||
int vlen;
|
||||
@ -438,7 +429,6 @@ void MultiplayerAPI::_process_rpc(Node *p_node, const uint16_t p_rpc_method_id,
|
||||
}
|
||||
|
||||
void MultiplayerAPI::_process_rset(Node *p_node, const uint16_t p_rpc_property_id, int p_from, const uint8_t *p_packet, int p_packet_len, int p_offset) {
|
||||
|
||||
ERR_FAIL_COND_MSG(p_offset >= p_packet_len, "Invalid packet received. Size too small.");
|
||||
|
||||
// Check that remote can call the RSET on this node.
|
||||
@ -472,7 +462,6 @@ void MultiplayerAPI::_process_rset(Node *p_node, const uint16_t p_rpc_property_i
|
||||
}
|
||||
|
||||
void MultiplayerAPI::_process_simplify_path(int p_from, const uint8_t *p_packet, int p_packet_len) {
|
||||
|
||||
ERR_FAIL_COND_MSG(p_packet_len < 38, "Invalid packet received. Size too small.");
|
||||
int ofs = 1;
|
||||
|
||||
@ -521,7 +510,6 @@ void MultiplayerAPI::_process_simplify_path(int p_from, const uint8_t *p_packet,
|
||||
}
|
||||
|
||||
void MultiplayerAPI::_process_confirm_path(int p_from, const uint8_t *p_packet, int p_packet_len) {
|
||||
|
||||
ERR_FAIL_COND_MSG(p_packet_len < 3, "Invalid packet received. Size too small.");
|
||||
|
||||
const bool valid_rpc_checksum = p_packet[1];
|
||||
@ -548,12 +536,13 @@ bool MultiplayerAPI::_send_confirm_path(Node *p_node, NodePath p_path, PathSentC
|
||||
List<int> peers_to_add; // If one is missing, take note to add it.
|
||||
|
||||
for (Set<int>::Element *E = connected_peers.front(); E; E = E->next()) {
|
||||
|
||||
if (p_target < 0 && E->get() == -p_target)
|
||||
if (p_target < 0 && E->get() == -p_target) {
|
||||
continue; // Continue, excluded.
|
||||
}
|
||||
|
||||
if (p_target > 0 && E->get() != p_target)
|
||||
if (p_target > 0 && E->get() != p_target) {
|
||||
continue; // Continue, not for this peer.
|
||||
}
|
||||
|
||||
Map<int, bool>::Element *F = psc->confirmed_peers.find(E->get());
|
||||
|
||||
@ -569,7 +558,6 @@ bool MultiplayerAPI::_send_confirm_path(Node *p_node, NodePath p_path, PathSentC
|
||||
}
|
||||
|
||||
if (peers_to_add.size() > 0) {
|
||||
|
||||
// Those that need to be added, send a message for this.
|
||||
|
||||
// Encode function name.
|
||||
@ -594,7 +582,6 @@ bool MultiplayerAPI::_send_confirm_path(Node *p_node, NodePath p_path, PathSentC
|
||||
ofs += encode_cstring(path.get_data(), &packet.write[ofs]);
|
||||
|
||||
for (List<int>::Element *E = peers_to_add.front(); E; E = E->next()) {
|
||||
|
||||
network_peer->set_target_peer(E->get()); // To all of you.
|
||||
network_peer->set_transfer_mode(NetworkedMultiplayerPeer::TRANSFER_MODE_RELIABLE);
|
||||
network_peer->put_packet(packet.ptr(), packet.size());
|
||||
@ -619,7 +606,6 @@ bool MultiplayerAPI::_send_confirm_path(Node *p_node, NodePath p_path, PathSentC
|
||||
#define ENCODE_32 2 << 5
|
||||
#define ENCODE_64 3 << 5
|
||||
Error MultiplayerAPI::_encode_and_compress_variant(const Variant &p_variant, uint8_t *r_buffer, int &r_len) {
|
||||
|
||||
// Unreachable because `VARIANT_MAX` == 27 and `ENCODE_VARIANT_MASK` == 31
|
||||
CRASH_COND(p_variant.get_type() > VARIANT_META_TYPE_MASK);
|
||||
|
||||
@ -681,8 +667,9 @@ Error MultiplayerAPI::_encode_and_compress_variant(const Variant &p_variant, uin
|
||||
default:
|
||||
// Any other case is not yet compressed.
|
||||
Error err = encode_variant(p_variant, r_buffer, r_len, allow_object_decoding);
|
||||
if (err != OK)
|
||||
if (err != OK) {
|
||||
return err;
|
||||
}
|
||||
if (r_buffer) {
|
||||
// The first byte is not used by the marshaling, so store the type
|
||||
// so we know how to decompress and decode this variant.
|
||||
@ -692,8 +679,8 @@ Error MultiplayerAPI::_encode_and_compress_variant(const Variant &p_variant, uin
|
||||
|
||||
return OK;
|
||||
}
|
||||
Error MultiplayerAPI::_decode_and_decompress_variant(Variant &r_variant, const uint8_t *p_buffer, int p_len, int *r_len) {
|
||||
|
||||
Error MultiplayerAPI::_decode_and_decompress_variant(Variant &r_variant, const uint8_t *p_buffer, int p_len, int *r_len) {
|
||||
const uint8_t *buf = p_buffer;
|
||||
int len = p_len;
|
||||
|
||||
@ -707,55 +694,61 @@ Error MultiplayerAPI::_decode_and_decompress_variant(Variant &r_variant, const u
|
||||
case Variant::BOOL: {
|
||||
bool val = (buf[0] & VARIANT_META_BOOL_MASK) > 0;
|
||||
r_variant = val;
|
||||
if (r_len)
|
||||
if (r_len) {
|
||||
*r_len = 1;
|
||||
}
|
||||
} break;
|
||||
case Variant::INT: {
|
||||
buf += 1;
|
||||
len -= 1;
|
||||
if (r_len)
|
||||
if (r_len) {
|
||||
*r_len = 1;
|
||||
}
|
||||
if (encode_mode == ENCODE_8) {
|
||||
// 8 bits.
|
||||
ERR_FAIL_COND_V(len < 1, ERR_INVALID_DATA);
|
||||
int8_t val = buf[0];
|
||||
r_variant = val;
|
||||
if (r_len)
|
||||
if (r_len) {
|
||||
(*r_len) += 1;
|
||||
}
|
||||
} else if (encode_mode == ENCODE_16) {
|
||||
// 16 bits.
|
||||
ERR_FAIL_COND_V(len < 2, ERR_INVALID_DATA);
|
||||
int16_t val = decode_uint16(buf);
|
||||
r_variant = val;
|
||||
if (r_len)
|
||||
if (r_len) {
|
||||
(*r_len) += 2;
|
||||
}
|
||||
} else if (encode_mode == ENCODE_32) {
|
||||
// 32 bits.
|
||||
ERR_FAIL_COND_V(len < 4, ERR_INVALID_DATA);
|
||||
int32_t val = decode_uint32(buf);
|
||||
r_variant = val;
|
||||
if (r_len)
|
||||
if (r_len) {
|
||||
(*r_len) += 4;
|
||||
}
|
||||
} else {
|
||||
// 64 bits.
|
||||
ERR_FAIL_COND_V(len < 8, ERR_INVALID_DATA);
|
||||
int64_t val = decode_uint64(buf);
|
||||
r_variant = val;
|
||||
if (r_len)
|
||||
if (r_len) {
|
||||
(*r_len) += 8;
|
||||
}
|
||||
}
|
||||
} break;
|
||||
default:
|
||||
Error err = decode_variant(r_variant, p_buffer, p_len, r_len, allow_object_decoding);
|
||||
if (err != OK)
|
||||
if (err != OK) {
|
||||
return err;
|
||||
}
|
||||
}
|
||||
|
||||
return OK;
|
||||
}
|
||||
|
||||
void MultiplayerAPI::_send_rpc(Node *p_from, int p_to, bool p_unreliable, bool p_set, const StringName &p_name, const Variant **p_arg, int p_argcount) {
|
||||
|
||||
ERR_FAIL_COND_MSG(network_peer.is_null(), "Attempt to remote call/set when networking is not active in SceneTree.");
|
||||
|
||||
ERR_FAIL_COND_MSG(network_peer->get_connection_status() == NetworkedMultiplayerPeer::CONNECTION_CONNECTING, "Attempt to remote call/set when networking is not connected yet in SceneTree.");
|
||||
@ -841,7 +834,6 @@ void MultiplayerAPI::_send_rpc(Node *p_from, int p_to, bool p_unreliable, bool p
|
||||
}
|
||||
|
||||
if (p_set) {
|
||||
|
||||
// Take the rpc property ID
|
||||
uint16_t property_id = p_from->get_node_rset_property_id(p_name);
|
||||
if (property_id == UINT16_MAX && p_from->get_script_instance()) {
|
||||
@ -934,7 +926,6 @@ void MultiplayerAPI::_send_rpc(Node *p_from, int p_to, bool p_unreliable, bool p
|
||||
network_peer->set_transfer_mode(p_unreliable ? NetworkedMultiplayerPeer::TRANSFER_MODE_UNRELIABLE : NetworkedMultiplayerPeer::TRANSFER_MODE_RELIABLE);
|
||||
|
||||
if (has_all_peers) {
|
||||
|
||||
// They all have verified paths, so send fast.
|
||||
network_peer->set_target_peer(p_to); // To all of you.
|
||||
network_peer->put_packet(packet_cache.ptr(), ofs); // A message with love.
|
||||
@ -951,12 +942,13 @@ void MultiplayerAPI::_send_rpc(Node *p_from, int p_to, bool p_unreliable, bool p
|
||||
encode_cstring(pname.get_data(), &(packet_cache.write[ofs]));
|
||||
|
||||
for (Set<int>::Element *E = connected_peers.front(); E; E = E->next()) {
|
||||
|
||||
if (p_to < 0 && E->get() == -p_to)
|
||||
if (p_to < 0 && E->get() == -p_to) {
|
||||
continue; // Continue, excluded.
|
||||
}
|
||||
|
||||
if (p_to > 0 && E->get() != p_to)
|
||||
if (p_to > 0 && E->get() != p_to) {
|
||||
continue; // Continue, not for this peer.
|
||||
}
|
||||
|
||||
Map<int, bool>::Element *F = psc->confirmed_peers.find(E->get());
|
||||
ERR_CONTINUE(!F); // Should never happen.
|
||||
@ -998,22 +990,18 @@ void MultiplayerAPI::_del_peer(int p_id) {
|
||||
}
|
||||
|
||||
void MultiplayerAPI::_connected_to_server() {
|
||||
|
||||
emit_signal("connected_to_server");
|
||||
}
|
||||
|
||||
void MultiplayerAPI::_connection_failed() {
|
||||
|
||||
emit_signal("connection_failed");
|
||||
}
|
||||
|
||||
void MultiplayerAPI::_server_disconnected() {
|
||||
|
||||
emit_signal("server_disconnected");
|
||||
}
|
||||
|
||||
void MultiplayerAPI::rpcp(Node *p_node, int p_peer_id, bool p_unreliable, const StringName &p_method, const Variant **p_arg, int p_argcount) {
|
||||
|
||||
ERR_FAIL_COND_MSG(!network_peer.is_valid(), "Trying to call an RPC while no network peer is active.");
|
||||
ERR_FAIL_COND_MSG(!p_node->is_inside_tree(), "Trying to call an RPC on a node which is not inside SceneTree.");
|
||||
ERR_FAIL_COND_MSG(network_peer->get_connection_status() != NetworkedMultiplayerPeer::CONNECTION_CONNECTED, "Trying to call an RPC via a network peer which is not connected.");
|
||||
@ -1040,7 +1028,6 @@ void MultiplayerAPI::rpcp(Node *p_node, int p_peer_id, bool p_unreliable, const
|
||||
}
|
||||
|
||||
if (!skip_rpc) {
|
||||
|
||||
#ifdef DEBUG_ENABLED
|
||||
_profile_node_data("out_rpc", p_node->get_instance_id());
|
||||
#endif
|
||||
@ -1081,7 +1068,6 @@ void MultiplayerAPI::rpcp(Node *p_node, int p_peer_id, bool p_unreliable, const
|
||||
}
|
||||
|
||||
void MultiplayerAPI::rsetp(Node *p_node, int p_peer_id, bool p_unreliable, const StringName &p_property, const Variant &p_value) {
|
||||
|
||||
ERR_FAIL_COND_MSG(!network_peer.is_valid(), "Trying to RSET while no network peer is active.");
|
||||
ERR_FAIL_COND_MSG(!p_node->is_inside_tree(), "Trying to RSET on a node which is not inside SceneTree.");
|
||||
ERR_FAIL_COND_MSG(network_peer->get_connection_status() != NetworkedMultiplayerPeer::CONNECTION_CONNECTED, "Trying to send an RSET via a network peer which is not connected.");
|
||||
@ -1146,7 +1132,6 @@ void MultiplayerAPI::rsetp(Node *p_node, int p_peer_id, bool p_unreliable, const
|
||||
}
|
||||
|
||||
Error MultiplayerAPI::send_bytes(Vector<uint8_t> p_data, int p_to, NetworkedMultiplayerPeer::TransferMode p_mode) {
|
||||
|
||||
ERR_FAIL_COND_V_MSG(p_data.size() < 1, ERR_INVALID_DATA, "Trying to send an empty raw packet.");
|
||||
ERR_FAIL_COND_V_MSG(!network_peer.is_valid(), ERR_UNCONFIGURED, "Trying to send a raw packet while no network peer is active.");
|
||||
ERR_FAIL_COND_V_MSG(network_peer->get_connection_status() != NetworkedMultiplayerPeer::CONNECTION_CONNECTED, ERR_UNCONFIGURED, "Trying to send a raw packet via a network peer which is not connected.");
|
||||
@ -1163,7 +1148,6 @@ Error MultiplayerAPI::send_bytes(Vector<uint8_t> p_data, int p_to, NetworkedMult
|
||||
}
|
||||
|
||||
void MultiplayerAPI::_process_raw(int p_from, const uint8_t *p_packet, int p_packet_len) {
|
||||
|
||||
ERR_FAIL_COND_MSG(p_packet_len < 2, "Invalid packet received. Size too small.");
|
||||
|
||||
Vector<uint8_t> out;
|
||||
@ -1177,32 +1161,27 @@ void MultiplayerAPI::_process_raw(int p_from, const uint8_t *p_packet, int p_pac
|
||||
}
|
||||
|
||||
int MultiplayerAPI::get_network_unique_id() const {
|
||||
|
||||
ERR_FAIL_COND_V_MSG(!network_peer.is_valid(), 0, "No network peer is assigned. Unable to get unique network ID.");
|
||||
return network_peer->get_unique_id();
|
||||
}
|
||||
|
||||
bool MultiplayerAPI::is_network_server() const {
|
||||
|
||||
// XXX Maybe fail silently? Maybe should actually return true to make development of both local and online multiplayer easier?
|
||||
ERR_FAIL_COND_V_MSG(!network_peer.is_valid(), false, "No network peer is assigned. I can't be a server.");
|
||||
return network_peer->is_server();
|
||||
}
|
||||
|
||||
void MultiplayerAPI::set_refuse_new_network_connections(bool p_refuse) {
|
||||
|
||||
ERR_FAIL_COND_MSG(!network_peer.is_valid(), "No network peer is assigned. Unable to set 'refuse_new_connections'.");
|
||||
network_peer->set_refuse_new_connections(p_refuse);
|
||||
}
|
||||
|
||||
bool MultiplayerAPI::is_refusing_new_network_connections() const {
|
||||
|
||||
ERR_FAIL_COND_V_MSG(!network_peer.is_valid(), false, "No network peer is assigned. Unable to get 'refuse_new_connections'.");
|
||||
return network_peer->is_refusing_new_connections();
|
||||
}
|
||||
|
||||
Vector<int> MultiplayerAPI::get_network_connected_peers() const {
|
||||
|
||||
ERR_FAIL_COND_V_MSG(!network_peer.is_valid(), Vector<int>(), "No network peer is assigned. Assume no peers are connected.");
|
||||
|
||||
Vector<int> ret;
|
||||
@ -1214,12 +1193,10 @@ Vector<int> MultiplayerAPI::get_network_connected_peers() const {
|
||||
}
|
||||
|
||||
void MultiplayerAPI::set_allow_object_decoding(bool p_enable) {
|
||||
|
||||
allow_object_decoding = p_enable;
|
||||
}
|
||||
|
||||
bool MultiplayerAPI::is_object_decoding_allowed() const {
|
||||
|
||||
return allow_object_decoding;
|
||||
}
|
||||
|
||||
|
@ -35,7 +35,6 @@
|
||||
#include "core/reference.h"
|
||||
|
||||
class MultiplayerAPI : public Reference {
|
||||
|
||||
GDCLASS(MultiplayerAPI, Reference);
|
||||
|
||||
private:
|
||||
|
@ -33,9 +33,9 @@
|
||||
NetSocket *(*NetSocket::_create)() = nullptr;
|
||||
|
||||
NetSocket *NetSocket::create() {
|
||||
|
||||
if (_create)
|
||||
if (_create) {
|
||||
return _create();
|
||||
}
|
||||
|
||||
ERR_PRINT("Unable to create network socket, platform not supported");
|
||||
return nullptr;
|
||||
|
@ -35,7 +35,6 @@
|
||||
#include "core/reference.h"
|
||||
|
||||
class NetSocket : public Reference {
|
||||
|
||||
protected:
|
||||
static NetSocket *(*_create)();
|
||||
|
||||
|
@ -31,7 +31,6 @@
|
||||
#include "networked_multiplayer_peer.h"
|
||||
|
||||
void NetworkedMultiplayerPeer::_bind_methods() {
|
||||
|
||||
ClassDB::bind_method(D_METHOD("set_transfer_mode", "mode"), &NetworkedMultiplayerPeer::set_transfer_mode);
|
||||
ClassDB::bind_method(D_METHOD("get_transfer_mode"), &NetworkedMultiplayerPeer::get_transfer_mode);
|
||||
ClassDB::bind_method(D_METHOD("set_target_peer", "id"), &NetworkedMultiplayerPeer::set_target_peer);
|
||||
|
@ -34,7 +34,6 @@
|
||||
#include "core/io/packet_peer.h"
|
||||
|
||||
class NetworkedMultiplayerPeer : public PacketPeer {
|
||||
|
||||
GDCLASS(NetworkedMultiplayerPeer, PacketPeer);
|
||||
|
||||
protected:
|
||||
|
@ -36,7 +36,6 @@
|
||||
/* helpers / binders */
|
||||
|
||||
void PacketPeer::set_encode_buffer_max_size(int p_max_size) {
|
||||
|
||||
ERR_FAIL_COND_MSG(p_max_size < 1024, "Max encode buffer must be at least 1024 bytes");
|
||||
ERR_FAIL_COND_MSG(p_max_size > 256 * 1024 * 1024, "Max encode buffer cannot exceed 256 MiB");
|
||||
encode_buffer_max_size = next_power_of_2(p_max_size);
|
||||
@ -44,59 +43,61 @@ void PacketPeer::set_encode_buffer_max_size(int p_max_size) {
|
||||
}
|
||||
|
||||
int PacketPeer::get_encode_buffer_max_size() const {
|
||||
|
||||
return encode_buffer_max_size;
|
||||
}
|
||||
|
||||
Error PacketPeer::get_packet_buffer(Vector<uint8_t> &r_buffer) {
|
||||
|
||||
const uint8_t *buffer;
|
||||
int buffer_size;
|
||||
Error err = get_packet(&buffer, buffer_size);
|
||||
if (err)
|
||||
if (err) {
|
||||
return err;
|
||||
}
|
||||
|
||||
r_buffer.resize(buffer_size);
|
||||
if (buffer_size == 0)
|
||||
if (buffer_size == 0) {
|
||||
return OK;
|
||||
}
|
||||
|
||||
uint8_t *w = r_buffer.ptrw();
|
||||
for (int i = 0; i < buffer_size; i++)
|
||||
for (int i = 0; i < buffer_size; i++) {
|
||||
w[i] = buffer[i];
|
||||
}
|
||||
|
||||
return OK;
|
||||
}
|
||||
|
||||
Error PacketPeer::put_packet_buffer(const Vector<uint8_t> &p_buffer) {
|
||||
|
||||
int len = p_buffer.size();
|
||||
if (len == 0)
|
||||
if (len == 0) {
|
||||
return OK;
|
||||
}
|
||||
|
||||
const uint8_t *r = p_buffer.ptr();
|
||||
return put_packet(&r[0], len);
|
||||
}
|
||||
|
||||
Error PacketPeer::get_var(Variant &r_variant, bool p_allow_objects) {
|
||||
|
||||
const uint8_t *buffer;
|
||||
int buffer_size;
|
||||
Error err = get_packet(&buffer, buffer_size);
|
||||
if (err)
|
||||
if (err) {
|
||||
return err;
|
||||
}
|
||||
|
||||
return decode_variant(r_variant, buffer, buffer_size, nullptr, p_allow_objects);
|
||||
}
|
||||
|
||||
Error PacketPeer::put_var(const Variant &p_packet, bool p_full_objects) {
|
||||
|
||||
int len;
|
||||
Error err = encode_variant(p_packet, nullptr, len, p_full_objects); // compute len first
|
||||
if (err)
|
||||
if (err) {
|
||||
return err;
|
||||
}
|
||||
|
||||
if (len == 0)
|
||||
if (len == 0) {
|
||||
return OK;
|
||||
}
|
||||
|
||||
ERR_FAIL_COND_V_MSG(len > encode_buffer_max_size, ERR_OUT_OF_MEMORY, "Failed to encode variant, encode size is bigger then encode_buffer_max_size. Consider raising it via 'set_encode_buffer_max_size'.");
|
||||
|
||||
@ -123,20 +124,18 @@ Variant PacketPeer::_bnd_get_var(bool p_allow_objects) {
|
||||
Error PacketPeer::_put_packet(const Vector<uint8_t> &p_buffer) {
|
||||
return put_packet_buffer(p_buffer);
|
||||
}
|
||||
Vector<uint8_t> PacketPeer::_get_packet() {
|
||||
|
||||
Vector<uint8_t> PacketPeer::_get_packet() {
|
||||
Vector<uint8_t> raw;
|
||||
last_get_error = get_packet_buffer(raw);
|
||||
return raw;
|
||||
}
|
||||
|
||||
Error PacketPeer::_get_packet_error() const {
|
||||
|
||||
return last_get_error;
|
||||
}
|
||||
|
||||
void PacketPeer::_bind_methods() {
|
||||
|
||||
ClassDB::bind_method(D_METHOD("get_var", "allow_objects"), &PacketPeer::_bnd_get_var, DEFVAL(false));
|
||||
ClassDB::bind_method(D_METHOD("put_var", "var", "full_objects"), &PacketPeer::put_var, DEFVAL(false));
|
||||
ClassDB::bind_method(D_METHOD("get_packet"), &PacketPeer::_get_packet);
|
||||
@ -153,13 +152,11 @@ void PacketPeer::_bind_methods() {
|
||||
/***************/
|
||||
|
||||
void PacketPeerStream::_set_stream_peer(REF p_peer) {
|
||||
|
||||
ERR_FAIL_COND_MSG(p_peer.is_null(), "It's not a reference to a valid Resource object.");
|
||||
set_stream_peer(p_peer);
|
||||
}
|
||||
|
||||
void PacketPeerStream::_bind_methods() {
|
||||
|
||||
ClassDB::bind_method(D_METHOD("set_stream_peer", "peer"), &PacketPeerStream::set_stream_peer);
|
||||
ClassDB::bind_method(D_METHOD("get_stream_peer"), &PacketPeerStream::get_stream_peer);
|
||||
ClassDB::bind_method(D_METHOD("set_input_buffer_max_size", "max_size_bytes"), &PacketPeerStream::set_input_buffer_max_size);
|
||||
@ -173,16 +170,17 @@ void PacketPeerStream::_bind_methods() {
|
||||
}
|
||||
|
||||
Error PacketPeerStream::_poll_buffer() const {
|
||||
|
||||
ERR_FAIL_COND_V(peer.is_null(), ERR_UNCONFIGURED);
|
||||
|
||||
int read = 0;
|
||||
ERR_FAIL_COND_V(input_buffer.size() < ring_buffer.space_left(), ERR_UNAVAILABLE);
|
||||
Error err = peer->get_partial_data(input_buffer.ptrw(), ring_buffer.space_left(), read);
|
||||
if (err)
|
||||
if (err) {
|
||||
return err;
|
||||
if (read == 0)
|
||||
}
|
||||
if (read == 0) {
|
||||
return OK;
|
||||
}
|
||||
|
||||
int w = ring_buffer.write(&input_buffer[0], read);
|
||||
ERR_FAIL_COND_V(w != read, ERR_BUG);
|
||||
@ -191,7 +189,6 @@ Error PacketPeerStream::_poll_buffer() const {
|
||||
}
|
||||
|
||||
int PacketPeerStream::get_available_packet_count() const {
|
||||
|
||||
_poll_buffer();
|
||||
|
||||
uint32_t remaining = ring_buffer.data_left();
|
||||
@ -200,14 +197,14 @@ int PacketPeerStream::get_available_packet_count() const {
|
||||
int count = 0;
|
||||
|
||||
while (remaining >= 4) {
|
||||
|
||||
uint8_t lbuf[4];
|
||||
ring_buffer.copy(lbuf, ofs, 4);
|
||||
uint32_t len = decode_uint32(lbuf);
|
||||
remaining -= 4;
|
||||
ofs += 4;
|
||||
if (len > remaining)
|
||||
if (len > remaining) {
|
||||
break;
|
||||
}
|
||||
remaining -= len;
|
||||
ofs += len;
|
||||
count++;
|
||||
@ -217,7 +214,6 @@ int PacketPeerStream::get_available_packet_count() const {
|
||||
}
|
||||
|
||||
Error PacketPeerStream::get_packet(const uint8_t **r_buffer, int &r_buffer_size) {
|
||||
|
||||
ERR_FAIL_COND_V(peer.is_null(), ERR_UNCONFIGURED);
|
||||
_poll_buffer();
|
||||
|
||||
@ -239,34 +235,34 @@ Error PacketPeerStream::get_packet(const uint8_t **r_buffer, int &r_buffer_size)
|
||||
}
|
||||
|
||||
Error PacketPeerStream::put_packet(const uint8_t *p_buffer, int p_buffer_size) {
|
||||
|
||||
ERR_FAIL_COND_V(peer.is_null(), ERR_UNCONFIGURED);
|
||||
Error err = _poll_buffer(); //won't hurt to poll here too
|
||||
|
||||
if (err)
|
||||
if (err) {
|
||||
return err;
|
||||
}
|
||||
|
||||
if (p_buffer_size == 0)
|
||||
if (p_buffer_size == 0) {
|
||||
return OK;
|
||||
}
|
||||
|
||||
ERR_FAIL_COND_V(p_buffer_size < 0, ERR_INVALID_PARAMETER);
|
||||
ERR_FAIL_COND_V(p_buffer_size + 4 > output_buffer.size(), ERR_INVALID_PARAMETER);
|
||||
|
||||
encode_uint32(p_buffer_size, output_buffer.ptrw());
|
||||
uint8_t *dst = &output_buffer.write[4];
|
||||
for (int i = 0; i < p_buffer_size; i++)
|
||||
for (int i = 0; i < p_buffer_size; i++) {
|
||||
dst[i] = p_buffer[i];
|
||||
}
|
||||
|
||||
return peer->put_data(&output_buffer[0], p_buffer_size + 4);
|
||||
}
|
||||
|
||||
int PacketPeerStream::get_max_packet_size() const {
|
||||
|
||||
return output_buffer.size();
|
||||
}
|
||||
|
||||
void PacketPeerStream::set_stream_peer(const Ref<StreamPeer> &p_peer) {
|
||||
|
||||
//ERR_FAIL_COND(p_peer.is_null());
|
||||
|
||||
if (p_peer.ptr() != peer.ptr()) {
|
||||
@ -277,12 +273,10 @@ void PacketPeerStream::set_stream_peer(const Ref<StreamPeer> &p_peer) {
|
||||
}
|
||||
|
||||
Ref<StreamPeer> PacketPeerStream::get_stream_peer() const {
|
||||
|
||||
return peer;
|
||||
}
|
||||
|
||||
void PacketPeerStream::set_input_buffer_max_size(int p_max_size) {
|
||||
|
||||
ERR_FAIL_COND_MSG(p_max_size < 0, "Max size of input buffer size cannot be smaller than 0.");
|
||||
//warning may lose packets
|
||||
ERR_FAIL_COND_MSG(ring_buffer.data_left(), "Buffer in use, resizing would cause loss of data.");
|
||||
@ -291,22 +285,18 @@ void PacketPeerStream::set_input_buffer_max_size(int p_max_size) {
|
||||
}
|
||||
|
||||
int PacketPeerStream::get_input_buffer_max_size() const {
|
||||
|
||||
return input_buffer.size() - 4;
|
||||
}
|
||||
|
||||
void PacketPeerStream::set_output_buffer_max_size(int p_max_size) {
|
||||
|
||||
output_buffer.resize(next_power_of_2(p_max_size + 4));
|
||||
}
|
||||
|
||||
int PacketPeerStream::get_output_buffer_max_size() const {
|
||||
|
||||
return output_buffer.size() - 4;
|
||||
}
|
||||
|
||||
PacketPeerStream::PacketPeerStream() {
|
||||
|
||||
int rbsize = GLOBAL_GET("network/limits/packet_peer_stream/max_buffer_po2");
|
||||
|
||||
ring_buffer.resize(rbsize);
|
||||
|
@ -36,7 +36,6 @@
|
||||
#include "core/ring_buffer.h"
|
||||
|
||||
class PacketPeer : public Reference {
|
||||
|
||||
GDCLASS(PacketPeer, Reference);
|
||||
|
||||
Variant _bnd_get_var(bool p_allow_objects = false);
|
||||
@ -75,7 +74,6 @@ public:
|
||||
};
|
||||
|
||||
class PacketPeerStream : public PacketPeer {
|
||||
|
||||
GDCLASS(PacketPeerStream, PacketPeer);
|
||||
|
||||
//the way the buffers work sucks, will change later
|
||||
|
@ -36,7 +36,6 @@ PacketPeerDTLS *(*PacketPeerDTLS::_create)() = nullptr;
|
||||
bool PacketPeerDTLS::available = false;
|
||||
|
||||
PacketPeerDTLS *PacketPeerDTLS::create() {
|
||||
|
||||
return _create();
|
||||
}
|
||||
|
||||
@ -45,7 +44,6 @@ bool PacketPeerDTLS::is_available() {
|
||||
}
|
||||
|
||||
void PacketPeerDTLS::_bind_methods() {
|
||||
|
||||
ClassDB::bind_method(D_METHOD("poll"), &PacketPeerDTLS::poll);
|
||||
ClassDB::bind_method(D_METHOD("connect_to_peer", "packet_peer", "validate_certs", "for_hostname", "valid_certificate"), &PacketPeerDTLS::connect_to_peer, DEFVAL(true), DEFVAL(String()), DEFVAL(Ref<X509Certificate>()));
|
||||
ClassDB::bind_method(D_METHOD("get_status"), &PacketPeerDTLS::get_status);
|
||||
|
@ -33,18 +33,17 @@
|
||||
#include "core/io/ip.h"
|
||||
|
||||
void PacketPeerUDP::set_blocking_mode(bool p_enable) {
|
||||
|
||||
blocking = p_enable;
|
||||
}
|
||||
|
||||
void PacketPeerUDP::set_broadcast_enabled(bool p_enabled) {
|
||||
broadcast = p_enabled;
|
||||
if (_sock.is_valid() && _sock->is_open())
|
||||
if (_sock.is_valid() && _sock->is_open()) {
|
||||
_sock->set_broadcasting_enabled(p_enabled);
|
||||
}
|
||||
}
|
||||
|
||||
Error PacketPeerUDP::join_multicast_group(IP_Address p_multi_address, String p_if_name) {
|
||||
|
||||
ERR_FAIL_COND_V(!_sock.is_valid(), ERR_UNAVAILABLE);
|
||||
ERR_FAIL_COND_V(!p_multi_address.is_valid(), ERR_INVALID_PARAMETER);
|
||||
|
||||
@ -59,49 +58,48 @@ Error PacketPeerUDP::join_multicast_group(IP_Address p_multi_address, String p_i
|
||||
}
|
||||
|
||||
Error PacketPeerUDP::leave_multicast_group(IP_Address p_multi_address, String p_if_name) {
|
||||
|
||||
ERR_FAIL_COND_V(!_sock.is_valid(), ERR_UNAVAILABLE);
|
||||
ERR_FAIL_COND_V(!_sock->is_open(), ERR_UNCONFIGURED);
|
||||
return _sock->leave_multicast_group(p_multi_address, p_if_name);
|
||||
}
|
||||
|
||||
String PacketPeerUDP::_get_packet_ip() const {
|
||||
|
||||
return get_packet_address();
|
||||
}
|
||||
|
||||
Error PacketPeerUDP::_set_dest_address(const String &p_address, int p_port) {
|
||||
|
||||
IP_Address ip;
|
||||
if (p_address.is_valid_ip_address()) {
|
||||
ip = p_address;
|
||||
} else {
|
||||
ip = IP::get_singleton()->resolve_hostname(p_address);
|
||||
if (!ip.is_valid())
|
||||
if (!ip.is_valid()) {
|
||||
return ERR_CANT_RESOLVE;
|
||||
}
|
||||
}
|
||||
|
||||
set_dest_address(ip, p_port);
|
||||
return OK;
|
||||
}
|
||||
|
||||
int PacketPeerUDP::get_available_packet_count() const {
|
||||
|
||||
// TODO we should deprecate this, and expose poll instead!
|
||||
Error err = const_cast<PacketPeerUDP *>(this)->_poll();
|
||||
if (err != OK)
|
||||
if (err != OK) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
return queue_count;
|
||||
}
|
||||
|
||||
Error PacketPeerUDP::get_packet(const uint8_t **r_buffer, int &r_buffer_size) {
|
||||
|
||||
Error err = _poll();
|
||||
if (err != OK)
|
||||
if (err != OK) {
|
||||
return err;
|
||||
if (queue_count == 0)
|
||||
}
|
||||
if (queue_count == 0) {
|
||||
return ERR_UNAVAILABLE;
|
||||
}
|
||||
|
||||
uint32_t size = 0;
|
||||
uint8_t ipv6[16];
|
||||
@ -117,7 +115,6 @@ Error PacketPeerUDP::get_packet(const uint8_t **r_buffer, int &r_buffer_size) {
|
||||
}
|
||||
|
||||
Error PacketPeerUDP::put_packet(const uint8_t *p_buffer, int p_buffer_size) {
|
||||
|
||||
ERR_FAIL_COND_V(!_sock.is_valid(), ERR_UNAVAILABLE);
|
||||
ERR_FAIL_COND_V(!peer_addr.is_valid(), ERR_UNCONFIGURED);
|
||||
|
||||
@ -139,10 +136,11 @@ Error PacketPeerUDP::put_packet(const uint8_t *p_buffer, int p_buffer_size) {
|
||||
err = _sock->sendto(p_buffer, p_buffer_size, sent, peer_addr, peer_port);
|
||||
}
|
||||
if (err != OK) {
|
||||
if (err != ERR_BUSY)
|
||||
if (err != ERR_BUSY) {
|
||||
return FAILED;
|
||||
else if (!blocking)
|
||||
} else if (!blocking) {
|
||||
return ERR_BUSY;
|
||||
}
|
||||
// Keep trying to send full packet
|
||||
continue;
|
||||
}
|
||||
@ -154,12 +152,10 @@ Error PacketPeerUDP::put_packet(const uint8_t *p_buffer, int p_buffer_size) {
|
||||
}
|
||||
|
||||
int PacketPeerUDP::get_max_packet_size() const {
|
||||
|
||||
return 512; // uhm maybe not
|
||||
}
|
||||
|
||||
Error PacketPeerUDP::listen(int p_port, const IP_Address &p_bind_address, int p_recv_buffer_size) {
|
||||
|
||||
ERR_FAIL_COND_V(!_sock.is_valid(), ERR_UNAVAILABLE);
|
||||
ERR_FAIL_COND_V(_sock->is_open(), ERR_ALREADY_IN_USE);
|
||||
ERR_FAIL_COND_V(!p_bind_address.is_valid() && !p_bind_address.is_wildcard(), ERR_INVALID_PARAMETER);
|
||||
@ -167,13 +163,15 @@ Error PacketPeerUDP::listen(int p_port, const IP_Address &p_bind_address, int p_
|
||||
Error err;
|
||||
IP::Type ip_type = IP::TYPE_ANY;
|
||||
|
||||
if (p_bind_address.is_valid())
|
||||
if (p_bind_address.is_valid()) {
|
||||
ip_type = p_bind_address.is_ipv4() ? IP::TYPE_IPV4 : IP::TYPE_IPV6;
|
||||
}
|
||||
|
||||
err = _sock->open(NetSocket::TYPE_UDP, ip_type);
|
||||
|
||||
if (err != OK)
|
||||
if (err != OK) {
|
||||
return ERR_CANT_CREATE;
|
||||
}
|
||||
|
||||
_sock->set_blocking_enabled(false);
|
||||
_sock->set_reuse_address_enabled(true);
|
||||
@ -245,22 +243,20 @@ bool PacketPeerUDP::is_connected_to_host() const {
|
||||
}
|
||||
|
||||
void PacketPeerUDP::close() {
|
||||
|
||||
if (_sock.is_valid())
|
||||
if (_sock.is_valid()) {
|
||||
_sock->close();
|
||||
}
|
||||
rb.resize(16);
|
||||
queue_count = 0;
|
||||
connected = false;
|
||||
}
|
||||
|
||||
Error PacketPeerUDP::wait() {
|
||||
|
||||
ERR_FAIL_COND_V(!_sock.is_valid(), ERR_UNAVAILABLE);
|
||||
return _sock->poll(NetSocket::POLL_TYPE_IN, -1);
|
||||
}
|
||||
|
||||
Error PacketPeerUDP::_poll() {
|
||||
|
||||
ERR_FAIL_COND_V(!_sock.is_valid(), ERR_UNAVAILABLE);
|
||||
|
||||
if (!_sock->is_open()) {
|
||||
@ -282,8 +278,9 @@ Error PacketPeerUDP::_poll() {
|
||||
}
|
||||
|
||||
if (err != OK) {
|
||||
if (err == ERR_BUSY)
|
||||
if (err == ERR_BUSY) {
|
||||
break;
|
||||
}
|
||||
return FAILED;
|
||||
}
|
||||
|
||||
@ -304,30 +301,26 @@ Error PacketPeerUDP::_poll() {
|
||||
|
||||
return OK;
|
||||
}
|
||||
bool PacketPeerUDP::is_listening() const {
|
||||
|
||||
bool PacketPeerUDP::is_listening() const {
|
||||
return _sock.is_valid() && _sock->is_open();
|
||||
}
|
||||
|
||||
IP_Address PacketPeerUDP::get_packet_address() const {
|
||||
|
||||
return packet_ip;
|
||||
}
|
||||
|
||||
int PacketPeerUDP::get_packet_port() const {
|
||||
|
||||
return packet_port;
|
||||
}
|
||||
|
||||
void PacketPeerUDP::set_dest_address(const IP_Address &p_address, int p_port) {
|
||||
|
||||
ERR_FAIL_COND_MSG(connected, "Destination address cannot be set for connected sockets");
|
||||
peer_addr = p_address;
|
||||
peer_port = p_port;
|
||||
}
|
||||
|
||||
void PacketPeerUDP::_bind_methods() {
|
||||
|
||||
ClassDB::bind_method(D_METHOD("listen", "port", "bind_address", "recv_buf_size"), &PacketPeerUDP::listen, DEFVAL("*"), DEFVAL(65536));
|
||||
ClassDB::bind_method(D_METHOD("close"), &PacketPeerUDP::close);
|
||||
ClassDB::bind_method(D_METHOD("wait"), &PacketPeerUDP::wait);
|
||||
@ -348,6 +341,5 @@ PacketPeerUDP::PacketPeerUDP() :
|
||||
}
|
||||
|
||||
PacketPeerUDP::~PacketPeerUDP() {
|
||||
|
||||
close();
|
||||
}
|
||||
|
@ -35,34 +35,31 @@
|
||||
#include "core/version.h"
|
||||
|
||||
static uint64_t _align(uint64_t p_n, int p_alignment) {
|
||||
|
||||
if (p_alignment == 0)
|
||||
if (p_alignment == 0) {
|
||||
return p_n;
|
||||
}
|
||||
|
||||
uint64_t rest = p_n % p_alignment;
|
||||
if (rest == 0)
|
||||
if (rest == 0) {
|
||||
return p_n;
|
||||
else
|
||||
} else {
|
||||
return p_n + (p_alignment - rest);
|
||||
}
|
||||
};
|
||||
|
||||
static void _pad(FileAccess *p_file, int p_bytes) {
|
||||
|
||||
for (int i = 0; i < p_bytes; i++) {
|
||||
|
||||
p_file->store_8(0);
|
||||
};
|
||||
};
|
||||
|
||||
void PCKPacker::_bind_methods() {
|
||||
|
||||
ClassDB::bind_method(D_METHOD("pck_start", "pck_name", "alignment"), &PCKPacker::pck_start, DEFVAL(0));
|
||||
ClassDB::bind_method(D_METHOD("add_file", "pck_path", "source_path"), &PCKPacker::add_file);
|
||||
ClassDB::bind_method(D_METHOD("flush", "verbose"), &PCKPacker::flush, DEFVAL(false));
|
||||
};
|
||||
|
||||
Error PCKPacker::pck_start(const String &p_file, int p_alignment) {
|
||||
|
||||
if (file != nullptr) {
|
||||
memdelete(file);
|
||||
}
|
||||
@ -80,7 +77,6 @@ Error PCKPacker::pck_start(const String &p_file, int p_alignment) {
|
||||
file->store_32(VERSION_PATCH);
|
||||
|
||||
for (int i = 0; i < 16; i++) {
|
||||
|
||||
file->store_32(0); // reserved
|
||||
};
|
||||
|
||||
@ -90,7 +86,6 @@ Error PCKPacker::pck_start(const String &p_file, int p_alignment) {
|
||||
};
|
||||
|
||||
Error PCKPacker::add_file(const String &p_file, const String &p_src) {
|
||||
|
||||
FileAccess *f = FileAccess::open(p_src, FileAccess::READ);
|
||||
if (!f) {
|
||||
return ERR_FILE_CANT_OPEN;
|
||||
@ -111,7 +106,6 @@ Error PCKPacker::add_file(const String &p_file, const String &p_src) {
|
||||
};
|
||||
|
||||
Error PCKPacker::flush(bool p_verbose) {
|
||||
|
||||
ERR_FAIL_COND_V_MSG(!file, ERR_INVALID_PARAMETER, "File must be opened before use.");
|
||||
|
||||
// write the index
|
||||
@ -119,7 +113,6 @@ Error PCKPacker::flush(bool p_verbose) {
|
||||
file->store_32(files.size());
|
||||
|
||||
for (int i = 0; i < files.size(); i++) {
|
||||
|
||||
file->store_pascal_string(files[i].path);
|
||||
files.write[i].offset_offset = file->get_position();
|
||||
file->store_64(0); // offset
|
||||
@ -142,11 +135,9 @@ Error PCKPacker::flush(bool p_verbose) {
|
||||
|
||||
int count = 0;
|
||||
for (int i = 0; i < files.size(); i++) {
|
||||
|
||||
FileAccess *src = FileAccess::open(files[i].src_path, FileAccess::READ);
|
||||
uint64_t to_write = files[i].size;
|
||||
while (to_write > 0) {
|
||||
|
||||
int read = src->get_buffer(buf, MIN(to_write, buf_max));
|
||||
file->store_buffer(buf, read);
|
||||
to_write -= read;
|
||||
@ -171,8 +162,9 @@ Error PCKPacker::flush(bool p_verbose) {
|
||||
};
|
||||
};
|
||||
|
||||
if (p_verbose)
|
||||
if (p_verbose) {
|
||||
printf("\n");
|
||||
}
|
||||
|
||||
file->close();
|
||||
memdelete_arr(buf);
|
||||
|
@ -36,7 +36,6 @@
|
||||
class FileAccess;
|
||||
|
||||
class PCKPacker : public Reference {
|
||||
|
||||
GDCLASS(PCKPacker, Reference);
|
||||
|
||||
FileAccess *file = nullptr;
|
||||
@ -45,7 +44,6 @@ class PCKPacker : public Reference {
|
||||
static void _bind_methods();
|
||||
|
||||
struct File {
|
||||
|
||||
String path;
|
||||
String src_path;
|
||||
int size;
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -36,7 +36,6 @@
|
||||
#include "core/os/file_access.h"
|
||||
|
||||
class ResourceLoaderBinary {
|
||||
|
||||
bool translation_remapped = false;
|
||||
String local_path;
|
||||
String res_path;
|
||||
@ -114,7 +113,6 @@ public:
|
||||
};
|
||||
|
||||
class ResourceFormatSaverBinaryInstance {
|
||||
|
||||
String local_path;
|
||||
String path;
|
||||
|
||||
@ -147,7 +145,6 @@ class ResourceFormatSaverBinaryInstance {
|
||||
};
|
||||
|
||||
struct ResourceData {
|
||||
|
||||
String type;
|
||||
List<Property> properties;
|
||||
};
|
||||
|
@ -38,7 +38,6 @@ bool ResourceFormatImporter::SortImporterByName::operator()(const Ref<ResourceIm
|
||||
}
|
||||
|
||||
Error ResourceFormatImporter::_get_path_and_type(const String &p_path, PathAndType &r_path_and_type, bool *r_valid) const {
|
||||
|
||||
Error err;
|
||||
FileAccess *f = FileAccess::open(p_path + ".import", FileAccess::READ, &err);
|
||||
|
||||
@ -64,7 +63,6 @@ Error ResourceFormatImporter::_get_path_and_type(const String &p_path, PathAndTy
|
||||
String error_text;
|
||||
bool path_found = false; //first match must have priority
|
||||
while (true) {
|
||||
|
||||
assign = Variant();
|
||||
next_tag.fields.clear();
|
||||
next_tag.name = String();
|
||||
@ -118,14 +116,13 @@ Error ResourceFormatImporter::_get_path_and_type(const String &p_path, PathAndTy
|
||||
}
|
||||
|
||||
RES ResourceFormatImporter::load(const String &p_path, const String &p_original_path, Error *r_error, bool p_use_sub_threads, float *r_progress, bool p_no_cache) {
|
||||
|
||||
PathAndType pat;
|
||||
Error err = _get_path_and_type(p_path, pat);
|
||||
|
||||
if (err != OK) {
|
||||
|
||||
if (r_error)
|
||||
if (r_error) {
|
||||
*r_error = err;
|
||||
}
|
||||
|
||||
return RES();
|
||||
}
|
||||
@ -143,7 +140,6 @@ RES ResourceFormatImporter::load(const String &p_path, const String &p_original_
|
||||
}
|
||||
|
||||
void ResourceFormatImporter::get_recognized_extensions(List<String> *p_extensions) const {
|
||||
|
||||
Set<String> found;
|
||||
|
||||
for (int i = 0; i < importers.size(); i++) {
|
||||
@ -159,7 +155,6 @@ void ResourceFormatImporter::get_recognized_extensions(List<String> *p_extension
|
||||
}
|
||||
|
||||
void ResourceFormatImporter::get_recognized_extensions_for_type(const String &p_type, List<String> *p_extensions) const {
|
||||
|
||||
if (p_type == "") {
|
||||
get_recognized_extensions(p_extensions);
|
||||
return;
|
||||
@ -169,11 +164,13 @@ void ResourceFormatImporter::get_recognized_extensions_for_type(const String &p_
|
||||
|
||||
for (int i = 0; i < importers.size(); i++) {
|
||||
String res_type = importers[i]->get_resource_type();
|
||||
if (res_type == String())
|
||||
if (res_type == String()) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (!ClassDB::is_parent_class(res_type, p_type))
|
||||
if (!ClassDB::is_parent_class(res_type, p_type)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
List<String> local_exts;
|
||||
importers[i]->get_recognized_extensions(&local_exts);
|
||||
@ -187,26 +184,21 @@ void ResourceFormatImporter::get_recognized_extensions_for_type(const String &p_
|
||||
}
|
||||
|
||||
bool ResourceFormatImporter::exists(const String &p_path) const {
|
||||
|
||||
return FileAccess::exists(p_path + ".import");
|
||||
}
|
||||
|
||||
bool ResourceFormatImporter::recognize_path(const String &p_path, const String &p_for_type) const {
|
||||
|
||||
return FileAccess::exists(p_path + ".import");
|
||||
}
|
||||
|
||||
bool ResourceFormatImporter::can_be_imported(const String &p_path) const {
|
||||
|
||||
return ResourceFormatLoader::recognize_path(p_path);
|
||||
}
|
||||
|
||||
int ResourceFormatImporter::get_import_order(const String &p_path) const {
|
||||
|
||||
Ref<ResourceImporter> importer;
|
||||
|
||||
if (FileAccess::exists(p_path + ".import")) {
|
||||
|
||||
PathAndType pat;
|
||||
Error err = _get_path_and_type(p_path, pat);
|
||||
|
||||
@ -214,37 +206,35 @@ int ResourceFormatImporter::get_import_order(const String &p_path) const {
|
||||
importer = get_importer_by_name(pat.importer);
|
||||
}
|
||||
} else {
|
||||
|
||||
importer = get_importer_by_extension(p_path.get_extension().to_lower());
|
||||
}
|
||||
|
||||
if (importer.is_valid())
|
||||
if (importer.is_valid()) {
|
||||
return importer->get_import_order();
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
bool ResourceFormatImporter::handles_type(const String &p_type) const {
|
||||
|
||||
for (int i = 0; i < importers.size(); i++) {
|
||||
|
||||
String res_type = importers[i]->get_resource_type();
|
||||
if (res_type == String())
|
||||
if (res_type == String()) {
|
||||
continue;
|
||||
if (ClassDB::is_parent_class(res_type, p_type))
|
||||
}
|
||||
if (ClassDB::is_parent_class(res_type, p_type)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
String ResourceFormatImporter::get_internal_resource_path(const String &p_path) const {
|
||||
|
||||
PathAndType pat;
|
||||
Error err = _get_path_and_type(p_path, pat);
|
||||
|
||||
if (err != OK) {
|
||||
|
||||
return String();
|
||||
}
|
||||
|
||||
@ -252,12 +242,12 @@ String ResourceFormatImporter::get_internal_resource_path(const String &p_path)
|
||||
}
|
||||
|
||||
void ResourceFormatImporter::get_internal_resource_path_list(const String &p_path, List<String> *r_paths) {
|
||||
|
||||
Error err;
|
||||
FileAccess *f = FileAccess::open(p_path + ".import", FileAccess::READ, &err);
|
||||
|
||||
if (!f)
|
||||
if (!f) {
|
||||
return;
|
||||
}
|
||||
|
||||
VariantParser::StreamFile stream;
|
||||
stream.f = f;
|
||||
@ -269,7 +259,6 @@ void ResourceFormatImporter::get_internal_resource_path_list(const String &p_pat
|
||||
int lines = 0;
|
||||
String error_text;
|
||||
while (true) {
|
||||
|
||||
assign = Variant();
|
||||
next_tag.fields.clear();
|
||||
next_tag.name = String();
|
||||
@ -298,7 +287,6 @@ void ResourceFormatImporter::get_internal_resource_path_list(const String &p_pat
|
||||
}
|
||||
|
||||
String ResourceFormatImporter::get_import_group_file(const String &p_path) const {
|
||||
|
||||
bool valid = true;
|
||||
PathAndType pat;
|
||||
_get_path_and_type(p_path, pat, &valid);
|
||||
@ -306,7 +294,6 @@ String ResourceFormatImporter::get_import_group_file(const String &p_path) const
|
||||
}
|
||||
|
||||
bool ResourceFormatImporter::is_import_valid(const String &p_path) const {
|
||||
|
||||
bool valid = true;
|
||||
PathAndType pat;
|
||||
_get_path_and_type(p_path, pat, &valid);
|
||||
@ -314,12 +301,10 @@ bool ResourceFormatImporter::is_import_valid(const String &p_path) const {
|
||||
}
|
||||
|
||||
String ResourceFormatImporter::get_resource_type(const String &p_path) const {
|
||||
|
||||
PathAndType pat;
|
||||
Error err = _get_path_and_type(p_path, pat);
|
||||
|
||||
if (err != OK) {
|
||||
|
||||
return "";
|
||||
}
|
||||
|
||||
@ -331,7 +316,6 @@ Variant ResourceFormatImporter::get_resource_metadata(const String &p_path) cons
|
||||
Error err = _get_path_and_type(p_path, pat);
|
||||
|
||||
if (err != OK) {
|
||||
|
||||
return Variant();
|
||||
}
|
||||
|
||||
@ -339,12 +323,10 @@ Variant ResourceFormatImporter::get_resource_metadata(const String &p_path) cons
|
||||
}
|
||||
|
||||
void ResourceFormatImporter::get_dependencies(const String &p_path, List<String> *p_dependencies, bool p_add_types) {
|
||||
|
||||
PathAndType pat;
|
||||
Error err = _get_path_and_type(p_path, pat);
|
||||
|
||||
if (err != OK) {
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
@ -352,7 +334,6 @@ void ResourceFormatImporter::get_dependencies(const String &p_path, List<String>
|
||||
}
|
||||
|
||||
Ref<ResourceImporter> ResourceFormatImporter::get_importer_by_name(const String &p_name) const {
|
||||
|
||||
for (int i = 0; i < importers.size(); i++) {
|
||||
if (importers[i]->get_importer_name() == p_name) {
|
||||
return importers[i];
|
||||
@ -363,7 +344,6 @@ Ref<ResourceImporter> ResourceFormatImporter::get_importer_by_name(const String
|
||||
}
|
||||
|
||||
void ResourceFormatImporter::get_importers_for_extension(const String &p_extension, List<Ref<ResourceImporter>> *r_importers) {
|
||||
|
||||
for (int i = 0; i < importers.size(); i++) {
|
||||
List<String> local_exts;
|
||||
importers[i]->get_recognized_extensions(&local_exts);
|
||||
@ -376,12 +356,10 @@ void ResourceFormatImporter::get_importers_for_extension(const String &p_extensi
|
||||
}
|
||||
|
||||
Ref<ResourceImporter> ResourceFormatImporter::get_importer_by_extension(const String &p_extension) const {
|
||||
|
||||
Ref<ResourceImporter> importer;
|
||||
float priority = 0;
|
||||
|
||||
for (int i = 0; i < importers.size(); i++) {
|
||||
|
||||
List<String> local_exts;
|
||||
importers[i]->get_recognized_extensions(&local_exts);
|
||||
for (List<String>::Element *F = local_exts.front(); F; F = F->next()) {
|
||||
@ -396,12 +374,10 @@ Ref<ResourceImporter> ResourceFormatImporter::get_importer_by_extension(const St
|
||||
}
|
||||
|
||||
String ResourceFormatImporter::get_import_base_path(const String &p_for_file) const {
|
||||
|
||||
return "res://.import/" + p_for_file.get_file() + "-" + p_for_file.md5_text();
|
||||
}
|
||||
|
||||
bool ResourceFormatImporter::are_import_settings_valid(const String &p_path) const {
|
||||
|
||||
bool valid = true;
|
||||
PathAndType pat;
|
||||
_get_path_and_type(p_path, pat, &valid);
|
||||
@ -422,7 +398,6 @@ bool ResourceFormatImporter::are_import_settings_valid(const String &p_path) con
|
||||
}
|
||||
|
||||
String ResourceFormatImporter::get_import_settings_hash() const {
|
||||
|
||||
Vector<Ref<ResourceImporter>> sorted_importers = importers;
|
||||
|
||||
sorted_importers.sort_custom<SortImporterByName>();
|
||||
|
@ -36,7 +36,6 @@
|
||||
class ResourceImporter;
|
||||
|
||||
class ResourceFormatImporter : public ResourceFormatLoader {
|
||||
|
||||
struct PathAndType {
|
||||
String path;
|
||||
String type;
|
||||
@ -93,7 +92,6 @@ public:
|
||||
};
|
||||
|
||||
class ResourceImporter : public Reference {
|
||||
|
||||
GDCLASS(ResourceImporter, Reference);
|
||||
|
||||
public:
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user