summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--core/error_macros.h5
-rw-r--r--core/io/resource_format_binary.cpp2
-rw-r--r--core/object.cpp27
-rw-r--r--core/object.h2
-rw-r--r--core/object_type_db.cpp39
-rw-r--r--core/object_type_db.h4
-rw-r--r--core/ring_buffer.h6
-rw-r--r--core/script_language.cpp14
-rw-r--r--core/script_language.h3
-rw-r--r--core/variant.h2
-rw-r--r--core/variant_call.cpp11
-rw-r--r--doc/base/classes.xml15
-rw-r--r--drivers/theora/video_stream_theora.cpp117
-rw-r--r--drivers/theora/video_stream_theora.h32
-rw-r--r--drivers/webp/dec/alpha.c2
-rw-r--r--drivers/webp/dec/decode_vp8.h2
-rw-r--r--drivers/webp/dec/webp.c2
-rw-r--r--drivers/webp/demux/anim_decode.c6
-rw-r--r--drivers/webp/demux/demux.c8
-rw-r--r--drivers/webp/dsp/dsp.h4
-rw-r--r--drivers/webp/dsp/lossless.h4
-rw-r--r--drivers/webp/enc/alpha.c2
-rw-r--r--drivers/webp/enc/backward_references.h4
-rw-r--r--drivers/webp/enc/config.c2
-rw-r--r--drivers/webp/enc/delta_palettization.c2
-rw-r--r--drivers/webp/enc/delta_palettization.h2
-rw-r--r--drivers/webp/enc/frame.c2
-rw-r--r--drivers/webp/enc/histogram.c2
-rw-r--r--drivers/webp/enc/histogram.h4
-rw-r--r--drivers/webp/enc/syntax.c4
-rw-r--r--drivers/webp/enc/vp8enci.h2
-rw-r--r--drivers/webp/enc/vp8l.c2
-rw-r--r--drivers/webp/enc/vp8li.h4
-rw-r--r--drivers/webp/mux/anim_encode.c8
-rw-r--r--drivers/webp/mux/muxi.h2
-rw-r--r--drivers/webp/utils/bit_reader.c2
-rw-r--r--drivers/webp/utils/bit_reader.h2
-rw-r--r--drivers/webp/utils/bit_reader_inl.h2
-rw-r--r--drivers/webp/utils/bit_writer.h2
-rw-r--r--drivers/webp/utils/color_cache.h2
-rw-r--r--drivers/webp/utils/endian_inl.h4
-rw-r--r--drivers/webp/utils/filters.h2
-rw-r--r--drivers/webp/utils/huffman.c2
-rw-r--r--drivers/webp/utils/huffman.h4
-rw-r--r--drivers/webp/utils/huffman_encode.c2
-rw-r--r--drivers/webp/utils/huffman_encode.h2
-rw-r--r--drivers/webp/utils/quant_levels.h2
-rw-r--r--drivers/webp/utils/quant_levels_dec.h2
-rw-r--r--drivers/webp/utils/random.h2
-rw-r--r--drivers/webp/utils/rescaler.h2
-rw-r--r--drivers/webp/utils/thread.h4
-rw-r--r--drivers/webp/utils/utils.c4
-rw-r--r--drivers/webp/utils/utils.h2
-rw-r--r--modules/gdscript/gd_script.cpp20
-rw-r--r--modules/gdscript/gd_script.h2
-rw-r--r--platform/windows/detect.py1
-rw-r--r--scene/animation/animation_player.cpp87
-rw-r--r--scene/animation/animation_player.h2
-rw-r--r--tools/editor/animation_editor.cpp171
-rw-r--r--tools/editor/animation_editor.h8
-rw-r--r--tools/editor/icons/icon_key_invalid.pngbin0 -> 239 bytes
-rw-r--r--tools/editor/icons/icon_key_invalid_hover.pngbin0 -> 239 bytes
-rw-r--r--tools/editor/plugins/animation_player_editor_plugin.cpp7
-rw-r--r--tools/editor/plugins/animation_player_editor_plugin.h4
-rw-r--r--tools/editor/plugins/script_editor_plugin.cpp4
65 files changed, 605 insertions, 94 deletions
diff --git a/core/error_macros.h b/core/error_macros.h
index 76da88287b..cc88686301 100644
--- a/core/error_macros.h
+++ b/core/error_macros.h
@@ -207,6 +207,11 @@ extern bool _err_error_exists;
_err_error_exists=false;\
} \
+#define ERR_PRINTS(m_string) \
+ { \
+ _err_print_error(FUNCTION_STR,__FILE__,__LINE__,String(m_string).utf8().get_data()); \
+ _err_error_exists=false;\
+ } \
/** Print a warning string.
*/
diff --git a/core/io/resource_format_binary.cpp b/core/io/resource_format_binary.cpp
index 1a0552e8d1..4cd3cd595f 100644
--- a/core/io/resource_format_binary.cpp
+++ b/core/io/resource_format_binary.cpp
@@ -905,7 +905,7 @@ void ResourceInteractiveLoaderBinary::open(FileAccess *p_f) {
error=ERR_FILE_UNRECOGNIZED;
ERR_EXPLAIN("Unrecognized binary resource file: "+local_path);
- ERR_FAIL_V();
+ ERR_FAIL();
}
bool big_endian = f->get_32();
diff --git a/core/object.cpp b/core/object.cpp
index 3a4c06e7e7..96f0c86832 100644
--- a/core/object.cpp
+++ b/core/object.cpp
@@ -314,6 +314,7 @@ void Object::set(const StringName& p_name, const Variant& p_value, bool *r_valid
_edited=true;
#endif
+
if (script_instance) {
if (script_instance->set(p_name,p_value)) {
@@ -326,9 +327,9 @@ void Object::set(const StringName& p_name, const Variant& p_value, bool *r_valid
//try built-in setgetter
{
- if (ObjectTypeDB::set_property(this,p_name,p_value)) {
- if (r_valid)
- *r_valid=true;
+ if (ObjectTypeDB::set_property(this,p_name,p_value,r_valid)) {
+ //if (r_valid)
+ // *r_valid=true;
return;
}
}
@@ -1694,6 +1695,26 @@ void Object::get_translatable_strings(List<String> *p_strings) const {
}
+Variant::Type Object::get_static_property_type(const StringName& p_property, bool *r_valid) const {
+
+ bool valid;
+ Variant::Type t = ObjectTypeDB::get_property_type(get_type_name(),p_property,&valid);
+ if (valid) {
+ if (r_valid)
+ *r_valid=true;
+ return t;
+ }
+
+ if (get_script_instance()) {
+ return get_script_instance()->get_property_type(p_property,r_valid);
+ }
+ if (r_valid)
+ *r_valid=false;
+
+ return Variant::NIL;
+
+}
+
bool Object::is_queued_for_deletion() const {
return _is_queued_for_deletion;
}
diff --git a/core/object.h b/core/object.h
index 981a83958c..5b6361796f 100644
--- a/core/object.h
+++ b/core/object.h
@@ -606,6 +606,8 @@ public:
void set_block_signals(bool p_block);
bool is_blocking_signals() const;
+ Variant::Type get_static_property_type(const StringName& p_property,bool *r_valid=NULL) const;
+
virtual void get_translatable_strings(List<String> *p_strings) const;
virtual void get_argument_options(const StringName& p_function,int p_idx,List<String>*r_options) const;
diff --git a/core/object_type_db.cpp b/core/object_type_db.cpp
index a64b3d2715..f8ba0a9b15 100644
--- a/core/object_type_db.cpp
+++ b/core/object_type_db.cpp
@@ -612,6 +612,7 @@ void ObjectTypeDB::add_property(StringName p_type,const PropertyInfo& p_pinfo, c
psg._setptr=mb_set;
psg._getptr=mb_get;
psg.index=p_index;
+ psg.type=p_pinfo.type;
type->property_setget[p_pinfo.name]=psg;
@@ -634,7 +635,7 @@ void ObjectTypeDB::get_property_list(StringName p_type,List<PropertyInfo> *p_lis
}
}
-bool ObjectTypeDB::set_property(Object* p_object,const StringName& p_property, const Variant& p_value) {
+bool ObjectTypeDB::set_property(Object* p_object,const StringName& p_property, const Variant& p_value,bool *r_valid) {
TypeInfo *type=types.getptr(p_object->get_type_name());
@@ -643,13 +644,17 @@ bool ObjectTypeDB::set_property(Object* p_object,const StringName& p_property, c
const PropertySetGet *psg = check->property_setget.getptr(p_property);
if (psg) {
- if (!psg->setter)
+ if (!psg->setter) {
+ if (r_valid)
+ *r_valid=false;
return true; //return true but do nothing
+ }
+
+ Variant::CallError ce;
if (psg->index>=0) {
Variant index=psg->index;
const Variant* arg[2]={&index,&p_value};
- Variant::CallError ce;
// p_object->call(psg->setter,arg,2,ce);
if (psg->_setptr) {
psg->_setptr->call(p_object,arg,2,ce);
@@ -660,13 +665,16 @@ bool ObjectTypeDB::set_property(Object* p_object,const StringName& p_property, c
} else {
const Variant* arg[1]={&p_value};
- Variant::CallError ce;
if (psg->_setptr) {
psg->_setptr->call(p_object,arg,1,ce);
} else {
p_object->call(psg->setter,arg,1,ce);
}
}
+
+ if (r_valid)
+ *r_valid=ce.error==Variant::CallError::CALL_OK;
+
return true;
}
@@ -718,6 +726,29 @@ bool ObjectTypeDB::get_property(Object* p_object,const StringName& p_property, V
return false;
}
+Variant::Type ObjectTypeDB::get_property_type(const StringName& p_type, const StringName& p_property,bool *r_is_valid) {
+
+ TypeInfo *type=types.getptr(p_type);
+ TypeInfo *check=type;
+ while(check) {
+ const PropertySetGet *psg = check->property_setget.getptr(p_property);
+ if (psg) {
+
+ if (r_is_valid)
+ *r_is_valid=true;
+
+ return psg->type;
+ }
+
+ check=check->inherits_ptr;
+ }
+ if (r_is_valid)
+ *r_is_valid=false;
+
+ return Variant::NIL;
+
+}
+
void ObjectTypeDB::set_method_flags(StringName p_type,StringName p_method,int p_flags) {
diff --git a/core/object_type_db.h b/core/object_type_db.h
index bfa0f921e5..319e3ec02c 100644
--- a/core/object_type_db.h
+++ b/core/object_type_db.h
@@ -117,6 +117,7 @@ class ObjectTypeDB {
StringName getter;
MethodBind *_setptr;
MethodBind *_getptr;
+ Variant::Type type;
};
struct TypeInfo {
@@ -456,8 +457,9 @@ public:
static void add_property(StringName p_type,const PropertyInfo& p_pinfo, const StringName& p_setter, const StringName& p_getter, int p_index=-1);
static void get_property_list(StringName p_type,List<PropertyInfo> *p_list,bool p_no_inheritance=false);
- static bool set_property(Object* p_object,const StringName& p_property, const Variant& p_value);
+ static bool set_property(Object* p_object, const StringName& p_property, const Variant& p_value, bool *r_valid=NULL);
static bool get_property(Object* p_object,const StringName& p_property, Variant& r_value);
+ static Variant::Type get_property_type(const StringName& p_type, const StringName& p_property,bool *r_is_valid=NULL);
diff --git a/core/ring_buffer.h b/core/ring_buffer.h
index 3cf9cf9064..5cbd261ec8 100644
--- a/core/ring_buffer.h
+++ b/core/ring_buffer.h
@@ -155,6 +155,12 @@ public:
inline int size() {
return data.size();
};
+
+ inline void clear() {
+ read_pos = 0;
+ write_pos = 0;
+
+ }
void resize(int p_power) {
int old_size = size();
diff --git a/core/script_language.cpp b/core/script_language.cpp
index 35c50b1022..b7a0f579f4 100644
--- a/core/script_language.cpp
+++ b/core/script_language.cpp
@@ -267,6 +267,20 @@ void PlaceHolderScriptInstance::get_property_list(List<PropertyInfo> *p_properti
}
}
+Variant::Type PlaceHolderScriptInstance::get_property_type(const StringName& p_name,bool *r_is_valid) const {
+
+ if (values.has(p_name)) {
+ if (r_is_valid)
+ *r_is_valid=true;
+ return values[p_name].get_type();
+ }
+ if (r_is_valid)
+ *r_is_valid=false;
+
+ return Variant::NIL;
+}
+
+
void PlaceHolderScriptInstance::update(const List<PropertyInfo> &p_properties,const Map<StringName,Variant>& p_values) {
diff --git a/core/script_language.h b/core/script_language.h
index 5a0f673b94..9660f141c7 100644
--- a/core/script_language.h
+++ b/core/script_language.h
@@ -82,6 +82,7 @@ public:
virtual StringName get_instance_base_type() const=0; // this may not work in all scripts, will return empty if so
virtual ScriptInstance* instance_create(Object *p_this)=0;
virtual bool instance_has(const Object *p_this) const=0;
+
virtual bool has_source_code() const=0;
virtual String get_source_code() const=0;
@@ -109,6 +110,7 @@ public:
virtual bool set(const StringName& p_name, const Variant& p_value)=0;
virtual bool get(const StringName& p_name, Variant &r_ret) const=0;
virtual void get_property_list(List<PropertyInfo> *p_properties) const=0;
+ virtual Variant::Type get_property_type(const StringName& p_name,bool *r_is_valid=NULL) const=0;
virtual void get_method_list(List<MethodInfo> *p_list) const=0;
virtual bool has_method(const StringName& p_method) const=0;
@@ -208,6 +210,7 @@ public:
virtual bool set(const StringName& p_name, const Variant& p_value);
virtual bool get(const StringName& p_name, Variant &r_ret) const;
virtual void get_property_list(List<PropertyInfo> *p_properties) const;
+ virtual Variant::Type get_property_type(const StringName& p_name,bool *r_is_valid=NULL) const;
virtual void get_method_list(List<MethodInfo> *p_list) const {}
virtual bool has_method(const StringName& p_method) const { return false; }
diff --git a/core/variant.h b/core/variant.h
index 8fd9662c36..e75a2b1c92 100644
--- a/core/variant.h
+++ b/core/variant.h
@@ -390,7 +390,7 @@ public:
Variant call(const StringName& p_method,const Variant** p_args,int p_argcount,CallError &r_error);
Variant call(const StringName& p_method,const Variant& p_arg1=Variant(),const Variant& p_arg2=Variant(),const Variant& p_arg3=Variant(),const Variant& p_arg4=Variant(),const Variant& p_arg5=Variant());
- static Variant construct(const Variant::Type,const Variant** p_args,int p_argcount,CallError &r_error);
+ static Variant construct(const Variant::Type,const Variant** p_args,int p_argcount,CallError &r_error,bool p_strict=true);
void get_method_list(List<MethodInfo> *p_list) const;
bool has_method(const StringName& p_method) const;
diff --git a/core/variant_call.cpp b/core/variant_call.cpp
index 48c38f05f9..2d10cf4d44 100644
--- a/core/variant_call.cpp
+++ b/core/variant_call.cpp
@@ -858,6 +858,11 @@ static void _call_##m_type##_##m_method(Variant& r_ret,Variant& p_self,const Var
r_ret=Transform(p_args[0]->operator Matrix3(),p_args[1]->operator Vector3());
}
+ static void Image_init1(Variant& r_ret, const Variant** p_args) {
+
+ r_ret=Image(*p_args[0],*p_args[1],*p_args[2],Image::Format(p_args[3]->operator int()));
+ }
+
static void add_constructor(VariantConstructFunc p_func,const Variant::Type p_type,
const String& p_name1="", const Variant::Type p_type1=Variant::NIL,
const String& p_name2="", const Variant::Type p_type2=Variant::NIL,
@@ -959,7 +964,7 @@ Variant Variant::call(const StringName& p_method,const Variant** p_args,int p_ar
#define VCALL(m_type,m_method) _VariantCall::_call_##m_type##_##m_method
-Variant Variant::construct(const Variant::Type p_type,const Variant** p_args,int p_argcount,CallError &r_error) {
+Variant Variant::construct(const Variant::Type p_type, const Variant** p_args, int p_argcount, CallError &r_error, bool p_strict) {
r_error.error=Variant::CallError::CALL_ERROR_INVALID_METHOD;
ERR_FAIL_INDEX_V(p_type,VARIANT_MAX,Variant());
@@ -1035,7 +1040,7 @@ Variant Variant::construct(const Variant::Type p_type,const Variant** p_args,int
} else if (p_argcount==1 && p_args[0]->type==p_type) {
return *p_args[0]; //copy construct
- } else if (p_argcount==1 && Variant::can_convert(p_args[0]->type,p_type)) {
+ } else if (p_argcount==1 && (!p_strict || Variant::can_convert(p_args[0]->type,p_type))) {
//near match construct
switch(p_type) {
@@ -1583,6 +1588,8 @@ _VariantCall::addfunc(Variant::m_vtype,Variant::m_ret,_SCS(#m_method),VCALL(m_cl
_VariantCall::add_constructor(_VariantCall::Transform_init1,Variant::TRANSFORM,"x_axis",Variant::VECTOR3,"y_axis",Variant::VECTOR3,"z_axis",Variant::VECTOR3,"origin",Variant::VECTOR3);
_VariantCall::add_constructor(_VariantCall::Transform_init2,Variant::TRANSFORM,"basis",Variant::MATRIX3,"origin",Variant::VECTOR3);
+ _VariantCall::add_constructor(_VariantCall::Image_init1,Variant::IMAGE,"width",Variant::INT,"height",Variant::INT,"mipmaps",Variant::BOOL,"format",Variant::INT);
+
/* REGISTER CONSTANTS */
_VariantCall::constant_data[Variant::VECTOR3].value["AXIS_X"]=Vector3::AXIS_X;
diff --git a/doc/base/classes.xml b/doc/base/classes.xml
index fd5df945ba..ab1320908e 100644
--- a/doc/base/classes.xml
+++ b/doc/base/classes.xml
@@ -13147,6 +13147,21 @@ returns:= "username=user&amp;password=pass"
<description>
</description>
</method>
+ <method name="Image">
+ <return type="Image">
+ </return>
+ <argument index="0" name="width" type="int">
+ </argument>
+ <argument index="1" name="height" type="int">
+ </argument>
+ <argument index="2" name="mipmaps" type="bool">
+ </argument>
+ <argument index="3" name="format" type="int">
+ </argument>
+ <description>
+ Create an empty image of a specific size and format.
+ </description>
+ </method>
</methods>
<constants>
<constant name="COMPRESS_BC" value="0">
diff --git a/drivers/theora/video_stream_theora.cpp b/drivers/theora/video_stream_theora.cpp
index f301bd7515..fe248bc911 100644
--- a/drivers/theora/video_stream_theora.cpp
+++ b/drivers/theora/video_stream_theora.cpp
@@ -7,11 +7,34 @@
int VideoStreamPlaybackTheora:: buffer_data() {
- char *buffer=ogg_sync_buffer(&oy,4096);
- int bytes=file->get_buffer((uint8_t*)buffer, 4096);
- ogg_sync_wrote(&oy,bytes);
- return(bytes);
+ char *buffer=ogg_sync_buffer(&oy,4096);
+
+#ifdef THEORA_USE_THREAD_STREAMING
+
+ int read;
+
+ do {
+ thread_sem->post();
+ read = MIN(ring_buffer.data_left(),4096);
+ if (read) {
+ ring_buffer.read((uint8_t*)buffer,read);
+ ogg_sync_wrote(&oy,read);
+ } else {
+ OS::get_singleton()->delay_usec(100);
+ }
+
+ } while(read==0);
+
+ return read;
+
+#else
+
+ int bytes=file->get_buffer((uint8_t*)buffer, 4096);
+ ogg_sync_wrote(&oy,bytes);
+ return(bytes);
+
+#endif
}
int VideoStreamPlaybackTheora::queue_page(ogg_page *page){
@@ -200,6 +223,14 @@ void VideoStreamPlaybackTheora::clear() {
}
ogg_sync_clear(&oy);
+#ifdef THEORA_USE_THREAD_STREAMING
+ thread_exit=true;
+ thread_sem->post(); //just in case
+ Thread::wait_to_finish(thread);
+ memdelete(thread);
+ thread=NULL;
+ ring_buffer.clear();
+#endif
//file_name = "";
theora_p = 0;
@@ -217,6 +248,7 @@ void VideoStreamPlaybackTheora::clear() {
void VideoStreamPlaybackTheora::set_file(const String& p_file) {
+ ERR_FAIL_COND(playing);
ogg_packet op;
th_setup_info *ts = NULL;
@@ -227,7 +259,17 @@ void VideoStreamPlaybackTheora::set_file(const String& p_file) {
file = FileAccess::open(p_file, FileAccess::READ);
ERR_FAIL_COND(!file);
+#ifdef THEORA_USE_THREAD_STREAMING
+ thread_exit=false;
+ thread_eof=false;
+ //pre-fill buffer
+ int to_read = ring_buffer.space_left();
+ int read = file->get_buffer(read_buffer.ptr(),to_read);
+ ring_buffer.write(read_buffer.ptr(),read);
+ thread=Thread::create(_streaming_thread,this);
+
+#endif
ogg_sync_init(&oy);
@@ -369,6 +411,7 @@ void VideoStreamPlaybackTheora::set_file(const String& p_file) {
th_decode_ctl(td,TH_DECCTL_GET_PPLEVEL_MAX,&pp_level_max,
sizeof(pp_level_max));
pp_level=pp_level_max;
+ pp_level=0;
th_decode_ctl(td,TH_DECCTL_SET_PPLEVEL,&pp_level,sizeof(pp_level));
pp_inc=0;
@@ -415,6 +458,8 @@ void VideoStreamPlaybackTheora::set_file(const String& p_file) {
buffering=true;
time=0;
audio_frames_wrote=0;
+
+
};
float VideoStreamPlaybackTheora::get_time() const {
@@ -436,13 +481,16 @@ void VideoStreamPlaybackTheora::update(float p_delta) {
return;
};
+#ifdef THEORA_USE_THREAD_STREAMING
+ thread_sem->post();
+#endif
+
//double ctime =AudioServer::get_singleton()->get_mix_time();
//print_line("play "+rtos(p_delta));
time+=p_delta;
if (videobuf_time>get_time()) {
-
return; //no new frames need to be produced
}
@@ -573,21 +621,22 @@ void VideoStreamPlaybackTheora::update(float p_delta) {
if(videobuf_time>=get_time()) {
frame_done=true;
- print_line("frame!");
} else{
/*If we are too slow, reduce the pp level.*/
pp_inc=pp_level>0?-1:0;
- print_line("skip!");
}
}
} else {
- print_line("no packet..");
+
break;
}
}
-
+#ifdef THEORA_USE_THREAD_STREAMING
+ if (file && thread_eof && ring_buffer.data_left()==0) {
+#else
if (file && /*!videobuf_ready && */ file->eof_reached()) {
+#endif
printf("video done, stopping\n");
stop();
return;
@@ -633,6 +682,7 @@ void VideoStreamPlaybackTheora::update(float p_delta) {
else if(tdiff<ti.fps_denominator*0.05/ti.fps_numerator){
pp_inc=pp_level>0?-1:0;
}
+
}
video_write();
@@ -644,15 +694,21 @@ void VideoStreamPlaybackTheora::play() {
if (!playing)
time=0;
+ else {
+ stop();
+ }
+
playing = true;
delay_compensation=Globals::get_singleton()->get("audio/video_delay_compensation_ms");
delay_compensation/=1000.0;
+
};
void VideoStreamPlaybackTheora::stop() {
if (playing) {
+
clear();
set_file(file_name); //reset
}
@@ -730,7 +786,33 @@ int VideoStreamPlaybackTheora::get_mix_rate() const{
return vi.rate;
}
+#ifdef THEORA_USE_THREAD_STREAMING
+
+
+void VideoStreamPlaybackTheora::_streaming_thread(void *ud) {
+
+ VideoStreamPlaybackTheora *vs=(VideoStreamPlaybackTheora*)ud;
+
+ while(!vs->thread_exit) {
+
+ //just fill back the buffer
+ if (!vs->thread_eof) {
+
+ int to_read = vs->ring_buffer.space_left();
+ if (to_read) {
+ int read = vs->file->get_buffer(vs->read_buffer.ptr(),to_read);
+ vs->ring_buffer.write(vs->read_buffer.ptr(),read);
+ vs->thread_eof=vs->file->eof_reached();
+ }
+
+
+ }
+
+ vs->thread_sem->wait();
+ }
+}
+#endif
VideoStreamPlaybackTheora::VideoStreamPlaybackTheora() {
@@ -749,14 +831,31 @@ VideoStreamPlaybackTheora::VideoStreamPlaybackTheora() {
audio_track=0;
delay_compensation=0;
audio_frames_wrote=0;
+
+#ifdef THEORA_USE_THREAD_STREAMING
+ int rb_power = nearest_shift(RB_SIZE_KB*1024);
+ ring_buffer.resize(rb_power);
+ read_buffer.resize(RB_SIZE_KB*1024);
+ thread_sem=Semaphore::create();
+ thread=NULL;
+ thread_exit=false;
+ thread_eof=false;
+
+#endif
};
VideoStreamPlaybackTheora::~VideoStreamPlaybackTheora() {
+#ifdef THEORA_USE_THREAD_STREAMING
+
+ memdelete(thread_sem);
+#endif
clear();
if (file)
memdelete(file);
+
+
};
diff --git a/drivers/theora/video_stream_theora.h b/drivers/theora/video_stream_theora.h
index 5540f050f9..c15ef31cfc 100644
--- a/drivers/theora/video_stream_theora.h
+++ b/drivers/theora/video_stream_theora.h
@@ -6,9 +6,13 @@
#include "theora/theoradec.h"
#include "vorbis/codec.h"
#include "os/file_access.h"
-
+#include "ring_buffer.h"
#include "io/resource_loader.h"
#include "scene/resources/video_stream.h"
+#include "os/thread.h"
+#include "os/semaphore.h"
+
+//#define THEORA_USE_THREAD_STREAMING
class VideoStreamPlaybackTheora : public VideoStreamPlayback {
@@ -66,7 +70,25 @@ class VideoStreamPlaybackTheora : public VideoStreamPlayback {
AudioMixCallback mix_callback;
void* mix_udata;
- int audio_track;
+#ifdef THEORA_USE_THREAD_STREAMING
+
+ enum {
+ RB_SIZE_KB=1024
+ };
+
+ RingBuffer<uint8_t> ring_buffer;
+ Vector<uint8_t> read_buffer;
+ bool thread_eof;
+ Semaphore *thread_sem;
+ Thread *thread;
+ volatile bool thread_exit;
+
+ static void _streaming_thread(void *ud);
+
+#endif
+
+
+ int audio_track;
protected:
@@ -116,20 +138,20 @@ class VideoStreamTheora : public VideoStream {
OBJ_TYPE(VideoStreamTheora,VideoStream);
String file;
- int audio_track;
+ int audio_track;
public:
Ref<VideoStreamPlayback> instance_playback() {
Ref<VideoStreamPlaybackTheora> pb = memnew( VideoStreamPlaybackTheora );
- pb->set_audio_track(audio_track);
+ pb->set_audio_track(audio_track);
pb->set_file(file);
return pb;
}
void set_file(const String& p_file) { file=p_file; }
- void set_audio_track(int p_track) { audio_track=p_track; }
+ void set_audio_track(int p_track) { audio_track=p_track; }
VideoStreamTheora() { audio_track=0; }
diff --git a/drivers/webp/dec/alpha.c b/drivers/webp/dec/alpha.c
index 52216fc4d6..1d029b0e6a 100644
--- a/drivers/webp/dec/alpha.c
+++ b/drivers/webp/dec/alpha.c
@@ -18,7 +18,7 @@
#include "../dsp/dsp.h"
#include "../utils/quant_levels_dec.h"
#include "../utils/utils.h"
-#include "../webp/format_constants.h"
+#include "webp/format_constants.h"
//------------------------------------------------------------------------------
// ALPHDecoder object.
diff --git a/drivers/webp/dec/decode_vp8.h b/drivers/webp/dec/decode_vp8.h
index b9337bbec0..2bf1bdbbf5 100644
--- a/drivers/webp/dec/decode_vp8.h
+++ b/drivers/webp/dec/decode_vp8.h
@@ -14,7 +14,7 @@
#ifndef WEBP_WEBP_DECODE_VP8_H_
#define WEBP_WEBP_DECODE_VP8_H_
-#include "../webp/decode.h"
+#include "webp/decode.h"
#ifdef __cplusplus
extern "C" {
diff --git a/drivers/webp/dec/webp.c b/drivers/webp/dec/webp.c
index 952178fa89..93a113a48d 100644
--- a/drivers/webp/dec/webp.c
+++ b/drivers/webp/dec/webp.c
@@ -17,7 +17,7 @@
#include "./vp8li.h"
#include "./webpi.h"
#include "../utils/utils.h"
-#include "../webp/mux_types.h" // ALPHA_FLAG
+#include "webp/mux_types.h" // ALPHA_FLAG
//------------------------------------------------------------------------------
// RIFF layout is:
diff --git a/drivers/webp/demux/anim_decode.c b/drivers/webp/demux/anim_decode.c
index adf84cd193..c81cedfba0 100644
--- a/drivers/webp/demux/anim_decode.c
+++ b/drivers/webp/demux/anim_decode.c
@@ -11,15 +11,15 @@
//
#ifdef HAVE_CONFIG_H
-#include "../webp/config.h"
+#include "webp/config.h"
#endif
#include <assert.h>
#include <string.h>
#include "../utils/utils.h"
-#include "../webp/decode.h"
-#include "../webp/demux.h"
+#include "webp/decode.h"
+#include "webp/demux.h"
#define NUM_CHANNELS 4
diff --git a/drivers/webp/demux/demux.c b/drivers/webp/demux/demux.c
index e8e5418efe..3717e21165 100644
--- a/drivers/webp/demux/demux.c
+++ b/drivers/webp/demux/demux.c
@@ -11,7 +11,7 @@
//
#ifdef HAVE_CONFIG_H
-#include "../webp/config.h"
+#include "webp/config.h"
#endif
#include <assert.h>
@@ -19,9 +19,9 @@
#include <string.h>
#include "../utils/utils.h"
-#include "../webp/decode.h" // WebPGetFeatures
-#include "../webp/demux.h"
-#include "../webp/format_constants.h"
+#include "webp/decode.h" // WebPGetFeatures
+#include "webp/demux.h"
+#include "webp/format_constants.h"
#define DMUX_MAJ_VERSION 0
#define DMUX_MIN_VERSION 2
diff --git a/drivers/webp/dsp/dsp.h b/drivers/webp/dsp/dsp.h
index 8395df40e4..4613d9c3ff 100644
--- a/drivers/webp/dsp/dsp.h
+++ b/drivers/webp/dsp/dsp.h
@@ -15,10 +15,10 @@
#define WEBP_DSP_DSP_H_
#ifdef HAVE_CONFIG_H
-#include "../webp/config.h"
+#include "webp/config.h"
#endif
-#include "../webp/types.h"
+#include "webp/types.h"
#ifdef __cplusplus
extern "C" {
diff --git a/drivers/webp/dsp/lossless.h b/drivers/webp/dsp/lossless.h
index ee6771333f..149c6a01d3 100644
--- a/drivers/webp/dsp/lossless.h
+++ b/drivers/webp/dsp/lossless.h
@@ -15,8 +15,8 @@
#ifndef WEBP_DSP_LOSSLESS_H_
#define WEBP_DSP_LOSSLESS_H_
-#include "../webp/types.h"
-#include "../webp/decode.h"
+#include "webp/types.h"
+#include "webp/decode.h"
#include "../enc/histogram.h"
#include "../utils/utils.h"
diff --git a/drivers/webp/enc/alpha.c b/drivers/webp/enc/alpha.c
index fad6346e43..1842b36401 100644
--- a/drivers/webp/enc/alpha.c
+++ b/drivers/webp/enc/alpha.c
@@ -19,7 +19,7 @@
#include "../utils/filters.h"
#include "../utils/quant_levels.h"
#include "../utils/utils.h"
-#include "../webp/format_constants.h"
+#include "webp/format_constants.h"
// -----------------------------------------------------------------------------
// Encodes the given alpha data via specified compression method 'method'.
diff --git a/drivers/webp/enc/backward_references.h b/drivers/webp/enc/backward_references.h
index daa084d846..e410b06f7d 100644
--- a/drivers/webp/enc/backward_references.h
+++ b/drivers/webp/enc/backward_references.h
@@ -15,8 +15,8 @@
#include <assert.h>
#include <stdlib.h>
-#include "../webp/types.h"
-#include "../webp/format_constants.h"
+#include "webp/types.h"
+#include "webp/format_constants.h"
#ifdef __cplusplus
extern "C" {
diff --git a/drivers/webp/enc/config.c b/drivers/webp/enc/config.c
index f9f7961d58..8fd2276cb5 100644
--- a/drivers/webp/enc/config.c
+++ b/drivers/webp/enc/config.c
@@ -11,7 +11,7 @@
//
// Author: Skal (pascal.massimino@gmail.com)
-#include "../webp/encode.h"
+#include "webp/encode.h"
//------------------------------------------------------------------------------
// WebPConfig
diff --git a/drivers/webp/enc/delta_palettization.c b/drivers/webp/enc/delta_palettization.c
index 062e588d79..8bd3a3d233 100644
--- a/drivers/webp/enc/delta_palettization.c
+++ b/drivers/webp/enc/delta_palettization.c
@@ -13,7 +13,7 @@
#include "./delta_palettization.h"
#ifdef WEBP_EXPERIMENTAL_FEATURES
-#include "../webp/types.h"
+#include "webp/types.h"
#include "../dsp/lossless.h"
#define MK_COL(r, g, b) (((r) << 16) + ((g) << 8) + (b))
diff --git a/drivers/webp/enc/delta_palettization.h b/drivers/webp/enc/delta_palettization.h
index e41c0c5ab5..54195d452c 100644
--- a/drivers/webp/enc/delta_palettization.h
+++ b/drivers/webp/enc/delta_palettization.h
@@ -13,7 +13,7 @@
#ifndef WEBP_ENC_DELTA_PALETTIZATION_H_
#define WEBP_ENC_DELTA_PALETTIZATION_H_
-#include "../webp/encode.h"
+#include "webp/encode.h"
#include "../enc/vp8li.h"
// Replaces enc->argb_[] input by a palettizable approximation of it,
diff --git a/drivers/webp/enc/frame.c b/drivers/webp/enc/frame.c
index 5b7a40b9ad..65a98ada4d 100644
--- a/drivers/webp/enc/frame.c
+++ b/drivers/webp/enc/frame.c
@@ -17,7 +17,7 @@
#include "./cost.h"
#include "./vp8enci.h"
#include "../dsp/dsp.h"
-#include "../webp/format_constants.h" // RIFF constants
+#include "webp/format_constants.h" // RIFF constants
#define SEGMENT_VISU 0
#define DEBUG_SEARCH 0 // useful to track search convergence
diff --git a/drivers/webp/enc/histogram.c b/drivers/webp/enc/histogram.c
index 62c320d809..68c27fb1db 100644
--- a/drivers/webp/enc/histogram.c
+++ b/drivers/webp/enc/histogram.c
@@ -10,7 +10,7 @@
// Author: Jyrki Alakuijala (jyrki@google.com)
//
#ifdef HAVE_CONFIG_H
-#include "../webp/config.h"
+#include "webp/config.h"
#endif
#include <math.h>
diff --git a/drivers/webp/enc/histogram.h b/drivers/webp/enc/histogram.h
index adb16c01ca..72f045793a 100644
--- a/drivers/webp/enc/histogram.h
+++ b/drivers/webp/enc/histogram.h
@@ -17,8 +17,8 @@
#include <string.h>
#include "./backward_references.h"
-#include "../webp/format_constants.h"
-#include "../webp/types.h"
+#include "webp/format_constants.h"
+#include "webp/types.h"
#ifdef __cplusplus
extern "C" {
diff --git a/drivers/webp/enc/syntax.c b/drivers/webp/enc/syntax.c
index a0e79ef404..2b65f15ca1 100644
--- a/drivers/webp/enc/syntax.c
+++ b/drivers/webp/enc/syntax.c
@@ -14,8 +14,8 @@
#include <assert.h>
#include "../utils/utils.h"
-#include "../webp/format_constants.h" // RIFF constants
-#include "../webp/mux_types.h" // ALPHA_FLAG
+#include "webp/format_constants.h" // RIFF constants
+#include "webp/mux_types.h" // ALPHA_FLAG
#include "./vp8enci.h"
//------------------------------------------------------------------------------
diff --git a/drivers/webp/enc/vp8enci.h b/drivers/webp/enc/vp8enci.h
index 1a7ebe5703..0cb2ccc353 100644
--- a/drivers/webp/enc/vp8enci.h
+++ b/drivers/webp/enc/vp8enci.h
@@ -20,7 +20,7 @@
#include "../utils/bit_writer.h"
#include "../utils/thread.h"
#include "../utils/utils.h"
-#include "../webp/encode.h"
+#include "webp/encode.h"
#ifdef WEBP_EXPERIMENTAL_FEATURES
#include "./vp8li.h"
diff --git a/drivers/webp/enc/vp8l.c b/drivers/webp/enc/vp8l.c
index 047c9032ac..284995e830 100644
--- a/drivers/webp/enc/vp8l.c
+++ b/drivers/webp/enc/vp8l.c
@@ -22,7 +22,7 @@
#include "../utils/bit_writer.h"
#include "../utils/huffman_encode.h"
#include "../utils/utils.h"
-#include "../webp/format_constants.h"
+#include "webp/format_constants.h"
#include "./delta_palettization.h"
diff --git a/drivers/webp/enc/vp8li.h b/drivers/webp/enc/vp8li.h
index 6b6db127db..4543c3b260 100644
--- a/drivers/webp/enc/vp8li.h
+++ b/drivers/webp/enc/vp8li.h
@@ -17,8 +17,8 @@
#include "./backward_references.h"
#include "./histogram.h"
#include "../utils/bit_writer.h"
-#include "../webp/encode.h"
-#include "../webp/format_constants.h"
+#include "webp/encode.h"
+#include "webp/format_constants.h"
#ifdef __cplusplus
extern "C" {
diff --git a/drivers/webp/mux/anim_encode.c b/drivers/webp/mux/anim_encode.c
index fa86eaac94..bb7c0f50b9 100644
--- a/drivers/webp/mux/anim_encode.c
+++ b/drivers/webp/mux/anim_encode.c
@@ -15,10 +15,10 @@
#include <stdio.h>
#include "../utils/utils.h"
-#include "../webp/decode.h"
-#include "../webp/encode.h"
-#include "../webp/format_constants.h"
-#include "../webp/mux.h"
+#include "webp/decode.h"
+#include "webp/encode.h"
+#include "webp/format_constants.h"
+#include "webp/mux.h"
#if defined(_MSC_VER) && _MSC_VER < 1900
#define snprintf _snprintf
diff --git a/drivers/webp/mux/muxi.h b/drivers/webp/mux/muxi.h
index 718b2f5d58..8bd5291661 100644
--- a/drivers/webp/mux/muxi.h
+++ b/drivers/webp/mux/muxi.h
@@ -17,7 +17,7 @@
#include <stdlib.h>
#include "../dec/vp8i.h"
#include "../dec/vp8li.h"
-#include "../webp/mux.h"
+#include "webp/mux.h"
#ifdef __cplusplus
extern "C" {
diff --git a/drivers/webp/utils/bit_reader.c b/drivers/webp/utils/bit_reader.c
index cd265321bb..5081d5cd4d 100644
--- a/drivers/webp/utils/bit_reader.c
+++ b/drivers/webp/utils/bit_reader.c
@@ -12,7 +12,7 @@
// Author: Skal (pascal.massimino@gmail.com)
#ifdef HAVE_CONFIG_H
-#include "../webp/config.h"
+#include "webp/config.h"
#endif
#include "./bit_reader_inl.h"
diff --git a/drivers/webp/utils/bit_reader.h b/drivers/webp/utils/bit_reader.h
index 0fc62d33b7..7e09653ebc 100644
--- a/drivers/webp/utils/bit_reader.h
+++ b/drivers/webp/utils/bit_reader.h
@@ -19,7 +19,7 @@
#ifdef _MSC_VER
#include <stdlib.h> // _byteswap_ulong
#endif
-#include "../webp/types.h"
+#include "webp/types.h"
#ifdef __cplusplus
extern "C" {
diff --git a/drivers/webp/utils/bit_reader_inl.h b/drivers/webp/utils/bit_reader_inl.h
index 37215702d4..20ce5f3cc7 100644
--- a/drivers/webp/utils/bit_reader_inl.h
+++ b/drivers/webp/utils/bit_reader_inl.h
@@ -17,7 +17,7 @@
#define WEBP_UTILS_BIT_READER_INL_H_
#ifdef HAVE_CONFIG_H
-#include "../webp/config.h"
+#include "webp/config.h"
#endif
#ifdef WEBP_FORCE_ALIGNED
diff --git a/drivers/webp/utils/bit_writer.h b/drivers/webp/utils/bit_writer.h
index ef360d1dc6..867a5ee055 100644
--- a/drivers/webp/utils/bit_writer.h
+++ b/drivers/webp/utils/bit_writer.h
@@ -14,7 +14,7 @@
#ifndef WEBP_UTILS_BIT_WRITER_H_
#define WEBP_UTILS_BIT_WRITER_H_
-#include "../webp/types.h"
+#include "webp/types.h"
#ifdef __cplusplus
extern "C" {
diff --git a/drivers/webp/utils/color_cache.h b/drivers/webp/utils/color_cache.h
index a9a9f64270..34299e4c4e 100644
--- a/drivers/webp/utils/color_cache.h
+++ b/drivers/webp/utils/color_cache.h
@@ -15,7 +15,7 @@
#ifndef WEBP_UTILS_COLOR_CACHE_H_
#define WEBP_UTILS_COLOR_CACHE_H_
-#include "../webp/types.h"
+#include "webp/types.h"
#ifdef __cplusplus
extern "C" {
diff --git a/drivers/webp/utils/endian_inl.h b/drivers/webp/utils/endian_inl.h
index e11260ff7d..253b7be8ee 100644
--- a/drivers/webp/utils/endian_inl.h
+++ b/drivers/webp/utils/endian_inl.h
@@ -13,11 +13,11 @@
#define WEBP_UTILS_ENDIAN_INL_H_
#ifdef HAVE_CONFIG_H
-#include "../webp/config.h"
+#include "webp/config.h"
#endif
#include "../dsp/dsp.h"
-#include "../webp/types.h"
+#include "webp/types.h"
// some endian fix (e.g.: mips-gcc doesn't define __BIG_ENDIAN__)
#if !defined(WORDS_BIGENDIAN) && \
diff --git a/drivers/webp/utils/filters.h b/drivers/webp/utils/filters.h
index 088b132fc5..4aba3fd3b7 100644
--- a/drivers/webp/utils/filters.h
+++ b/drivers/webp/utils/filters.h
@@ -14,7 +14,7 @@
#ifndef WEBP_UTILS_FILTERS_H_
#define WEBP_UTILS_FILTERS_H_
-#include "../webp/types.h"
+#include "webp/types.h"
#include "../dsp/dsp.h"
#ifdef __cplusplus
diff --git a/drivers/webp/utils/huffman.c b/drivers/webp/utils/huffman.c
index d57376aa6b..e6f482a6a8 100644
--- a/drivers/webp/utils/huffman.c
+++ b/drivers/webp/utils/huffman.c
@@ -16,7 +16,7 @@
#include <string.h>
#include "./huffman.h"
#include "../utils/utils.h"
-#include "../webp/format_constants.h"
+#include "webp/format_constants.h"
// Huffman data read via DecodeImageStream is represented in two (red and green)
// bytes.
diff --git a/drivers/webp/utils/huffman.h b/drivers/webp/utils/huffman.h
index c6dd6aaa45..a8cc0da1c3 100644
--- a/drivers/webp/utils/huffman.h
+++ b/drivers/webp/utils/huffman.h
@@ -15,8 +15,8 @@
#define WEBP_UTILS_HUFFMAN_H_
#include <assert.h>
-#include "../webp/format_constants.h"
-#include "../webp/types.h"
+#include "webp/format_constants.h"
+#include "webp/types.h"
#ifdef __cplusplus
extern "C" {
diff --git a/drivers/webp/utils/huffman_encode.c b/drivers/webp/utils/huffman_encode.c
index 6421c2beed..d7aad6f56d 100644
--- a/drivers/webp/utils/huffman_encode.c
+++ b/drivers/webp/utils/huffman_encode.c
@@ -16,7 +16,7 @@
#include <string.h>
#include "./huffman_encode.h"
#include "../utils/utils.h"
-#include "../webp/format_constants.h"
+#include "webp/format_constants.h"
// -----------------------------------------------------------------------------
// Util function to optimize the symbol map for RLE coding
diff --git a/drivers/webp/utils/huffman_encode.h b/drivers/webp/utils/huffman_encode.h
index a157165148..93610066f3 100644
--- a/drivers/webp/utils/huffman_encode.h
+++ b/drivers/webp/utils/huffman_encode.h
@@ -14,7 +14,7 @@
#ifndef WEBP_UTILS_HUFFMAN_ENCODE_H_
#define WEBP_UTILS_HUFFMAN_ENCODE_H_
-#include "../webp/types.h"
+#include "webp/types.h"
#ifdef __cplusplus
extern "C" {
diff --git a/drivers/webp/utils/quant_levels.h b/drivers/webp/utils/quant_levels.h
index 1cb5a32cae..3916b977ab 100644
--- a/drivers/webp/utils/quant_levels.h
+++ b/drivers/webp/utils/quant_levels.h
@@ -16,7 +16,7 @@
#include <stdlib.h>
-#include "../webp/types.h"
+#include "webp/types.h"
#ifdef __cplusplus
extern "C" {
diff --git a/drivers/webp/utils/quant_levels_dec.h b/drivers/webp/utils/quant_levels_dec.h
index 9aab068076..29c7e6e205 100644
--- a/drivers/webp/utils/quant_levels_dec.h
+++ b/drivers/webp/utils/quant_levels_dec.h
@@ -14,7 +14,7 @@
#ifndef WEBP_UTILS_QUANT_LEVELS_DEC_H_
#define WEBP_UTILS_QUANT_LEVELS_DEC_H_
-#include "../webp/types.h"
+#include "webp/types.h"
#ifdef __cplusplus
extern "C" {
diff --git a/drivers/webp/utils/random.h b/drivers/webp/utils/random.h
index c392a615ca..745f3e2e87 100644
--- a/drivers/webp/utils/random.h
+++ b/drivers/webp/utils/random.h
@@ -15,7 +15,7 @@
#define WEBP_UTILS_RANDOM_H_
#include <assert.h>
-#include "../webp/types.h"
+#include "webp/types.h"
#ifdef __cplusplus
extern "C" {
diff --git a/drivers/webp/utils/rescaler.h b/drivers/webp/utils/rescaler.h
index 98b01a76d0..868467b4d7 100644
--- a/drivers/webp/utils/rescaler.h
+++ b/drivers/webp/utils/rescaler.h
@@ -18,7 +18,7 @@
extern "C" {
#endif
-#include "../webp/types.h"
+#include "webp/types.h"
#define WEBP_RESCALER_RFIX 32 // fixed-point precision for multiplies
#define WEBP_RESCALER_ONE (1ull << WEBP_RESCALER_RFIX)
diff --git a/drivers/webp/utils/thread.h b/drivers/webp/utils/thread.h
index 8408311855..6008bb7c01 100644
--- a/drivers/webp/utils/thread.h
+++ b/drivers/webp/utils/thread.h
@@ -15,10 +15,10 @@
#define WEBP_UTILS_THREAD_H_
#ifdef HAVE_CONFIG_H
-#include "../webp/config.h"
+#include "webp/config.h"
#endif
-#include "../webp/types.h"
+#include "webp/types.h"
#ifdef __cplusplus
extern "C" {
diff --git a/drivers/webp/utils/utils.c b/drivers/webp/utils/utils.c
index d8e30930af..35aeae6ab8 100644
--- a/drivers/webp/utils/utils.c
+++ b/drivers/webp/utils/utils.c
@@ -13,8 +13,8 @@
#include <stdlib.h>
#include <string.h> // for memcpy()
-#include "../webp/decode.h"
-#include "../webp/encode.h"
+#include "webp/decode.h"
+#include "webp/encode.h"
#include "./utils.h"
// If PRINT_MEM_INFO is defined, extra info (like total memory used, number of
diff --git a/drivers/webp/utils/utils.h b/drivers/webp/utils/utils.h
index fcdb7e139b..d0e1cb250a 100644
--- a/drivers/webp/utils/utils.h
+++ b/drivers/webp/utils/utils.h
@@ -17,7 +17,7 @@
#include <assert.h>
-#include "../webp/types.h"
+#include "webp/types.h"
#ifdef __cplusplus
extern "C" {
diff --git a/modules/gdscript/gd_script.cpp b/modules/gdscript/gd_script.cpp
index 8746f92c9e..c3cc779bce 100644
--- a/modules/gdscript/gd_script.cpp
+++ b/modules/gdscript/gd_script.cpp
@@ -2274,6 +2274,26 @@ bool GDInstance::get(const StringName& p_name, Variant &r_ret) const {
return false;
}
+
+Variant::Type GDInstance::get_property_type(const StringName& p_name,bool *r_is_valid) const {
+
+
+ const GDScript *sptr=script.ptr();
+ while(sptr) {
+
+ if (sptr->member_info.has(p_name)) {
+ if (r_is_valid)
+ *r_is_valid=true;
+ return sptr->member_info[p_name].type;
+ }
+ sptr = sptr->_base;
+ }
+
+ if (r_is_valid)
+ *r_is_valid=false;
+ return Variant::NIL;
+}
+
void GDInstance::get_property_list(List<PropertyInfo> *p_properties) const {
// exported members, not doen yet!
diff --git a/modules/gdscript/gd_script.h b/modules/gdscript/gd_script.h
index 850ffec05f..3d16b59065 100644
--- a/modules/gdscript/gd_script.h
+++ b/modules/gdscript/gd_script.h
@@ -373,6 +373,8 @@ public:
virtual bool set(const StringName& p_name, const Variant& p_value);
virtual bool get(const StringName& p_name, Variant &r_ret) const;
virtual void get_property_list(List<PropertyInfo> *p_properties) const;
+ virtual Variant::Type get_property_type(const StringName& p_name,bool *r_is_valid=NULL) const;
+
virtual void get_method_list(List<MethodInfo> *p_list) const;
virtual bool has_method(const StringName& p_method) const;
diff --git a/platform/windows/detect.py b/platform/windows/detect.py
index 4ec4b054db..3193a2acbb 100644
--- a/platform/windows/detect.py
+++ b/platform/windows/detect.py
@@ -170,7 +170,6 @@ def get_flags():
return [
('freetype','builtin'), #use builtin freetype
('openssl','builtin'), #use builtin openssl
- ('theora','no'),
]
def build_res_file( target, source, env ):
diff --git a/scene/animation/animation_player.cpp b/scene/animation/animation_player.cpp
index c2ea1c8bb6..b040e59d16 100644
--- a/scene/animation/animation_player.cpp
+++ b/scene/animation/animation_player.cpp
@@ -268,6 +268,7 @@ void AnimationPlayer::_generate_node_caches(AnimationData* p_anim) {
TrackNodeCacheKey key;
key.id=id;
key.bone_idx=bone_idx;
+
if (node_cache_map.has(key)) {
@@ -278,6 +279,7 @@ void AnimationPlayer::_generate_node_caches(AnimationData* p_anim) {
node_cache_map[key]=TrackNodeCache();
p_anim->node_cache[i]=&node_cache_map[key];
+ p_anim->node_cache[i]->path=a->track_get_path(i);
p_anim->node_cache[i]->node=child;
p_anim->node_cache[i]->resource=resource;
p_anim->node_cache[i]->node_2d=child->cast_to<Node2D>();
@@ -320,6 +322,7 @@ void AnimationPlayer::_generate_node_caches(AnimationData* p_anim) {
pa.prop=property;
pa.object=resource.is_valid()?(Object*)resource.ptr():(Object*)child;
pa.special=SP_NONE;
+ pa.owner=p_anim->node_cache[i];
if (false && p_anim->node_cache[i]->node_2d) {
if (pa.prop==SceneStringNames::get_singleton()->transform_pos)
@@ -410,7 +413,7 @@ void AnimationPlayer::_animation_process_animation(AnimationData* p_anim,float p
TrackNodeCache::PropertyAnim *pa = &E->get();
- if (a->value_track_is_continuous(i) || p_delta==0) {
+ if (a->value_track_is_continuous(i) || p_delta==0) { //delta == 0 means seek
Variant value=a->value_track_interpolate(i,p_time);
@@ -436,10 +439,42 @@ void AnimationPlayer::_animation_process_animation(AnimationData* p_anim,float p
Variant value=a->track_get_key_value(i,F->get());
switch(pa->special) {
- case SP_NONE: pa->object->set(pa->prop,value); break; //you are not speshul
- case SP_NODE2D_POS: static_cast<Node2D*>(pa->object)->set_pos(value); break;
- case SP_NODE2D_ROT: static_cast<Node2D*>(pa->object)->set_rot(Math::deg2rad(value)); break;
- case SP_NODE2D_SCALE: static_cast<Node2D*>(pa->object)->set_scale(value); break;
+ case SP_NONE: {
+ bool valid;
+ pa->object->set(pa->prop,value,&valid); //you are not speshul
+#ifdef DEBUG_ENABLED
+ if (!valid) {
+ ERR_PRINTS("Failed setting track value '"+String(pa->owner->path)+"'. Check if property exists or the type of key is valid");
+ }
+#endif
+
+ } break;
+ case SP_NODE2D_POS: {
+#ifdef DEBUG_ENABLED
+ if (value.get_type()!=Variant::VECTOR2) {
+ ERR_PRINTS("Position key at time "+rtos(p_time)+" in Animation Track '"+String(pa->owner->path)+"' not of type Vector2()");
+ }
+#endif
+ static_cast<Node2D*>(pa->object)->set_pos(value);
+ } break;
+ case SP_NODE2D_ROT: {
+#ifdef DEBUG_ENABLED
+ if (value.is_num()) {
+ ERR_PRINTS("Rotation key at time "+rtos(p_time)+" in Animation Track '"+String(pa->owner->path)+"' not numerical");
+ }
+#endif
+
+ static_cast<Node2D*>(pa->object)->set_rot(Math::deg2rad(value));
+ } break;
+ case SP_NODE2D_SCALE: {
+#ifdef DEBUG_ENABLED
+ if (value.get_type()!=Variant::VECTOR2) {
+ ERR_PRINTS("Scale key at time "+rtos(p_time)+" in Animation Track '"+String(pa->owner->path)+"' not of type Vector2()");
+ }
+#endif
+
+ static_cast<Node2D*>(pa->object)->set_scale(value);
+ } break;
}
}
@@ -607,13 +642,53 @@ void AnimationPlayer::_animation_update_transforms() {
ERR_CONTINUE( pa->accum_pass!=accum_pass );
#if 1
- switch(pa->special) {
+/* switch(pa->special) {
case SP_NONE: pa->object->set(pa->prop,pa->value_accum); break; //you are not speshul
case SP_NODE2D_POS: static_cast<Node2D*>(pa->object)->set_pos(pa->value_accum); break;
case SP_NODE2D_ROT: static_cast<Node2D*>(pa->object)->set_rot(Math::deg2rad(pa->value_accum)); break;
case SP_NODE2D_SCALE: static_cast<Node2D*>(pa->object)->set_scale(pa->value_accum); break;
+ }*/
+
+ switch(pa->special) {
+
+ case SP_NONE: {
+ bool valid;
+ pa->object->set(pa->prop,pa->value_accum,&valid); //you are not speshul
+#ifdef DEBUG_ENABLED
+ if (!valid) {
+ ERR_PRINTS("Failed setting key at time "+rtos(playback.current.pos)+" in Animation '"+get_current_animation()+"', Track '"+String(pa->owner->path)+"'. Check if property exists or the type of key is right for the property");
+ }
+#endif
+
+ } break;
+ case SP_NODE2D_POS: {
+#ifdef DEBUG_ENABLED
+ if (pa->value_accum.get_type()!=Variant::VECTOR2) {
+ ERR_PRINTS("Position key at time "+rtos(playback.current.pos)+" in Animation '"+get_current_animation()+"', Track '"+String(pa->owner->path)+"' not of type Vector2()");
+ }
+#endif
+ static_cast<Node2D*>(pa->object)->set_pos(pa->value_accum);
+ } break;
+ case SP_NODE2D_ROT: {
+#ifdef DEBUG_ENABLED
+ if (pa->value_accum.is_num()) {
+ ERR_PRINTS("Rotation key at time "+rtos(playback.current.pos)+" in Animation '"+get_current_animation()+"', Track '"+String(pa->owner->path)+"' not numerical");
+ }
+#endif
+
+ static_cast<Node2D*>(pa->object)->set_rot(Math::deg2rad(pa->value_accum));
+ } break;
+ case SP_NODE2D_SCALE: {
+#ifdef DEBUG_ENABLED
+ if (pa->value_accum.get_type()!=Variant::VECTOR2) {
+ ERR_PRINTS("Scale key at time "+rtos(playback.current.pos)+" in Animation '"+get_current_animation()+"', Track '"+String(pa->owner->path)+"' not of type Vector2()");
+ }
+#endif
+
+ static_cast<Node2D*>(pa->object)->set_scale(pa->value_accum);
+ } break;
}
#else
diff --git a/scene/animation/animation_player.h b/scene/animation/animation_player.h
index 1e3c37c4d6..18cedee796 100644
--- a/scene/animation/animation_player.h
+++ b/scene/animation/animation_player.h
@@ -68,6 +68,7 @@ private:
struct TrackNodeCache {
+ NodePath path;
uint32_t id;
RES resource;
Node *node;
@@ -84,6 +85,7 @@ private:
struct PropertyAnim {
+ TrackNodeCache *owner;
SpecialProperty special; //small optimization
StringName prop;
Object *object;
diff --git a/tools/editor/animation_editor.cpp b/tools/editor/animation_editor.cpp
index ace6fda696..4ccb612a39 100644
--- a/tools/editor/animation_editor.cpp
+++ b/tools/editor/animation_editor.cpp
@@ -34,6 +34,7 @@
#include "pair.h"
#include "scene/gui/separator.h"
#include "editor_node.h"
+#include "tools/editor/plugins/animation_player_editor_plugin.h"
/* Missing to fix:
*Set
@@ -903,6 +904,23 @@ void AnimationKeyEditor::_menu_track(int p_type) {
optimize_dialog->popup_centered(Size2(250,180));
} break;
+ case TRACK_MENU_CLEAN_UP: {
+
+ cleanup_dialog->popup_centered_minsize(Size2(300,0));
+ } break;
+ case TRACK_MENU_CLEAN_UP_CONFIRM: {
+
+ if (cleanup_all->is_pressed()) {
+ List<StringName> names;
+ AnimationPlayerEditor::singleton->get_player()->get_animation_list(&names);
+ for (List<StringName>::Element *E=names.front();E;E=E->next()) {
+ _cleanup_animation(AnimationPlayerEditor::singleton->get_player()->get_animation(E->get()));
+ }
+ } else {
+ _cleanup_animation(animation);
+
+ }
+ } break;
case CURVE_SET_LINEAR: {
curve_edit->force_transition(1.0);
@@ -933,6 +951,57 @@ void AnimationKeyEditor::_menu_track(int p_type) {
}
+void AnimationKeyEditor::_cleanup_animation(Ref<Animation> p_animation) {
+
+
+ for(int i=0;i<p_animation->get_track_count();i++) {
+
+ bool prop_exists=false;
+ Variant::Type valid_type=Variant::NIL;
+ Object *obj=NULL;
+
+ RES res;
+ Node *node = root->get_node_and_resource(animation->track_get_path(i),res);
+
+ if (res.is_valid()) {
+ obj=res.ptr();
+ } else if (node) {
+ obj=node;
+ }
+
+ if (obj && animation->track_get_type(i)==Animation::TYPE_VALUE) {
+ valid_type=obj->get_static_property_type(animation->track_get_path(i).get_property(),&prop_exists);
+ }
+
+ if (!obj && cleanup_tracks->is_pressed()) {
+
+ animation->remove_track(i);
+ i--;
+ continue;
+ }
+
+ if (!prop_exists || animation->track_get_type(i)!=Animation::TYPE_VALUE || cleanup_keys->is_pressed()==false)
+ continue;
+
+ for(int j=0;j<animation->track_get_key_count(i);j++) {
+
+ Variant v = animation->track_get_key_value(i,j);
+
+ if (!Variant::can_convert(v.get_type(),valid_type)) {
+ animation->track_remove_key(i,j);
+ j--;
+ }
+ }
+
+ if (animation->track_get_key_count(i)==0 && cleanup_tracks->is_pressed()) {
+ animation->remove_track(i);
+ i--;
+ }
+ }
+
+ undo_redo->clear_history();
+ _update_paths();
+}
void AnimationKeyEditor::_animation_optimize() {
@@ -1042,6 +1111,7 @@ void AnimationKeyEditor::_track_editor_draw() {
timecolor = Color::html("ff4a414f");
Color hover_color = Color(1,1,1,0.05);
Color select_color = Color(1,1,1,0.1);
+ Color invalid_path_color = Color(1,0.6,0.4,0.5);
Color track_select_color =Color::html("ffbd8e8e");
Ref<Texture> remove_icon = get_icon("Remove","EditorIcons");
@@ -1068,6 +1138,9 @@ void AnimationKeyEditor::_track_editor_draw() {
get_icon("KeyCall","EditorIcons")
};
+ Ref<Texture> invalid_icon = get_icon("KeyInvalid","EditorIcons");
+ Ref<Texture> invalid_icon_hover = get_icon("KeyInvalidHover","EditorIcons");
+
Ref<Texture> hsize_icon = get_icon("Hsize","EditorIcons");
Ref<Texture> type_hover=get_icon("KeyHover","EditorIcons");
@@ -1254,6 +1327,23 @@ void AnimationKeyEditor::_track_editor_draw() {
break;
int y = h+i*h+sep;
+ bool prop_exists=false;
+ Variant::Type valid_type=Variant::NIL;
+ Object *obj=NULL;
+
+ RES res;
+ Node *node = root->get_node_and_resource(animation->track_get_path(idx),res);
+
+ if (res.is_valid()) {
+ obj=res.ptr();
+ } else if (node) {
+ obj=node;
+ }
+
+ if (obj && animation->track_get_type(idx)==Animation::TYPE_VALUE) {
+ valid_type=obj->get_static_property_type(animation->track_get_path(idx).get_property(),&prop_exists);
+ }
+
if (/*mouse_over.over!=MouseOver::OVER_NONE &&*/ idx==mouse_over.track) {
Color sepc=hover_color;
@@ -1274,6 +1364,8 @@ void AnimationKeyEditor::_track_editor_draw() {
ncol=track_select_color;
te->draw_string(font,Point2(ofs+Point2(type_icon[0]->get_width()+sep,y+font->get_ascent()+(sep/2))).floor(),np,ncol,name_limit-(type_icon[0]->get_width()+sep)-5);
+ if (!obj)
+ te->draw_line(ofs+Point2(0,y+h/2),ofs+Point2(name_limit,y+h/2),invalid_path_color);
te->draw_line(ofs+Point2(0,y+h),ofs+Point2(size.width,y+h),sepcolor);
@@ -1339,6 +1431,8 @@ void AnimationKeyEditor::_track_editor_draw() {
int kc=animation->track_get_key_count(idx);
bool first=true;
+
+
for(int i=0;i<kc;i++) {
@@ -1386,7 +1480,21 @@ void AnimationKeyEditor::_track_editor_draw() {
}
- te->draw_texture(tex,ofs+Point2(x,y+key_vofs).floor());
+ if (prop_exists && !Variant::can_convert(value.get_type(),valid_type)) {
+ te->draw_texture(invalid_icon,ofs+Point2(x,y+key_vofs).floor());
+ }
+
+ if (prop_exists && !Variant::can_convert(value.get_type(),valid_type)) {
+ if (tex==type_hover)
+ te->draw_texture(invalid_icon_hover,ofs+Point2(x,y+key_vofs).floor());
+ else
+ te->draw_texture(invalid_icon,ofs+Point2(x,y+key_vofs).floor());
+ } else {
+
+ te->draw_texture(tex,ofs+Point2(x,y+key_vofs).floor());
+ }
+
+
first=false;
}
@@ -2555,6 +2663,8 @@ void AnimationKeyEditor::_track_editor_input_event(const InputEvent& p_input) {
String text;
text="time: "+rtos(animation->track_get_key_time(idx,mouse_over.over_key))+"\n";
+
+
switch(animation->track_get_type(idx)) {
case Animation::TYPE_TRANSFORM: {
@@ -2569,8 +2679,33 @@ void AnimationKeyEditor::_track_editor_input_event(const InputEvent& p_input) {
} break;
case Animation::TYPE_VALUE: {
- Variant v = animation->track_get_key_value(idx,mouse_over.over_key);
- text+="value: "+String(v)+"\n";
+ Variant v = animation->track_get_key_value(idx,mouse_over.over_key);;
+ //text+="value: "+String(v)+"\n";
+
+ bool prop_exists=false;
+ Variant::Type valid_type=Variant::NIL;
+ Object *obj=NULL;
+
+ RES res;
+ Node *node = root->get_node_and_resource(animation->track_get_path(idx),res);
+
+ if (res.is_valid()) {
+ obj=res.ptr();
+ } else if (node) {
+ obj=node;
+ }
+
+ if (obj) {
+ valid_type=obj->get_static_property_type(animation->track_get_path(idx).get_property(),&prop_exists);
+ }
+
+ text+="type: "+Variant::get_type_name(v.get_type())+"\n";
+ if (prop_exists && !Variant::can_convert(v.get_type(),valid_type)) {
+ text+="value: "+String(v)+" (Invalid, expected type: "+Variant::get_type_name(valid_type)+")\n";
+ } else {
+ text+="value: "+String(v)+"\n";
+ }
+
} break;
case Animation::TYPE_METHOD: {
@@ -2593,6 +2728,9 @@ void AnimationKeyEditor::_track_editor_input_event(const InputEvent& p_input) {
} break;
}
text+="easing: "+rtos(animation->track_get_key_transition(idx,mouse_over.over_key));
+
+
+
track_editor->set_tooltip(text);
return;
@@ -2703,6 +2841,7 @@ void AnimationKeyEditor::_notification(int p_what) {
//menu_track->get_popup()->add_submenu_item("Set Transitions..","Transitions");
//menu_track->get_popup()->add_separator();
menu_track->get_popup()->add_item("Optimize Animation",TRACK_MENU_OPTIMIZE);
+ menu_track->get_popup()->add_item("Clean-Up Animation",TRACK_MENU_CLEAN_UP);
curve_linear->set_icon(get_icon("CurveLinear","EditorIcons"));
curve_in->set_icon(get_icon("CurveIn","EditorIcons"));
@@ -3862,6 +4001,32 @@ AnimationKeyEditor::AnimationKeyEditor(UndoRedo *p_undo_redo, EditorHistory *p_h
add_child(call_select);
call_select->set_title("Call Functions in Which Node?");
+ cleanup_dialog = memnew( ConfirmationDialog );
+ add_child(cleanup_dialog);
+ VBoxContainer *cleanup_vb = memnew( VBoxContainer );
+ cleanup_dialog->add_child(cleanup_vb);
+ cleanup_dialog->set_child_rect(cleanup_vb);
+ cleanup_keys = memnew( CheckButton );
+ cleanup_keys->set_text("Remove invalid keys");
+ cleanup_keys->set_pressed(true);
+ cleanup_vb->add_child(cleanup_keys);
+
+ cleanup_tracks = memnew( CheckButton );
+ cleanup_tracks->set_text("Remove unresolved and empty tracks");
+ cleanup_tracks->set_pressed(true);
+ cleanup_vb->add_child(cleanup_tracks);
+
+ cleanup_all = memnew( CheckButton );
+ cleanup_all->set_text("Clean-Up all animations");
+ cleanup_vb->add_child(cleanup_all);
+
+ cleanup_dialog->set_title("Clean up Animation(s) (NO UNDO!)");
+ cleanup_dialog->get_ok()->set_text("Clean-Up");
+
+ cleanup_dialog->connect("confirmed",this,"_menu_track",varray(TRACK_MENU_CLEAN_UP_CONFIRM));
+
+
+
}
AnimationKeyEditor::~AnimationKeyEditor() {
diff --git a/tools/editor/animation_editor.h b/tools/editor/animation_editor.h
index 629377d78e..743242fe94 100644
--- a/tools/editor/animation_editor.h
+++ b/tools/editor/animation_editor.h
@@ -89,6 +89,8 @@ class AnimationKeyEditor : public VBoxContainer {
TRACK_MENU_NEXT_STEP,
TRACK_MENU_PREV_STEP,
TRACK_MENU_OPTIMIZE,
+ TRACK_MENU_CLEAN_UP,
+ TRACK_MENU_CLEAN_UP_CONFIRM,
CURVE_SET_LINEAR,
CURVE_SET_IN,
CURVE_SET_OUT,
@@ -190,6 +192,11 @@ class AnimationKeyEditor : public VBoxContainer {
SpinBox *optimize_angular_error;
SpinBox *optimize_max_angle;
+ ConfirmationDialog *cleanup_dialog;
+ CheckButton *cleanup_keys;
+ CheckButton *cleanup_tracks;
+ CheckButton *cleanup_all;
+
SpinBox *step;
MenuButton *menu_add_track;
@@ -284,6 +291,7 @@ class AnimationKeyEditor : public VBoxContainer {
void _animation_changed();
void _animation_optimize();
+ void _cleanup_animation(Ref<Animation> p_animation);
void _scroll_changed(double);
diff --git a/tools/editor/icons/icon_key_invalid.png b/tools/editor/icons/icon_key_invalid.png
new file mode 100644
index 0000000000..e8e6c87180
--- /dev/null
+++ b/tools/editor/icons/icon_key_invalid.png
Binary files differ
diff --git a/tools/editor/icons/icon_key_invalid_hover.png b/tools/editor/icons/icon_key_invalid_hover.png
new file mode 100644
index 0000000000..6f0396d96a
--- /dev/null
+++ b/tools/editor/icons/icon_key_invalid_hover.png
Binary files differ
diff --git a/tools/editor/plugins/animation_player_editor_plugin.cpp b/tools/editor/plugins/animation_player_editor_plugin.cpp
index 6542fc8b4a..dc2c241d2f 100644
--- a/tools/editor/plugins/animation_player_editor_plugin.cpp
+++ b/tools/editor/plugins/animation_player_editor_plugin.cpp
@@ -1250,8 +1250,15 @@ void AnimationPlayerEditor::_bind_methods() {
}
+AnimationPlayerEditor *AnimationPlayerEditor::singleton=NULL;
+
+AnimationPlayer *AnimationPlayerEditor::get_player() const {
+
+ return player;
+}
AnimationPlayerEditor::AnimationPlayerEditor(EditorNode *p_editor) {
editor=p_editor;
+ singleton=this;
updating=false;
diff --git a/tools/editor/plugins/animation_player_editor_plugin.h b/tools/editor/plugins/animation_player_editor_plugin.h
index ac4d1ab6ba..839df3ddcc 100644
--- a/tools/editor/plugins/animation_player_editor_plugin.h
+++ b/tools/editor/plugins/animation_player_editor_plugin.h
@@ -162,6 +162,7 @@ class AnimationPlayerEditor : public VBoxContainer {
void _animation_tool_menu(int p_option);
void _animation_save_menu(int p_option);
+
AnimationPlayerEditor();
protected:
@@ -171,6 +172,9 @@ protected:
static void _bind_methods();
public:
+ AnimationPlayer *get_player() const;
+ static AnimationPlayerEditor *singleton;
+
Dictionary get_state() const;
void set_state(const Dictionary& p_state);
diff --git a/tools/editor/plugins/script_editor_plugin.cpp b/tools/editor/plugins/script_editor_plugin.cpp
index 956e7a98a2..4e394f9e3f 100644
--- a/tools/editor/plugins/script_editor_plugin.cpp
+++ b/tools/editor/plugins/script_editor_plugin.cpp
@@ -1137,12 +1137,14 @@ void ScriptEditor::_menu_option(int p_option) {
return;
int line = tx->cursor_get_line();
int next_line = line + 1;
+ int column = tx->cursor_get_column();
- if (line == tx->get_line_count() - 1 || next_line >= tx->get_line_count())
+ if (line >= tx->get_line_count() - 1)
tx->set_line(line, tx->get_line(line) + "\n");
String line_clone = tx->get_line(line);
tx->insert_at(line_clone, next_line);
+ tx->cursor_set_column(column);
tx->update();
} break;