summaryrefslogtreecommitdiff
path: root/core/io
diff options
context:
space:
mode:
Diffstat (limited to 'core/io')
-rw-r--r--core/io/file_access_compressed.cpp20
-rw-r--r--core/io/image_loader.cpp4
-rw-r--r--core/io/image_loader.h4
-rw-r--r--core/io/marshalls.cpp213
-rw-r--r--core/io/marshalls.h21
-rw-r--r--core/io/packet_peer.cpp20
-rw-r--r--core/io/packet_peer.h2
7 files changed, 189 insertions, 95 deletions
diff --git a/core/io/file_access_compressed.cpp b/core/io/file_access_compressed.cpp
index 4e802579c6..34bce3f04f 100644
--- a/core/io/file_access_compressed.cpp
+++ b/core/io/file_access_compressed.cpp
@@ -43,16 +43,16 @@ void FileAccessCompressed::configure(const String &p_magic, Compression::Mode p_
block_size = p_block_size;
}
-#define WRITE_FIT(m_bytes) \
- { \
- if (write_pos + (m_bytes) > write_max) { \
- write_max = write_pos + (m_bytes); \
- } \
- if (write_max > write_buffer_size) { \
- write_buffer_size = nearest_power_of_2(write_max); \
- buffer.resize(write_buffer_size); \
- write_ptr = buffer.ptr(); \
- } \
+#define WRITE_FIT(m_bytes) \
+ { \
+ if (write_pos + (m_bytes) > write_max) { \
+ write_max = write_pos + (m_bytes); \
+ } \
+ if (write_max > write_buffer_size) { \
+ write_buffer_size = next_power_of_2(write_max); \
+ buffer.resize(write_buffer_size); \
+ write_ptr = buffer.ptr(); \
+ } \
}
Error FileAccessCompressed::open_after_magic(FileAccess *p_base) {
diff --git a/core/io/image_loader.cpp b/core/io/image_loader.cpp
index 23719940be..7b5b4a13ea 100644
--- a/core/io/image_loader.cpp
+++ b/core/io/image_loader.cpp
@@ -43,7 +43,7 @@ bool ImageFormatLoader::recognize(const String &p_extension) const {
return false;
}
-Error ImageLoader::load_image(String p_file, Ref<Image> p_image, FileAccess *p_custom, bool p_force_linear) {
+Error ImageLoader::load_image(String p_file, Ref<Image> p_image, FileAccess *p_custom, bool p_force_linear, float p_scale) {
ERR_FAIL_COND_V(p_image.is_null(), ERR_INVALID_PARAMETER);
FileAccess *f = p_custom;
@@ -62,7 +62,7 @@ Error ImageLoader::load_image(String p_file, Ref<Image> p_image, FileAccess *p_c
if (!loader[i]->recognize(extension))
continue;
- Error err = loader[i]->load_image(p_image, f, p_force_linear);
+ Error err = loader[i]->load_image(p_image, f, p_force_linear, p_scale);
if (err != ERR_FILE_UNRECOGNIZED) {
diff --git a/core/io/image_loader.h b/core/io/image_loader.h
index e528d1423b..f79d9789bf 100644
--- a/core/io/image_loader.h
+++ b/core/io/image_loader.h
@@ -56,7 +56,7 @@ class ImageFormatLoader {
friend class ImageLoader;
protected:
- virtual Error load_image(Ref<Image> p_image, FileAccess *p_fileaccess, bool p_force_linear) = 0;
+ virtual Error load_image(Ref<Image> p_image, FileAccess *p_fileaccess, bool p_force_linear, float p_scale) = 0;
virtual void get_recognized_extensions(List<String> *p_extensions) const = 0;
bool recognize(const String &p_extension) const;
@@ -75,7 +75,7 @@ class ImageLoader {
protected:
public:
- static Error load_image(String p_file, Ref<Image> p_image, FileAccess *p_custom = NULL, bool p_force_linear = false);
+ static Error load_image(String p_file, Ref<Image> p_image, FileAccess *p_custom = NULL, bool p_force_linear = false, float p_scale = 1.0);
static void get_recognized_extensions(List<String> *p_extensions);
static bool recognize(const String &p_extension);
diff --git a/core/io/marshalls.cpp b/core/io/marshalls.cpp
index 8eb40b61d7..e701a89c78 100644
--- a/core/io/marshalls.cpp
+++ b/core/io/marshalls.cpp
@@ -33,8 +33,28 @@
#include "reference.h"
#include <stdio.h>
+void EncodedObjectAsID::_bind_methods() {
+ ClassDB::bind_method(D_METHOD("set_object_id", "id"), &EncodedObjectAsID::set_object_id);
+ ClassDB::bind_method(D_METHOD("get_object_id"), &EncodedObjectAsID::get_object_id);
+}
+
+void EncodedObjectAsID::set_object_id(ObjectID p_id) {
+ id = p_id;
+}
+
+ObjectID EncodedObjectAsID::get_object_id() const {
+
+ return id;
+}
+
+EncodedObjectAsID::EncodedObjectAsID() {
+
+ id = 0;
+}
+
#define ENCODE_MASK 0xFF
#define ENCODE_FLAG_64 1 << 16
+#define ENCODE_FLAG_OBJECT_AS_ID 1 << 16
static Error _decode_string(const uint8_t *&buf, int &len, int *r_len, String &r_string) {
ERR_FAIL_COND_V(len < 4, ERR_INVALID_DATA);
@@ -381,56 +401,74 @@ Error decode_variant(Variant &r_variant, const uint8_t *p_buffer, int p_len, int
} break;
case Variant::OBJECT: {
- ERR_FAIL_COND_V(!p_allow_objects, ERR_UNAUTHORIZED);
-
- String str;
- Error err = _decode_string(buf, len, r_len, str);
- if (err)
- return err;
+ if (type & ENCODE_FLAG_OBJECT_AS_ID) {
+ //this _is_ allowed
+ ObjectID val = decode_uint64(buf);
+ if (r_len)
+ (*r_len) += 8;
- if (str == String()) {
- r_variant = (Object *)NULL;
- } else {
+ if (val == 0) {
+ r_variant = (Object *)NULL;
+ } else {
+ Ref<EncodedObjectAsID> obj_as_id;
+ obj_as_id.instance();
+ obj_as_id->set_object_id(val);
- Object *obj = ClassDB::instance(str);
+ r_variant = obj_as_id;
+ }
- ERR_FAIL_COND_V(!obj, ERR_UNAVAILABLE);
- ERR_FAIL_COND_V(len < 4, ERR_INVALID_DATA);
+ } else {
+ ERR_FAIL_COND_V(!p_allow_objects, ERR_UNAUTHORIZED);
- int32_t count = decode_uint32(buf);
- buf += 4;
- len -= 4;
- if (r_len) {
- (*r_len) += 4;
- }
+ String str;
+ Error err = _decode_string(buf, len, r_len, str);
+ if (err)
+ return err;
- for (int i = 0; i < count; i++) {
+ if (str == String()) {
+ r_variant = (Object *)NULL;
+ } else {
- str = String();
- err = _decode_string(buf, len, r_len, str);
- if (err)
- return err;
+ Object *obj = ClassDB::instance(str);
- Variant value;
- int used;
- err = decode_variant(value, buf, len, &used, p_allow_objects);
- if (err)
- return err;
+ ERR_FAIL_COND_V(!obj, ERR_UNAVAILABLE);
+ ERR_FAIL_COND_V(len < 4, ERR_INVALID_DATA);
- buf += used;
- len -= used;
+ int32_t count = decode_uint32(buf);
+ buf += 4;
+ len -= 4;
if (r_len) {
- (*r_len) += used;
+ (*r_len) += 4;
}
- obj->set(str, value);
- }
+ for (int i = 0; i < count; i++) {
- if (obj->cast_to<Reference>()) {
- REF ref = REF(obj->cast_to<Reference>());
- r_variant = ref;
- } else {
- r_variant = obj;
+ str = String();
+ err = _decode_string(buf, len, r_len, str);
+ if (err)
+ return err;
+
+ Variant value;
+ int used;
+ err = decode_variant(value, buf, len, &used, p_allow_objects);
+ if (err)
+ return err;
+
+ buf += used;
+ len -= used;
+ if (r_len) {
+ (*r_len) += used;
+ }
+
+ obj->set(str, value);
+ }
+
+ if (obj->cast_to<Reference>()) {
+ REF ref = REF(obj->cast_to<Reference>());
+ r_variant = ref;
+ } else {
+ r_variant = obj;
+ }
}
}
@@ -769,14 +807,19 @@ static void _encode_string(const String &p_string, uint8_t *&buf, int &r_len) {
encode_uint32(utf8.length(), buf);
buf += 4;
copymem(buf, utf8.get_data(), utf8.length());
+ buf += utf8.length();
}
r_len += 4 + utf8.length();
- while (r_len % 4)
+ while (r_len % 4) {
r_len++; //pad
+ if (buf) {
+ buf++;
+ }
+ }
}
-Error encode_variant(const Variant &p_variant, uint8_t *r_buffer, int &r_len) {
+Error encode_variant(const Variant &p_variant, uint8_t *r_buffer, int &r_len, bool p_object_as_id) {
uint8_t *buf = r_buffer;
@@ -800,6 +843,11 @@ Error encode_variant(const Variant &p_variant, uint8_t *r_buffer, int &r_len) {
flags |= ENCODE_FLAG_64; //always encode real as double
}
} break;
+ case Variant::OBJECT: {
+ if (p_object_as_id) {
+ flags |= ENCODE_FLAG_OBJECT_AS_ID;
+ }
+ } break;
}
if (buf) {
@@ -1071,49 +1119,66 @@ Error encode_variant(const Variant &p_variant, uint8_t *r_buffer, int &r_len) {
} break;
case Variant::OBJECT: {
- Object *obj = p_variant;
- if (!obj) {
+ if (p_object_as_id) {
+
if (buf) {
- encode_uint32(0, buf);
- buf += 4;
- r_len += 4;
+
+ Object *obj = p_variant;
+ ObjectID id = 0;
+ if (obj && ObjectDB::instance_validate(obj)) {
+ id = obj->get_instance_id();
+ }
+
+ encode_uint64(id, buf);
}
+
+ r_len += 8;
+
} else {
- _encode_string(obj->get_class(), buf, r_len);
+ Object *obj = p_variant;
+ if (!obj) {
+ if (buf) {
+ encode_uint32(0, buf);
+ buf += 4;
+ r_len += 4;
+ }
+ } else {
+ _encode_string(obj->get_class(), buf, r_len);
- List<PropertyInfo> props;
- obj->get_property_list(&props);
+ List<PropertyInfo> props;
+ obj->get_property_list(&props);
- int pc = 0;
- for (List<PropertyInfo>::Element *E = props.front(); E; E = E->next()) {
+ int pc = 0;
+ for (List<PropertyInfo>::Element *E = props.front(); E; E = E->next()) {
- if (!(E->get().usage & PROPERTY_USAGE_STORAGE))
- continue;
- pc++;
- }
+ if (!(E->get().usage & PROPERTY_USAGE_STORAGE))
+ continue;
+ pc++;
+ }
- if (buf) {
- encode_uint32(pc, buf);
- buf += 4;
- }
+ if (buf) {
+ encode_uint32(pc, buf);
+ buf += 4;
+ }
- r_len += 4;
+ r_len += 4;
- for (List<PropertyInfo>::Element *E = props.front(); E; E = E->next()) {
+ for (List<PropertyInfo>::Element *E = props.front(); E; E = E->next()) {
- if (!(E->get().usage & PROPERTY_USAGE_STORAGE))
- continue;
+ if (!(E->get().usage & PROPERTY_USAGE_STORAGE))
+ continue;
- _encode_string(E->get().name, buf, r_len);
+ _encode_string(E->get().name, buf, r_len);
- int len;
- Error err = encode_variant(obj->get(E->get().name), buf, len);
- if (err)
- return err;
- ERR_FAIL_COND_V(len % 4, ERR_BUG);
- r_len += len;
- if (buf)
- buf += len;
+ int len;
+ Error err = encode_variant(obj->get(E->get().name), buf, len, p_object_as_id);
+ if (err)
+ return err;
+ ERR_FAIL_COND_V(len % 4, ERR_BUG);
+ r_len += len;
+ if (buf)
+ buf += len;
+ }
}
}
@@ -1147,12 +1212,12 @@ Error encode_variant(const Variant &p_variant, uint8_t *r_buffer, int &r_len) {
r_len++; //pad
*/
int len;
- encode_variant(E->get(), buf, len);
+ encode_variant(E->get(), buf, len, p_object_as_id);
ERR_FAIL_COND_V(len % 4, ERR_BUG);
r_len += len;
if (buf)
buf += len;
- encode_variant(d[E->get()], buf, len);
+ encode_variant(d[E->get()], buf, len, p_object_as_id);
ERR_FAIL_COND_V(len % 4, ERR_BUG);
r_len += len;
if (buf)
@@ -1174,7 +1239,7 @@ Error encode_variant(const Variant &p_variant, uint8_t *r_buffer, int &r_len) {
for (int i = 0; i < v.size(); i++) {
int len;
- encode_variant(v.get(i), buf, len);
+ encode_variant(v.get(i), buf, len, p_object_as_id);
ERR_FAIL_COND_V(len % 4, ERR_BUG);
r_len += len;
if (buf)
diff --git a/core/io/marshalls.h b/core/io/marshalls.h
index a6cc72b691..234ae3b183 100644
--- a/core/io/marshalls.h
+++ b/core/io/marshalls.h
@@ -32,8 +32,8 @@
#include "typedefs.h"
+#include "reference.h"
#include "variant.h"
-
/**
* Miscellaneous helpers for marshalling data types, and encoding
* in an endian independent way
@@ -183,7 +183,22 @@ static inline double decode_double(const uint8_t *p_arr) {
return md.d;
}
-Error decode_variant(Variant &r_variant, const uint8_t *p_buffer, int p_len, int *r_len = NULL, bool p_allow_objects=true);
-Error encode_variant(const Variant &p_variant, uint8_t *r_buffer, int &r_len);
+class EncodedObjectAsID : public Reference {
+ GDCLASS(EncodedObjectAsID, Reference);
+
+ ObjectID id;
+
+protected:
+ static void _bind_methods();
+
+public:
+ void set_object_id(ObjectID p_id);
+ ObjectID get_object_id() const;
+
+ EncodedObjectAsID();
+};
+
+Error decode_variant(Variant &r_variant, const uint8_t *p_buffer, int p_len, int *r_len = NULL, bool p_allow_objects = true);
+Error encode_variant(const Variant &p_variant, uint8_t *r_buffer, int &r_len, bool p_object_as_id = false);
#endif
diff --git a/core/io/packet_peer.cpp b/core/io/packet_peer.cpp
index f62ffd7183..ca00b8b480 100644
--- a/core/io/packet_peer.cpp
+++ b/core/io/packet_peer.cpp
@@ -92,7 +92,7 @@ Error PacketPeer::get_var(Variant &r_variant) const {
Error PacketPeer::put_var(const Variant &p_packet) {
int len;
- Error err = encode_variant(p_packet, NULL, len); // compute len first
+ Error err = encode_variant(p_packet, NULL, len, !allow_object_decoding); // compute len first
if (err)
return err;
@@ -101,7 +101,7 @@ Error PacketPeer::put_var(const Variant &p_packet) {
uint8_t *buf = (uint8_t *)alloca(len);
ERR_FAIL_COND_V(!buf, ERR_OUT_OF_MEMORY);
- err = encode_variant(p_packet, buf, len);
+ err = encode_variant(p_packet, buf, len, !allow_object_decoding);
ERR_FAIL_COND_V(err, err);
return put_packet(buf, len);
@@ -155,6 +155,8 @@ void PacketPeerStream::_bind_methods() {
ClassDB::bind_method(D_METHOD("set_stream_peer", "peer"), &PacketPeerStream::_set_stream_peer);
ClassDB::bind_method(D_METHOD("set_input_buffer_max_size", "max_size_bytes"), &PacketPeerStream::set_input_buffer_max_size);
ClassDB::bind_method(D_METHOD("set_output_buffer_max_size", "max_size_bytes"), &PacketPeerStream::set_output_buffer_max_size);
+ ClassDB::bind_method(D_METHOD("get_input_buffer_max_size"), &PacketPeerStream::get_input_buffer_max_size);
+ ClassDB::bind_method(D_METHOD("get_output_buffer_max_size"), &PacketPeerStream::get_output_buffer_max_size);
}
Error PacketPeerStream::_poll_buffer() const {
@@ -265,12 +267,22 @@ void PacketPeerStream::set_input_buffer_max_size(int p_max_size) {
ERR_EXPLAIN("Buffer in use, resizing would cause loss of data");
ERR_FAIL_COND(ring_buffer.data_left());
ring_buffer.resize(nearest_shift(p_max_size + 4));
- input_buffer.resize(nearest_power_of_2(p_max_size + 4));
+ input_buffer.resize(next_power_of_2(p_max_size + 4));
+}
+
+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(nearest_power_of_2(p_max_size + 4));
+ 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() {
diff --git a/core/io/packet_peer.h b/core/io/packet_peer.h
index 3bd6876aa7..597119f7f4 100644
--- a/core/io/packet_peer.h
+++ b/core/io/packet_peer.h
@@ -98,7 +98,9 @@ public:
void set_stream_peer(const Ref<StreamPeer> &p_peer);
void set_input_buffer_max_size(int p_max_size);
+ int get_input_buffer_max_size() const;
void set_output_buffer_max_size(int p_max_size);
+ int get_output_buffer_max_size() const;
PacketPeerStream();
};