mirror of
https://github.com/godotengine/godot.git
synced 2025-01-23 18:31:25 +00:00
Merge remote-tracking branch 'upstream/master'
This commit is contained in:
commit
cdf1ac7d58
11
SConstruct
11
SConstruct
@ -54,13 +54,16 @@ methods.save_active_platforms(active_platforms,active_platform_ids)
|
||||
|
||||
custom_tools=['default']
|
||||
|
||||
platform_arg = ARGUMENTS.get("platform", False)
|
||||
|
||||
if (os.name=="posix"):
|
||||
pass
|
||||
elif (os.name=="nt"):
|
||||
if (os.getenv("VSINSTALLDIR")==None):
|
||||
custom_tools=['mingw']
|
||||
if (os.getenv("VSINSTALLDIR")==None or platform_arg=="android"):
|
||||
custom_tools=['mingw']
|
||||
|
||||
env_base=Environment(tools=custom_tools,ENV = {'PATH' : os.environ['PATH']});
|
||||
|
||||
#env_base=Environment(tools=custom_tools);
|
||||
env_base.global_defaults=global_defaults
|
||||
env_base.android_source_modules=[]
|
||||
@ -363,8 +366,8 @@ if selected_platform in platform_list:
|
||||
|
||||
#env['MSVS_VERSION']='9.0'
|
||||
env['MSVSBUILDCOM'] = "scons platform=" + selected_platform + " target=" + env["target"] + " bits=" + env["bits"] + " tools=yes"
|
||||
env['MSVSREBUILDCOM'] = "scons platform=" + selected_platform + " target=" + env["target"] + " bits=" + env["bits"] + " tools=yes"
|
||||
env['MSVSCLEANCOM'] = "scons platform=" + selected_platform + " target=" + env["target"] + " bits=" + env["bits"] + " tools=yes"
|
||||
env['MSVSREBUILDCOM'] = "scons platform=" + selected_platform + " target=" + env["target"] + " bits=" + env["bits"] + " tools=yes vsproj=true"
|
||||
env['MSVSCLEANCOM'] = "scons --clean platform=" + selected_platform + " target=" + env["target"] + " bits=" + env["bits"] + " tools=yes"
|
||||
|
||||
debug_variants = ['Debug|Win32']+['Debug|x64']
|
||||
release_variants = ['Release|Win32']+['Release|x64']
|
||||
|
@ -31,7 +31,7 @@
|
||||
//#include "math_funcs.h"
|
||||
#include <stdio.h>
|
||||
#include "os/os.h"
|
||||
#include "drivers/trex/regex.h"
|
||||
#include "drivers/nrex/regex.h"
|
||||
|
||||
#include "test_string.h"
|
||||
|
||||
@ -463,20 +463,16 @@ bool test_26() {
|
||||
|
||||
OS::get_singleton()->print("\n\nTest 26: RegEx\n");
|
||||
RegEx regexp("(.*):(.*)");
|
||||
List<String> captures;
|
||||
|
||||
bool match = regexp.match("name:password", &captures);
|
||||
printf("\tmatch: %s\n", match?"true":"false");
|
||||
int res = regexp.find("name:password");
|
||||
printf("\tmatch: %s\n", (res>=0)?"true":"false");
|
||||
|
||||
printf("\t%i captures:\n", captures.size());
|
||||
List<String>::Element *I = captures.front();
|
||||
while (I) {
|
||||
|
||||
printf("%ls\n", I->get().c_str());
|
||||
|
||||
I = I->next();
|
||||
};
|
||||
return captures.size();
|
||||
printf("\t%i captures:\n", regexp.get_capture_count());
|
||||
for (int i = 0; i<regexp.get_capture_count(); i++)
|
||||
{
|
||||
printf("%ls\n", regexp.get_capture(i).c_str());
|
||||
}
|
||||
return res;
|
||||
};
|
||||
|
||||
struct test_27_data {
|
||||
|
@ -494,6 +494,10 @@ uint64_t _OS::get_unix_time() const {
|
||||
return OS::get_singleton()->get_unix_time();
|
||||
};
|
||||
|
||||
uint64_t _OS::get_system_time_msec() const {
|
||||
return OS::get_singleton()->get_system_time_msec();
|
||||
}
|
||||
|
||||
void _OS::delay_usec(uint32_t p_usec) const {
|
||||
|
||||
OS::get_singleton()->delay_usec(p_usec);
|
||||
@ -694,6 +698,17 @@ bool _OS::is_debug_build() const {
|
||||
|
||||
}
|
||||
|
||||
void _OS::set_screen_orientation(ScreenOrientation p_orientation) {
|
||||
|
||||
OS::get_singleton()->set_screen_orientation(OS::ScreenOrientation(p_orientation));
|
||||
}
|
||||
|
||||
_OS::ScreenOrientation _OS::get_screen_orientation() const {
|
||||
|
||||
return ScreenOrientation(OS::get_singleton()->get_screen_orientation());
|
||||
}
|
||||
|
||||
|
||||
String _OS::get_system_dir(SystemDir p_dir) const {
|
||||
|
||||
return OS::get_singleton()->get_system_dir(OS::SystemDir(p_dir));
|
||||
@ -752,6 +767,9 @@ void _OS::_bind_methods() {
|
||||
ObjectTypeDB::bind_method(_MD("set_window_maximized", "enabled"),&_OS::set_window_maximized);
|
||||
ObjectTypeDB::bind_method(_MD("is_window_maximized"),&_OS::is_window_maximized);
|
||||
|
||||
ObjectTypeDB::bind_method(_MD("set_screen_orientation","orientation"),&_OS::set_screen_orientation);
|
||||
ObjectTypeDB::bind_method(_MD("get_screen_orientation"),&_OS::get_screen_orientation);
|
||||
|
||||
|
||||
ObjectTypeDB::bind_method(_MD("set_iterations_per_second","iterations_per_second"),&_OS::set_iterations_per_second);
|
||||
ObjectTypeDB::bind_method(_MD("get_iterations_per_second"),&_OS::get_iterations_per_second);
|
||||
@ -787,6 +805,7 @@ void _OS::_bind_methods() {
|
||||
ObjectTypeDB::bind_method(_MD("get_time","utc"),&_OS::get_time,DEFVAL(false));
|
||||
ObjectTypeDB::bind_method(_MD("get_time_zone_info"),&_OS::get_time_zone_info);
|
||||
ObjectTypeDB::bind_method(_MD("get_unix_time"),&_OS::get_unix_time);
|
||||
ObjectTypeDB::bind_method(_MD("get_system_time_msec"), &_OS::get_system_time_msec);
|
||||
|
||||
ObjectTypeDB::bind_method(_MD("set_icon"),&_OS::set_icon);
|
||||
|
||||
@ -863,6 +882,14 @@ void _OS::_bind_methods() {
|
||||
BIND_CONSTANT( MONTH_NOVEMBER );
|
||||
BIND_CONSTANT( MONTH_DECEMBER );
|
||||
|
||||
BIND_CONSTANT( SCREEN_ORIENTATION_LANDSCAPE );
|
||||
BIND_CONSTANT( SCREEN_ORIENTATION_PORTRAIT );
|
||||
BIND_CONSTANT( SCREEN_ORIENTATION_REVERSE_LANDSCAPE );
|
||||
BIND_CONSTANT( SCREEN_ORIENTATION_REVERSE_PORTRAIT );
|
||||
BIND_CONSTANT( SCREEN_ORIENTATION_SENSOR_LANDSCAPE );
|
||||
BIND_CONSTANT( SCREEN_ORIENTATION_SENSOR_PORTRAIT );
|
||||
BIND_CONSTANT( SCREEN_ORIENTATION_SENSOR );
|
||||
|
||||
BIND_CONSTANT( SYSTEM_DIR_DESKTOP);
|
||||
BIND_CONSTANT( SYSTEM_DIR_DCIM );
|
||||
BIND_CONSTANT( SYSTEM_DIR_DOCUMENTS );
|
||||
@ -1678,12 +1705,89 @@ Variant _Marshalls::base64_to_variant(const String& p_str) {
|
||||
return v;
|
||||
};
|
||||
|
||||
String _Marshalls::raw_to_base64(const DVector<uint8_t> &p_arr) {
|
||||
|
||||
int len = p_arr.size();
|
||||
DVector<uint8_t>::Read r = p_arr.read();
|
||||
|
||||
int b64len = len / 3 * 4 + 4 + 1;
|
||||
DVector<uint8_t> b64buff;
|
||||
b64buff.resize(b64len);
|
||||
DVector<uint8_t>::Write w64 = b64buff.write();
|
||||
|
||||
int strlen = base64_encode((char*)(&w64[0]), (char*)(&r[0]), len);
|
||||
w64[strlen] = 0;
|
||||
String ret = (char*)&w64[0];
|
||||
|
||||
return ret;
|
||||
};
|
||||
|
||||
DVector<uint8_t> _Marshalls::base64_to_raw(const String &p_str) {
|
||||
|
||||
int strlen = p_str.length();
|
||||
CharString cstr = p_str.ascii();
|
||||
|
||||
int arr_len;
|
||||
DVector<uint8_t> buf;
|
||||
{
|
||||
buf.resize(strlen / 4 * 3 + 1);
|
||||
DVector<uint8_t>::Write w = buf.write();
|
||||
|
||||
arr_len = base64_decode((char*)(&w[0]), (char*)cstr.get_data(), strlen);
|
||||
};
|
||||
buf.resize(arr_len);
|
||||
|
||||
// conversion from DVector<uint8_t> to raw array?
|
||||
return buf;
|
||||
};
|
||||
|
||||
String _Marshalls::utf8_to_base64(const String& p_str) {
|
||||
|
||||
CharString cstr = p_str.utf8();
|
||||
int len = cstr.length();
|
||||
|
||||
int b64len = len / 3 * 4 + 4 + 1;
|
||||
DVector<uint8_t> b64buff;
|
||||
b64buff.resize(b64len);
|
||||
DVector<uint8_t>::Write w64 = b64buff.write();
|
||||
|
||||
int strlen = base64_encode((char*)(&w64[0]), (char*)cstr.get_data(), len);
|
||||
|
||||
w64[strlen] = 0;
|
||||
String ret = (char*)&w64[0];
|
||||
|
||||
return ret;
|
||||
};
|
||||
|
||||
String _Marshalls::base64_to_utf8(const String& p_str) {
|
||||
|
||||
int strlen = p_str.length();
|
||||
CharString cstr = p_str.ascii();
|
||||
|
||||
DVector<uint8_t> buf;
|
||||
buf.resize(strlen / 4 * 3 + 1 + 1);
|
||||
DVector<uint8_t>::Write w = buf.write();
|
||||
|
||||
int len = base64_decode((char*)(&w[0]), (char*)cstr.get_data(), strlen);
|
||||
|
||||
w[len] = 0;
|
||||
String ret = String::utf8((char*)&w[0]);
|
||||
|
||||
return ret;
|
||||
};
|
||||
|
||||
|
||||
void _Marshalls::_bind_methods() {
|
||||
|
||||
ObjectTypeDB::bind_method(_MD("variant_to_base64:String","variant"),&_Marshalls::variant_to_base64);
|
||||
ObjectTypeDB::bind_method(_MD("base64_to_variant:Variant","base64_str"),&_Marshalls::base64_to_variant);
|
||||
|
||||
ObjectTypeDB::bind_method(_MD("raw_to_base64:String","array"),&_Marshalls::raw_to_base64);
|
||||
ObjectTypeDB::bind_method(_MD("base64_to_raw:RawArray","base64_str"),&_Marshalls::base64_to_raw);
|
||||
|
||||
ObjectTypeDB::bind_method(_MD("utf8_to_base64:String","utf8_str"),&_Marshalls::utf8_to_base64);
|
||||
ObjectTypeDB::bind_method(_MD("base64_to_utf8:String","base64_str"),&_Marshalls::base64_to_utf8);
|
||||
|
||||
};
|
||||
|
||||
|
||||
@ -1772,6 +1876,7 @@ void _Thread::_start_func(void *ud) {
|
||||
memdelete(tud);
|
||||
Variant::CallError ce;
|
||||
const Variant* arg[1]={&t->userdata};
|
||||
|
||||
t->ret=t->target_instance->call(t->target_method,arg,1,ce);
|
||||
if (ce.error!=Variant::CallError::CALL_OK) {
|
||||
|
||||
@ -1796,6 +1901,7 @@ void _Thread::_start_func(void *ud) {
|
||||
default: {}
|
||||
}
|
||||
|
||||
|
||||
ERR_EXPLAIN("Could not call function '"+t->target_method.operator String()+"'' starting thread ID: "+t->get_id()+" Reason: "+reason);
|
||||
ERR_FAIL();
|
||||
}
|
||||
|
@ -208,6 +208,7 @@ public:
|
||||
Dictionary get_time(bool utc) const;
|
||||
Dictionary get_time_zone_info() const;
|
||||
uint64_t get_unix_time() const;
|
||||
uint64_t get_system_time_msec() const;
|
||||
|
||||
int get_static_memory_usage() const;
|
||||
int get_static_memory_peak_usage() const;
|
||||
@ -239,11 +240,25 @@ public:
|
||||
SYSTEM_DIR_RINGTONES,
|
||||
};
|
||||
|
||||
enum ScreenOrientation {
|
||||
|
||||
SCREEN_ORIENTATION_LANDSCAPE,
|
||||
SCREEN_ORIENTATION_PORTRAIT,
|
||||
SCREEN_ORIENTATION_REVERSE_LANDSCAPE,
|
||||
SCREEN_ORIENTATION_REVERSE_PORTRAIT,
|
||||
SCREEN_ORIENTATION_SENSOR_LANDSCAPE,
|
||||
SCREEN_ORIENTATION_SENSOR_PORTRAIT,
|
||||
SCREEN_ORIENTATION_SENSOR,
|
||||
};
|
||||
|
||||
String get_system_dir(SystemDir p_dir) const;
|
||||
|
||||
|
||||
String get_data_dir() const;
|
||||
|
||||
void set_screen_orientation(ScreenOrientation p_orientation);
|
||||
ScreenOrientation get_screen_orientation() const;
|
||||
|
||||
void set_time_scale(float p_scale);
|
||||
float get_time_scale();
|
||||
|
||||
@ -255,6 +270,7 @@ public:
|
||||
};
|
||||
|
||||
VARIANT_ENUM_CAST(_OS::SystemDir);
|
||||
VARIANT_ENUM_CAST(_OS::ScreenOrientation);
|
||||
|
||||
|
||||
class _Geometry : public Object {
|
||||
@ -436,6 +452,12 @@ public:
|
||||
String variant_to_base64(const Variant& p_var);
|
||||
Variant base64_to_variant(const String& p_str);
|
||||
|
||||
String raw_to_base64(const DVector<uint8_t>& p_arr);
|
||||
DVector<uint8_t> base64_to_raw(const String& p_str);
|
||||
|
||||
String utf8_to_base64(const String& p_str);
|
||||
String base64_to_utf8(const String& p_str);
|
||||
|
||||
_Marshalls() {};
|
||||
};
|
||||
|
||||
|
@ -1149,6 +1149,12 @@ Error Globals::_save_settings_text(const String& p_file,const Map<String,List<St
|
||||
|
||||
return OK;
|
||||
}
|
||||
|
||||
Error Globals::_save_custom_bnd(const String &p_file) { // add other params as dictionary and array?
|
||||
|
||||
return save_custom(p_file);
|
||||
};
|
||||
|
||||
Error Globals::save_custom(const String& p_path,const CustomMap& p_custom,const Set<String>& p_ignore_masks) {
|
||||
|
||||
ERR_FAIL_COND_V(p_path=="",ERR_INVALID_PARAMETER);
|
||||
@ -1321,7 +1327,7 @@ Vector<String> Globals::get_optimizer_presets() const {
|
||||
|
||||
if (!E->get().name.begins_with("optimizer_presets/"))
|
||||
continue;
|
||||
names.push_back(E->get().name.get_slice("/",1));
|
||||
names.push_back(E->get().name.get_slicec('/',1));
|
||||
}
|
||||
|
||||
names.sort();
|
||||
@ -1361,6 +1367,9 @@ void Globals::_bind_methods() {
|
||||
ObjectTypeDB::bind_method(_MD("has_singleton"),&Globals::has_singleton);
|
||||
ObjectTypeDB::bind_method(_MD("get_singleton"),&Globals::get_singleton_object);
|
||||
ObjectTypeDB::bind_method(_MD("load_resource_pack"),&Globals::_load_resource_pack);
|
||||
|
||||
ObjectTypeDB::bind_method(_MD("save_custom"),&Globals::_save_custom_bnd);
|
||||
|
||||
}
|
||||
|
||||
Globals::Globals() {
|
||||
|
@ -86,6 +86,7 @@ protected:
|
||||
|
||||
List<Singleton> singletons;
|
||||
|
||||
Error _save_custom_bnd(const String& p_file);
|
||||
|
||||
bool _load_resource_pack(const String& p_pack);
|
||||
|
||||
|
@ -1016,10 +1016,10 @@ void Image::create( const char ** p_xpm ) {
|
||||
String line_str=line_ptr;
|
||||
line_str.replace("\t"," ");
|
||||
|
||||
size_width=line_str.get_slice(" ",0).to_int();
|
||||
size_height=line_str.get_slice(" ",1).to_int();
|
||||
colormap_size=line_str.get_slice(" ",2).to_int();
|
||||
pixelchars=line_str.get_slice(" ",3).to_int();
|
||||
size_width=line_str.get_slicec(' ',0).to_int();
|
||||
size_height=line_str.get_slicec(' ',1).to_int();
|
||||
colormap_size=line_str.get_slicec(' ',2).to_int();
|
||||
pixelchars=line_str.get_slicec(' ',3).to_int();
|
||||
ERR_FAIL_COND(colormap_size > 32766);
|
||||
ERR_FAIL_COND(pixelchars > 5);
|
||||
ERR_FAIL_COND(size_width > 32767);
|
||||
|
@ -5,10 +5,12 @@
|
||||
#include "print_string.h"
|
||||
#define COMP_MAGIC 0x43454447
|
||||
|
||||
#include "core/variant.h"
|
||||
#include <stdio.h>
|
||||
|
||||
Error FileAccessEncrypted::open_and_parse(FileAccess *p_base,const Vector<uint8_t>& p_key,Mode p_mode) {
|
||||
|
||||
print_line("open and parse!");
|
||||
//print_line("open and parse!");
|
||||
ERR_FAIL_COND_V(file!=NULL,ERR_ALREADY_IN_USE);
|
||||
ERR_FAIL_COND_V(p_key.size()!=32,ERR_INVALID_PARAMETER);
|
||||
|
||||
|
@ -325,7 +325,7 @@ Error HTTPClient::poll(){
|
||||
|
||||
if (i==0 && responses[i].begins_with("HTTP")) {
|
||||
|
||||
String num = responses[i].get_slice(" ",1);
|
||||
String num = responses[i].get_slicec(' ',1);
|
||||
response_num=num.to_int();
|
||||
} else {
|
||||
|
||||
|
@ -47,7 +47,7 @@ IP_Address::IP_Address(const String& p_string) {
|
||||
}
|
||||
for(int i=0;i<4;i++) {
|
||||
|
||||
field[i]=p_string.get_slice(".",i).to_int();
|
||||
field[i]=p_string.get_slicec('.',i).to_int();
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1819,7 +1819,7 @@ Error ResourceFormatSaverBinaryInstance::save(const String &p_path,const RES& p_
|
||||
Property p;
|
||||
p.name_idx=get_string_index(F->get().name);
|
||||
p.value=E->get()->get(F->get().name);
|
||||
if (F->get().usage&PROPERTY_USAGE_STORE_IF_NONZERO && p.value.is_zero())
|
||||
if ((F->get().usage&PROPERTY_USAGE_STORE_IF_NONZERO && p.value.is_zero())||(F->get().usage&PROPERTY_USAGE_STORE_IF_NONONE && p.value.is_one()) )
|
||||
continue;
|
||||
p.pi=F->get();
|
||||
|
||||
|
@ -1207,47 +1207,47 @@ Error ResourceInteractiveLoaderXML::parse_property(Variant& r_v, String &r_name)
|
||||
|
||||
|
||||
r_v=Vector3(
|
||||
data.get_slice(",",0).to_double(),
|
||||
data.get_slice(",",1).to_double(),
|
||||
data.get_slice(",",2).to_double()
|
||||
data.get_slicec(',',0).to_double(),
|
||||
data.get_slicec(',',1).to_double(),
|
||||
data.get_slicec(',',2).to_double()
|
||||
);
|
||||
|
||||
} else if (type=="vector2") {
|
||||
|
||||
|
||||
r_v=Vector2(
|
||||
data.get_slice(",",0).to_double(),
|
||||
data.get_slice(",",1).to_double()
|
||||
data.get_slicec(',',0).to_double(),
|
||||
data.get_slicec(',',1).to_double()
|
||||
);
|
||||
|
||||
} else if (type=="plane") {
|
||||
|
||||
r_v=Plane(
|
||||
data.get_slice(",",0).to_double(),
|
||||
data.get_slice(",",1).to_double(),
|
||||
data.get_slice(",",2).to_double(),
|
||||
data.get_slice(",",3).to_double()
|
||||
data.get_slicec(',',0).to_double(),
|
||||
data.get_slicec(',',1).to_double(),
|
||||
data.get_slicec(',',2).to_double(),
|
||||
data.get_slicec(',',3).to_double()
|
||||
);
|
||||
|
||||
} else if (type=="quaternion") {
|
||||
|
||||
r_v=Quat(
|
||||
data.get_slice(",",0).to_double(),
|
||||
data.get_slice(",",1).to_double(),
|
||||
data.get_slice(",",2).to_double(),
|
||||
data.get_slice(",",3).to_double()
|
||||
data.get_slicec(',',0).to_double(),
|
||||
data.get_slicec(',',1).to_double(),
|
||||
data.get_slicec(',',2).to_double(),
|
||||
data.get_slicec(',',3).to_double()
|
||||
);
|
||||
|
||||
} else if (type=="rect2") {
|
||||
|
||||
r_v=Rect2(
|
||||
Vector2(
|
||||
data.get_slice(",",0).to_double(),
|
||||
data.get_slice(",",1).to_double()
|
||||
data.get_slicec(',',0).to_double(),
|
||||
data.get_slicec(',',1).to_double()
|
||||
),
|
||||
Vector2(
|
||||
data.get_slice(",",2).to_double(),
|
||||
data.get_slice(",",3).to_double()
|
||||
data.get_slicec(',',2).to_double(),
|
||||
data.get_slicec(',',3).to_double()
|
||||
)
|
||||
);
|
||||
|
||||
@ -1256,14 +1256,14 @@ Error ResourceInteractiveLoaderXML::parse_property(Variant& r_v, String &r_name)
|
||||
|
||||
r_v=AABB(
|
||||
Vector3(
|
||||
data.get_slice(",",0).to_double(),
|
||||
data.get_slice(",",1).to_double(),
|
||||
data.get_slice(",",2).to_double()
|
||||
data.get_slicec(',',0).to_double(),
|
||||
data.get_slicec(',',1).to_double(),
|
||||
data.get_slicec(',',2).to_double()
|
||||
),
|
||||
Vector3(
|
||||
data.get_slice(",",3).to_double(),
|
||||
data.get_slice(",",4).to_double(),
|
||||
data.get_slice(",",5).to_double()
|
||||
data.get_slicec(',',3).to_double(),
|
||||
data.get_slicec(',',4).to_double(),
|
||||
data.get_slicec(',',5).to_double()
|
||||
)
|
||||
);
|
||||
|
||||
@ -1272,7 +1272,7 @@ Error ResourceInteractiveLoaderXML::parse_property(Variant& r_v, String &r_name)
|
||||
Matrix32 m3;
|
||||
for (int i=0;i<3;i++) {
|
||||
for (int j=0;j<2;j++) {
|
||||
m3.elements[i][j]=data.get_slice(",",i*2+j).to_double();
|
||||
m3.elements[i][j]=data.get_slicec(',',i*2+j).to_double();
|
||||
}
|
||||
}
|
||||
r_v=m3;
|
||||
@ -1282,7 +1282,7 @@ Error ResourceInteractiveLoaderXML::parse_property(Variant& r_v, String &r_name)
|
||||
Matrix3 m3;
|
||||
for (int i=0;i<3;i++) {
|
||||
for (int j=0;j<3;j++) {
|
||||
m3.elements[i][j]=data.get_slice(",",i*3+j).to_double();
|
||||
m3.elements[i][j]=data.get_slicec(',',i*3+j).to_double();
|
||||
}
|
||||
}
|
||||
r_v=m3;
|
||||
@ -1292,24 +1292,24 @@ Error ResourceInteractiveLoaderXML::parse_property(Variant& r_v, String &r_name)
|
||||
Transform tr;
|
||||
for (int i=0;i<3;i++) {
|
||||
for (int j=0;j<3;j++) {
|
||||
tr.basis.elements[i][j]=data.get_slice(",",i*3+j).to_double();
|
||||
tr.basis.elements[i][j]=data.get_slicec(',',i*3+j).to_double();
|
||||
}
|
||||
|
||||
}
|
||||
tr.origin=Vector3(
|
||||
data.get_slice(",",9).to_double(),
|
||||
data.get_slice(",",10).to_double(),
|
||||
data.get_slice(",",11).to_double()
|
||||
data.get_slicec(',',9).to_double(),
|
||||
data.get_slicec(',',10).to_double(),
|
||||
data.get_slicec(',',11).to_double()
|
||||
);
|
||||
r_v=tr;
|
||||
|
||||
} else if (type=="color") {
|
||||
|
||||
r_v=Color(
|
||||
data.get_slice(",",0).to_double(),
|
||||
data.get_slice(",",1).to_double(),
|
||||
data.get_slice(",",2).to_double(),
|
||||
data.get_slice(",",3).to_double()
|
||||
data.get_slicec(',',0).to_double(),
|
||||
data.get_slicec(',',1).to_double(),
|
||||
data.get_slicec(',',2).to_double(),
|
||||
data.get_slicec(',',3).to_double()
|
||||
);
|
||||
|
||||
} else if (type=="node_path") {
|
||||
@ -1674,8 +1674,8 @@ void ResourceInteractiveLoaderXML::open(FileAccess *p_f) {
|
||||
ERR_FAIL();
|
||||
}
|
||||
|
||||
int major = version.get_slice(".",0).to_int();
|
||||
int minor = version.get_slice(".",1).to_int();
|
||||
int major = version.get_slicec('.',0).to_int();
|
||||
int minor = version.get_slicec('.',1).to_int();
|
||||
|
||||
if (major>VERSION_MAJOR) {
|
||||
|
||||
@ -2607,9 +2607,12 @@ Error ResourceFormatSaverXMLInstance::save(const String &p_path,const RES& p_res
|
||||
|
||||
String name = PE->get().name;
|
||||
Variant value = res->get(name);
|
||||
if (PE->get().usage&PROPERTY_USAGE_STORE_IF_NONZERO && value.is_zero())
|
||||
|
||||
|
||||
if ((PE->get().usage&PROPERTY_USAGE_STORE_IF_NONZERO && value.is_zero())||(PE->get().usage&PROPERTY_USAGE_STORE_IF_NONONE && value.is_one()) )
|
||||
continue;
|
||||
|
||||
|
||||
write_property(name,value);
|
||||
}
|
||||
|
||||
|
@ -40,8 +40,8 @@ PropertyInfo MethodBind::get_argument_info(int p_argument) const {
|
||||
PropertyInfo pi( get_argument_type(p_argument), name );
|
||||
if ((pi.type==Variant::OBJECT) && name.find(":")!=-1) {
|
||||
pi.hint=PROPERTY_HINT_RESOURCE_TYPE;
|
||||
pi.hint_string=name.get_slice(":",1);
|
||||
pi.name=name.get_slice(":",0);
|
||||
pi.hint_string=name.get_slicec(':',1);
|
||||
pi.name=name.get_slicec(':',0);
|
||||
}
|
||||
return pi;
|
||||
|
||||
|
@ -258,12 +258,15 @@ bool Object::_predelete() {
|
||||
|
||||
_predelete_ok=1;
|
||||
notification(NOTIFICATION_PREDELETE,true);
|
||||
if (_predelete_ok) {
|
||||
_type_ptr=NULL; //must restore so destructors can access type ptr correctly
|
||||
}
|
||||
return _predelete_ok;
|
||||
|
||||
}
|
||||
|
||||
void Object::_postinitialize() {
|
||||
|
||||
_type_ptr=_get_type_namev();
|
||||
_initialize_typev();
|
||||
notification(NOTIFICATION_POSTINITIALIZE);
|
||||
|
||||
@ -1707,7 +1710,7 @@ bool Object::is_edited() const {
|
||||
|
||||
Object::Object() {
|
||||
|
||||
|
||||
_type_ptr=NULL;
|
||||
_block_signals=false;
|
||||
_predelete_ok=0;
|
||||
_instance_ID=0;
|
||||
|
@ -82,7 +82,8 @@ enum PropertyUsageFlags {
|
||||
PROPERTY_USAGE_BUNDLE=128, //used for optimized bundles
|
||||
PROPERTY_USAGE_CATEGORY=256,
|
||||
PROPERTY_USAGE_STORE_IF_NONZERO=512, //only store if nonzero
|
||||
PROPERTY_USAGE_NO_INSTANCE_STATE=1024,
|
||||
PROPERTY_USAGE_STORE_IF_NONONE=1024, //only store if false
|
||||
PROPERTY_USAGE_NO_INSTANCE_STATE=2048,
|
||||
|
||||
PROPERTY_USAGE_DEFAULT=PROPERTY_USAGE_STORAGE|PROPERTY_USAGE_EDITOR|PROPERTY_USAGE_NETWORK,
|
||||
PROPERTY_USAGE_DEFAULT_INTL=PROPERTY_USAGE_STORAGE|PROPERTY_USAGE_EDITOR|PROPERTY_USAGE_NETWORK|PROPERTY_USAGE_INTERNATIONALIZED,
|
||||
@ -97,6 +98,8 @@ enum PropertyUsageFlags {
|
||||
#define ADD_PROPERTYI( m_property, m_setter, m_getter, m_index ) ObjectTypeDB::add_property( get_type_static(), m_property, m_setter, m_getter, m_index )
|
||||
#define ADD_PROPERTYNZ( m_property, m_setter, m_getter ) ObjectTypeDB::add_property( get_type_static(), (m_property).added_usage(PROPERTY_USAGE_STORE_IF_NONZERO), m_setter, m_getter )
|
||||
#define ADD_PROPERTYINZ( m_property, m_setter, m_getter, m_index ) ObjectTypeDB::add_property( get_type_static(), (m_property).added_usage(PROPERTY_USAGE_STORE_IF_NONZERO), m_setter, m_getter, m_index )
|
||||
#define ADD_PROPERTYNO( m_property, m_setter, m_getter ) ObjectTypeDB::add_property( get_type_static(), (m_property).added_usage(PROPERTY_USAGE_STORE_IF_NONONE), m_setter, m_getter )
|
||||
#define ADD_PROPERTYINO( m_property, m_setter, m_getter, m_index ) ObjectTypeDB::add_property( get_type_static(), (m_property).added_usage(PROPERTY_USAGE_STORE_IF_NONONE), m_setter, m_getter, m_index )
|
||||
|
||||
struct PropertyInfo {
|
||||
|
||||
@ -179,10 +182,10 @@ public:\
|
||||
virtual String get_type() const { \
|
||||
return String(#m_type);\
|
||||
}\
|
||||
virtual StringName get_type_name() const { \
|
||||
virtual const StringName* _get_type_namev() const { \
|
||||
if (!_type_name)\
|
||||
_type_name=get_type_static();\
|
||||
return _type_name;\
|
||||
return &_type_name;\
|
||||
}\
|
||||
static _FORCE_INLINE_ void* get_type_ptr_static() { \
|
||||
static int ptr;\
|
||||
@ -388,6 +391,8 @@ friend void postinitialize_handler(Object*);
|
||||
ScriptInstance *script_instance;
|
||||
RefPtr script;
|
||||
Dictionary metadata;
|
||||
mutable StringName _type_name;
|
||||
mutable const StringName* _type_ptr;
|
||||
|
||||
void _add_user_signal(const String& p_name, const Array& p_pargs=Array());
|
||||
bool _has_user_signal(const StringName& p_name) const;
|
||||
@ -445,7 +450,11 @@ protected:
|
||||
Variant _call_deferred_bind(const Variant** p_args, int p_argcount, Variant::CallError& r_error);
|
||||
|
||||
|
||||
|
||||
virtual const StringName* _get_type_namev() const {
|
||||
if (!_type_name)
|
||||
_type_name=get_type_static();
|
||||
return &_type_name;
|
||||
}
|
||||
|
||||
DVector<String> _get_meta_list_bind() const;
|
||||
Array _get_property_list_bind() const;
|
||||
@ -523,11 +532,19 @@ public:
|
||||
|
||||
virtual String get_type() const { return "Object"; }
|
||||
virtual String get_save_type() const { return get_type(); } //type stored when saving
|
||||
virtual StringName get_type_name() const { return StringName("Object"); }
|
||||
|
||||
|
||||
|
||||
virtual bool is_type(const String& p_type) const { return (p_type=="Object"); }
|
||||
virtual bool is_type_ptr(void *p_ptr) const { return get_type_ptr_static()==p_ptr; }
|
||||
|
||||
|
||||
_FORCE_INLINE_ const StringName& get_type_name() const {
|
||||
if (!_type_ptr) {
|
||||
return *_get_type_namev();
|
||||
} else {
|
||||
return *_type_ptr;
|
||||
}
|
||||
}
|
||||
|
||||
/* IAPI */
|
||||
// void set(const String& p_name, const Variant& p_value);
|
||||
|
@ -205,7 +205,7 @@ ObjectTypeDB::TypeInfo::~TypeInfo() {
|
||||
}
|
||||
|
||||
|
||||
bool ObjectTypeDB::is_type(const String &p_type,const String& p_inherits) {
|
||||
bool ObjectTypeDB::is_type(const StringName &p_type,const StringName& p_inherits) {
|
||||
|
||||
OBJTYPE_LOCK;
|
||||
|
||||
@ -220,7 +220,7 @@ bool ObjectTypeDB::is_type(const String &p_type,const String& p_inherits) {
|
||||
|
||||
return false;
|
||||
}
|
||||
void ObjectTypeDB::get_type_list( List<String> *p_types) {
|
||||
void ObjectTypeDB::get_type_list( List<StringName> *p_types) {
|
||||
|
||||
OBJTYPE_LOCK;
|
||||
|
||||
@ -235,7 +235,7 @@ void ObjectTypeDB::get_type_list( List<String> *p_types) {
|
||||
}
|
||||
|
||||
|
||||
void ObjectTypeDB::get_inheriters_from( const String& p_type,List<String> *p_types) {
|
||||
void ObjectTypeDB::get_inheriters_from( const StringName& p_type,List<StringName> *p_types) {
|
||||
|
||||
OBJTYPE_LOCK;
|
||||
|
||||
@ -249,7 +249,7 @@ void ObjectTypeDB::get_inheriters_from( const String& p_type,List<String> *p_typ
|
||||
|
||||
}
|
||||
|
||||
String ObjectTypeDB::type_inherits_from(const String& p_type) {
|
||||
StringName ObjectTypeDB::type_inherits_from(const StringName& p_type) {
|
||||
|
||||
OBJTYPE_LOCK;
|
||||
|
||||
@ -258,7 +258,7 @@ String ObjectTypeDB::type_inherits_from(const String& p_type) {
|
||||
return ti->inherits;
|
||||
}
|
||||
|
||||
bool ObjectTypeDB::type_exists(const String &p_type) {
|
||||
bool ObjectTypeDB::type_exists(const StringName &p_type) {
|
||||
|
||||
OBJTYPE_LOCK;
|
||||
return types.has(p_type);
|
||||
@ -269,7 +269,7 @@ void ObjectTypeDB::add_compatibility_type(const StringName& p_type,const StringN
|
||||
compat_types[p_type]=p_fallback;
|
||||
}
|
||||
|
||||
Object *ObjectTypeDB::instance(const String &p_type) {
|
||||
Object *ObjectTypeDB::instance(const StringName &p_type) {
|
||||
|
||||
TypeInfo *ti;
|
||||
{
|
||||
@ -287,7 +287,7 @@ Object *ObjectTypeDB::instance(const String &p_type) {
|
||||
|
||||
return ti->creation_func();
|
||||
}
|
||||
bool ObjectTypeDB::can_instance(const String &p_type) {
|
||||
bool ObjectTypeDB::can_instance(const StringName &p_type) {
|
||||
|
||||
OBJTYPE_LOCK;
|
||||
|
||||
@ -650,7 +650,13 @@ bool ObjectTypeDB::set_property(Object* p_object,const StringName& p_property, c
|
||||
Variant index=psg->index;
|
||||
const Variant* arg[2]={&index,&p_value};
|
||||
Variant::CallError ce;
|
||||
p_object->call(psg->setter,arg,2,ce);
|
||||
// p_object->call(psg->setter,arg,2,ce);
|
||||
if (psg->_setptr) {
|
||||
psg->_setptr->call(p_object,arg,2,ce);
|
||||
} else {
|
||||
p_object->call(psg->setter,arg,2,ce);
|
||||
}
|
||||
|
||||
|
||||
} else {
|
||||
const Variant* arg[1]={&p_value};
|
||||
|
@ -228,13 +228,13 @@ public:
|
||||
T::register_custom_data_to_otdb();
|
||||
}
|
||||
|
||||
static void get_type_list( List<String> *p_types);
|
||||
static void get_inheriters_from( const String& p_type,List<String> *p_types);
|
||||
static String type_inherits_from(const String& p_type);
|
||||
static bool type_exists(const String &p_type);
|
||||
static bool is_type(const String &p_type,const String& p_inherits);
|
||||
static bool can_instance(const String &p_type);
|
||||
static Object *instance(const String &p_type);
|
||||
static void get_type_list( List<StringName> *p_types);
|
||||
static void get_inheriters_from( const StringName& p_type,List<StringName> *p_types);
|
||||
static StringName type_inherits_from(const StringName& p_type);
|
||||
static bool type_exists(const StringName &p_type);
|
||||
static bool is_type(const StringName &p_type,const StringName& p_inherits);
|
||||
static bool can_instance(const StringName &p_type);
|
||||
static Object *instance(const StringName &p_type);
|
||||
|
||||
#if 0
|
||||
template<class N, class M>
|
||||
|
@ -50,7 +50,9 @@ uint64_t OS::get_unix_time() const {
|
||||
|
||||
return 0;
|
||||
};
|
||||
|
||||
uint64_t OS::get_system_time_msec() const {
|
||||
return 0;
|
||||
}
|
||||
void OS::debug_break() {
|
||||
|
||||
// something
|
||||
|
@ -254,6 +254,7 @@ public:
|
||||
virtual Time get_time(bool local=false) const=0;
|
||||
virtual TimeZoneInfo get_time_zone_info() const=0;
|
||||
virtual uint64_t get_unix_time() const;
|
||||
virtual uint64_t get_system_time_msec() const;
|
||||
|
||||
virtual void delay_usec(uint32_t p_usec) const=0;
|
||||
virtual uint64_t get_ticks_usec() const=0;
|
||||
|
@ -32,6 +32,7 @@
|
||||
|
||||
static PrintHandlerList *print_handler_list=NULL;
|
||||
bool _print_line_enabled=true;
|
||||
bool _print_error_enabled = true;
|
||||
|
||||
void add_print_handler(PrintHandlerList *p_handler) {
|
||||
|
||||
|
@ -52,6 +52,7 @@ void add_print_handler(PrintHandlerList *p_handler);
|
||||
void remove_print_handler(PrintHandlerList *p_handler);
|
||||
|
||||
extern bool _print_line_enabled;
|
||||
extern bool _print_error_enabled;
|
||||
extern void print_line(String p_string);
|
||||
|
||||
#endif
|
||||
|
@ -60,7 +60,7 @@ void ScriptDebuggerLocal::debug(ScriptLanguage *p_script,bool p_can_continue) {
|
||||
if (line.get_slice_count(" ")==1) {
|
||||
print_line("*Frame "+itos(current_frame)+" - "+p_script->debug_get_stack_level_source(current_frame)+":"+itos(p_script->debug_get_stack_level_line(current_frame))+" in function '"+p_script->debug_get_stack_level_function(current_frame)+"'");
|
||||
} else {
|
||||
int frame = line.get_slice(" ",1).to_int();
|
||||
int frame = line.get_slicec(' ',1).to_int();
|
||||
if (frame<0 || frame >=total_frames) {
|
||||
print_line("Error: Invalid frame.");
|
||||
} else {
|
||||
@ -108,7 +108,7 @@ void ScriptDebuggerLocal::debug(ScriptLanguage *p_script,bool p_can_continue) {
|
||||
print_line("Usage: print <expre>");
|
||||
} else {
|
||||
|
||||
String expr = line.get_slice(" ",2);
|
||||
String expr = line.get_slicec(' ',2);
|
||||
String res = p_script->debug_parse_stack_level_expression(current_frame,expr);
|
||||
print_line(res);
|
||||
}
|
||||
@ -130,9 +130,9 @@ void ScriptDebuggerLocal::debug(ScriptLanguage *p_script,bool p_can_continue) {
|
||||
} else {
|
||||
|
||||
|
||||
String bppos=line.get_slice(" ",1);
|
||||
String source=bppos.get_slice(":",0).strip_edges();
|
||||
int line=bppos.get_slice(":",1).strip_edges().to_int();
|
||||
String bppos=line.get_slicec(' ',1);
|
||||
String source=bppos.get_slicec(':',0).strip_edges();
|
||||
int line=bppos.get_slicec(':',1).strip_edges().to_int();
|
||||
|
||||
source = breakpoint_find_source(source);
|
||||
|
||||
@ -147,9 +147,9 @@ void ScriptDebuggerLocal::debug(ScriptLanguage *p_script,bool p_can_continue) {
|
||||
clear_breakpoints();
|
||||
} else {
|
||||
|
||||
String bppos=line.get_slice(" ",1);
|
||||
String source=bppos.get_slice(":",0).strip_edges();
|
||||
int line=bppos.get_slice(":",1).strip_edges().to_int();
|
||||
String bppos=line.get_slicec(' ',1);
|
||||
String source=bppos.get_slicec(':',0).strip_edges();
|
||||
int line=bppos.get_slicec(':',1).strip_edges().to_int();
|
||||
|
||||
source = breakpoint_find_source(source);
|
||||
|
||||
|
@ -34,7 +34,11 @@
|
||||
Error ScriptDebuggerRemote::connect_to_host(const String& p_host,uint16_t p_port) {
|
||||
|
||||
|
||||
IP_Address ip = IP::get_singleton()->resolve_hostname(p_host);
|
||||
IP_Address ip;
|
||||
if (p_host.is_valid_ip_address())
|
||||
ip=p_host;
|
||||
else
|
||||
ip = IP::get_singleton()->resolve_hostname(p_host);
|
||||
|
||||
|
||||
int port = p_port;
|
||||
@ -127,7 +131,7 @@ void ScriptDebuggerRemote::debug(ScriptLanguage *p_script,bool p_can_continue) {
|
||||
ERR_CONTINUE( cmd[0].get_type()!=Variant::STRING );
|
||||
|
||||
String command = cmd[0];
|
||||
cmd.remove(0);
|
||||
|
||||
|
||||
|
||||
if (command=="get_stack_dump") {
|
||||
@ -150,7 +154,7 @@ void ScriptDebuggerRemote::debug(ScriptLanguage *p_script,bool p_can_continue) {
|
||||
|
||||
} else if (command=="get_stack_frame_vars") {
|
||||
|
||||
|
||||
cmd.remove(0);
|
||||
ERR_CONTINUE( cmd.size()!=1 );
|
||||
int lv = cmd[0];
|
||||
|
||||
@ -243,6 +247,17 @@ void ScriptDebuggerRemote::debug(ScriptLanguage *p_script,bool p_can_continue) {
|
||||
|
||||
if (request_scene_tree)
|
||||
request_scene_tree(request_scene_tree_ud);
|
||||
|
||||
} else if (command=="breakpoint") {
|
||||
|
||||
bool set = cmd[3];
|
||||
if (set)
|
||||
insert_breakpoint(cmd[2],cmd[1]);
|
||||
else
|
||||
remove_breakpoint(cmd[2],cmd[1]);
|
||||
|
||||
} else {
|
||||
_parse_live_edit(cmd);
|
||||
}
|
||||
|
||||
|
||||
@ -287,6 +302,37 @@ void ScriptDebuggerRemote::_get_output() {
|
||||
messages.pop_front();
|
||||
locking=false;
|
||||
}
|
||||
|
||||
while (errors.size()) {
|
||||
locking=true;
|
||||
packet_peer_stream->put_var("error");
|
||||
OutputError oe = errors.front()->get();
|
||||
|
||||
packet_peer_stream->put_var(oe.callstack.size()+2);
|
||||
|
||||
Array error_data;
|
||||
|
||||
error_data.push_back(oe.hr);
|
||||
error_data.push_back(oe.min);
|
||||
error_data.push_back(oe.sec);
|
||||
error_data.push_back(oe.msec);
|
||||
error_data.push_back(oe.source_func);
|
||||
error_data.push_back(oe.source_file);
|
||||
error_data.push_back(oe.source_line);
|
||||
error_data.push_back(oe.error);
|
||||
error_data.push_back(oe.error_descr);
|
||||
error_data.push_back(oe.warning);
|
||||
packet_peer_stream->put_var(error_data);
|
||||
packet_peer_stream->put_var(oe.callstack.size());
|
||||
for(int i=0;i<oe.callstack.size();i++) {
|
||||
packet_peer_stream->put_var(oe.callstack[i]);
|
||||
|
||||
}
|
||||
|
||||
errors.pop_front();
|
||||
locking=false;
|
||||
|
||||
}
|
||||
mutex->unlock();
|
||||
}
|
||||
|
||||
@ -301,6 +347,160 @@ void ScriptDebuggerRemote::line_poll() {
|
||||
}
|
||||
|
||||
|
||||
void ScriptDebuggerRemote::_err_handler(void* ud,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)
|
||||
return; //ignore script errors, those go through debugger
|
||||
|
||||
ScriptDebuggerRemote *sdr = (ScriptDebuggerRemote*)ud;
|
||||
|
||||
OutputError oe;
|
||||
oe.error=p_err;
|
||||
oe.error_descr=p_descr;
|
||||
oe.source_file=p_file;
|
||||
oe.source_line=p_line;
|
||||
oe.source_func=p_func;
|
||||
oe.warning=p_type==ERR_HANDLER_WARNING;
|
||||
uint64_t time = OS::get_singleton()->get_ticks_msec();
|
||||
oe.hr=time/3600000;
|
||||
oe.min=(time/60000)%60;
|
||||
oe.sec=(time/1000)%60;
|
||||
oe.msec=time%1000;
|
||||
Array cstack;
|
||||
|
||||
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())
|
||||
break;
|
||||
}
|
||||
|
||||
cstack.resize(si.size()*2);
|
||||
for(int i=0;i<si.size();i++) {
|
||||
String path;
|
||||
int line=0;
|
||||
if (si[i].script.is_valid()) {
|
||||
path=si[i].script->get_path();
|
||||
line=si[i].line;
|
||||
}
|
||||
cstack[i*2+0]=path;
|
||||
cstack[i*2+1]=line;
|
||||
}
|
||||
|
||||
oe.callstack=cstack;
|
||||
|
||||
|
||||
sdr->mutex->lock();
|
||||
|
||||
if (!sdr->locking && sdr->tcp_client->is_connected()) {
|
||||
|
||||
sdr->errors.push_back(oe);
|
||||
}
|
||||
|
||||
sdr->mutex->unlock();
|
||||
}
|
||||
|
||||
|
||||
bool ScriptDebuggerRemote::_parse_live_edit(const Array& cmd) {
|
||||
|
||||
String cmdstr = cmd[0];
|
||||
if (!live_edit_funcs || !cmdstr.begins_with("live_"))
|
||||
return false;
|
||||
|
||||
|
||||
//print_line(Variant(cmd).get_construct_string());
|
||||
if (cmdstr=="live_set_root") {
|
||||
|
||||
if (!live_edit_funcs->root_func)
|
||||
return true;
|
||||
//print_line("root: "+Variant(cmd).get_construct_string());
|
||||
live_edit_funcs->root_func(live_edit_funcs->udata,cmd[1],cmd[2]);
|
||||
|
||||
} else if (cmdstr=="live_node_path") {
|
||||
|
||||
if (!live_edit_funcs->node_path_func)
|
||||
return true;
|
||||
//print_line("path: "+Variant(cmd).get_construct_string());
|
||||
|
||||
live_edit_funcs->node_path_func(live_edit_funcs->udata,cmd[1],cmd[2]);
|
||||
|
||||
} else if (cmdstr=="live_res_path") {
|
||||
|
||||
if (!live_edit_funcs->res_path_func)
|
||||
return true;
|
||||
live_edit_funcs->res_path_func(live_edit_funcs->udata,cmd[1],cmd[2]);
|
||||
|
||||
} else if (cmdstr=="live_node_prop_res") {
|
||||
if (!live_edit_funcs->node_set_res_func)
|
||||
return true;
|
||||
|
||||
live_edit_funcs->node_set_res_func(live_edit_funcs->udata,cmd[1],cmd[2],cmd[3]);
|
||||
|
||||
} else if (cmdstr=="live_node_prop") {
|
||||
|
||||
if (!live_edit_funcs->node_set_func)
|
||||
return true;
|
||||
live_edit_funcs->node_set_func(live_edit_funcs->udata,cmd[1],cmd[2],cmd[3]);
|
||||
|
||||
} else if (cmdstr=="live_res_prop_res") {
|
||||
|
||||
if (!live_edit_funcs->res_set_res_func)
|
||||
return true;
|
||||
live_edit_funcs->res_set_res_func(live_edit_funcs->udata,cmd[1],cmd[2],cmd[3]);
|
||||
|
||||
} else if (cmdstr=="live_res_prop") {
|
||||
|
||||
if (!live_edit_funcs->res_set_func)
|
||||
return true;
|
||||
live_edit_funcs->res_set_func(live_edit_funcs->udata,cmd[1],cmd[2],cmd[3]);
|
||||
|
||||
} else if (cmdstr=="live_node_call") {
|
||||
|
||||
if (!live_edit_funcs->node_call_func)
|
||||
return true;
|
||||
live_edit_funcs->node_call_func(live_edit_funcs->udata,cmd[1],cmd[2], cmd[3],cmd[4],cmd[5],cmd[6],cmd[7]);
|
||||
|
||||
} else if (cmdstr=="live_res_call") {
|
||||
|
||||
if (!live_edit_funcs->res_call_func)
|
||||
return true;
|
||||
live_edit_funcs->res_call_func(live_edit_funcs->udata,cmd[1],cmd[2], cmd[3],cmd[4],cmd[5],cmd[6],cmd[7]);
|
||||
|
||||
} else if (cmdstr=="live_create_node") {
|
||||
|
||||
live_edit_funcs->tree_create_node_func(live_edit_funcs->udata,cmd[1],cmd[2],cmd[3]);
|
||||
|
||||
} else if (cmdstr=="live_instance_node") {
|
||||
|
||||
live_edit_funcs->tree_instance_node_func(live_edit_funcs->udata,cmd[1],cmd[2],cmd[3]);
|
||||
|
||||
} else if (cmdstr=="live_remove_node") {
|
||||
|
||||
live_edit_funcs->tree_remove_node_func(live_edit_funcs->udata,cmd[1]);
|
||||
|
||||
} else if (cmdstr=="live_remove_and_keep_node") {
|
||||
|
||||
live_edit_funcs->tree_remove_and_keep_node_func(live_edit_funcs->udata,cmd[1],cmd[2]);
|
||||
} else if (cmdstr=="live_restore_node") {
|
||||
|
||||
live_edit_funcs->tree_restore_node_func(live_edit_funcs->udata,cmd[1],cmd[2],cmd[3]);
|
||||
|
||||
} else if (cmdstr=="live_duplicate_node") {
|
||||
|
||||
live_edit_funcs->tree_duplicate_node_func(live_edit_funcs->udata,cmd[1],cmd[2]);
|
||||
} else if (cmdstr=="live_reparent_node") {
|
||||
|
||||
live_edit_funcs->tree_reparent_node_func(live_edit_funcs->udata,cmd[1],cmd[2],cmd[3],cmd[4]);
|
||||
|
||||
} else {
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void ScriptDebuggerRemote::_poll_events() {
|
||||
|
||||
while(packet_peer_stream->get_available_packet_count()>0) {
|
||||
@ -321,7 +521,7 @@ void ScriptDebuggerRemote::_poll_events() {
|
||||
ERR_CONTINUE( cmd[0].get_type()!=Variant::STRING );
|
||||
|
||||
String command = cmd[0];
|
||||
cmd.remove(0);
|
||||
//cmd.remove(0);
|
||||
|
||||
if (command=="break") {
|
||||
|
||||
@ -331,6 +531,15 @@ void ScriptDebuggerRemote::_poll_events() {
|
||||
|
||||
if (request_scene_tree)
|
||||
request_scene_tree(request_scene_tree_ud);
|
||||
} else if (command=="breakpoint") {
|
||||
|
||||
bool set = cmd[3];
|
||||
if (set)
|
||||
insert_breakpoint(cmd[2],cmd[1]);
|
||||
else
|
||||
remove_breakpoint(cmd[2],cmd[1]);
|
||||
} else {
|
||||
_parse_live_edit(cmd);
|
||||
}
|
||||
|
||||
}
|
||||
@ -394,10 +603,35 @@ void ScriptDebuggerRemote::_print_handler(void *p_this,const String& p_string) {
|
||||
|
||||
ScriptDebuggerRemote *sdr = (ScriptDebuggerRemote*)p_this;
|
||||
|
||||
uint64_t ticks = OS::get_singleton()->get_ticks_usec()/1000;
|
||||
sdr->msec_count+=ticks-sdr->last_msec;
|
||||
sdr->last_msec=ticks;
|
||||
|
||||
if (sdr->msec_count>1000) {
|
||||
sdr->char_count=0;
|
||||
sdr->msec_count=0;
|
||||
}
|
||||
|
||||
String s = p_string;
|
||||
int allowed_chars = MIN(MAX(sdr->max_cps - sdr->char_count,0), s.length());
|
||||
|
||||
if (allowed_chars==0)
|
||||
return;
|
||||
|
||||
if (allowed_chars<s.length()) {
|
||||
s=s.substr(0,allowed_chars);
|
||||
}
|
||||
|
||||
sdr->char_count+=allowed_chars;
|
||||
|
||||
if (sdr->char_count>=sdr->max_cps) {
|
||||
s+="\n[output overflow, print less text!]\n";
|
||||
}
|
||||
|
||||
sdr->mutex->lock();
|
||||
if (!sdr->locking && sdr->tcp_client->is_connected()) {
|
||||
|
||||
sdr->output_strings .push_back(p_string);
|
||||
sdr->output_strings.push_back(s);
|
||||
}
|
||||
sdr->mutex->unlock();
|
||||
}
|
||||
@ -413,6 +647,11 @@ void ScriptDebuggerRemote::set_request_scene_tree_message_func(RequestSceneTreeM
|
||||
request_scene_tree_ud=p_udata;
|
||||
}
|
||||
|
||||
void ScriptDebuggerRemote::set_live_edit_funcs(LiveEditFuncs *p_funcs) {
|
||||
|
||||
live_edit_funcs=p_funcs;
|
||||
}
|
||||
|
||||
ScriptDebuggerRemote::ScriptDebuggerRemote() {
|
||||
|
||||
tcp_client = StreamPeerTCP::create_ref();
|
||||
@ -429,13 +668,22 @@ ScriptDebuggerRemote::ScriptDebuggerRemote() {
|
||||
last_perf_time=0;
|
||||
poll_every=0;
|
||||
request_scene_tree=NULL;
|
||||
live_edit_funcs=NULL;
|
||||
max_cps = GLOBAL_DEF("debug/max_remote_stdout_chars_per_second",2048);
|
||||
char_count=0;
|
||||
msec_count=0;
|
||||
last_msec=0;
|
||||
|
||||
eh.errfunc=_err_handler;
|
||||
eh.userdata=this;
|
||||
add_error_handler(&eh);
|
||||
|
||||
}
|
||||
|
||||
ScriptDebuggerRemote::~ScriptDebuggerRemote() {
|
||||
|
||||
remove_print_handler(&phl);
|
||||
remove_error_handler(&eh);
|
||||
memdelete(mutex);
|
||||
|
||||
|
||||
}
|
||||
|
@ -49,8 +49,31 @@ class ScriptDebuggerRemote : public ScriptDebugger {
|
||||
Object *performance;
|
||||
bool requested_quit;
|
||||
Mutex *mutex;
|
||||
|
||||
struct OutputError {
|
||||
|
||||
int hr;
|
||||
int min;
|
||||
int sec;
|
||||
int msec;
|
||||
String source_file;
|
||||
String source_func;
|
||||
int source_line;
|
||||
String error;
|
||||
String error_descr;
|
||||
bool warning;
|
||||
Array callstack;
|
||||
|
||||
};
|
||||
|
||||
List<String> output_strings;
|
||||
List<Message> messages;
|
||||
List<OutputError> errors;
|
||||
|
||||
int max_cps;
|
||||
int char_count;
|
||||
uint64_t last_msec;
|
||||
uint64_t msec_count;
|
||||
|
||||
bool locking; //hack to avoid a deadloop
|
||||
static void _print_handler(void *p_this,const String& p_string);
|
||||
@ -62,9 +85,16 @@ class ScriptDebuggerRemote : public ScriptDebugger {
|
||||
uint32_t poll_every;
|
||||
|
||||
|
||||
bool _parse_live_edit(const Array &p_command);
|
||||
|
||||
RequestSceneTreeMessageFunc request_scene_tree;
|
||||
void *request_scene_tree_ud;
|
||||
|
||||
LiveEditFuncs *live_edit_funcs;
|
||||
|
||||
ErrorHandlerList eh;
|
||||
static void _err_handler(void*,const char*,const char*,int p_line,const char *, const char *,ErrorHandlerType p_type);
|
||||
|
||||
|
||||
public:
|
||||
|
||||
@ -79,6 +109,7 @@ public:
|
||||
virtual void send_message(const String& p_message, const Array& p_args);
|
||||
|
||||
virtual void set_request_scene_tree_message_func(RequestSceneTreeMessageFunc p_func, void *p_udata);
|
||||
virtual void set_live_edit_funcs(LiveEditFuncs *p_funcs);
|
||||
|
||||
ScriptDebuggerRemote();
|
||||
~ScriptDebuggerRemote();
|
||||
|
@ -176,6 +176,13 @@ public:
|
||||
virtual void debug_get_globals(List<String> *p_locals, List<Variant> *p_values, int p_max_subitems=-1,int p_max_depth=-1)=0;
|
||||
virtual String debug_parse_stack_level_expression(int p_level,const String& p_expression,int p_max_subitems=-1,int p_max_depth=-1)=0;
|
||||
|
||||
struct StackInfo {
|
||||
Ref<Script> script;
|
||||
int line;
|
||||
};
|
||||
|
||||
virtual Vector<StackInfo> debug_get_current_stack_info() { return Vector<StackInfo>(); }
|
||||
|
||||
/* LOADER FUNCTIONS */
|
||||
|
||||
virtual void get_recognized_extensions(List<String> *p_extensions) const=0;
|
||||
@ -238,6 +245,32 @@ public:
|
||||
|
||||
typedef void (*RequestSceneTreeMessageFunc)(void *);
|
||||
|
||||
struct LiveEditFuncs {
|
||||
|
||||
void *udata;
|
||||
void (*node_path_func)(void *,const NodePath &p_path,int p_id);
|
||||
void (*res_path_func)(void *,const String &p_path,int p_id);
|
||||
|
||||
void (*node_set_func)(void *,int p_id,const StringName& p_prop,const Variant& p_value);
|
||||
void (*node_set_res_func)(void *,int p_id,const StringName& p_prop,const String& p_value);
|
||||
void (*node_call_func)(void *,int p_id,const StringName& p_method,VARIANT_ARG_DECLARE);
|
||||
void (*res_set_func)(void *,int p_id,const StringName& p_prop,const Variant& p_value);
|
||||
void (*res_set_res_func)(void *,int p_id,const StringName& p_prop,const String& p_value);
|
||||
void (*res_call_func)(void *,int p_id,const StringName& p_method,VARIANT_ARG_DECLARE);
|
||||
void (*root_func)(void*, const NodePath& p_scene_path,const String& p_scene_from);
|
||||
|
||||
void (*tree_create_node_func)(void*,const NodePath& p_parent,const String& p_type,const String& p_name);
|
||||
void (*tree_instance_node_func)(void*,const NodePath& p_parent,const String& p_path,const String& p_name);
|
||||
void (*tree_remove_node_func)(void*,const NodePath& p_at);
|
||||
void (*tree_remove_and_keep_node_func)(void*,const NodePath& p_at,ObjectID p_keep_id);
|
||||
void (*tree_restore_node_func)(void*,ObjectID p_id,const NodePath& p_at,int p_at_pos);
|
||||
void (*tree_duplicate_node_func)(void*,const NodePath& p_at,const String& p_new_name);
|
||||
void (*tree_reparent_node_func)(void*,const NodePath& p_at,const NodePath& p_new_place,const String& p_new_name,int p_at_pos);
|
||||
|
||||
};
|
||||
|
||||
|
||||
|
||||
_FORCE_INLINE_ static ScriptDebugger * get_singleton() { return singleton; }
|
||||
void set_lines_left(int p_left);
|
||||
int get_lines_left() const;
|
||||
@ -252,10 +285,12 @@ public:
|
||||
bool is_breakpoint_line(int p_line) const;
|
||||
void clear_breakpoints();
|
||||
|
||||
|
||||
virtual void debug(ScriptLanguage *p_script,bool p_can_continue=true)=0;
|
||||
virtual void idle_poll();
|
||||
virtual void line_poll();
|
||||
|
||||
|
||||
void set_break_language(ScriptLanguage *p_lang);
|
||||
ScriptLanguage* get_break_language() const;
|
||||
|
||||
@ -265,6 +300,7 @@ public:
|
||||
virtual void request_quit() {}
|
||||
|
||||
virtual void set_request_scene_tree_message_func(RequestSceneTreeMessageFunc p_func, void *p_udata) {}
|
||||
virtual void set_live_edit_funcs(LiveEditFuncs *p_funcs) {}
|
||||
|
||||
ScriptDebugger();
|
||||
virtual ~ScriptDebugger() {singleton=NULL;}
|
||||
|
@ -158,7 +158,7 @@ void StringName::operator=(const StringName& p_name) {
|
||||
_data = p_name._data;
|
||||
}
|
||||
}
|
||||
|
||||
/* was inlined
|
||||
StringName::operator String() const {
|
||||
|
||||
if (_data)
|
||||
@ -166,7 +166,7 @@ StringName::operator String() const {
|
||||
|
||||
return "";
|
||||
}
|
||||
|
||||
*/
|
||||
StringName::StringName(const StringName& p_name) {
|
||||
|
||||
ERR_FAIL_COND(!configured);
|
||||
|
@ -114,7 +114,17 @@ public:
|
||||
}
|
||||
bool operator!=(const StringName& p_name) const;
|
||||
|
||||
operator String() const;
|
||||
_FORCE_INLINE_ operator String() const {
|
||||
|
||||
if (_data) {
|
||||
if (_data->cname )
|
||||
return String(_data->cname);
|
||||
else
|
||||
return _data->name;
|
||||
}
|
||||
|
||||
return String();
|
||||
}
|
||||
|
||||
static StringName search(const char *p_name);
|
||||
static StringName search(const CharType *p_name);
|
||||
|
@ -244,7 +244,12 @@ void UndoRedo::_process_operation_list(List<Operation>::Element *E) {
|
||||
Resource* res = obj->cast_to<Resource>();
|
||||
if (res)
|
||||
res->set_edited(true);
|
||||
|
||||
#endif
|
||||
|
||||
if (method_callback) {
|
||||
method_callback(method_callbck_ud,obj,op.name,VARIANT_ARGS_FROM_ARRAY(op.args));
|
||||
}
|
||||
} break;
|
||||
case Operation::TYPE_PROPERTY: {
|
||||
|
||||
@ -254,6 +259,9 @@ void UndoRedo::_process_operation_list(List<Operation>::Element *E) {
|
||||
if (res)
|
||||
res->set_edited(true);
|
||||
#endif
|
||||
if (property_callback) {
|
||||
property_callback(prop_callback_ud,obj,op.name,op.args[0]);
|
||||
}
|
||||
} break;
|
||||
case Operation::TYPE_REFERENCE: {
|
||||
//do nothing
|
||||
@ -325,6 +333,19 @@ void UndoRedo::set_commit_notify_callback(CommitNotifyCallback p_callback,void*
|
||||
callback_ud=p_ud;
|
||||
}
|
||||
|
||||
void UndoRedo::set_method_notify_callback(MethodNotifyCallback p_method_callback,void* p_ud) {
|
||||
|
||||
method_callback=p_method_callback;
|
||||
method_callbck_ud=p_ud;
|
||||
}
|
||||
|
||||
void UndoRedo::set_property_notify_callback(PropertyNotifyCallback p_property_callback,void* p_ud){
|
||||
|
||||
property_callback=p_property_callback;
|
||||
prop_callback_ud=p_ud;
|
||||
}
|
||||
|
||||
|
||||
UndoRedo::UndoRedo() {
|
||||
|
||||
version=1;
|
||||
@ -334,6 +355,12 @@ UndoRedo::UndoRedo() {
|
||||
merging=true;
|
||||
callback=NULL;
|
||||
callback_ud=NULL;
|
||||
|
||||
method_callbck_ud=NULL;
|
||||
prop_callback_ud=NULL;
|
||||
method_callback=NULL;
|
||||
property_callback=NULL;
|
||||
|
||||
}
|
||||
|
||||
UndoRedo::~UndoRedo() {
|
||||
|
@ -45,6 +45,9 @@ public:
|
||||
Variant _add_do_method(const Variant** p_args, int p_argcount, Variant::CallError& r_error);
|
||||
Variant _add_undo_method(const Variant** p_args, int p_argcount, Variant::CallError& r_error);
|
||||
|
||||
typedef void (*MethodNotifyCallback)(void *p_ud,Object*p_base,const StringName& p_name,VARIANT_ARG_DECLARE);
|
||||
typedef void (*PropertyNotifyCallback)(void *p_ud,Object*p_base,const StringName& p_property,const Variant& p_value);
|
||||
|
||||
private:
|
||||
struct Operation {
|
||||
|
||||
@ -83,6 +86,11 @@ private:
|
||||
|
||||
CommitNotifyCallback callback;
|
||||
void* callback_ud;
|
||||
void* method_callbck_ud;
|
||||
void* prop_callback_ud;
|
||||
|
||||
MethodNotifyCallback method_callback;
|
||||
PropertyNotifyCallback property_callback;
|
||||
|
||||
|
||||
protected:
|
||||
@ -113,6 +121,9 @@ public:
|
||||
|
||||
void set_commit_notify_callback(CommitNotifyCallback p_callback,void* p_ud);
|
||||
|
||||
void set_method_notify_callback(MethodNotifyCallback p_method_callback,void* p_ud);
|
||||
void set_property_notify_callback(PropertyNotifyCallback p_property_callback,void* p_ud);
|
||||
|
||||
UndoRedo();
|
||||
~UndoRedo();
|
||||
};
|
||||
|
@ -67,11 +67,14 @@ void String::copy_from(const char *p_cstr) {
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
resize(len+1); // include 0
|
||||
|
||||
for(int i=0;i<len+1;i++) {
|
||||
|
||||
set(i,p_cstr[i]);
|
||||
CharType *dst = this->ptr();
|
||||
|
||||
for (int i=0;i<len+1;i++) {
|
||||
|
||||
dst[i]=p_cstr[i];
|
||||
}
|
||||
|
||||
}
|
||||
@ -486,7 +489,7 @@ String String::capitalize() const {
|
||||
String cap;
|
||||
for (int i=0;i<aux.get_slice_count(" ");i++) {
|
||||
|
||||
String slice=aux.get_slice(" ",i);
|
||||
String slice=aux.get_slicec(' ',i);
|
||||
if (slice.length()>0) {
|
||||
|
||||
slice[0]=_find_upper(slice[0]);
|
||||
@ -577,6 +580,41 @@ String String::get_slice(String p_splitter, int p_slice) const {
|
||||
|
||||
}
|
||||
|
||||
String String::get_slicec(CharType p_splitter, int p_slice) const {
|
||||
|
||||
if (empty())
|
||||
return String();
|
||||
|
||||
if (p_slice<0)
|
||||
return String();
|
||||
|
||||
const CharType *c=this->ptr();
|
||||
int i=0;
|
||||
int prev=0;
|
||||
int count=0;
|
||||
while(true) {
|
||||
|
||||
|
||||
if (c[i]==0 || c[i]==p_splitter) {
|
||||
|
||||
if (p_slice==count) {
|
||||
|
||||
return substr(prev,i-prev);
|
||||
} else {
|
||||
count++;
|
||||
prev=i+1;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
i++;
|
||||
|
||||
}
|
||||
|
||||
return String(); //no find!
|
||||
|
||||
}
|
||||
|
||||
|
||||
Vector<String> String::split_spaces() const {
|
||||
|
||||
@ -3333,8 +3371,8 @@ String String::path_to(const String& p_path) const {
|
||||
//nothing
|
||||
} else {
|
||||
//dos style
|
||||
String src_begin=src.get_slice("/",0);
|
||||
String dst_begin=dst.get_slice("/",0);
|
||||
String src_begin=src.get_slicec('/',0);
|
||||
String dst_begin=dst.get_slicec('/',0);
|
||||
|
||||
if (src_begin!=dst_begin)
|
||||
return p_path; //impossible to do this
|
||||
|
@ -153,6 +153,7 @@ public:
|
||||
|
||||
int get_slice_count(String p_splitter) const;
|
||||
String get_slice(String p_splitter,int p_slice) const;
|
||||
String get_slicec(CharType splitter,int p_slice) const;
|
||||
|
||||
Vector<String> split(const String &p_splitter,bool p_allow_empty=true) const;
|
||||
Vector<String> split_spaces() const;
|
||||
|
@ -878,6 +878,63 @@ bool Variant::is_zero() const {
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
bool Variant::is_one() const {
|
||||
|
||||
switch( type ) {
|
||||
case NIL: {
|
||||
|
||||
return true;
|
||||
} break;
|
||||
|
||||
// atomic types
|
||||
case BOOL: {
|
||||
|
||||
return _data._bool==true;
|
||||
} break;
|
||||
case INT: {
|
||||
|
||||
return _data._int==1;
|
||||
|
||||
} break;
|
||||
case REAL: {
|
||||
|
||||
return _data._real==1;
|
||||
|
||||
} break;
|
||||
case VECTOR2: {
|
||||
|
||||
return *reinterpret_cast<const Vector2*>(_data._mem)==Vector2(1,1);
|
||||
|
||||
} break;
|
||||
case RECT2: {
|
||||
|
||||
return *reinterpret_cast<const Rect2*>(_data._mem)==Rect2(1,1,1,1);
|
||||
|
||||
} break;
|
||||
case VECTOR3: {
|
||||
|
||||
return *reinterpret_cast<const Vector3*>(_data._mem)==Vector3(1,1,1);
|
||||
|
||||
} break;
|
||||
case PLANE: {
|
||||
|
||||
return *reinterpret_cast<const Plane*>(_data._mem)==Plane(1,1,1,1);
|
||||
|
||||
} break;
|
||||
case COLOR: {
|
||||
|
||||
return *reinterpret_cast<const Color*>(_data._mem)==Color(1,1,1,1);
|
||||
|
||||
} break;
|
||||
|
||||
default: { return !is_zero(); }
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
void Variant::reference(const Variant& p_variant) {
|
||||
|
||||
|
||||
|
@ -185,6 +185,7 @@ public:
|
||||
_FORCE_INLINE_ bool is_array() const { return type>=ARRAY; };
|
||||
bool is_shared() const;
|
||||
bool is_zero() const;
|
||||
bool is_one() const;
|
||||
|
||||
operator bool() const;
|
||||
operator signed int() const;
|
||||
|
@ -340,12 +340,14 @@ template<class T>
|
||||
void Vector<T>::remove(int p_index) {
|
||||
|
||||
ERR_FAIL_INDEX(p_index, size());
|
||||
for (int i=p_index; i<size()-1; i++) {
|
||||
T*p=ptr();
|
||||
int len=size();
|
||||
for (int i=p_index; i<len-1; i++) {
|
||||
|
||||
set(i, get(i+1));
|
||||
p[i]=p[i+1];
|
||||
};
|
||||
|
||||
resize(size()-1);
|
||||
resize(len-1);
|
||||
};
|
||||
|
||||
template<class T>
|
||||
|
@ -1,15 +1,15 @@
|
||||
<?xml version="1.0" encoding="UTF-8" ?>
|
||||
<resource_file type="PackedScene" subresource_count="24" version="1.0" version_name="Godot Engine v1.0.rc2.custom_build">
|
||||
<ext_resource path="res://osb_jump.png" type="Texture"></ext_resource>
|
||||
<resource_file type="PackedScene" subresource_count="25" version="1.1" version_name="Godot Engine v1.1.stable.custom_build">
|
||||
<ext_resource path="res://player.gd" type="Script"></ext_resource>
|
||||
<ext_resource path="res://robot_demo.png" type="Texture"></ext_resource>
|
||||
<ext_resource path="res://bullet.png" type="Texture"></ext_resource>
|
||||
<ext_resource path="res://osb_right.png" type="Texture"></ext_resource>
|
||||
<ext_resource path="res://sound_coin.wav" type="Sample"></ext_resource>
|
||||
<ext_resource path="res://osb_fire.png" type="Texture"></ext_resource>
|
||||
<ext_resource path="res://sound_jump.wav" type="Sample"></ext_resource>
|
||||
<ext_resource path="res://sound_shoot.wav" type="Sample"></ext_resource>
|
||||
<ext_resource path="res://osb_left.png" type="Texture"></ext_resource>
|
||||
<ext_resource path="res://robot_demo.png" type="Texture"></ext_resource>
|
||||
<ext_resource path="res://player.gd" type="Script"></ext_resource>
|
||||
<ext_resource path="res://sound_jump.wav" type="Sample"></ext_resource>
|
||||
<ext_resource path="res://osb_right.png" type="Texture"></ext_resource>
|
||||
<ext_resource path="res://osb_jump.png" type="Texture"></ext_resource>
|
||||
<ext_resource path="res://osb_fire.png" type="Texture"></ext_resource>
|
||||
<resource type="RayShape2D" path="local://1">
|
||||
<real name="custom_solver_bias"> 0.5 </real>
|
||||
<real name="length"> 20 </real>
|
||||
@ -19,6 +19,11 @@
|
||||
<real name="custom_solver_bias"> 0 </real>
|
||||
<vector2_array name="points" len="3"> -19.902, -24.8691, 19.3625, -24.6056, -0.138023, 16.5036 </vector2_array>
|
||||
|
||||
</resource>
|
||||
<resource type="ColorRamp" path="local://14">
|
||||
<real_array name="offsets" len="2"> 0, 1 </real_array>
|
||||
<color_array name="colors" len="2"> 1, 1, 1, 1, 0, 0, 0, 0.0442478 </color_array>
|
||||
|
||||
</resource>
|
||||
<resource type="Animation" path="local://3">
|
||||
<string name="resource/name"> "idle" </string>
|
||||
@ -31,6 +36,8 @@
|
||||
<dictionary name="tracks/0/keys" shared="false">
|
||||
<string> "cont" </string>
|
||||
<bool> False </bool>
|
||||
<string> "times" </string>
|
||||
<real_array len="8"> 0, 1.25, 1.5, 2, 4.5, 4.75, 5, 5.25 </real_array>
|
||||
<string> "transitions" </string>
|
||||
<real_array len="8"> 1, 1, 1, 1, 1, 1, 1, 1 </real_array>
|
||||
<string> "values" </string>
|
||||
@ -44,8 +51,6 @@
|
||||
<int> 19 </int>
|
||||
<int> 16 </int>
|
||||
</array>
|
||||
<string> "times" </string>
|
||||
<real_array len="8"> 0, 1.25, 1.5, 2, 4.5, 4.75, 5, 5.25 </real_array>
|
||||
</dictionary>
|
||||
|
||||
</resource>
|
||||
@ -60,6 +65,8 @@
|
||||
<dictionary name="tracks/0/keys" shared="false">
|
||||
<string> "cont" </string>
|
||||
<bool> False </bool>
|
||||
<string> "times" </string>
|
||||
<real_array len="3"> 0, 0.25, 0.5 </real_array>
|
||||
<string> "transitions" </string>
|
||||
<real_array len="3"> 1, 1, 1 </real_array>
|
||||
<string> "values" </string>
|
||||
@ -68,8 +75,6 @@
|
||||
<int> 24 </int>
|
||||
<int> 23 </int>
|
||||
</array>
|
||||
<string> "times" </string>
|
||||
<real_array len="3"> 0, 0.25, 0.5 </real_array>
|
||||
</dictionary>
|
||||
|
||||
</resource>
|
||||
@ -84,14 +89,14 @@
|
||||
<dictionary name="tracks/0/keys" shared="false">
|
||||
<string> "cont" </string>
|
||||
<bool> False </bool>
|
||||
<string> "times" </string>
|
||||
<real_array len="1"> 0 </real_array>
|
||||
<string> "transitions" </string>
|
||||
<real_array len="1"> 1 </real_array>
|
||||
<string> "values" </string>
|
||||
<array len="1" shared="false">
|
||||
<int> 25 </int>
|
||||
</array>
|
||||
<string> "times" </string>
|
||||
<real_array len="1"> 0 </real_array>
|
||||
</dictionary>
|
||||
|
||||
</resource>
|
||||
@ -105,6 +110,8 @@
|
||||
<dictionary name="tracks/0/keys" shared="false">
|
||||
<string> "cont" </string>
|
||||
<bool> False </bool>
|
||||
<string> "times" </string>
|
||||
<real_array len="6"> 0, 0.25, 0.5, 0.75, 1, 1.25 </real_array>
|
||||
<string> "transitions" </string>
|
||||
<real_array len="6"> 1, 1, 1, 1, 1, 1 </real_array>
|
||||
<string> "values" </string>
|
||||
@ -116,56 +123,10 @@
|
||||
<int> 4 </int>
|
||||
<int> 0 </int>
|
||||
</array>
|
||||
<string> "times" </string>
|
||||
<real_array len="6"> 0, 0.25, 0.5, 0.75, 1, 1.25 </real_array>
|
||||
</dictionary>
|
||||
|
||||
</resource>
|
||||
<resource type="Animation" path="local://7">
|
||||
<string name="resource/name"> "crouch" </string>
|
||||
<real name="length"> 0.01 </real>
|
||||
<bool name="loop"> True </bool>
|
||||
<real name="step"> 0.25 </real>
|
||||
<string name="tracks/0/type"> "value" </string>
|
||||
<node_path name="tracks/0/path"> "sprite:frame" </node_path>
|
||||
<int name="tracks/0/interp"> 1 </int>
|
||||
<dictionary name="tracks/0/keys" shared="false">
|
||||
<string> "cont" </string>
|
||||
<bool> False </bool>
|
||||
<string> "transitions" </string>
|
||||
<real_array len="1"> 1 </real_array>
|
||||
<string> "values" </string>
|
||||
<array len="1" shared="false">
|
||||
<int> 22 </int>
|
||||
</array>
|
||||
<string> "times" </string>
|
||||
<real_array len="1"> 0 </real_array>
|
||||
</dictionary>
|
||||
|
||||
</resource>
|
||||
<resource type="Animation" path="local://8">
|
||||
<string name="resource/name"> "falling" </string>
|
||||
<real name="length"> 0.01 </real>
|
||||
<bool name="loop"> True </bool>
|
||||
<real name="step"> 0.25 </real>
|
||||
<string name="tracks/0/type"> "value" </string>
|
||||
<node_path name="tracks/0/path"> "sprite:frame" </node_path>
|
||||
<int name="tracks/0/interp"> 1 </int>
|
||||
<dictionary name="tracks/0/keys" shared="false">
|
||||
<string> "cont" </string>
|
||||
<bool> False </bool>
|
||||
<string> "transitions" </string>
|
||||
<real_array len="1"> 1 </real_array>
|
||||
<string> "values" </string>
|
||||
<array len="1" shared="false">
|
||||
<int> 21 </int>
|
||||
</array>
|
||||
<string> "times" </string>
|
||||
<real_array len="1"> 0 </real_array>
|
||||
</dictionary>
|
||||
|
||||
</resource>
|
||||
<resource type="Animation" path="local://9">
|
||||
<resource type="Animation" path="local://11">
|
||||
<real name="length"> 1.25 </real>
|
||||
<bool name="loop"> True </bool>
|
||||
<real name="step"> 0.25 </real>
|
||||
@ -175,19 +136,19 @@
|
||||
<dictionary name="tracks/0/keys" shared="false">
|
||||
<string> "cont" </string>
|
||||
<bool> False </bool>
|
||||
<string> "times" </string>
|
||||
<real_array len="6"> 0, 0.25, 0.5, 0.75, 1, 1.25 </real_array>
|
||||
<string> "transitions" </string>
|
||||
<real_array len="6"> 1, 1, 1, 1, 1, 1 </real_array>
|
||||
<string> "values" </string>
|
||||
<array len="6" shared="false">
|
||||
<int> 10 </int>
|
||||
<int> 11 </int>
|
||||
<int> 12 </int>
|
||||
<int> 13 </int>
|
||||
<int> 14 </int>
|
||||
<int> 5 </int>
|
||||
<int> 6 </int>
|
||||
<int> 7 </int>
|
||||
<int> 8 </int>
|
||||
<int> 9 </int>
|
||||
<int> 5 </int>
|
||||
</array>
|
||||
<string> "times" </string>
|
||||
<real_array len="6"> 0, 0.25, 0.5, 0.75, 1, 1.25 </real_array>
|
||||
</dictionary>
|
||||
|
||||
</resource>
|
||||
@ -202,18 +163,62 @@
|
||||
<dictionary name="tracks/0/keys" shared="false">
|
||||
<string> "cont" </string>
|
||||
<bool> False </bool>
|
||||
<string> "times" </string>
|
||||
<real_array len="1"> 0 </real_array>
|
||||
<string> "transitions" </string>
|
||||
<real_array len="1"> 1 </real_array>
|
||||
<string> "values" </string>
|
||||
<array len="1" shared="false">
|
||||
<int> 26 </int>
|
||||
</array>
|
||||
<string> "times" </string>
|
||||
<real_array len="1"> 0 </real_array>
|
||||
</dictionary>
|
||||
|
||||
</resource>
|
||||
<resource type="Animation" path="local://11">
|
||||
<resource type="Animation" path="local://7">
|
||||
<string name="resource/name"> "crouch" </string>
|
||||
<real name="length"> 0.01 </real>
|
||||
<bool name="loop"> True </bool>
|
||||
<real name="step"> 0.25 </real>
|
||||
<string name="tracks/0/type"> "value" </string>
|
||||
<node_path name="tracks/0/path"> "sprite:frame" </node_path>
|
||||
<int name="tracks/0/interp"> 1 </int>
|
||||
<dictionary name="tracks/0/keys" shared="false">
|
||||
<string> "cont" </string>
|
||||
<bool> False </bool>
|
||||
<string> "times" </string>
|
||||
<real_array len="1"> 0 </real_array>
|
||||
<string> "transitions" </string>
|
||||
<real_array len="1"> 1 </real_array>
|
||||
<string> "values" </string>
|
||||
<array len="1" shared="false">
|
||||
<int> 22 </int>
|
||||
</array>
|
||||
</dictionary>
|
||||
|
||||
</resource>
|
||||
<resource type="Animation" path="local://8">
|
||||
<string name="resource/name"> "falling" </string>
|
||||
<real name="length"> 0.01 </real>
|
||||
<bool name="loop"> True </bool>
|
||||
<real name="step"> 0.25 </real>
|
||||
<string name="tracks/0/type"> "value" </string>
|
||||
<node_path name="tracks/0/path"> "sprite:frame" </node_path>
|
||||
<int name="tracks/0/interp"> 1 </int>
|
||||
<dictionary name="tracks/0/keys" shared="false">
|
||||
<string> "cont" </string>
|
||||
<bool> False </bool>
|
||||
<string> "times" </string>
|
||||
<real_array len="1"> 0 </real_array>
|
||||
<string> "transitions" </string>
|
||||
<real_array len="1"> 1 </real_array>
|
||||
<string> "values" </string>
|
||||
<array len="1" shared="false">
|
||||
<int> 21 </int>
|
||||
</array>
|
||||
</dictionary>
|
||||
|
||||
</resource>
|
||||
<resource type="Animation" path="local://9">
|
||||
<real name="length"> 1.25 </real>
|
||||
<bool name="loop"> True </bool>
|
||||
<real name="step"> 0.25 </real>
|
||||
@ -223,19 +228,19 @@
|
||||
<dictionary name="tracks/0/keys" shared="false">
|
||||
<string> "cont" </string>
|
||||
<bool> False </bool>
|
||||
<string> "times" </string>
|
||||
<real_array len="6"> 0, 0.25, 0.5, 0.75, 1, 1.25 </real_array>
|
||||
<string> "transitions" </string>
|
||||
<real_array len="6"> 1, 1, 1, 1, 1, 1 </real_array>
|
||||
<string> "values" </string>
|
||||
<array len="6" shared="false">
|
||||
<int> 5 </int>
|
||||
<int> 6 </int>
|
||||
<int> 7 </int>
|
||||
<int> 8 </int>
|
||||
<int> 9 </int>
|
||||
<int> 10 </int>
|
||||
<int> 11 </int>
|
||||
<int> 12 </int>
|
||||
<int> 13 </int>
|
||||
<int> 14 </int>
|
||||
<int> 5 </int>
|
||||
</array>
|
||||
<string> "times" </string>
|
||||
<real_array len="6"> 0, 0.25, 0.5, 0.75, 1, 1.25 </real_array>
|
||||
</dictionary>
|
||||
|
||||
</resource>
|
||||
@ -249,14 +254,14 @@
|
||||
<dictionary name="tracks/0/keys" shared="false">
|
||||
<string> "cont" </string>
|
||||
<bool> False </bool>
|
||||
<string> "times" </string>
|
||||
<real_array len="1"> 0 </real_array>
|
||||
<string> "transitions" </string>
|
||||
<real_array len="1"> 1 </real_array>
|
||||
<string> "values" </string>
|
||||
<array len="1" shared="false">
|
||||
<int> 26 </int>
|
||||
</array>
|
||||
<string> "times" </string>
|
||||
<real_array len="1"> 0 </real_array>
|
||||
</dictionary>
|
||||
|
||||
</resource>
|
||||
@ -289,30 +294,28 @@
|
||||
</resource>
|
||||
<main_resource>
|
||||
<dictionary name="_bundled" shared="false">
|
||||
<string> "conn_count" </string>
|
||||
<int> 0 </int>
|
||||
<string> "conns" </string>
|
||||
<int_array len="0"> </int_array>
|
||||
<string> "names" </string>
|
||||
<string_array len="180">
|
||||
<string_array len="142">
|
||||
<string> "player" </string>
|
||||
<string> "RigidBody2D" </string>
|
||||
<string> "_import_path" </string>
|
||||
<string> "visibility/visible" </string>
|
||||
<string> "visibility/opacity" </string>
|
||||
<string> "visibility/self_opacity" </string>
|
||||
<string> "visibility/behind_parent" </string>
|
||||
<string> "transform/pos" </string>
|
||||
<string> "transform/rot" </string>
|
||||
<string> "transform/scale" </string>
|
||||
<string> "shape_count" </string>
|
||||
<string> "input/pickable" </string>
|
||||
<string> "shapes/0/shape" </string>
|
||||
<string> "shapes/0/transform" </string>
|
||||
<string> "shapes/0/trigger" </string>
|
||||
<string> "shapes/1/shape" </string>
|
||||
<string> "shapes/1/transform" </string>
|
||||
<string> "shapes/1/trigger" </string>
|
||||
<string> "layers" </string>
|
||||
<string> "collision/layers" </string>
|
||||
<string> "collision/mask" </string>
|
||||
<string> "mode" </string>
|
||||
<string> "mass" </string>
|
||||
<string> "friction" </string>
|
||||
<string> "bounce" </string>
|
||||
<string> "gravity_scale" </string>
|
||||
<string> "custom_integrator" </string>
|
||||
<string> "continuous_cd" </string>
|
||||
<string> "contacts_reported" </string>
|
||||
@ -321,39 +324,28 @@
|
||||
<string> "can_sleep" </string>
|
||||
<string> "velocity/linear" </string>
|
||||
<string> "velocity/angular" </string>
|
||||
<string> "damp_override/linear" </string>
|
||||
<string> "damp_override/angular" </string>
|
||||
<string> "script/script" </string>
|
||||
<string> "__meta__" </string>
|
||||
<string> "sprite" </string>
|
||||
<string> "Sprite" </string>
|
||||
<string> "texture" </string>
|
||||
<string> "centered" </string>
|
||||
<string> "offset" </string>
|
||||
<string> "flip_h" </string>
|
||||
<string> "flip_v" </string>
|
||||
<string> "vframes" </string>
|
||||
<string> "hframes" </string>
|
||||
<string> "frame" </string>
|
||||
<string> "modulate" </string>
|
||||
<string> "region" </string>
|
||||
<string> "region_rect" </string>
|
||||
<string> "smoke" </string>
|
||||
<string> "Particles2D" </string>
|
||||
<string> "visibility/self_opacity" </string>
|
||||
<string> "visibility/blend_mode" </string>
|
||||
<string> "transform/pos" </string>
|
||||
<string> "transform/rot" </string>
|
||||
<string> "config/amount" </string>
|
||||
<string> "config/lifetime" </string>
|
||||
<string> "config/time_scale" </string>
|
||||
<string> "config/preprocess" </string>
|
||||
<string> "config/emit_timeout" </string>
|
||||
<string> "config/emitting" </string>
|
||||
<string> "config/offset" </string>
|
||||
<string> "config/half_extents" </string>
|
||||
<string> "config/local_space" </string>
|
||||
<string> "config/explosiveness" </string>
|
||||
<string> "config/flip_h" </string>
|
||||
<string> "config/flip_v" </string>
|
||||
<string> "config/texture" </string>
|
||||
<string> "config/h_frames" </string>
|
||||
<string> "config/v_frames" </string>
|
||||
<string> "params/direction" </string>
|
||||
<string> "params/spread" </string>
|
||||
<string> "params/linear_velocity" </string>
|
||||
@ -370,32 +362,8 @@
|
||||
<string> "params/hue_variation" </string>
|
||||
<string> "params/anim_speed_scale" </string>
|
||||
<string> "params/anim_initial_pos" </string>
|
||||
<string> "randomness/direction" </string>
|
||||
<string> "randomness/spread" </string>
|
||||
<string> "randomness/linear_velocity" </string>
|
||||
<string> "randomness/spin_velocity" </string>
|
||||
<string> "randomness/orbit_velocity" </string>
|
||||
<string> "randomness/gravity_direction" </string>
|
||||
<string> "randomness/gravity_strength" </string>
|
||||
<string> "randomness/radial_accel" </string>
|
||||
<string> "randomness/tangential_accel" </string>
|
||||
<string> "randomness/damping" </string>
|
||||
<string> "randomness/initial_angle" </string>
|
||||
<string> "randomness/initial_size" </string>
|
||||
<string> "randomness/final_size" </string>
|
||||
<string> "randomness/hue_variation" </string>
|
||||
<string> "randomness/anim_speed_scale" </string>
|
||||
<string> "randomness/anim_initial_pos" </string>
|
||||
<string> "color_phases/count" </string>
|
||||
<string> "phase_0/pos" </string>
|
||||
<string> "phase_0/color" </string>
|
||||
<string> "phase_1/pos" </string>
|
||||
<string> "phase_1/color" </string>
|
||||
<string> "phase_2/pos" </string>
|
||||
<string> "phase_2/color" </string>
|
||||
<string> "phase_3/pos" </string>
|
||||
<string> "phase_3/color" </string>
|
||||
<string> "emission_points" </string>
|
||||
<string> "color/color_ramp" </string>
|
||||
<string> "anim" </string>
|
||||
<string> "AnimationPlayer" </string>
|
||||
<string> "playback/process_mode" </string>
|
||||
@ -405,11 +373,11 @@
|
||||
<string> "anims/jumping" </string>
|
||||
<string> "anims/idle_weapon" </string>
|
||||
<string> "anims/run" </string>
|
||||
<string> "anims/run_weapon" </string>
|
||||
<string> "anims/falling_weapon" </string>
|
||||
<string> "anims/crouch" </string>
|
||||
<string> "anims/falling" </string>
|
||||
<string> "anims/standing_weapon_ready" </string>
|
||||
<string> "anims/falling_weapon" </string>
|
||||
<string> "anims/run_weapon" </string>
|
||||
<string> "anims/jumping_weapon" </string>
|
||||
<string> "playback/active" </string>
|
||||
<string> "playback/speed" </string>
|
||||
@ -417,6 +385,7 @@
|
||||
<string> "autoplay" </string>
|
||||
<string> "camera" </string>
|
||||
<string> "Camera2D" </string>
|
||||
<string> "anchor_mode" </string>
|
||||
<string> "rotating" </string>
|
||||
<string> "current" </string>
|
||||
<string> "smoothing" </string>
|
||||
@ -434,6 +403,7 @@
|
||||
<string> "bullet_shoot" </string>
|
||||
<string> "Position2D" </string>
|
||||
<string> "CollisionShape2D" </string>
|
||||
<string> "transform/scale" </string>
|
||||
<string> "shape" </string>
|
||||
<string> "trigger" </string>
|
||||
<string> "sound" </string>
|
||||
@ -458,6 +428,7 @@
|
||||
<string> "ui" </string>
|
||||
<string> "CanvasLayer" </string>
|
||||
<string> "layer" </string>
|
||||
<string> "offset" </string>
|
||||
<string> "rotation" </string>
|
||||
<string> "scale" </string>
|
||||
<string> "left" </string>
|
||||
@ -472,147 +443,149 @@
|
||||
<string> "jump" </string>
|
||||
<string> "fire" </string>
|
||||
</string_array>
|
||||
<string> "version" </string>
|
||||
<int> 1 </int>
|
||||
<string> "conn_count" </string>
|
||||
<int> 0 </int>
|
||||
<string> "node_count" </string>
|
||||
<int> 14 </int>
|
||||
<string> "nodes" </string>
|
||||
<int_array len="394"> -1, -1, 1, 0, -1, 26, 2, 0, 3, 1, 4, 2, 5, 0, 6, 3, 7, 4, 8, 0, 9, 5, 10, 5, 11, 6, 12, 7, 13, 8, 14, 8, 15, 9, 16, 10, 17, 11, 18, 12, 19, 0, 20, 0, 21, 10, 22, 13, 23, 8, 24, 14, 25, 14, 26, 15, 27, 16, 0, 0, 0, 29, 28, -1, 3, 30, 17, 31, 6, 32, 18, 0, 1, 0, 34, 33, -1, 29, 35, 19, 36, 5, 37, 20, 38, 21, 39, 22, 40, 23, 41, 23, 42, 0, 43, 0, 44, 24, 45, 25, 46, 8, 47, 26, 48, 27, 49, 9, 50, 8, 51, 8, 52, 28, 53, 8, 54, 8, 55, 8, 56, 8, 57, 29, 58, 29, 59, 8, 60, 9, 61, 8, 62, 29, 63, 30, 0, 0, 0, 65, 64, -1, 17, 66, 5, 67, 8, 68, 31, 69, 32, 70, 33, 71, 34, 72, 35, 73, 36, 74, 37, 75, 38, 76, 39, 77, 40, 78, 41, 79, 10, 80, 29, 81, 42, 82, 43, 0, 0, 0, 84, 83, -1, 15, 85, 5, 86, 0, 87, 10, 88, 8, 89, 44, 90, 11, 91, 11, 92, 45, 93, 45, 94, 10, 95, 10, 96, 46, 97, 46, 98, 46, 99, 46, 0, 0, 0, 101, 100, -1, 1, 37, 47, 0, 0, 0, 102, 102, -1, 4, 37, 48, 103, 49, 104, 1, 105, 0, 0, 0, 0, 107, 106, -1, 14, 108, 12, 109, 50, 110, 8, 111, 9, 112, 8, 113, 8, 114, 8, 115, 51, 116, 51, 117, 51, 118, 51, 119, 6, 120, 8, 121, 8, 0, 0, 0, 122, 122, -1, 3, 123, 11, 124, 52, 105, 0, 0, 0, 0, 126, 125, -1, 4, 127, 11, 128, 13, 129, 8, 130, 44, 0, 9, 0, 132, 131, -1, 8, 37, 53, 103, 54, 133, 55, 134, 56, 135, 56, 136, 10, 137, 57, 138, 5, 0, 9, 0, 132, 139, -1, 8, 37, 58, 103, 54, 133, 59, 134, 56, 135, 56, 136, 10, 137, 60, 138, 5, 0, 9, 0, 132, 140, -1, 8, 37, 61, 103, 54, 133, 62, 134, 56, 135, 56, 136, 0, 137, 63, 138, 5, 0, 9, 0, 132, 141, -1, 8, 37, 64, 103, 54, 133, 65, 134, 56, 135, 56, 136, 0, 137, 66, 138, 5, 0 </int_array>
|
||||
<string> "variants" </string>
|
||||
<array len="72" shared="false">
|
||||
<node_path> "" </node_path>
|
||||
<bool> True </bool>
|
||||
<real> 1 </real>
|
||||
<array len="67" shared="false">
|
||||
<bool> False </bool>
|
||||
<vector2> 0, 0 </vector2>
|
||||
<real> 0 </real>
|
||||
<vector2> 1, 1 </vector2>
|
||||
<int> 2 </int>
|
||||
<resource resource_type="Shape2D" path="local://1"> </resource>
|
||||
<matrix32> 1, -0, 0, 1.76469, 0.291992, -12.1587 </matrix32>
|
||||
<resource resource_type="Shape2D" path="local://2"> </resource>
|
||||
<matrix32> 1, -0, 0, 1, 0, 0 </matrix32>
|
||||
<int> 1 </int>
|
||||
<int> 2 </int>
|
||||
<real> 3 </real>
|
||||
<real> 0 </real>
|
||||
<real> 1 </real>
|
||||
<bool> True </bool>
|
||||
<int> 0 </int>
|
||||
<int> 3 </int>
|
||||
<vector2> 0, 0 </vector2>
|
||||
<real> -1 </real>
|
||||
<resource resource_type="Script" path="res://player.gd"> </resource>
|
||||
<dictionary shared="false">
|
||||
<string> "__editor_plugin_screen__" </string>
|
||||
<string> "2D" </string>
|
||||
<string> "__editor_plugin_states__" </string>
|
||||
<dictionary shared="false">
|
||||
<string> "Script" </string>
|
||||
<dictionary shared="false">
|
||||
<string> "current" </string>
|
||||
<int> 0 </int>
|
||||
<string> "sources" </string>
|
||||
<array len="1" shared="false">
|
||||
<string> "res://player.gd" </string>
|
||||
</array>
|
||||
</dictionary>
|
||||
<string> "2D" </string>
|
||||
<dictionary shared="false">
|
||||
<string> "pixel_snap" </string>
|
||||
<bool> False </bool>
|
||||
<string> "zoom" </string>
|
||||
<real> 2.272073 </real>
|
||||
<string> "use_snap" </string>
|
||||
<bool> False </bool>
|
||||
<string> "ofs" </string>
|
||||
<vector2> -181.946, -86.2812 </vector2>
|
||||
<string> "snap" </string>
|
||||
<int> 10 </int>
|
||||
<vector2> -110.795, -101.2 </vector2>
|
||||
<string> "snap_grid" </string>
|
||||
<bool> False </bool>
|
||||
<string> "snap_offset" </string>
|
||||
<vector2> 0, 0 </vector2>
|
||||
<string> "snap_pixel" </string>
|
||||
<bool> False </bool>
|
||||
<string> "snap_relative" </string>
|
||||
<bool> False </bool>
|
||||
<string> "snap_rotation" </string>
|
||||
<bool> False </bool>
|
||||
<string> "snap_rotation_offset" </string>
|
||||
<real> 0 </real>
|
||||
<string> "snap_rotation_step" </string>
|
||||
<real> 0.261799 </real>
|
||||
<string> "snap_show_grid" </string>
|
||||
<bool> False </bool>
|
||||
<string> "snap_step" </string>
|
||||
<vector2> 10, 10 </vector2>
|
||||
<string> "zoom" </string>
|
||||
<real> 2.050546 </real>
|
||||
</dictionary>
|
||||
<string> "3D" </string>
|
||||
<dictionary shared="false">
|
||||
<string> "ambient_light_color" </string>
|
||||
<color> 0.15, 0.15, 0.15, 1 </color>
|
||||
<string> "default_light" </string>
|
||||
<bool> True </bool>
|
||||
<string> "default_srgb" </string>
|
||||
<bool> False </bool>
|
||||
<string> "deflight_rot_x" </string>
|
||||
<real> 0.942478 </real>
|
||||
<string> "deflight_rot_y" </string>
|
||||
<real> 0.628319 </real>
|
||||
<string> "zfar" </string>
|
||||
<real> 500 </real>
|
||||
<string> "fov" </string>
|
||||
<real> 45 </real>
|
||||
<string> "show_grid" </string>
|
||||
<bool> True </bool>
|
||||
<string> "show_origin" </string>
|
||||
<bool> True </bool>
|
||||
<string> "viewport_mode" </string>
|
||||
<int> 1 </int>
|
||||
<string> "viewports" </string>
|
||||
<array len="4" shared="false">
|
||||
<dictionary shared="false">
|
||||
<string> "distance" </string>
|
||||
<real> 4 </real>
|
||||
<string> "x_rot" </string>
|
||||
<real> 0 </real>
|
||||
<string> "y_rot" </string>
|
||||
<real> 0 </real>
|
||||
<string> "listener" </string>
|
||||
<bool> True </bool>
|
||||
<string> "pos" </string>
|
||||
<vector3> 0, 0, 0 </vector3>
|
||||
<string> "use_environment" </string>
|
||||
<bool> False </bool>
|
||||
<string> "use_orthogonal" </string>
|
||||
<bool> False </bool>
|
||||
<string> "pos" </string>
|
||||
<vector3> 0, 0, 0 </vector3>
|
||||
</dictionary>
|
||||
<dictionary shared="false">
|
||||
<string> "distance" </string>
|
||||
<real> 4 </real>
|
||||
<string> "x_rot" </string>
|
||||
<real> 0 </real>
|
||||
<string> "y_rot" </string>
|
||||
<real> 0 </real>
|
||||
<string> "listener" </string>
|
||||
<bool> False </bool>
|
||||
<string> "use_environment" </string>
|
||||
<bool> False </bool>
|
||||
<string> "use_orthogonal" </string>
|
||||
<bool> False </bool>
|
||||
<string> "pos" </string>
|
||||
<vector3> 0, 0, 0 </vector3>
|
||||
</dictionary>
|
||||
<dictionary shared="false">
|
||||
<string> "distance" </string>
|
||||
<real> 4 </real>
|
||||
<string> "x_rot" </string>
|
||||
<real> 0 </real>
|
||||
<string> "y_rot" </string>
|
||||
<real> 0 </real>
|
||||
<string> "listener" </string>
|
||||
<bool> False </bool>
|
||||
<string> "pos" </string>
|
||||
<vector3> 0, 0, 0 </vector3>
|
||||
<string> "use_environment" </string>
|
||||
<bool> False </bool>
|
||||
<string> "use_orthogonal" </string>
|
||||
<bool> False </bool>
|
||||
<string> "pos" </string>
|
||||
<vector3> 0, 0, 0 </vector3>
|
||||
<string> "x_rot" </string>
|
||||
<real> 0 </real>
|
||||
<string> "y_rot" </string>
|
||||
<real> 0 </real>
|
||||
</dictionary>
|
||||
<dictionary shared="false">
|
||||
<string> "distance" </string>
|
||||
<real> 4 </real>
|
||||
<string> "x_rot" </string>
|
||||
<real> 0 </real>
|
||||
<string> "y_rot" </string>
|
||||
<real> 0 </real>
|
||||
<string> "listener" </string>
|
||||
<bool> False </bool>
|
||||
<string> "pos" </string>
|
||||
<vector3> 0, 0, 0 </vector3>
|
||||
<string> "use_environment" </string>
|
||||
<bool> False </bool>
|
||||
<string> "use_orthogonal" </string>
|
||||
<bool> False </bool>
|
||||
<string> "x_rot" </string>
|
||||
<real> 0 </real>
|
||||
<string> "y_rot" </string>
|
||||
<real> 0 </real>
|
||||
</dictionary>
|
||||
<dictionary shared="false">
|
||||
<string> "distance" </string>
|
||||
<real> 4 </real>
|
||||
<string> "listener" </string>
|
||||
<bool> False </bool>
|
||||
<string> "pos" </string>
|
||||
<vector3> 0, 0, 0 </vector3>
|
||||
<string> "use_environment" </string>
|
||||
<bool> False </bool>
|
||||
<string> "use_orthogonal" </string>
|
||||
<bool> False </bool>
|
||||
<string> "x_rot" </string>
|
||||
<real> 0 </real>
|
||||
<string> "y_rot" </string>
|
||||
<real> 0 </real>
|
||||
</dictionary>
|
||||
</array>
|
||||
<string> "viewport_mode" </string>
|
||||
<int> 1 </int>
|
||||
<string> "default_light" </string>
|
||||
<bool> True </bool>
|
||||
<string> "ambient_light_color" </string>
|
||||
<color> 0.15, 0.15, 0.15, 1 </color>
|
||||
<string> "show_grid" </string>
|
||||
<bool> True </bool>
|
||||
<string> "show_origin" </string>
|
||||
<bool> True </bool>
|
||||
<string> "zfar" </string>
|
||||
<real> 500 </real>
|
||||
<string> "znear" </string>
|
||||
<real> 0.1 </real>
|
||||
<string> "default_srgb" </string>
|
||||
<bool> False </bool>
|
||||
<string> "deflight_rot_x" </string>
|
||||
<real> 0.942478 </real>
|
||||
</dictionary>
|
||||
</dictionary>
|
||||
<string> "__editor_run_settings__" </string>
|
||||
@ -622,13 +595,9 @@
|
||||
<string> "run_mode" </string>
|
||||
<int> 0 </int>
|
||||
</dictionary>
|
||||
<string> "__editor_plugin_screen__" </string>
|
||||
<string> "Script" </string>
|
||||
</dictionary>
|
||||
<resource resource_type="Texture" path="res://robot_demo.png"> </resource>
|
||||
<int> 16 </int>
|
||||
<color> 1, 1, 1, 1 </color>
|
||||
<rect2> 0, 0, 0, 0 </rect2>
|
||||
<real> 0.363636 </real>
|
||||
<vector2> 20.7312, 3.21187 </vector2>
|
||||
<real> 83.450417 </real>
|
||||
@ -640,24 +609,22 @@
|
||||
<real> 20 </real>
|
||||
<real> 9.8 </real>
|
||||
<real> 2 </real>
|
||||
<color> 0, 0, 0, 0.0442478 </color>
|
||||
<color> 1, 0, 0, 1 </color>
|
||||
<color> 0, 0, 0, 1 </color>
|
||||
<vector2_array len="0"> </vector2_array>
|
||||
<resource resource_type="ColorRamp" path="local://14"> </resource>
|
||||
<node_path> ".." </node_path>
|
||||
<resource resource_type="Animation" path="local://3"> </resource>
|
||||
<resource resource_type="Animation" path="local://4"> </resource>
|
||||
<resource resource_type="Animation" path="local://5"> </resource>
|
||||
<resource resource_type="Animation" path="local://6"> </resource>
|
||||
<resource resource_type="Animation" path="local://11"> </resource>
|
||||
<resource resource_type="Animation" path="local://10"> </resource>
|
||||
<resource resource_type="Animation" path="local://7"> </resource>
|
||||
<resource resource_type="Animation" path="local://8"> </resource>
|
||||
<resource resource_type="Animation" path="local://9"> </resource>
|
||||
<resource resource_type="Animation" path="local://10"> </resource>
|
||||
<resource resource_type="Animation" path="local://11"> </resource>
|
||||
<resource resource_type="Animation" path="local://12"> </resource>
|
||||
<array len="0" shared="false">
|
||||
</array>
|
||||
<string> "" </string>
|
||||
<vector2> 1, 1 </vector2>
|
||||
<int> 10000000 </int>
|
||||
<real> 0.2 </real>
|
||||
<vector2> 31.2428, 4.08784 </vector2>
|
||||
@ -680,10 +647,8 @@
|
||||
<resource resource_type="Texture" path="res://osb_fire.png"> </resource>
|
||||
<string> "shoot" </string>
|
||||
</array>
|
||||
<string> "nodes" </string>
|
||||
<int_array len="618"> -1, -1, 1, 0, -1, 30, 2, 0, 3, 1, 4, 2, 5, 2, 6, 3, 7, 4, 8, 5, 9, 6, 10, 7, 11, 8, 12, 9, 13, 3, 14, 10, 15, 11, 16, 3, 17, 12, 18, 7, 19, 13, 20, 5, 21, 5, 22, 1, 23, 14, 24, 15, 25, 3, 26, 3, 27, 1, 28, 4, 29, 5, 30, 16, 31, 17, 0, 0, 0, 33, 32, -1, 19, 2, 0, 3, 1, 4, 2, 5, 2, 6, 3, 7, 4, 8, 5, 9, 6, 34, 18, 35, 1, 36, 4, 37, 3, 38, 3, 39, 7, 40, 19, 41, 14, 42, 20, 43, 3, 44, 21, 0, 1, 0, 46, 45, -1, 66, 2, 0, 3, 1, 4, 2, 5, 22, 6, 3, 47, 12, 7, 23, 8, 24, 9, 6, 48, 25, 49, 26, 50, 2, 51, 5, 52, 26, 53, 3, 54, 4, 55, 4, 56, 3, 57, 27, 58, 3, 59, 3, 60, 28, 61, 12, 62, 12, 63, 5, 64, 29, 65, 30, 66, 2, 67, 5, 68, 5, 69, 31, 70, 5, 71, 5, 72, 5, 73, 5, 74, 32, 75, 32, 76, 5, 77, 2, 78, 5, 79, 5, 80, 5, 81, 5, 82, 32, 83, 5, 84, 5, 85, 5, 86, 5, 87, 5, 88, 5, 89, 5, 90, 5, 91, 5, 92, 5, 93, 5, 94, 5, 95, 7, 96, 5, 97, 20, 98, 2, 99, 33, 100, 2, 101, 34, 102, 2, 103, 35, 104, 36, 0, 0, 0, 106, 105, -1, 18, 2, 0, 107, 12, 108, 5, 109, 37, 110, 38, 111, 39, 112, 40, 113, 41, 114, 42, 115, 43, 116, 44, 117, 45, 118, 46, 119, 47, 120, 1, 121, 32, 122, 48, 123, 49, 0, 0, 0, 125, 124, -1, 23, 2, 0, 3, 1, 4, 2, 5, 2, 6, 3, 7, 4, 8, 5, 9, 6, 35, 1, 126, 3, 127, 1, 128, 5, 129, 6, 130, 14, 131, 14, 132, 50, 133, 50, 134, 1, 135, 1, 136, 51, 137, 51, 138, 51, 139, 51, 0, 0, 0, 141, 140, -1, 8, 2, 0, 3, 1, 4, 2, 5, 2, 6, 3, 7, 52, 8, 5, 9, 6, 0, 0, 0, 142, 142, -1, 10, 2, 0, 3, 1, 4, 2, 5, 2, 6, 3, 7, 53, 8, 5, 9, 54, 143, 8, 144, 3, 0, 0, 0, 146, 145, -1, 15, 2, 0, 147, 15, 148, 55, 149, 5, 150, 2, 151, 5, 152, 5, 153, 5, 154, 56, 155, 56, 156, 56, 157, 56, 158, 7, 159, 5, 160, 5, 0, 0, 0, 161, 161, -1, 10, 2, 0, 3, 1, 4, 2, 5, 2, 6, 3, 7, 4, 8, 5, 9, 6, 162, 14, 163, 57, 0, 0, 0, 165, 164, -1, 5, 2, 0, 166, 14, 36, 4, 167, 5, 168, 6, 0, 9, 0, 170, 169, -1, 14, 2, 0, 3, 1, 4, 2, 5, 2, 6, 3, 7, 58, 8, 5, 9, 59, 171, 60, 172, 61, 173, 61, 174, 1, 175, 62, 176, 12, 0, 9, 0, 170, 177, -1, 14, 2, 0, 3, 1, 4, 2, 5, 2, 6, 3, 7, 63, 8, 5, 9, 59, 171, 64, 172, 61, 173, 61, 174, 1, 175, 65, 176, 12, 0, 9, 0, 170, 178, -1, 14, 2, 0, 3, 1, 4, 2, 5, 2, 6, 3, 7, 66, 8, 5, 9, 59, 171, 67, 172, 61, 173, 61, 174, 3, 175, 68, 176, 12, 0, 9, 0, 170, 179, -1, 14, 2, 0, 3, 1, 4, 2, 5, 2, 6, 3, 7, 69, 8, 5, 9, 59, 171, 70, 172, 61, 173, 61, 174, 3, 175, 71, 176, 12, 0 </int_array>
|
||||
<string> "conns" </string>
|
||||
<int_array len="0"> </int_array>
|
||||
<string> "version" </string>
|
||||
<int> 1 </int>
|
||||
</dictionary>
|
||||
|
||||
</main_resource>
|
||||
|
@ -8,12 +8,12 @@ var max_points = 0
|
||||
func _ready():
|
||||
var f = File.new()
|
||||
#load high score
|
||||
|
||||
if (f.open("user://highscore",File.READ)==OK):
|
||||
|
||||
max_points=f.get_var()
|
||||
|
||||
|
||||
|
||||
func game_over():
|
||||
if (points>max_points):
|
||||
max_points=points
|
||||
|
@ -14,7 +14,6 @@ var offset=0
|
||||
|
||||
|
||||
func _process(delta):
|
||||
|
||||
offset+=delta*SPEED
|
||||
set_pos(Vector2(offset,0))
|
||||
|
||||
|
4
demos/misc/regex/engine.cfg
Normal file
4
demos/misc/regex/engine.cfg
Normal file
@ -0,0 +1,4 @@
|
||||
[application]
|
||||
|
||||
name="RegEx"
|
||||
main_scene="res://regex.scn"
|
22
demos/misc/regex/regex.gd
Normal file
22
demos/misc/regex/regex.gd
Normal file
@ -0,0 +1,22 @@
|
||||
extends VBoxContainer
|
||||
|
||||
var regex = RegEx.new()
|
||||
|
||||
func update_expression():
|
||||
regex.compile(get_node("Expression").get_text())
|
||||
update_text()
|
||||
|
||||
func update_text():
|
||||
var text = get_node("Text").get_text()
|
||||
regex.find(text)
|
||||
var list = get_node("List")
|
||||
for child in list.get_children():
|
||||
child.queue_free()
|
||||
for res in regex.get_captures():
|
||||
var label = Label.new()
|
||||
label.set_text(res)
|
||||
list.add_child(label)
|
||||
|
||||
func _ready():
|
||||
get_node("Text").set_text("They asked me \"What's going on \\\"in the manor\\\"?\"")
|
||||
update_expression()
|
BIN
demos/misc/regex/regex.scn
Normal file
BIN
demos/misc/regex/regex.scn
Normal file
Binary file not shown.
7943
doc/base/classes.xml
7943
doc/base/classes.xml
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@ -30,7 +30,7 @@ if (env["openssl"]=="builtin"):
|
||||
|
||||
SConscript("rtaudio/SCsub");
|
||||
SConscript("nedmalloc/SCsub");
|
||||
SConscript("trex/SCsub");
|
||||
SConscript("nrex/SCsub");
|
||||
SConscript("chibi/SCsub");
|
||||
if (env["vorbis"]=="yes" or env["speex"]=="yes" or env["theora"]=="yes"):
|
||||
SConscript("ogg/SCsub");
|
||||
|
64
drivers/nrex/README.md
Normal file
64
drivers/nrex/README.md
Normal file
@ -0,0 +1,64 @@
|
||||
# NREX: Node RegEx
|
||||
|
||||
Small node-based regular expression library. It only does text pattern
|
||||
matchhing, not replacement. To use add the files `nrex.hpp`, `nrex.cpp`
|
||||
and `nrex_config.h` to your project and follow the example:
|
||||
|
||||
nrex regex;
|
||||
regex.compile("^(fo+)bar$");
|
||||
|
||||
nrex_result captures[regex.capture_size()];
|
||||
if (regex.match("foobar", captures))
|
||||
{
|
||||
std::cout << captures[0].start << std::endl;
|
||||
std::cout << captures[0].length << std::endl;
|
||||
}
|
||||
|
||||
More details about its use is documented in `nrex.hpp`
|
||||
|
||||
Currently supported features:
|
||||
* Capturing `()` and non-capturing `(?:)` groups
|
||||
* Any character `.`
|
||||
* Shorthand caracter classes `\w\W\s\S\d\D`
|
||||
* User-defined character classes such as `[A-Za-z]`
|
||||
* Simple quantifiers `?`, `*` and `+`
|
||||
* Range quantifiers `{0,1}`
|
||||
* Lazy (non-greedy) quantifiers `*?`
|
||||
* Begining `^` and end `$` anchors
|
||||
* Alternation `|`
|
||||
* Backreferences `\1` to `\99`
|
||||
|
||||
To do list:
|
||||
* Unicode `\uFFFF` code points
|
||||
|
||||
## License
|
||||
|
||||
Copyright (c) 2015, Zher Huei Lee
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions are
|
||||
met:
|
||||
|
||||
1. Redistributions of source code must retain the above copyright
|
||||
notice, this list of conditions and the following disclaimer.
|
||||
|
||||
2. Redistributions in binary form must reproduce the above copyright
|
||||
notice, this list of conditions and the following disclaimer in the
|
||||
documentation and/or other materials provided with the distribution.
|
||||
|
||||
3. Neither the name of the copyright holder nor the names of its
|
||||
contributors may be used to endorse or promote products derived from
|
||||
this software without specific prior written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
|
||||
IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
|
||||
TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
|
||||
PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
|
||||
TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
|
||||
PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
|
||||
LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
||||
NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
@ -2,8 +2,7 @@
|
||||
Import('env')
|
||||
|
||||
sources = [
|
||||
|
||||
'trex.c',
|
||||
'nrex.cpp',
|
||||
'regex.cpp',
|
||||
]
|
||||
env.add_source_files(env.drivers_sources, sources)
|
910
drivers/nrex/nrex.cpp
Normal file
910
drivers/nrex/nrex.cpp
Normal file
@ -0,0 +1,910 @@
|
||||
// NREX: Node RegEx
|
||||
//
|
||||
// Copyright (c) 2015, Zher Huei Lee
|
||||
// All rights reserved.
|
||||
//
|
||||
// This software is provided 'as-is', without any express or implied
|
||||
// warranty. In no event will the authors be held liable for any damages
|
||||
// arising from the use of this software.
|
||||
//
|
||||
// Permission is granted to anyone to use this software for any purpose,
|
||||
// including commercial applications, and to alter it and redistribute it
|
||||
// freely, subject to the following restrictions:
|
||||
//
|
||||
// 1. The origin of this software must not be misrepresented; you must not
|
||||
// claim that you wrote the original software. If you use this software
|
||||
// in a product, an acknowledgment in the product documentation would
|
||||
// be appreciated but is not required.
|
||||
//
|
||||
// 2. Altered source versions must be plainly marked as such, and must not
|
||||
// be misrepresented as being the original software.
|
||||
//
|
||||
// 3. This notice may not be removed or altered from any source
|
||||
// distribution.
|
||||
//
|
||||
|
||||
#include "nrex.hpp"
|
||||
|
||||
#ifdef NREX_UNICODE
|
||||
#include <wctype.h>
|
||||
#include <wchar.h>
|
||||
#define NREX_ISALPHANUM iswalnum
|
||||
#define NREX_STRLEN wcslen
|
||||
#else
|
||||
#include <ctype.h>
|
||||
#include <string.h>
|
||||
#define NREX_ISALPHANUM isalnum
|
||||
#define NREX_STRLEN strlen
|
||||
#endif
|
||||
|
||||
#ifdef NREX_THROW_ERROR
|
||||
#define NREX_COMPILE_ERROR(M) throw nrex_compile_error(M)
|
||||
#else
|
||||
#define NREX_COMPILE_ERROR(M) reset(); return false
|
||||
#endif
|
||||
|
||||
#ifndef NREX_NEW
|
||||
#define NREX_NEW(X) new X
|
||||
#define NREX_NEW_ARRAY(X, N) new X[N]
|
||||
#define NREX_DELETE(X) delete X
|
||||
#define NREX_DELETE_ARRAY(X) delete[] X
|
||||
#endif
|
||||
|
||||
template<typename T>
|
||||
class nrex_array
|
||||
{
|
||||
private:
|
||||
T* _data;
|
||||
unsigned int _reserved;
|
||||
unsigned int _size;
|
||||
public:
|
||||
nrex_array()
|
||||
: _data(NREX_NEW_ARRAY(T, 2))
|
||||
, _reserved(2)
|
||||
, _size(0)
|
||||
{
|
||||
}
|
||||
|
||||
~nrex_array()
|
||||
{
|
||||
NREX_DELETE_ARRAY(_data);
|
||||
}
|
||||
|
||||
unsigned int size() const
|
||||
{
|
||||
return _size;
|
||||
}
|
||||
|
||||
void reserve(unsigned int size)
|
||||
{
|
||||
T* old = _data;
|
||||
_data = NREX_NEW_ARRAY(T, size);
|
||||
_reserved = size;
|
||||
for (unsigned int i = 0; i < _size; ++i)
|
||||
{
|
||||
_data[i] = old[i];
|
||||
}
|
||||
NREX_DELETE_ARRAY(old);
|
||||
}
|
||||
|
||||
void push(T item)
|
||||
{
|
||||
if (_size == _reserved)
|
||||
{
|
||||
reserve(_reserved * 2);
|
||||
}
|
||||
_data[_size] = item;
|
||||
_size++;
|
||||
}
|
||||
|
||||
T& top()
|
||||
{
|
||||
return _data[_size - 1];
|
||||
}
|
||||
|
||||
const T& operator[] (unsigned int i) const
|
||||
{
|
||||
return _data[i];
|
||||
}
|
||||
|
||||
void pop()
|
||||
{
|
||||
if (_size > 0)
|
||||
{
|
||||
--_size;
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
static nrex_char nrex_unescape(nrex_char repr)
|
||||
{
|
||||
switch (repr)
|
||||
{
|
||||
case '^': return '^';
|
||||
case '$': return '$';
|
||||
case '(': return '(';
|
||||
case ')': return ')';
|
||||
case '\\': return '\\';
|
||||
case '.': return '.';
|
||||
case '+': return '+';
|
||||
case '*': return '*';
|
||||
case '?': return '?';
|
||||
case '-': return '-';
|
||||
case 'a': return '\a';
|
||||
case 'e': return '\e';
|
||||
case 'f': return '\f';
|
||||
case 'n': return '\n';
|
||||
case 'r': return '\r';
|
||||
case 't': return '\t';
|
||||
case 'v': return '\v';
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
struct nrex_search
|
||||
{
|
||||
public:
|
||||
const nrex_char* str;
|
||||
nrex_result* captures;
|
||||
int end;
|
||||
bool complete;
|
||||
|
||||
nrex_char at(int pos)
|
||||
{
|
||||
return str[pos];
|
||||
}
|
||||
|
||||
nrex_search(const nrex_char* str, nrex_result* captures)
|
||||
: str(str)
|
||||
, captures(captures)
|
||||
, end(0)
|
||||
{
|
||||
}
|
||||
};
|
||||
|
||||
struct nrex_node
|
||||
{
|
||||
nrex_node* next;
|
||||
nrex_node* previous;
|
||||
nrex_node* parent;
|
||||
bool quantifiable;
|
||||
|
||||
nrex_node(bool quantify = false)
|
||||
: next(NULL)
|
||||
, previous(NULL)
|
||||
, parent(NULL)
|
||||
, quantifiable(quantify)
|
||||
{
|
||||
}
|
||||
|
||||
virtual ~nrex_node()
|
||||
{
|
||||
if (next)
|
||||
{
|
||||
NREX_DELETE(next);
|
||||
}
|
||||
}
|
||||
|
||||
virtual int test(nrex_search* s, int pos) const
|
||||
{
|
||||
return next ? next->test(s, pos) : -1;
|
||||
}
|
||||
|
||||
virtual int test_parent(nrex_search* s, int pos) const
|
||||
{
|
||||
if (next)
|
||||
{
|
||||
pos = next->test(s, pos);
|
||||
}
|
||||
if (parent && pos >= 0)
|
||||
{
|
||||
pos = parent->test_parent(s, pos);
|
||||
}
|
||||
if (pos >= 0)
|
||||
{
|
||||
s->complete = true;
|
||||
}
|
||||
return pos;
|
||||
}
|
||||
};
|
||||
|
||||
struct nrex_node_group : public nrex_node
|
||||
{
|
||||
int capturing;
|
||||
bool negate;
|
||||
nrex_array<nrex_node*> childset;
|
||||
nrex_node* back;
|
||||
|
||||
nrex_node_group(int capturing)
|
||||
: nrex_node(true)
|
||||
, capturing(capturing)
|
||||
, negate(false)
|
||||
, back(NULL)
|
||||
{
|
||||
}
|
||||
|
||||
virtual ~nrex_node_group()
|
||||
{
|
||||
for (unsigned int i = 0; i < childset.size(); ++i)
|
||||
{
|
||||
NREX_DELETE(childset[i]);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
int test(nrex_search* s, int pos) const
|
||||
{
|
||||
if (capturing >= 0)
|
||||
{
|
||||
s->captures[capturing].start = pos;
|
||||
}
|
||||
for (unsigned int i = 0; i < childset.size(); ++i)
|
||||
{
|
||||
s->complete = false;
|
||||
int res = childset[i]->test(s, pos);
|
||||
if (s->complete)
|
||||
{
|
||||
return res;
|
||||
}
|
||||
if (negate)
|
||||
{
|
||||
if (res < 0)
|
||||
{
|
||||
res = pos + 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
if (res >= 0)
|
||||
{
|
||||
if (capturing >= 0)
|
||||
{
|
||||
s->captures[capturing].length = res - pos;
|
||||
}
|
||||
return next ? next->test(s, res) : res;
|
||||
}
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
virtual int test_parent(nrex_search* s, int pos) const
|
||||
{
|
||||
if (capturing >= 0)
|
||||
{
|
||||
s->captures[capturing].length = pos - s->captures[capturing].start;
|
||||
}
|
||||
return nrex_node::test_parent(s, pos);
|
||||
}
|
||||
|
||||
void add_childset()
|
||||
{
|
||||
back = NULL;
|
||||
}
|
||||
|
||||
void add_child(nrex_node* node)
|
||||
{
|
||||
node->parent = this;
|
||||
node->previous = back;
|
||||
if (back)
|
||||
{
|
||||
back->next = node;
|
||||
}
|
||||
else
|
||||
{
|
||||
childset.push(node);
|
||||
}
|
||||
back = node;
|
||||
}
|
||||
|
||||
nrex_node* swap_back(nrex_node* node)
|
||||
{
|
||||
if (!back)
|
||||
{
|
||||
add_child(node);
|
||||
return NULL;
|
||||
}
|
||||
nrex_node* old = back;
|
||||
if (!old->previous)
|
||||
{
|
||||
childset.pop();
|
||||
}
|
||||
back = old->previous;
|
||||
add_child(node);
|
||||
return old;
|
||||
}
|
||||
};
|
||||
|
||||
struct nrex_node_char : public nrex_node
|
||||
{
|
||||
nrex_char ch;
|
||||
|
||||
nrex_node_char(nrex_char c)
|
||||
: nrex_node(true)
|
||||
, ch(c)
|
||||
{
|
||||
}
|
||||
|
||||
int test(nrex_search* s, int pos) const
|
||||
{
|
||||
if (s->end == pos || s->at(pos) != ch)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
return next ? next->test(s, pos + 1) : pos + 1;
|
||||
}
|
||||
};
|
||||
|
||||
struct nrex_node_range : public nrex_node
|
||||
{
|
||||
nrex_char start;
|
||||
nrex_char end;
|
||||
|
||||
nrex_node_range(nrex_char s, nrex_char e)
|
||||
: nrex_node(true)
|
||||
, start(s)
|
||||
, end(e)
|
||||
{
|
||||
}
|
||||
|
||||
int test(nrex_search* s, int pos) const
|
||||
{
|
||||
if (s->end == pos)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
nrex_char c = s->at(pos);
|
||||
if (c < start || end < c)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
return next ? next->test(s, pos + 1) : pos + 1;
|
||||
}
|
||||
};
|
||||
|
||||
static bool nrex_is_whitespace(nrex_char repr)
|
||||
{
|
||||
switch (repr)
|
||||
{
|
||||
case ' ':
|
||||
case '\t':
|
||||
case '\r':
|
||||
case '\n':
|
||||
case '\f':
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
static bool nrex_is_shorthand(nrex_char repr)
|
||||
{
|
||||
switch (repr)
|
||||
{
|
||||
case 'W':
|
||||
case 'w':
|
||||
case 'D':
|
||||
case 'd':
|
||||
case 'S':
|
||||
case 's':
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
struct nrex_node_shorthand : public nrex_node
|
||||
{
|
||||
nrex_char repr;
|
||||
|
||||
nrex_node_shorthand(nrex_char c)
|
||||
: nrex_node(true)
|
||||
, repr(c)
|
||||
{
|
||||
}
|
||||
|
||||
int test(nrex_search* s, int pos) const
|
||||
{
|
||||
if (s->end == pos)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
bool found = false;
|
||||
bool invert = false;
|
||||
nrex_char c = s->at(pos);
|
||||
switch (repr)
|
||||
{
|
||||
case '.':
|
||||
found = true;
|
||||
break;
|
||||
case 'W':
|
||||
invert = true;
|
||||
case 'w':
|
||||
if (c == '_' || NREX_ISALPHANUM(c))
|
||||
{
|
||||
found = true;
|
||||
}
|
||||
break;
|
||||
case 'D':
|
||||
invert = true;
|
||||
case 'd':
|
||||
if ('0' <= c && c <= '9')
|
||||
{
|
||||
found = true;
|
||||
}
|
||||
break;
|
||||
case 'S':
|
||||
invert = true;
|
||||
case 's':
|
||||
if (nrex_is_whitespace(c))
|
||||
{
|
||||
found = true;
|
||||
}
|
||||
break;
|
||||
}
|
||||
if (found == invert)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
return next ? next->test(s, pos + 1) : pos + 1;
|
||||
}
|
||||
};
|
||||
|
||||
static bool nrex_is_quantifier(nrex_char repr)
|
||||
{
|
||||
switch (repr)
|
||||
{
|
||||
case '?':
|
||||
case '*':
|
||||
case '+':
|
||||
case '{':
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
struct nrex_node_quantifier : public nrex_node
|
||||
{
|
||||
int min;
|
||||
int max;
|
||||
bool greedy;
|
||||
nrex_node* child;
|
||||
|
||||
nrex_node_quantifier()
|
||||
: nrex_node()
|
||||
, min(0)
|
||||
, max(0)
|
||||
, greedy(true)
|
||||
, child(NULL)
|
||||
{
|
||||
}
|
||||
|
||||
virtual ~nrex_node_quantifier()
|
||||
{
|
||||
if (child)
|
||||
{
|
||||
NREX_DELETE(child);
|
||||
}
|
||||
}
|
||||
|
||||
int test(nrex_search* s, int pos) const
|
||||
{
|
||||
nrex_array<int> backtrack;
|
||||
backtrack.push(pos);
|
||||
while (backtrack.top() <= s->end)
|
||||
{
|
||||
if (max >= 1 && backtrack.size() > (unsigned int)max)
|
||||
{
|
||||
break;
|
||||
}
|
||||
if (!greedy && (unsigned int)min < backtrack.size())
|
||||
{
|
||||
int res = backtrack.top();
|
||||
if (next)
|
||||
{
|
||||
res = next->test(s, res);
|
||||
}
|
||||
if (s->complete)
|
||||
{
|
||||
return res;
|
||||
}
|
||||
if (res >= 0 && parent->test_parent(s, res) >= 0)
|
||||
{
|
||||
return res;
|
||||
}
|
||||
}
|
||||
int res = child->test(s, backtrack.top());
|
||||
if (s->complete)
|
||||
{
|
||||
return res;
|
||||
}
|
||||
if (res < 0 || res == backtrack.top())
|
||||
{
|
||||
break;
|
||||
}
|
||||
backtrack.push(res);
|
||||
}
|
||||
while (greedy && (unsigned int) min < backtrack.size())
|
||||
{
|
||||
int res = backtrack.top();
|
||||
if (next)
|
||||
{
|
||||
res = next->test(s, res);
|
||||
}
|
||||
if (res >= 0 && parent->test_parent(s, res) >= 0)
|
||||
{
|
||||
return res;
|
||||
}
|
||||
if (s->complete)
|
||||
{
|
||||
return res;
|
||||
}
|
||||
backtrack.pop();
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
};
|
||||
|
||||
struct nrex_node_anchor : public nrex_node
|
||||
{
|
||||
bool end;
|
||||
|
||||
nrex_node_anchor(bool end)
|
||||
: nrex_node()
|
||||
, end(end)
|
||||
{
|
||||
}
|
||||
|
||||
int test(nrex_search* s, int pos) const
|
||||
{
|
||||
if (!end && pos != 0)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
else if (end && pos != s->end)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
return next ? next->test(s, pos) : pos;
|
||||
}
|
||||
};
|
||||
|
||||
struct nrex_node_backreference : public nrex_node
|
||||
{
|
||||
int ref;
|
||||
|
||||
nrex_node_backreference(int ref)
|
||||
: nrex_node(true)
|
||||
, ref(ref)
|
||||
{
|
||||
}
|
||||
|
||||
int test(nrex_search* s, int pos) const
|
||||
{
|
||||
nrex_result& r = s->captures[ref];
|
||||
for (int i = 0; i < r.length; ++i)
|
||||
{
|
||||
if (pos + i >= s->end)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
if (s->at(r.start + i) != s->at(pos + i))
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
return next ? next->test(s, pos + r.length) : pos + r.length;
|
||||
}
|
||||
};
|
||||
|
||||
nrex::nrex()
|
||||
: _capturing(0)
|
||||
, _root(NULL)
|
||||
{
|
||||
}
|
||||
|
||||
nrex::~nrex()
|
||||
{
|
||||
if (_root)
|
||||
{
|
||||
NREX_DELETE(_root);
|
||||
}
|
||||
}
|
||||
|
||||
bool nrex::valid() const
|
||||
{
|
||||
return (_root != NULL);
|
||||
}
|
||||
|
||||
void nrex::reset()
|
||||
{
|
||||
_capturing = 0;
|
||||
if (_root)
|
||||
{
|
||||
NREX_DELETE(_root);
|
||||
}
|
||||
_root = NULL;
|
||||
}
|
||||
|
||||
int nrex::capture_size() const
|
||||
{
|
||||
return _capturing + 1;
|
||||
}
|
||||
|
||||
bool nrex::compile(const nrex_char* pattern)
|
||||
{
|
||||
reset();
|
||||
nrex_node_group* root = NREX_NEW(nrex_node_group(_capturing));
|
||||
nrex_array<nrex_node_group*> stack;
|
||||
stack.push(root);
|
||||
_root = root;
|
||||
|
||||
for (const nrex_char* c = pattern; c[0] != '\0'; ++c)
|
||||
{
|
||||
if (c[0] == '(')
|
||||
{
|
||||
if (c[1] == '?')
|
||||
{
|
||||
if (c[2] == ':')
|
||||
{
|
||||
c = &c[2];
|
||||
nrex_node_group* group = NREX_NEW(nrex_node_group(-1));
|
||||
stack.top()->add_child(group);
|
||||
stack.push(group);
|
||||
}
|
||||
else
|
||||
{
|
||||
NREX_COMPILE_ERROR("unrecognised qualifier for parenthesis");
|
||||
}
|
||||
}
|
||||
else if (_capturing < 99)
|
||||
{
|
||||
nrex_node_group* group = NREX_NEW(nrex_node_group(++_capturing));
|
||||
stack.top()->add_child(group);
|
||||
stack.push(group);
|
||||
}
|
||||
else
|
||||
{
|
||||
nrex_node_group* group = NREX_NEW(nrex_node_group(-1));
|
||||
stack.top()->add_child(group);
|
||||
stack.push(group);
|
||||
}
|
||||
}
|
||||
else if (c[0] == ')')
|
||||
{
|
||||
if (stack.size() > 1)
|
||||
{
|
||||
stack.pop();
|
||||
}
|
||||
else
|
||||
{
|
||||
NREX_COMPILE_ERROR("unexpected ')'");
|
||||
}
|
||||
}
|
||||
else if (c[0] == '[')
|
||||
{
|
||||
nrex_node_group* group = NREX_NEW(nrex_node_group(-1));
|
||||
stack.top()->add_child(group);
|
||||
if (c[1] == '^')
|
||||
{
|
||||
group->negate = true;
|
||||
++c;
|
||||
}
|
||||
while (true)
|
||||
{
|
||||
group->add_childset();
|
||||
++c;
|
||||
if (c[0] == '\0')
|
||||
{
|
||||
NREX_COMPILE_ERROR("unclosed character class '[]'");
|
||||
}
|
||||
if (c[0] == ']')
|
||||
{
|
||||
break;
|
||||
}
|
||||
else if (c[0] == '\\')
|
||||
{
|
||||
nrex_char unescaped = nrex_unescape(c[1]);
|
||||
if (unescaped)
|
||||
{
|
||||
group->add_child(NREX_NEW(nrex_node_char(unescaped)));
|
||||
++c;
|
||||
}
|
||||
else if (nrex_is_shorthand(c[1]))
|
||||
{
|
||||
group->add_child(NREX_NEW(nrex_node_shorthand(c[1])));
|
||||
++c;
|
||||
}
|
||||
else
|
||||
{
|
||||
NREX_COMPILE_ERROR("escape token not recognised");
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (c[1] == '-' && c[2] != '\0')
|
||||
{
|
||||
bool range = false;
|
||||
if ('A' <= c[0] && c[0] <= 'Z' && 'A' <= c[2] && c[2] <= 'Z')
|
||||
{
|
||||
range = true;
|
||||
}
|
||||
if ('a' <= c[0] && c[0] <= 'z' && 'a' <= c[2] && c[2] <= 'z')
|
||||
{
|
||||
range = true;
|
||||
}
|
||||
if ('0' <= c[0] && c[0] <= '9' && '0' <= c[2] && c[2] <= '9')
|
||||
{
|
||||
range = true;
|
||||
}
|
||||
if (range)
|
||||
{
|
||||
group->add_child(NREX_NEW(nrex_node_range(c[0], c[2])));
|
||||
c = &c[2];
|
||||
continue;
|
||||
}
|
||||
}
|
||||
group->add_child(NREX_NEW(nrex_node_char(c[0])));
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
else if (nrex_is_quantifier(c[0]))
|
||||
{
|
||||
nrex_node_quantifier* quant = NREX_NEW(nrex_node_quantifier);
|
||||
quant->child = stack.top()->swap_back(quant);
|
||||
if (quant->child == NULL || !quant->child->quantifiable)
|
||||
{
|
||||
NREX_COMPILE_ERROR("element not quantifiable");
|
||||
}
|
||||
quant->child->previous = NULL;
|
||||
quant->child->next = NULL;
|
||||
quant->child->parent = quant;
|
||||
if (c[0] == '?')
|
||||
{
|
||||
quant->min = 0;
|
||||
quant->max = 1;
|
||||
}
|
||||
else if (c[0] == '+')
|
||||
{
|
||||
quant->min = 1;
|
||||
quant->max = -1;
|
||||
}
|
||||
else if (c[0] == '*')
|
||||
{
|
||||
quant->min = 0;
|
||||
quant->max = -1;
|
||||
}
|
||||
else if (c[0] == '{')
|
||||
{
|
||||
bool max_set = false;
|
||||
quant->min = 0;
|
||||
quant->max = -1;
|
||||
while (true)
|
||||
{
|
||||
++c;
|
||||
if (c[0] == '\0')
|
||||
{
|
||||
NREX_COMPILE_ERROR("unclosed range quantifier '{}'");
|
||||
}
|
||||
else if (c[0] == '}')
|
||||
{
|
||||
break;
|
||||
}
|
||||
else if (c[0] == ',')
|
||||
{
|
||||
max_set = true;
|
||||
continue;
|
||||
}
|
||||
else if (c[0] < '0' || '9' < c[0])
|
||||
{
|
||||
NREX_COMPILE_ERROR("expected numeric digits, ',' or '}'");
|
||||
}
|
||||
if (max_set)
|
||||
{
|
||||
if (quant->max < 0)
|
||||
{
|
||||
quant->max = int(c[0] - '0');
|
||||
}
|
||||
else
|
||||
{
|
||||
quant->max = quant->max * 10 + int(c[0] - '0');
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
quant->min = quant->min * 10 + int(c[0] - '0');
|
||||
}
|
||||
}
|
||||
if (!max_set)
|
||||
{
|
||||
quant->max = quant->min;
|
||||
}
|
||||
}
|
||||
if (c[1] == '?')
|
||||
{
|
||||
quant->greedy = false;
|
||||
++c;
|
||||
}
|
||||
}
|
||||
else if (c[0] == '|')
|
||||
{
|
||||
stack.top()->add_childset();
|
||||
}
|
||||
else if (c[0] == '^' || c[0] == '$')
|
||||
{
|
||||
stack.top()->add_child(NREX_NEW(nrex_node_anchor((c[0] == '$'))));
|
||||
}
|
||||
else if (c[0] == '.')
|
||||
{
|
||||
stack.top()->add_child(NREX_NEW(nrex_node_shorthand('.')));
|
||||
}
|
||||
else if (c[0] == '\\')
|
||||
{
|
||||
nrex_char unescaped = nrex_unescape(c[1]);
|
||||
if (unescaped)
|
||||
{
|
||||
stack.top()->add_child(NREX_NEW(nrex_node_char(unescaped)));
|
||||
++c;
|
||||
}
|
||||
else if (nrex_is_shorthand(c[1]))
|
||||
{
|
||||
stack.top()->add_child(NREX_NEW(nrex_node_shorthand(c[1])));
|
||||
++c;
|
||||
}
|
||||
else if ('1' <= c[1] && c[1] <= '9')
|
||||
{
|
||||
int ref = 0;
|
||||
if ('0' <= c[2] && c[2] <= '9')
|
||||
{
|
||||
ref = int(c[1] - '0') * 10 + int(c[2] - '0');
|
||||
c = &c[2];
|
||||
}
|
||||
else
|
||||
{
|
||||
ref = int(c[1] - '0');
|
||||
++c;
|
||||
}
|
||||
if (ref > _capturing)
|
||||
{
|
||||
NREX_COMPILE_ERROR("backreference to non-existent capture");
|
||||
}
|
||||
stack.top()->add_child(NREX_NEW(nrex_node_backreference(ref)));
|
||||
}
|
||||
else
|
||||
{
|
||||
NREX_COMPILE_ERROR("escape token not recognised");
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
stack.top()->add_child(NREX_NEW(nrex_node_char(c[0])));
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
bool nrex::match(const nrex_char* str, nrex_result* captures, int offset, int end) const
|
||||
{
|
||||
nrex_search s(str, captures);
|
||||
if (end >= offset)
|
||||
{
|
||||
s.end = end;
|
||||
}
|
||||
else
|
||||
{
|
||||
s.end = NREX_STRLEN(str);
|
||||
}
|
||||
for (int i = offset; i < s.end; ++i)
|
||||
{
|
||||
for (int c = 0; c <= _capturing; ++c)
|
||||
{
|
||||
captures[c].start = 0;
|
||||
captures[c].length = 0;
|
||||
}
|
||||
if (_root->test(&s, i) >= 0)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
144
drivers/nrex/nrex.hpp
Normal file
144
drivers/nrex/nrex.hpp
Normal file
@ -0,0 +1,144 @@
|
||||
// NREX: Node RegEx
|
||||
//
|
||||
// Copyright (c) 2015, Zher Huei Lee
|
||||
// All rights reserved.
|
||||
//
|
||||
// This software is provided 'as-is', without any express or implied
|
||||
// warranty. In no event will the authors be held liable for any damages
|
||||
// arising from the use of this software.
|
||||
//
|
||||
// Permission is granted to anyone to use this software for any purpose,
|
||||
// including commercial applications, and to alter it and redistribute it
|
||||
// freely, subject to the following restrictions:
|
||||
//
|
||||
// 1. The origin of this software must not be misrepresented; you must not
|
||||
// claim that you wrote the original software. If you use this software
|
||||
// in a product, an acknowledgment in the product documentation would
|
||||
// be appreciated but is not required.
|
||||
//
|
||||
// 2. Altered source versions must be plainly marked as such, and must not
|
||||
// be misrepresented as being the original software.
|
||||
//
|
||||
// 3. This notice may not be removed or altered from any source
|
||||
// distribution.
|
||||
//
|
||||
|
||||
#ifndef NREX_HPP
|
||||
#define NREX_HPP
|
||||
|
||||
#include "nrex_config.h"
|
||||
|
||||
#ifdef NREX_UNICODE
|
||||
typedef wchar_t nrex_char;
|
||||
#else
|
||||
typedef char nrex_char;
|
||||
#endif
|
||||
|
||||
/*!
|
||||
* \brief Struct to contain the range of a capture result
|
||||
*
|
||||
* The range provided is relative to the begining of the searched string.
|
||||
*
|
||||
* \see nrex_node::match()
|
||||
*/
|
||||
struct nrex_result
|
||||
{
|
||||
public:
|
||||
int start; /*!< Start of text range */
|
||||
int length; /*!< Length of text range */
|
||||
};
|
||||
|
||||
class nrex_node;
|
||||
|
||||
/*!
|
||||
* \brief Holds the compiled regex pattern
|
||||
*/
|
||||
class nrex
|
||||
{
|
||||
private:
|
||||
int _capturing;
|
||||
nrex_node* _root;
|
||||
public:
|
||||
nrex();
|
||||
~nrex();
|
||||
|
||||
/*!
|
||||
* \brief Removes the compiled regex and frees up the memory
|
||||
*/
|
||||
void reset();
|
||||
|
||||
/*!
|
||||
* \brief Checks if there is a compiled regex being stored
|
||||
* \return True if present, False if not present
|
||||
*/
|
||||
bool valid() const;
|
||||
|
||||
/*!
|
||||
* \brief Provides number of captures the compiled regex uses
|
||||
*
|
||||
* This is used to provide the array size of the captures needed for
|
||||
* nrex::match() to work. The size is actually the number of capture
|
||||
* groups + one for the matching of the entire pattern. The result is
|
||||
* always capped at 100.
|
||||
*
|
||||
* \return The number of captures
|
||||
*/
|
||||
int capture_size() const;
|
||||
|
||||
/*!
|
||||
* \brief Compiles the provided regex pattern
|
||||
*
|
||||
* This automatically removes the existing compiled regex if already
|
||||
* present.
|
||||
*
|
||||
* If the NREX_THROW_ERROR was defined it would automatically throw a
|
||||
* runtime error nrex_compile_error if it encounters a problem when
|
||||
* parsing the pattern.
|
||||
*
|
||||
* \param The regex pattern
|
||||
* \return True if the pattern was succesfully compiled
|
||||
*/
|
||||
bool compile(const nrex_char* pattern);
|
||||
|
||||
/*!
|
||||
* \brief Uses the pattern to search through the provided string
|
||||
* \param str The text to search through. It only needs to be
|
||||
* null terminated if the end point is not provided.
|
||||
* This also determines the starting anchor.
|
||||
* \param captures The array of results to store the capture results.
|
||||
* The size of that array needs to be the same as the
|
||||
* size given in nrex::capture_size(). As it matches
|
||||
* the function fills the array with the results. 0 is
|
||||
* the result for the entire pattern, 1 and above
|
||||
* corresponds to the regex capture group if present.
|
||||
* \param offset The starting point of the search. This does not move
|
||||
* the starting anchor. Defaults to 0.
|
||||
* \param end The end point of the search. This also determines
|
||||
* the ending anchor. If a number less than the offset
|
||||
* is provided, the search would be done until null
|
||||
* termination. Defaults to -1.
|
||||
* \return True if a match was found. False otherwise.
|
||||
*/
|
||||
bool match(const nrex_char* str, nrex_result* captures, int offset = 0, int end = -1) const;
|
||||
};
|
||||
|
||||
#ifdef NREX_THROW_ERROR
|
||||
|
||||
#include <stdexcept>
|
||||
|
||||
class nrex_compile_error : std::runtime_error
|
||||
{
|
||||
public:
|
||||
nrex_compile_error(const char* message)
|
||||
: std::runtime_error(message)
|
||||
{
|
||||
}
|
||||
|
||||
~nrex_compile_error() throw()
|
||||
{
|
||||
}
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
#endif // NREX_HPP
|
12
drivers/nrex/nrex_config.h
Normal file
12
drivers/nrex/nrex_config.h
Normal file
@ -0,0 +1,12 @@
|
||||
// Godot-specific configuration
|
||||
// To use this, replace nrex_config.h
|
||||
|
||||
#include "core/os/memory.h"
|
||||
|
||||
#define NREX_UNICODE
|
||||
//#define NREX_THROW_ERROR
|
||||
|
||||
#define NREX_NEW(X) memnew(X)
|
||||
#define NREX_NEW_ARRAY(X, N) memnew_arr(X, N)
|
||||
#define NREX_DELETE(X) memdelete(X)
|
||||
#define NREX_DELETE_ARRAY(X) memdelete_arr(X)
|
114
drivers/nrex/regex.cpp
Normal file
114
drivers/nrex/regex.cpp
Normal file
@ -0,0 +1,114 @@
|
||||
/*************************************************/
|
||||
/* regex.cpp */
|
||||
/*************************************************/
|
||||
/* This file is part of: */
|
||||
/* GODOT ENGINE */
|
||||
/*************************************************/
|
||||
/* Source code within this file is: */
|
||||
/* (c) 2007-2010 Juan Linietsky, Ariel Manzur */
|
||||
/* All Rights Reserved. */
|
||||
/*************************************************/
|
||||
|
||||
#include "regex.h"
|
||||
#include "nrex.hpp"
|
||||
#include "core/os/memory.h"
|
||||
|
||||
void RegEx::_bind_methods() {
|
||||
|
||||
ObjectTypeDB::bind_method(_MD("compile","pattern"),&RegEx::compile);
|
||||
ObjectTypeDB::bind_method(_MD("find","text","start","end"),&RegEx::find, DEFVAL(0), DEFVAL(-1));
|
||||
ObjectTypeDB::bind_method(_MD("clear"),&RegEx::clear);
|
||||
ObjectTypeDB::bind_method(_MD("is_valid"),&RegEx::is_valid);
|
||||
ObjectTypeDB::bind_method(_MD("get_capture_count"),&RegEx::get_capture_count);
|
||||
ObjectTypeDB::bind_method(_MD("get_capture","capture"),&RegEx::get_capture);
|
||||
ObjectTypeDB::bind_method(_MD("get_captures"),&RegEx::_bind_get_captures);
|
||||
|
||||
};
|
||||
|
||||
StringArray RegEx::_bind_get_captures() const {
|
||||
|
||||
StringArray ret;
|
||||
int count = get_capture_count();
|
||||
for (int i=0; i<count; i++) {
|
||||
|
||||
String c = get_capture(i);
|
||||
ret.push_back(c);
|
||||
};
|
||||
|
||||
return ret;
|
||||
|
||||
};
|
||||
|
||||
void RegEx::clear() {
|
||||
|
||||
text.clear();
|
||||
captures.clear();
|
||||
exp.reset();
|
||||
|
||||
};
|
||||
|
||||
bool RegEx::is_valid() const {
|
||||
|
||||
return exp.valid();
|
||||
|
||||
};
|
||||
|
||||
int RegEx::get_capture_count() const {
|
||||
|
||||
return exp.capture_size();
|
||||
}
|
||||
|
||||
String RegEx::get_capture(int capture) const {
|
||||
|
||||
ERR_FAIL_COND_V( get_capture_count() <= capture, String() );
|
||||
|
||||
return text.substr(captures[capture].start, captures[capture].length);
|
||||
|
||||
}
|
||||
|
||||
Error RegEx::compile(const String& p_pattern) {
|
||||
|
||||
clear();
|
||||
|
||||
exp.compile(p_pattern.c_str());
|
||||
|
||||
ERR_FAIL_COND_V( !exp.valid(), FAILED );
|
||||
|
||||
captures.resize(exp.capture_size());
|
||||
|
||||
return OK;
|
||||
|
||||
};
|
||||
|
||||
int RegEx::find(const String& p_text, int p_start, int p_end) const {
|
||||
|
||||
ERR_FAIL_COND_V( !exp.valid(), -1 );
|
||||
ERR_FAIL_COND_V( p_text.length() < p_start, -1 );
|
||||
ERR_FAIL_COND_V( p_text.length() < p_end, -1 );
|
||||
|
||||
bool res = exp.match(p_text.c_str(), &captures[0], p_start, p_end);
|
||||
|
||||
if (res) {
|
||||
text = p_text;
|
||||
return captures[0].start;
|
||||
}
|
||||
text.clear();
|
||||
return -1;
|
||||
|
||||
};
|
||||
|
||||
RegEx::RegEx(const String& p_pattern) {
|
||||
|
||||
compile(p_pattern);
|
||||
|
||||
};
|
||||
|
||||
RegEx::RegEx() {
|
||||
|
||||
};
|
||||
|
||||
RegEx::~RegEx() {
|
||||
|
||||
clear();
|
||||
|
||||
};
|
@ -13,34 +13,31 @@
|
||||
#define REGEX_H
|
||||
|
||||
#include "ustring.h"
|
||||
#include "list.h"
|
||||
#include "vector.h"
|
||||
#include "core/reference.h"
|
||||
struct TRex;
|
||||
#include "nrex.hpp"
|
||||
|
||||
class RegEx : public Reference {
|
||||
|
||||
OBJ_TYPE(RegEx, Reference);
|
||||
|
||||
mutable String text;
|
||||
TRex *exp;
|
||||
mutable Vector<nrex_result> captures;
|
||||
nrex exp;
|
||||
|
||||
protected:
|
||||
|
||||
static void _bind_methods();
|
||||
|
||||
int _bind_find(const String& p_text, int p_start = 0, int p_end = -1) const;
|
||||
StringArray _bind_get_captures() const;
|
||||
|
||||
public:
|
||||
|
||||
void clear();
|
||||
|
||||
Error compile(const String& p_pattern);
|
||||
bool is_valid() const;
|
||||
bool match(const String& p_text, List<String>* p_captures = NULL, int p_start = 0, int p_end = -1) const;
|
||||
bool find(const String& p_text, int& p_rstart, int &p_rend, List<String>* p_captures = NULL, int p_start = 0, int p_end = -1) const;
|
||||
int get_capture_count() const;
|
||||
Error get_capture_limits(int p_capture, int& p_start, int& p_len) const;
|
||||
String get_capture(int p_idx) const;
|
||||
String get_capture(int capture) const;
|
||||
Error compile(const String& p_pattern);
|
||||
int find(const String& p_text, int p_start = 0, int p_end = -1) const;
|
||||
|
||||
RegEx();
|
||||
RegEx(const String& p_pattern);
|
@ -27,7 +27,10 @@ if ("neon_enabled" in env and env["neon_enabled"]):
|
||||
if "S_compiler" in env:
|
||||
env_neon['CC'] = env['S_compiler']
|
||||
env_neon.Append(CPPFLAGS=["-DPNG_ARM_NEON"])
|
||||
png_sources.append(env_neon.Object("#drivers/png/filter_neon.S"))
|
||||
import os
|
||||
# Currently .ASM filter_neon.S does not compile on NT.
|
||||
if (os.name!="nt"):
|
||||
png_sources.append(env_neon.Object("#drivers/png/filter_neon.S"))
|
||||
|
||||
|
||||
env.drivers_sources+=png_sources
|
||||
|
@ -48,7 +48,7 @@
|
||||
#endif
|
||||
|
||||
|
||||
#include "drivers/trex/regex.h"
|
||||
#include "drivers/nrex/regex.h"
|
||||
|
||||
#ifdef MUSEPACK_ENABLED
|
||||
#include "mpc/audio_stream_mpc.h"
|
||||
|
@ -21,7 +21,7 @@ void AudioStreamSpeex::update() {
|
||||
//printf("update, loops %i, read ofs %i\n", (int)loops, read_ofs);
|
||||
//printf("playing %i, paused %i\n", (int)playing, (int)paused);
|
||||
|
||||
if (!playing || paused || !data.size())
|
||||
if (!active || !playing || paused || !data.size())
|
||||
return;
|
||||
|
||||
/*
|
||||
|
@ -1,75 +0,0 @@
|
||||
#ifndef _TREXPP_H_
|
||||
#define _TREXPP_H_
|
||||
/***************************************************************
|
||||
T-Rex a tiny regular expression library
|
||||
|
||||
Copyright (C) 2003-2004 Alberto Demichelis
|
||||
|
||||
This software is provided 'as-is', without any express
|
||||
or implied warranty. In no event will the authors be held
|
||||
liable for any damages arising from the use of this software.
|
||||
|
||||
Permission is granted to anyone to use this software for
|
||||
any purpose, including commercial applications, and to alter
|
||||
it and redistribute it freely, subject to the following restrictions:
|
||||
|
||||
1. The origin of this software must not be misrepresented;
|
||||
you must not claim that you wrote the original software.
|
||||
If you use this software in a product, an acknowledgment
|
||||
in the product documentation would be appreciated but
|
||||
is not required.
|
||||
|
||||
2. Altered source versions must be plainly marked as such,
|
||||
and must not be misrepresented as being the original software.
|
||||
|
||||
3. This notice may not be removed or altered from any
|
||||
source distribution.
|
||||
|
||||
****************************************************************/
|
||||
|
||||
extern "C" {
|
||||
#include "trex.h"
|
||||
}
|
||||
|
||||
struct TRexParseException{TRexParseException(const TRexChar *c):desc(c){}const TRexChar *desc;};
|
||||
|
||||
class TRexpp {
|
||||
public:
|
||||
TRexpp() { _exp = (TRex *)0; }
|
||||
~TRexpp() { CleanUp(); }
|
||||
// compiles a regular expression
|
||||
void Compile(const TRexChar *pattern) {
|
||||
const TRexChar *error;
|
||||
CleanUp();
|
||||
if(!(_exp = trex_compile(pattern,&error)))
|
||||
throw TRexParseException(error);
|
||||
}
|
||||
// return true if the given text match the expression
|
||||
bool Match(const TRexChar* text) {
|
||||
return _exp?(trex_match(_exp,text) != 0):false;
|
||||
}
|
||||
// Searches for the first match of the expression in a zero terminated string
|
||||
bool Search(const TRexChar* text, const TRexChar** out_begin, const TRexChar** out_end) {
|
||||
return _exp?(trex_search(_exp,text,out_begin,out_end) != 0):false;
|
||||
}
|
||||
// Searches for the first match of the expression in a string sarting at text_begin and ending at text_end
|
||||
bool SearchRange(const TRexChar* text_begin,const TRexChar* text_end,const TRexChar** out_begin, const TRexChar** out_end) {
|
||||
return _exp?(trex_searchrange(_exp,text_begin,text_end,out_begin,out_end) != 0):false;
|
||||
}
|
||||
bool GetSubExp(int n, const TRexChar** out_begin, int *out_len)
|
||||
{
|
||||
TRexMatch match;
|
||||
TRexBool res = _exp?(trex_getsubexp(_exp,n,&match)):TRex_False;
|
||||
if(res) {
|
||||
*out_begin = match.begin;
|
||||
*out_len = match.len;
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
int GetSubExpCount() { return _exp?trex_getsubexpcount(_exp):0; }
|
||||
private:
|
||||
void CleanUp() { if(_exp) trex_free(_exp); _exp = (TRex *)0; }
|
||||
TRex *_exp;
|
||||
};
|
||||
#endif //_TREXPP_H_
|
@ -1,15 +0,0 @@
|
||||
===version 1.3
|
||||
-fixed a bug for GCC users(thx Brendan)
|
||||
|
||||
===version 1.2
|
||||
-added word boundary match \b and \B
|
||||
-added vertical tab escape \v
|
||||
-\w now also matches '_' (underscore)
|
||||
-fixed greediness for * and +
|
||||
|
||||
===version 1.1 , April 1, 2004
|
||||
-fixed some minor bug
|
||||
-added predefined character classes(\w,\W,\s,\S etc...)
|
||||
|
||||
===version 1.0 , February 23, 2004
|
||||
-first public realase
|
@ -1,171 +0,0 @@
|
||||
T-REX 1.3 http://tiny-rex.sourceforge.net
|
||||
----------------------------------------------------------------------
|
||||
T-Rex a tiny regular expression library
|
||||
|
||||
Copyright (C) 2003-2006 Alberto Demichelis
|
||||
|
||||
This software is provided 'as-is', without any express
|
||||
or implied warranty. In no event will the authors be held
|
||||
liable for any damages arising from the use of this software.
|
||||
|
||||
Permission is granted to anyone to use this software for
|
||||
any purpose, including commercial applications, and to alter
|
||||
it and redistribute it freely, subject to the following restrictions:
|
||||
|
||||
1. The origin of this software must not be misrepresented;
|
||||
you must not claim that you wrote the original software.
|
||||
If you use this software in a product, an acknowledgment
|
||||
in the product documentation would be appreciated but
|
||||
is not required.
|
||||
|
||||
2. Altered source versions must be plainly marked as such,
|
||||
and must not be misrepresented as being the original software.
|
||||
|
||||
3. This notice may not be removed or altered from any
|
||||
source distribution.
|
||||
|
||||
----------------------------------------------------------------------
|
||||
TRex implements the following expressions
|
||||
|
||||
\ Quote the next metacharacter
|
||||
^ Match the beginning of the string
|
||||
. Match any character
|
||||
$ Match the end of the string
|
||||
| Alternation
|
||||
() Grouping (creates a capture)
|
||||
[] Character class
|
||||
|
||||
==GREEDY CLOSURES==
|
||||
* Match 0 or more times
|
||||
+ Match 1 or more times
|
||||
? Match 1 or 0 times
|
||||
{n} Match exactly n times
|
||||
{n,} Match at least n times
|
||||
{n,m} Match at least n but not more than m times
|
||||
|
||||
==ESCAPE CHARACTERS==
|
||||
\t tab (HT, TAB)
|
||||
\n newline (LF, NL)
|
||||
\r return (CR)
|
||||
\f form feed (FF)
|
||||
|
||||
==PREDEFINED CLASSES==
|
||||
\l lowercase next char
|
||||
\u uppercase next char
|
||||
\a letters
|
||||
\A non letters
|
||||
\w alphanimeric [0-9a-zA-Z]
|
||||
\W non alphanimeric
|
||||
\s space
|
||||
\S non space
|
||||
\d digits
|
||||
\D non nondigits
|
||||
\x exadecimal digits
|
||||
\X non exadecimal digits
|
||||
\c control charactrs
|
||||
\C non control charactrs
|
||||
\p punctation
|
||||
\P non punctation
|
||||
\b word boundary
|
||||
\B non word boundary
|
||||
|
||||
----------------------------------------------------------------------
|
||||
API DOC
|
||||
----------------------------------------------------------------------
|
||||
TRex *trex_compile(const TRexChar *pattern,const TRexChar **error);
|
||||
|
||||
compiles an expression and returns a pointer to the compiled version.
|
||||
in case of failure returns NULL.The returned object has to be deleted
|
||||
through the function trex_free().
|
||||
|
||||
pattern
|
||||
a pointer to a zero terminated string containing the pattern that
|
||||
has to be compiled.
|
||||
error
|
||||
apointer to a string pointer that will be set with an error string
|
||||
in case of failure.
|
||||
|
||||
----------------------------------------------------------------------
|
||||
void trex_free(TRex *exp)
|
||||
|
||||
deletes a expression structure created with trex_compile()
|
||||
|
||||
exp
|
||||
the expression structure that has to be deleted
|
||||
|
||||
----------------------------------------------------------------------
|
||||
TRexBool trex_match(TRex* exp,const TRexChar* text)
|
||||
|
||||
returns TRex_True if the string specified in the parameter text is an
|
||||
exact match of the expression, otherwise returns TRex_False.
|
||||
|
||||
exp
|
||||
the compiled expression
|
||||
text
|
||||
the string that has to be tested
|
||||
|
||||
----------------------------------------------------------------------
|
||||
TRexBool trex_search(TRex* exp,const TRexChar* text, const TRexChar** out_begin, const TRexChar** out_end)
|
||||
|
||||
searches the first match of the expressin in the string specified in the parameter text.
|
||||
if the match is found returns TRex_True and the sets out_begin to the beginning of the
|
||||
match and out_end at the end of the match; otherwise returns TRex_False.
|
||||
|
||||
exp
|
||||
the compiled expression
|
||||
text
|
||||
the string that has to be tested
|
||||
out_begin
|
||||
a pointer to a string pointer that will be set with the beginning of the match
|
||||
out_end
|
||||
a pointer to a string pointer that will be set with the end of the match
|
||||
|
||||
----------------------------------------------------------------------
|
||||
TREX_API TRexBool trex_searchrange(TRex* exp,const TRexChar* text_begin,const TRexChar* text_end,const TRexChar** out_begin, const TRexChar** out_end)
|
||||
|
||||
searches the first match of the expressin in the string delimited
|
||||
by the parameter text_begin and text_end.
|
||||
if the match is found returns TRex_True and the sets out_begin to the beginning of the
|
||||
match and out_end at the end of the match; otherwise returns TRex_False.
|
||||
|
||||
exp
|
||||
the compiled expression
|
||||
text_begin
|
||||
a pointer to the beginnning of the string that has to be tested
|
||||
text_end
|
||||
a pointer to the end of the string that has to be tested
|
||||
out_begin
|
||||
a pointer to a string pointer that will be set with the beginning of the match
|
||||
out_end
|
||||
a pointer to a string pointer that will be set with the end of the match
|
||||
|
||||
----------------------------------------------------------------------
|
||||
int trex_getsubexpcount(TRex* exp)
|
||||
|
||||
returns the number of sub expressions matched by the expression
|
||||
|
||||
exp
|
||||
the compiled expression
|
||||
|
||||
---------------------------------------------------------------------
|
||||
TRexBool trex_getsubexp(TRex* exp, int n, TRexMatch *submatch)
|
||||
|
||||
retrieve the begin and and pointer to the length of the sub expression indexed
|
||||
by n. The result is passed trhough the struct TRexMatch:
|
||||
|
||||
typedef struct {
|
||||
const TRexChar *begin;
|
||||
int len;
|
||||
} TRexMatch;
|
||||
|
||||
the function returns TRex_True if n is valid index otherwise TRex_False.
|
||||
|
||||
exp
|
||||
the compiled expression
|
||||
n
|
||||
the index of the submatch
|
||||
submatch
|
||||
a pointer to structure that will store the result
|
||||
|
||||
this function works also after a match operation has been performend.
|
||||
|
@ -1,163 +0,0 @@
|
||||
/*************************************************/
|
||||
/* regex.cpp */
|
||||
/*************************************************/
|
||||
/* This file is part of: */
|
||||
/* GODOT ENGINE */
|
||||
/*************************************************/
|
||||
/* Source code within this file is: */
|
||||
/* (c) 2007-2010 Juan Linietsky, Ariel Manzur */
|
||||
/* All Rights Reserved. */
|
||||
/*************************************************/
|
||||
|
||||
#include "regex.h"
|
||||
|
||||
extern "C" {
|
||||
|
||||
#define _UNICODE
|
||||
#include "trex.h"
|
||||
|
||||
};
|
||||
|
||||
void RegEx::_bind_methods() {
|
||||
|
||||
ObjectTypeDB::bind_method(_MD("compile","pattern"),&RegEx::compile);
|
||||
ObjectTypeDB::bind_method(_MD("find","text", "start","end"),&RegEx::_bind_find, DEFVAL(0), DEFVAL(-1));
|
||||
ObjectTypeDB::bind_method(_MD("get_captures"),&RegEx::_bind_get_captures);
|
||||
};
|
||||
|
||||
Error RegEx::compile(const String& p_pattern) {
|
||||
|
||||
clear();
|
||||
const TRexChar* error;
|
||||
exp = trex_compile(p_pattern.c_str(), &error);
|
||||
ERR_FAIL_COND_V(!exp, FAILED);
|
||||
return OK;
|
||||
};
|
||||
|
||||
|
||||
int RegEx::_bind_find(const String& p_text, int p_start, int p_end) const {
|
||||
|
||||
int start, end;
|
||||
bool ret = find(p_text, start, end, NULL, p_start, p_end);
|
||||
|
||||
return ret?start:-1;
|
||||
};
|
||||
|
||||
bool RegEx::find(const String& p_text, int& p_rstart, int &p_rend, List<String>* p_captures, int p_start, int p_end) const {
|
||||
|
||||
ERR_FAIL_COND_V( !exp, false );
|
||||
text=p_text;
|
||||
|
||||
const CharType* str = p_text.c_str();
|
||||
const CharType* start = str + p_start;
|
||||
const CharType* end = str + (p_end == -1?p_text.size():p_end);
|
||||
|
||||
const CharType* out_begin;
|
||||
const CharType* out_end;
|
||||
|
||||
bool ret = trex_searchrange(exp, start, end, &out_begin, &out_end);
|
||||
if (ret) {
|
||||
|
||||
p_rstart = out_begin - str;
|
||||
p_rend = out_end - str;
|
||||
|
||||
if (p_captures) {
|
||||
|
||||
int count = get_capture_count();
|
||||
for (int i=0; i<count; i++) {
|
||||
|
||||
int start, len;
|
||||
get_capture_limits(i, start, len);
|
||||
p_captures->push_back(p_text.substr(start, len));
|
||||
};
|
||||
};
|
||||
} else {
|
||||
|
||||
p_rstart = -1;
|
||||
};
|
||||
|
||||
return ret;
|
||||
};
|
||||
|
||||
|
||||
bool RegEx::match(const String& p_text, List<String>* p_captures, int p_start, int p_end) const {
|
||||
|
||||
ERR_FAIL_COND_V( !exp, false );
|
||||
|
||||
int start, end;
|
||||
return find(p_text, start, end, p_captures, p_start, p_end);
|
||||
};
|
||||
|
||||
int RegEx::get_capture_count() const {
|
||||
|
||||
ERR_FAIL_COND_V( exp == NULL, -1 );
|
||||
|
||||
return trex_getsubexpcount(exp);
|
||||
};
|
||||
|
||||
Error RegEx::get_capture_limits(int p_capture, int& p_start, int& p_len) const {
|
||||
|
||||
ERR_FAIL_COND_V( exp == NULL, ERR_UNCONFIGURED );
|
||||
|
||||
TRexMatch match;
|
||||
TRexBool res = trex_getsubexp(exp, p_capture, &match);
|
||||
ERR_FAIL_COND_V( !res, FAILED );
|
||||
p_start = (int)(match.begin - text.c_str());
|
||||
p_len = match.len;
|
||||
|
||||
return OK;
|
||||
};
|
||||
|
||||
String RegEx::get_capture(int p_idx) const {
|
||||
|
||||
ERR_FAIL_COND_V( exp == NULL, "" );
|
||||
int start, len;
|
||||
Error ret = get_capture_limits(p_idx, start, len);
|
||||
ERR_FAIL_COND_V(ret != OK, "");
|
||||
if (len == 0)
|
||||
return "";
|
||||
return text.substr(start, len);
|
||||
};
|
||||
|
||||
StringArray RegEx::_bind_get_captures() const {
|
||||
|
||||
StringArray ret;
|
||||
int count = get_capture_count();
|
||||
for (int i=0; i<count; i++) {
|
||||
|
||||
String c = get_capture(i);
|
||||
ret.push_back(c);
|
||||
};
|
||||
|
||||
return ret;
|
||||
};
|
||||
|
||||
bool RegEx::is_valid() const {
|
||||
|
||||
return exp != NULL;
|
||||
};
|
||||
|
||||
void RegEx::clear() {
|
||||
|
||||
if (exp) {
|
||||
|
||||
trex_free(exp);
|
||||
exp = NULL;
|
||||
};
|
||||
};
|
||||
|
||||
RegEx::RegEx(const String& p_pattern) {
|
||||
|
||||
exp = NULL;
|
||||
compile(p_pattern);
|
||||
};
|
||||
|
||||
RegEx::RegEx() {
|
||||
|
||||
exp = NULL;
|
||||
};
|
||||
|
||||
RegEx::~RegEx() {
|
||||
|
||||
clear();
|
||||
};
|
@ -1,41 +0,0 @@
|
||||
#include "trex.h"
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
|
||||
#ifdef _UNICODE
|
||||
#define trex_sprintf swprintf
|
||||
#else
|
||||
#define trex_sprintf sprintf
|
||||
#endif
|
||||
|
||||
int main(int argc, char* argv[])
|
||||
{
|
||||
const TRexChar *begin,*end;
|
||||
TRexChar sTemp[200];
|
||||
const TRexChar *error = NULL;
|
||||
TRex *x = trex_compile(_TREXC("(x{1,5})xx"),&error);
|
||||
if(x) {
|
||||
trex_sprintf(sTemp,_TREXC("xxxxxxx"));
|
||||
if(trex_search(x,sTemp,&begin,&end))
|
||||
{
|
||||
int i,n = trex_getsubexpcount(x);
|
||||
TRexMatch match;
|
||||
for(i = 0; i < n; i++)
|
||||
{
|
||||
TRexChar t[200];
|
||||
trex_getsubexp(x,i,&match);
|
||||
trex_sprintf(t,_TREXC("[%%d]%%.%ds\n"),match.len);
|
||||
trex_printf(t,i,match.begin);
|
||||
}
|
||||
trex_printf(_TREXC("match! %d sub matches\n"),trex_getsubexpcount(x));
|
||||
}
|
||||
else {
|
||||
trex_printf(_TREXC("no match!\n"));
|
||||
}
|
||||
trex_free(x);
|
||||
}
|
||||
else {
|
||||
trex_printf(_TREXC("compilation error [%s]!\n"),error?error:_TREXC("undefined"));
|
||||
}
|
||||
return 0;
|
||||
}
|
@ -1,643 +0,0 @@
|
||||
/* see copyright notice in trex.h */
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
#include <ctype.h>
|
||||
#include <setjmp.h>
|
||||
#include "trex.h"
|
||||
|
||||
#ifdef _UINCODE
|
||||
#define scisprint iswprint
|
||||
#define scstrlen wcslen
|
||||
#define scprintf wprintf
|
||||
#define _SC(x) L##c
|
||||
#else
|
||||
#define scisprint isprint
|
||||
#define scstrlen strlen
|
||||
#define scprintf printf
|
||||
#define _SC(x) (x)
|
||||
#endif
|
||||
|
||||
#ifdef _DEBUG
|
||||
#include <stdio.h>
|
||||
|
||||
static const TRexChar *g_nnames[] =
|
||||
{
|
||||
_SC("NONE"),_SC("OP_GREEDY"), _SC("OP_OR"),
|
||||
_SC("OP_EXPR"),_SC("OP_NOCAPEXPR"),_SC("OP_DOT"), _SC("OP_CLASS"),
|
||||
_SC("OP_CCLASS"),_SC("OP_NCLASS"),_SC("OP_RANGE"),_SC("OP_CHAR"),
|
||||
_SC("OP_EOL"),_SC("OP_BOL"),_SC("OP_WB")
|
||||
};
|
||||
|
||||
#endif
|
||||
#define OP_GREEDY (MAX_CHAR+1) // * + ? {n}
|
||||
#define OP_OR (MAX_CHAR+2)
|
||||
#define OP_EXPR (MAX_CHAR+3) //parentesis ()
|
||||
#define OP_NOCAPEXPR (MAX_CHAR+4) //parentesis (?:)
|
||||
#define OP_DOT (MAX_CHAR+5)
|
||||
#define OP_CLASS (MAX_CHAR+6)
|
||||
#define OP_CCLASS (MAX_CHAR+7)
|
||||
#define OP_NCLASS (MAX_CHAR+8) //negates class the [^
|
||||
#define OP_RANGE (MAX_CHAR+9)
|
||||
#define OP_CHAR (MAX_CHAR+10)
|
||||
#define OP_EOL (MAX_CHAR+11)
|
||||
#define OP_BOL (MAX_CHAR+12)
|
||||
#define OP_WB (MAX_CHAR+13)
|
||||
|
||||
#define TREX_SYMBOL_ANY_CHAR ('.')
|
||||
#define TREX_SYMBOL_GREEDY_ONE_OR_MORE ('+')
|
||||
#define TREX_SYMBOL_GREEDY_ZERO_OR_MORE ('*')
|
||||
#define TREX_SYMBOL_GREEDY_ZERO_OR_ONE ('?')
|
||||
#define TREX_SYMBOL_BRANCH ('|')
|
||||
#define TREX_SYMBOL_END_OF_STRING ('$')
|
||||
#define TREX_SYMBOL_BEGINNING_OF_STRING ('^')
|
||||
#define TREX_SYMBOL_ESCAPE_CHAR ('\\')
|
||||
|
||||
|
||||
typedef int TRexNodeType;
|
||||
|
||||
typedef struct tagTRexNode{
|
||||
TRexNodeType type;
|
||||
int left;
|
||||
int right;
|
||||
int next;
|
||||
}TRexNode;
|
||||
|
||||
struct TRex{
|
||||
const TRexChar *_eol;
|
||||
const TRexChar *_bol;
|
||||
const TRexChar *_p;
|
||||
int _first;
|
||||
int _op;
|
||||
TRexNode *_nodes;
|
||||
int _nallocated;
|
||||
int _nsize;
|
||||
int _nsubexpr;
|
||||
TRexMatch *_matches;
|
||||
int _currsubexp;
|
||||
void *_jmpbuf;
|
||||
const TRexChar **_error;
|
||||
};
|
||||
|
||||
static int trex_list(TRex *exp);
|
||||
|
||||
static int trex_newnode(TRex *exp, TRexNodeType type)
|
||||
{
|
||||
TRexNode n;
|
||||
int newid;
|
||||
n.type = type;
|
||||
n.next = n.right = n.left = -1;
|
||||
if(type == OP_EXPR)
|
||||
n.right = exp->_nsubexpr++;
|
||||
if(exp->_nallocated < (exp->_nsize + 1)) {
|
||||
//int oldsize = exp->_nallocated;
|
||||
exp->_nallocated *= 2;
|
||||
exp->_nodes = (TRexNode *)realloc(exp->_nodes, exp->_nallocated * sizeof(TRexNode));
|
||||
}
|
||||
exp->_nodes[exp->_nsize++] = n;
|
||||
newid = exp->_nsize - 1;
|
||||
return (int)newid;
|
||||
}
|
||||
|
||||
static void trex_error(TRex *exp,const TRexChar *error)
|
||||
{
|
||||
if(exp->_error) *exp->_error = error;
|
||||
longjmp(*((jmp_buf*)exp->_jmpbuf),-1);
|
||||
}
|
||||
|
||||
static void trex_expect(TRex *exp, int n){
|
||||
if((*exp->_p) != n)
|
||||
trex_error(exp, _SC("expected paren"));
|
||||
exp->_p++;
|
||||
}
|
||||
|
||||
static TRexChar trex_escapechar(TRex *exp)
|
||||
{
|
||||
if(*exp->_p == TREX_SYMBOL_ESCAPE_CHAR){
|
||||
exp->_p++;
|
||||
switch(*exp->_p) {
|
||||
case 'v': exp->_p++; return '\v';
|
||||
case 'n': exp->_p++; return '\n';
|
||||
case 't': exp->_p++; return '\t';
|
||||
case 'r': exp->_p++; return '\r';
|
||||
case 'f': exp->_p++; return '\f';
|
||||
default: return (*exp->_p++);
|
||||
}
|
||||
} else if(!scisprint(*exp->_p)) trex_error(exp,_SC("letter expected"));
|
||||
return (*exp->_p++);
|
||||
}
|
||||
|
||||
static int trex_charclass(TRex *exp,int classid)
|
||||
{
|
||||
int n = trex_newnode(exp,OP_CCLASS);
|
||||
exp->_nodes[n].left = classid;
|
||||
return n;
|
||||
}
|
||||
|
||||
static int trex_charnode(TRex *exp,TRexBool isclass)
|
||||
{
|
||||
TRexChar t;
|
||||
if(*exp->_p == TREX_SYMBOL_ESCAPE_CHAR) {
|
||||
exp->_p++;
|
||||
switch(*exp->_p) {
|
||||
case 'n': exp->_p++; return trex_newnode(exp,'\n');
|
||||
case 't': exp->_p++; return trex_newnode(exp,'\t');
|
||||
case 'r': exp->_p++; return trex_newnode(exp,'\r');
|
||||
case 'f': exp->_p++; return trex_newnode(exp,'\f');
|
||||
case 'v': exp->_p++; return trex_newnode(exp,'\v');
|
||||
case 'a': case 'A': case 'w': case 'W': case 's': case 'S':
|
||||
case 'd': case 'D': case 'x': case 'X': case 'c': case 'C':
|
||||
case 'p': case 'P': case 'l': case 'u':
|
||||
{
|
||||
t = *exp->_p; exp->_p++;
|
||||
return trex_charclass(exp,t);
|
||||
}
|
||||
case 'b':
|
||||
case 'B':
|
||||
if(!isclass) {
|
||||
int node = trex_newnode(exp,OP_WB);
|
||||
exp->_nodes[node].left = *exp->_p;
|
||||
exp->_p++;
|
||||
return node;
|
||||
} //else default
|
||||
default:
|
||||
t = *exp->_p; exp->_p++;
|
||||
return trex_newnode(exp,t);
|
||||
}
|
||||
}
|
||||
else if(!scisprint(*exp->_p)) {
|
||||
|
||||
trex_error(exp,_SC("letter expected"));
|
||||
}
|
||||
t = *exp->_p; exp->_p++;
|
||||
return trex_newnode(exp,t);
|
||||
}
|
||||
static int trex_class(TRex *exp)
|
||||
{
|
||||
int ret = -1;
|
||||
int first = -1,chain;
|
||||
if(*exp->_p == TREX_SYMBOL_BEGINNING_OF_STRING){
|
||||
ret = trex_newnode(exp,OP_NCLASS);
|
||||
exp->_p++;
|
||||
}else ret = trex_newnode(exp,OP_CLASS);
|
||||
|
||||
if(*exp->_p == ']') trex_error(exp,_SC("empty class"));
|
||||
chain = ret;
|
||||
while(*exp->_p != ']' && exp->_p != exp->_eol) {
|
||||
if(*exp->_p == '-' && first != -1){
|
||||
int r,t;
|
||||
if(*exp->_p++ == ']') trex_error(exp,_SC("unfinished range"));
|
||||
r = trex_newnode(exp,OP_RANGE);
|
||||
if(first>*exp->_p) trex_error(exp,_SC("invalid range"));
|
||||
if(exp->_nodes[first].type == OP_CCLASS) trex_error(exp,_SC("cannot use character classes in ranges"));
|
||||
exp->_nodes[r].left = exp->_nodes[first].type;
|
||||
t = trex_escapechar(exp);
|
||||
exp->_nodes[r].right = t;
|
||||
exp->_nodes[chain].next = r;
|
||||
chain = r;
|
||||
first = -1;
|
||||
}
|
||||
else{
|
||||
if(first!=-1){
|
||||
int c = first;
|
||||
exp->_nodes[chain].next = c;
|
||||
chain = c;
|
||||
first = trex_charnode(exp,TRex_True);
|
||||
}
|
||||
else{
|
||||
first = trex_charnode(exp,TRex_True);
|
||||
}
|
||||
}
|
||||
}
|
||||
if(first!=-1){
|
||||
int c = first;
|
||||
exp->_nodes[chain].next = c;
|
||||
chain = c;
|
||||
first = -1;
|
||||
}
|
||||
/* hack? */
|
||||
exp->_nodes[ret].left = exp->_nodes[ret].next;
|
||||
exp->_nodes[ret].next = -1;
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int trex_parsenumber(TRex *exp)
|
||||
{
|
||||
int ret = *exp->_p-'0';
|
||||
int positions = 10;
|
||||
exp->_p++;
|
||||
while(isdigit(*exp->_p)) {
|
||||
ret = ret*10+(*exp->_p++-'0');
|
||||
if(positions==1000000000) trex_error(exp,_SC("overflow in numeric constant"));
|
||||
positions *= 10;
|
||||
};
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int trex_element(TRex *exp)
|
||||
{
|
||||
int ret = -1;
|
||||
switch(*exp->_p)
|
||||
{
|
||||
case '(': {
|
||||
int expr,newn;
|
||||
exp->_p++;
|
||||
|
||||
|
||||
if(*exp->_p =='?') {
|
||||
exp->_p++;
|
||||
trex_expect(exp,':');
|
||||
expr = trex_newnode(exp,OP_NOCAPEXPR);
|
||||
}
|
||||
else
|
||||
expr = trex_newnode(exp,OP_EXPR);
|
||||
newn = trex_list(exp);
|
||||
exp->_nodes[expr].left = newn;
|
||||
ret = expr;
|
||||
trex_expect(exp,')');
|
||||
}
|
||||
break;
|
||||
case '[':
|
||||
exp->_p++;
|
||||
ret = trex_class(exp);
|
||||
trex_expect(exp,']');
|
||||
break;
|
||||
case TREX_SYMBOL_END_OF_STRING: exp->_p++; ret = trex_newnode(exp,OP_EOL);break;
|
||||
case TREX_SYMBOL_ANY_CHAR: exp->_p++; ret = trex_newnode(exp,OP_DOT);break;
|
||||
default:
|
||||
ret = trex_charnode(exp,TRex_False);
|
||||
break;
|
||||
}
|
||||
|
||||
{
|
||||
int op;
|
||||
TRexBool isgreedy = TRex_False;
|
||||
unsigned short p0 = 0, p1 = 0;
|
||||
switch(*exp->_p){
|
||||
case TREX_SYMBOL_GREEDY_ZERO_OR_MORE: p0 = 0; p1 = 0xFFFF; exp->_p++; isgreedy = TRex_True; break;
|
||||
case TREX_SYMBOL_GREEDY_ONE_OR_MORE: p0 = 1; p1 = 0xFFFF; exp->_p++; isgreedy = TRex_True; break;
|
||||
case TREX_SYMBOL_GREEDY_ZERO_OR_ONE: p0 = 0; p1 = 1; exp->_p++; isgreedy = TRex_True; break;
|
||||
case '{':
|
||||
exp->_p++;
|
||||
if(!isdigit(*exp->_p)) trex_error(exp,_SC("number expected"));
|
||||
p0 = (unsigned short)trex_parsenumber(exp);
|
||||
/*******************************/
|
||||
switch(*exp->_p) {
|
||||
case '}':
|
||||
p1 = p0; exp->_p++;
|
||||
break;
|
||||
case ',':
|
||||
exp->_p++;
|
||||
p1 = 0xFFFF;
|
||||
if(isdigit(*exp->_p)){
|
||||
p1 = (unsigned short)trex_parsenumber(exp);
|
||||
}
|
||||
trex_expect(exp,'}');
|
||||
break;
|
||||
default:
|
||||
trex_error(exp,_SC(", or } expected"));
|
||||
}
|
||||
/*******************************/
|
||||
isgreedy = TRex_True;
|
||||
break;
|
||||
|
||||
}
|
||||
if(isgreedy) {
|
||||
int nnode = trex_newnode(exp,OP_GREEDY);
|
||||
op = OP_GREEDY;
|
||||
exp->_nodes[nnode].left = ret;
|
||||
exp->_nodes[nnode].right = ((p0)<<16)|p1;
|
||||
ret = nnode;
|
||||
}
|
||||
}
|
||||
if((*exp->_p != TREX_SYMBOL_BRANCH) && (*exp->_p != ')') && (*exp->_p != TREX_SYMBOL_GREEDY_ZERO_OR_MORE) && (*exp->_p != TREX_SYMBOL_GREEDY_ONE_OR_MORE) && (*exp->_p != '\0')) {
|
||||
int nnode = trex_element(exp);
|
||||
exp->_nodes[ret].next = nnode;
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int trex_list(TRex *exp)
|
||||
{
|
||||
int ret=-1,e;
|
||||
if(*exp->_p == TREX_SYMBOL_BEGINNING_OF_STRING) {
|
||||
exp->_p++;
|
||||
ret = trex_newnode(exp,OP_BOL);
|
||||
}
|
||||
e = trex_element(exp);
|
||||
if(ret != -1) {
|
||||
exp->_nodes[ret].next = e;
|
||||
}
|
||||
else ret = e;
|
||||
|
||||
if(*exp->_p == TREX_SYMBOL_BRANCH) {
|
||||
int temp,tright;
|
||||
exp->_p++;
|
||||
temp = trex_newnode(exp,OP_OR);
|
||||
exp->_nodes[temp].left = ret;
|
||||
tright = trex_list(exp);
|
||||
exp->_nodes[temp].right = tright;
|
||||
ret = temp;
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
static TRexBool trex_matchcclass(int cclass,TRexChar c)
|
||||
{
|
||||
switch(cclass) {
|
||||
case 'a': return isalpha(c)?TRex_True:TRex_False;
|
||||
case 'A': return !isalpha(c)?TRex_True:TRex_False;
|
||||
case 'w': return (isalnum(c) || c == '_')?TRex_True:TRex_False;
|
||||
case 'W': return (!isalnum(c) && c != '_')?TRex_True:TRex_False;
|
||||
case 's': return isspace(c)?TRex_True:TRex_False;
|
||||
case 'S': return !isspace(c)?TRex_True:TRex_False;
|
||||
case 'd': return isdigit(c)?TRex_True:TRex_False;
|
||||
case 'D': return !isdigit(c)?TRex_True:TRex_False;
|
||||
case 'x': return isxdigit(c)?TRex_True:TRex_False;
|
||||
case 'X': return !isxdigit(c)?TRex_True:TRex_False;
|
||||
case 'c': return iscntrl(c)?TRex_True:TRex_False;
|
||||
case 'C': return !iscntrl(c)?TRex_True:TRex_False;
|
||||
case 'p': return ispunct(c)?TRex_True:TRex_False;
|
||||
case 'P': return !ispunct(c)?TRex_True:TRex_False;
|
||||
case 'l': return islower(c)?TRex_True:TRex_False;
|
||||
case 'u': return isupper(c)?TRex_True:TRex_False;
|
||||
}
|
||||
return TRex_False; /*cannot happen*/
|
||||
}
|
||||
|
||||
static TRexBool trex_matchclass(TRex* exp,TRexNode *node,TRexChar c)
|
||||
{
|
||||
do {
|
||||
switch(node->type) {
|
||||
case OP_RANGE:
|
||||
if(c >= node->left && c <= node->right) return TRex_True;
|
||||
break;
|
||||
case OP_CCLASS:
|
||||
if(trex_matchcclass(node->left,c)) return TRex_True;
|
||||
break;
|
||||
default:
|
||||
if(c == node->type)return TRex_True;
|
||||
}
|
||||
} while((node->next != -1) && (node = &exp->_nodes[node->next]));
|
||||
return TRex_False;
|
||||
}
|
||||
|
||||
static const TRexChar *trex_matchnode(TRex* exp,TRexNode *node,const TRexChar *str,TRexNode *next)
|
||||
{
|
||||
|
||||
TRexNodeType type = node->type;
|
||||
switch(type) {
|
||||
case OP_GREEDY: {
|
||||
//TRexNode *greedystop = (node->next != -1) ? &exp->_nodes[node->next] : NULL;
|
||||
TRexNode *greedystop = NULL;
|
||||
int p0 = (node->right >> 16)&0x0000FFFF, p1 = node->right&0x0000FFFF, nmaches = 0;
|
||||
const TRexChar *s=str, *good = str;
|
||||
|
||||
if(node->next != -1) {
|
||||
greedystop = &exp->_nodes[node->next];
|
||||
}
|
||||
else {
|
||||
greedystop = next;
|
||||
}
|
||||
|
||||
while((nmaches == 0xFFFF || nmaches < p1)) {
|
||||
|
||||
const TRexChar *stop;
|
||||
if(!(s = trex_matchnode(exp,&exp->_nodes[node->left],s,greedystop)))
|
||||
break;
|
||||
nmaches++;
|
||||
good=s;
|
||||
if(greedystop) {
|
||||
//checks that 0 matches satisfy the expression(if so skips)
|
||||
//if not would always stop(for instance if is a '?')
|
||||
if(greedystop->type != OP_GREEDY ||
|
||||
(greedystop->type == OP_GREEDY && ((greedystop->right >> 16)&0x0000FFFF) != 0))
|
||||
{
|
||||
TRexNode *gnext = NULL;
|
||||
if(greedystop->next != -1) {
|
||||
gnext = &exp->_nodes[greedystop->next];
|
||||
}else if(next && next->next != -1){
|
||||
gnext = &exp->_nodes[next->next];
|
||||
}
|
||||
stop = trex_matchnode(exp,greedystop,s,gnext);
|
||||
if(stop) {
|
||||
//if satisfied stop it
|
||||
if(p0 == p1 && p0 == nmaches) break;
|
||||
else if(nmaches >= p0 && p1 == 0xFFFF) break;
|
||||
else if(nmaches >= p0 && nmaches <= p1) break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if(s >= exp->_eol)
|
||||
break;
|
||||
}
|
||||
if(p0 == p1 && p0 == nmaches) return good;
|
||||
else if(nmaches >= p0 && p1 == 0xFFFF) return good;
|
||||
else if(nmaches >= p0 && nmaches <= p1) return good;
|
||||
return NULL;
|
||||
}
|
||||
case OP_OR: {
|
||||
const TRexChar *asd = str;
|
||||
TRexNode *temp=&exp->_nodes[node->left];
|
||||
while( (asd = trex_matchnode(exp,temp,asd,NULL)) ) {
|
||||
if(temp->next != -1)
|
||||
temp = &exp->_nodes[temp->next];
|
||||
else
|
||||
return asd;
|
||||
}
|
||||
asd = str;
|
||||
temp = &exp->_nodes[node->right];
|
||||
while( (asd = trex_matchnode(exp,temp,asd,NULL)) ) {
|
||||
if(temp->next != -1)
|
||||
temp = &exp->_nodes[temp->next];
|
||||
else
|
||||
return asd;
|
||||
}
|
||||
return NULL;
|
||||
break;
|
||||
}
|
||||
case OP_EXPR:
|
||||
case OP_NOCAPEXPR:{
|
||||
TRexNode *n = &exp->_nodes[node->left];
|
||||
const TRexChar *cur = str;
|
||||
int capture = -1;
|
||||
if(node->type != OP_NOCAPEXPR && node->right == exp->_currsubexp) {
|
||||
capture = exp->_currsubexp;
|
||||
exp->_matches[capture].begin = cur;
|
||||
exp->_currsubexp++;
|
||||
}
|
||||
|
||||
do {
|
||||
TRexNode *subnext = NULL;
|
||||
if(n->next != -1) {
|
||||
subnext = &exp->_nodes[n->next];
|
||||
}else {
|
||||
subnext = next;
|
||||
}
|
||||
if(!(cur = trex_matchnode(exp,n,cur,subnext))) {
|
||||
if(capture != -1){
|
||||
exp->_matches[capture].begin = 0;
|
||||
exp->_matches[capture].len = 0;
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
} while((n->next != -1) && (n = &exp->_nodes[n->next]));
|
||||
|
||||
if(capture != -1)
|
||||
exp->_matches[capture].len = cur - exp->_matches[capture].begin;
|
||||
return cur;
|
||||
}
|
||||
case OP_WB:
|
||||
if((str == exp->_bol && !isspace(*str))
|
||||
|| (str == exp->_eol && !isspace(*(str-1)))
|
||||
|| (!isspace(*str) && isspace(*(str+1)))
|
||||
|| (isspace(*str) && !isspace(*(str+1))) ) {
|
||||
return (node->left == 'b')?str:NULL;
|
||||
}
|
||||
return (node->left == 'b')?NULL:str;
|
||||
case OP_BOL:
|
||||
if(str == exp->_bol) return str;
|
||||
return NULL;
|
||||
case OP_EOL:
|
||||
if(str == exp->_eol) return str;
|
||||
return NULL;
|
||||
case OP_DOT:{
|
||||
*str++;
|
||||
}
|
||||
return str;
|
||||
case OP_NCLASS:
|
||||
case OP_CLASS:
|
||||
if(trex_matchclass(exp,&exp->_nodes[node->left],*str)?(type == OP_CLASS?TRex_True:TRex_False):(type == OP_NCLASS?TRex_True:TRex_False)) {
|
||||
*str++;
|
||||
return str;
|
||||
}
|
||||
return NULL;
|
||||
case OP_CCLASS:
|
||||
if(trex_matchcclass(node->left,*str)) {
|
||||
*str++;
|
||||
return str;
|
||||
}
|
||||
return NULL;
|
||||
default: /* char */
|
||||
if(*str != node->type) return NULL;
|
||||
*str++;
|
||||
return str;
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* public api */
|
||||
TRex *trex_compile(const TRexChar *pattern,const TRexChar **error)
|
||||
{
|
||||
TRex *exp = (TRex *)malloc(sizeof(TRex));
|
||||
exp->_eol = exp->_bol = NULL;
|
||||
exp->_p = pattern;
|
||||
exp->_nallocated = (int)scstrlen(pattern) * sizeof(TRexChar);
|
||||
exp->_nodes = (TRexNode *)malloc(exp->_nallocated * sizeof(TRexNode));
|
||||
exp->_nsize = 0;
|
||||
exp->_matches = 0;
|
||||
exp->_nsubexpr = 0;
|
||||
exp->_first = trex_newnode(exp,OP_EXPR);
|
||||
exp->_error = error;
|
||||
exp->_jmpbuf = malloc(sizeof(jmp_buf));
|
||||
if(setjmp(*((jmp_buf*)exp->_jmpbuf)) == 0) {
|
||||
int res = trex_list(exp);
|
||||
exp->_nodes[exp->_first].left = res;
|
||||
if(*exp->_p!='\0')
|
||||
trex_error(exp,_SC("unexpected character"));
|
||||
#ifdef _DEBUG
|
||||
{
|
||||
int nsize,i;
|
||||
TRexNode *t;
|
||||
nsize = exp->_nsize;
|
||||
t = &exp->_nodes[0];
|
||||
scprintf(_SC("\n"));
|
||||
for(i = 0;i < nsize; i++) {
|
||||
if(exp->_nodes[i].type>MAX_CHAR)
|
||||
scprintf(_SC("[%02d] %10s "),i,g_nnames[exp->_nodes[i].type-MAX_CHAR]);
|
||||
else
|
||||
scprintf(_SC("[%02d] %10c "),i,exp->_nodes[i].type);
|
||||
scprintf(_SC("left %02d right %02d next %02d\n"),exp->_nodes[i].left,exp->_nodes[i].right,exp->_nodes[i].next);
|
||||
}
|
||||
scprintf(_SC("\n"));
|
||||
}
|
||||
#endif
|
||||
exp->_matches = (TRexMatch *) malloc(exp->_nsubexpr * sizeof(TRexMatch));
|
||||
memset(exp->_matches,0,exp->_nsubexpr * sizeof(TRexMatch));
|
||||
}
|
||||
else{
|
||||
trex_free(exp);
|
||||
return NULL;
|
||||
}
|
||||
return exp;
|
||||
}
|
||||
|
||||
void trex_free(TRex *exp)
|
||||
{
|
||||
if(exp) {
|
||||
if(exp->_nodes) free(exp->_nodes);
|
||||
if(exp->_jmpbuf) free(exp->_jmpbuf);
|
||||
if(exp->_matches) free(exp->_matches);
|
||||
free(exp);
|
||||
}
|
||||
}
|
||||
|
||||
TRexBool trex_match(TRex* exp,const TRexChar* text)
|
||||
{
|
||||
const TRexChar* res = NULL;
|
||||
exp->_bol = text;
|
||||
exp->_eol = text + scstrlen(text);
|
||||
exp->_currsubexp = 0;
|
||||
res = trex_matchnode(exp,exp->_nodes,text,NULL);
|
||||
if(res == NULL || res != exp->_eol)
|
||||
return TRex_False;
|
||||
return TRex_True;
|
||||
}
|
||||
|
||||
TRexBool trex_searchrange(TRex* exp,const TRexChar* text_begin,const TRexChar* text_end,const TRexChar** out_begin, const TRexChar** out_end)
|
||||
{
|
||||
const TRexChar *cur = NULL;
|
||||
int node = exp->_first;
|
||||
if(text_begin >= text_end) return TRex_False;
|
||||
exp->_bol = text_begin;
|
||||
exp->_eol = text_end;
|
||||
do {
|
||||
cur = text_begin;
|
||||
while(node != -1) {
|
||||
exp->_currsubexp = 0;
|
||||
cur = trex_matchnode(exp,&exp->_nodes[node],cur,NULL);
|
||||
if(!cur)
|
||||
break;
|
||||
node = exp->_nodes[node].next;
|
||||
}
|
||||
*text_begin++;
|
||||
} while(cur == NULL && text_begin != text_end);
|
||||
|
||||
if(cur == NULL)
|
||||
return TRex_False;
|
||||
|
||||
--text_begin;
|
||||
|
||||
if(out_begin) *out_begin = text_begin;
|
||||
if(out_end) *out_end = cur;
|
||||
return TRex_True;
|
||||
}
|
||||
|
||||
TRexBool trex_search(TRex* exp,const TRexChar* text, const TRexChar** out_begin, const TRexChar** out_end)
|
||||
{
|
||||
return trex_searchrange(exp,text,text + scstrlen(text),out_begin,out_end);
|
||||
}
|
||||
|
||||
int trex_getsubexpcount(TRex* exp)
|
||||
{
|
||||
return exp->_nsubexpr;
|
||||
}
|
||||
|
||||
TRexBool trex_getsubexp(TRex* exp, int n, TRexMatch *subexp)
|
||||
{
|
||||
if( n<0 || n >= exp->_nsubexpr) return TRex_False;
|
||||
*subexp = exp->_matches[n];
|
||||
return TRex_True;
|
||||
}
|
||||
|
@ -1,70 +0,0 @@
|
||||
#ifndef _TREX_H_
|
||||
#define _TREX_H_
|
||||
/***************************************************************
|
||||
T-Rex a tiny regular expression library
|
||||
|
||||
Copyright (C) 2003-2006 Alberto Demichelis
|
||||
|
||||
This software is provided 'as-is', without any express
|
||||
or implied warranty. In no event will the authors be held
|
||||
liable for any damages arising from the use of this software.
|
||||
|
||||
Permission is granted to anyone to use this software for
|
||||
any purpose, including commercial applications, and to alter
|
||||
it and redistribute it freely, subject to the following restrictions:
|
||||
|
||||
1. The origin of this software must not be misrepresented;
|
||||
you must not claim that you wrote the original software.
|
||||
If you use this software in a product, an acknowledgment
|
||||
in the product documentation would be appreciated but
|
||||
is not required.
|
||||
|
||||
2. Altered source versions must be plainly marked as such,
|
||||
and must not be misrepresented as being the original software.
|
||||
|
||||
3. This notice may not be removed or altered from any
|
||||
source distribution.
|
||||
|
||||
****************************************************************/
|
||||
|
||||
#define _UNICODE
|
||||
|
||||
|
||||
#ifdef _UNICODE
|
||||
#define TRexChar wchar_t
|
||||
#define MAX_CHAR 0xFFFF
|
||||
#define _TREXC(c) L##c
|
||||
#define trex_strlen wcslen
|
||||
#define trex_printf wprintf
|
||||
#else
|
||||
#define TRexChar char
|
||||
#define MAX_CHAR 0xFF
|
||||
#define _TREXC(c) (c)
|
||||
#define trex_strlen strlen
|
||||
#define trex_printf printf
|
||||
#endif
|
||||
|
||||
#ifndef TREX_API
|
||||
#define TREX_API extern
|
||||
#endif
|
||||
|
||||
#define TRex_True 1
|
||||
#define TRex_False 0
|
||||
|
||||
typedef unsigned int TRexBool;
|
||||
typedef struct TRex TRex;
|
||||
|
||||
typedef struct {
|
||||
const TRexChar *begin;
|
||||
int len;
|
||||
} TRexMatch;
|
||||
|
||||
TREX_API TRex *trex_compile(const TRexChar *pattern,const TRexChar **error);
|
||||
TREX_API void trex_free(TRex *exp);
|
||||
TREX_API TRexBool trex_match(TRex* exp,const TRexChar* text);
|
||||
TREX_API TRexBool trex_search(TRex* exp,const TRexChar* text, const TRexChar** out_begin, const TRexChar** out_end);
|
||||
TREX_API TRexBool trex_searchrange(TRex* exp,const TRexChar* text_begin,const TRexChar* text_end,const TRexChar** out_begin, const TRexChar** out_end);
|
||||
TREX_API int trex_getsubexpcount(TRex* exp);
|
||||
TREX_API TRexBool trex_getsubexp(TRex* exp, int n, TRexMatch *subexp);
|
||||
|
||||
#endif
|
@ -57,8 +57,14 @@
|
||||
#include <errno.h>
|
||||
#include <assert.h>
|
||||
#include "globals.h"
|
||||
|
||||
extern bool _print_error_enabled;
|
||||
|
||||
void OS_Unix::print_error(const char* p_function,const char* p_file,int p_line,const char *p_code,const char*p_rationale,ErrorType p_type) {
|
||||
|
||||
if (!_print_error_enabled)
|
||||
return;
|
||||
|
||||
if (p_rationale && p_rationale[0]) {
|
||||
|
||||
print("\E[1;31;40mERROR: %s: \E[1;37;40m%s\n",p_function,p_rationale);
|
||||
@ -217,6 +223,14 @@ uint64_t OS_Unix::get_unix_time() const {
|
||||
return time(NULL);
|
||||
};
|
||||
|
||||
uint64_t OS_Unix::get_system_time_msec() const {
|
||||
struct timeval tv_now;
|
||||
gettimeofday(&tv_now, NULL);
|
||||
localtime(&tv_now.tv_usec);
|
||||
uint64_t msec = tv_now.tv_usec/1000;
|
||||
return msec;
|
||||
}
|
||||
|
||||
|
||||
OS::Date OS_Unix::get_date(bool utc) const {
|
||||
|
||||
|
@ -93,6 +93,7 @@ public:
|
||||
virtual TimeZoneInfo get_time_zone_info() const;
|
||||
|
||||
virtual uint64_t get_unix_time() const;
|
||||
virtual uint64_t get_system_time_msec() const;
|
||||
|
||||
virtual void delay_usec(uint32_t p_usec) const;
|
||||
virtual uint64_t get_ticks_usec() const;
|
||||
|
@ -232,7 +232,7 @@ void AudioStreamOGGVorbis::seek_pos(float p_time) {
|
||||
|
||||
if (!playing)
|
||||
return;
|
||||
bool ok = ov_time_seek(&vf,p_time*1000)==0;
|
||||
bool ok = ov_time_seek(&vf,p_time)==0;
|
||||
ERR_FAIL_COND(!ok);
|
||||
frames_mixed=stream_srate*p_time;
|
||||
}
|
||||
|
@ -518,14 +518,14 @@ Error Main::setup(const char *execpath,int argc, char *argv[],bool p_second_phas
|
||||
}
|
||||
|
||||
|
||||
|
||||
GLOBAL_DEF("debug/max_remote_stdout_chars_per_second",2048);
|
||||
if (debug_mode == "remote") {
|
||||
|
||||
ScriptDebuggerRemote *sdr = memnew( ScriptDebuggerRemote );
|
||||
uint16_t debug_port = GLOBAL_DEF("debug/remote_port",6007);
|
||||
if (debug_host.find(":")!=-1) {
|
||||
debug_port=debug_host.get_slice(":",1).to_int();
|
||||
debug_host=debug_host.get_slice(":",0);
|
||||
debug_port=debug_host.get_slicec(':',1).to_int();
|
||||
debug_host=debug_host.get_slicec(':',0);
|
||||
}
|
||||
Error derr = sdr->connect_to_host(debug_host,debug_port);
|
||||
|
||||
@ -546,8 +546,8 @@ Error Main::setup(const char *execpath,int argc, char *argv[],bool p_second_phas
|
||||
file_access_network_client=memnew(FileAccessNetworkClient);
|
||||
int port;
|
||||
if (remotefs.find(":")!=-1) {
|
||||
port=remotefs.get_slice(":",1).to_int();
|
||||
remotefs=remotefs.get_slice(":",0);
|
||||
port=remotefs.get_slicec(':',1).to_int();
|
||||
remotefs=remotefs.get_slicec(':',0);
|
||||
} else {
|
||||
port=6010;
|
||||
}
|
||||
@ -605,6 +605,9 @@ Error Main::setup(const char *execpath,int argc, char *argv[],bool p_second_phas
|
||||
if (bool(Globals::get_singleton()->get("application/disable_stdout"))) {
|
||||
quiet_stdout=true;
|
||||
}
|
||||
if (bool(Globals::get_singleton()->get("application/disable_stderr"))) {
|
||||
_print_error_enabled = false;
|
||||
};
|
||||
|
||||
if (quiet_stdout)
|
||||
_print_line_enabled=false;
|
||||
@ -1219,7 +1222,7 @@ bool Main::start() {
|
||||
String s = E->get().name;
|
||||
if (!s.begins_with("autoload/"))
|
||||
continue;
|
||||
String name = s.get_slice("/",1);
|
||||
String name = s.get_slicec('/',1);
|
||||
String path = Globals::get_singleton()->get(s);
|
||||
RES res = ResourceLoader::load(path);
|
||||
ERR_EXPLAIN("Can't autoload: "+path);
|
||||
|
@ -29,6 +29,7 @@
|
||||
#include "gd_script.h"
|
||||
#include "gd_compiler.h"
|
||||
#include "globals.h"
|
||||
#include "os/file_access.h"
|
||||
|
||||
void GDScriptLanguage::get_comment_delimiters(List<String> *p_delimiters) const {
|
||||
|
||||
@ -238,26 +239,26 @@ void GDScriptLanguage::debug_get_stack_level_members(int p_level,List<String> *p
|
||||
if (_debug_parse_err_line>=0)
|
||||
return;
|
||||
|
||||
ERR_FAIL_INDEX(p_level,_debug_call_stack_pos);
|
||||
int l = _debug_call_stack_pos - p_level -1;
|
||||
ERR_FAIL_INDEX(p_level,_debug_call_stack_pos);
|
||||
int l = _debug_call_stack_pos - p_level -1;
|
||||
|
||||
|
||||
GDInstance *instance = _call_stack[l].instance;
|
||||
GDInstance *instance = _call_stack[l].instance;
|
||||
|
||||
if (!instance)
|
||||
return;
|
||||
if (!instance)
|
||||
return;
|
||||
|
||||
Ref<GDScript> script = instance->get_script();
|
||||
ERR_FAIL_COND( script.is_null() );
|
||||
Ref<GDScript> script = instance->get_script();
|
||||
ERR_FAIL_COND( script.is_null() );
|
||||
|
||||
|
||||
const Map<StringName,GDScript::MemberInfo>& mi = script->debug_get_member_indices();
|
||||
const Map<StringName,GDScript::MemberInfo>& mi = script->debug_get_member_indices();
|
||||
|
||||
for(const Map<StringName,GDScript::MemberInfo>::Element *E=mi.front();E;E=E->next()) {
|
||||
for(const Map<StringName,GDScript::MemberInfo>::Element *E=mi.front();E;E=E->next()) {
|
||||
|
||||
p_members->push_back(E->key());
|
||||
p_values->push_back( instance->debug_get_member_by_index(E->get().index));
|
||||
}
|
||||
p_members->push_back(E->key());
|
||||
p_values->push_back( instance->debug_get_member_by_index(E->get().index));
|
||||
}
|
||||
|
||||
}
|
||||
void GDScriptLanguage::debug_get_globals(List<String> *p_locals, List<Variant> *p_values, int p_max_subitems,int p_max_depth) {
|
||||
@ -317,6 +318,7 @@ String GDScriptLanguage::make_function(const String& p_class,const String& p_nam
|
||||
struct GDCompletionIdentifier {
|
||||
|
||||
StringName obj_type;
|
||||
Ref<GDScript> script;
|
||||
Variant::Type type;
|
||||
Variant value; //im case there is a value, also return it
|
||||
};
|
||||
@ -446,7 +448,7 @@ static Ref<Reference> _get_parent_class(GDCompletionContext& context) {
|
||||
base_class=base_class->subclasses[subclass];
|
||||
} else {
|
||||
|
||||
print_line("Could not find subclass: "+subclass);
|
||||
//print_line("Could not find subclass: "+subclass);
|
||||
return _get_type_from_class(context); //fail please
|
||||
}
|
||||
}
|
||||
@ -631,7 +633,9 @@ static bool _guess_expression_type(GDCompletionContext& context,const GDParser::
|
||||
//try calling the function if constant and all args are constant, should not crash..
|
||||
Object *baseptr = base.value;
|
||||
|
||||
if (baseptr && mb->is_const() && pi.type==Variant::OBJECT) {
|
||||
|
||||
if (mb->is_const() && pi.type==Variant::OBJECT) {
|
||||
|
||||
bool all_valid=true;
|
||||
Vector<Variant> args;
|
||||
for(int i=2;i<op->arguments.size();i++) {
|
||||
@ -648,25 +652,88 @@ static bool _guess_expression_type(GDCompletionContext& context,const GDParser::
|
||||
all_valid=false;
|
||||
}
|
||||
}
|
||||
if (all_valid) {
|
||||
Vector<const Variant*> argptr;
|
||||
for(int i=0;i<args.size();i++) {
|
||||
argptr.push_back(&args[i]);
|
||||
}
|
||||
|
||||
Variant::CallError ce;
|
||||
Variant ret=mb->call(baseptr,argptr.ptr(),argptr.size(),ce);
|
||||
if (all_valid && String(id)=="get_node" && ObjectTypeDB::is_type(base.obj_type,"Node") && args.size()) {
|
||||
|
||||
String arg1=args[0];
|
||||
if (arg1.begins_with("/root/")) {
|
||||
String which = arg1.get_slice("/",2);
|
||||
if (which!="") {
|
||||
List<PropertyInfo> props;
|
||||
Globals::get_singleton()->get_property_list(&props);
|
||||
//print_line("find singleton");
|
||||
|
||||
for(List<PropertyInfo>::Element *E=props.front();E;E=E->next()) {
|
||||
|
||||
String s = E->get().name;
|
||||
if (!s.begins_with("autoload/"))
|
||||
continue;
|
||||
//print_line("found "+s);
|
||||
String name = s.get_slice("/",1);
|
||||
//print_line("name: "+name+", which: "+which);
|
||||
if (name==which) {
|
||||
String script = Globals::get_singleton()->get(s);
|
||||
|
||||
if (!script.begins_with("res://")) {
|
||||
script="res://"+script;
|
||||
}
|
||||
|
||||
if (!script.ends_with(".gd")) {
|
||||
//not a script, try find the script anyway,
|
||||
//may have some success
|
||||
script=script.basename()+".gd";
|
||||
}
|
||||
|
||||
if (FileAccess::exists(script)) {
|
||||
|
||||
//print_line("is a script");
|
||||
|
||||
|
||||
if (ce.error==Variant::CallError::CALL_OK && ret.get_type()!=Variant::NIL) {
|
||||
Ref<Script> scr;
|
||||
if (ScriptCodeCompletionCache::get_sigleton())
|
||||
scr = ScriptCodeCompletionCache::get_sigleton()->get_cached_resource(script);
|
||||
else
|
||||
scr = ResourceLoader::load(script);
|
||||
|
||||
if (ret.get_type()!=Variant::OBJECT || ret.operator Object*()!=NULL) {
|
||||
|
||||
r_type=_get_type_from_variant(ret);
|
||||
return true;
|
||||
r_type.obj_type="Node";
|
||||
r_type.type=Variant::OBJECT;
|
||||
r_type.script=scr;
|
||||
r_type.value=Variant();
|
||||
|
||||
return true;
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
if (baseptr) {
|
||||
|
||||
if (all_valid) {
|
||||
Vector<const Variant*> argptr;
|
||||
for(int i=0;i<args.size();i++) {
|
||||
argptr.push_back(&args[i]);
|
||||
}
|
||||
|
||||
Variant::CallError ce;
|
||||
Variant ret=mb->call(baseptr,argptr.ptr(),argptr.size(),ce);
|
||||
|
||||
|
||||
if (ce.error==Variant::CallError::CALL_OK && ret.get_type()!=Variant::NIL) {
|
||||
|
||||
if (ret.get_type()!=Variant::OBJECT || ret.operator Object*()!=NULL) {
|
||||
|
||||
r_type=_get_type_from_variant(ret);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -1281,6 +1348,7 @@ static void _make_function_hint(const GDParser::FunctionNode* p_func,int p_argid
|
||||
static void _find_type_arguments(const GDParser::Node*p_node,int p_line,const StringName& p_method,const GDCompletionIdentifier& id, int p_argidx, Set<String>& result, String& arghint) {
|
||||
|
||||
|
||||
//print_line("find type arguments?");
|
||||
if (id.type==Variant::INPUT_EVENT && String(p_method)=="is_action" && p_argidx==0) {
|
||||
|
||||
List<PropertyInfo> pinfo;
|
||||
@ -1301,33 +1369,233 @@ static void _find_type_arguments(const GDParser::Node*p_node,int p_line,const St
|
||||
|
||||
|
||||
MethodBind *m = ObjectTypeDB::get_method(id.obj_type,p_method);
|
||||
if (!m)
|
||||
return;
|
||||
if (!m) {
|
||||
//not in static method, see script
|
||||
|
||||
if (p_method.operator String()=="connect") {
|
||||
//print_line("not in static: "+String(p_method));
|
||||
Ref<GDScript> on_script;
|
||||
|
||||
if (id.value.get_type()) {
|
||||
Object *obj=id.value;
|
||||
|
||||
|
||||
if (p_argidx==0) {
|
||||
List<MethodInfo> sigs;
|
||||
ObjectTypeDB::get_signal_list(id.obj_type,&sigs);
|
||||
for (List<MethodInfo>::Element *E=sigs.front();E;E=E->next()) {
|
||||
result.insert("\""+E->get().name+"\"");
|
||||
if (obj) {
|
||||
|
||||
|
||||
GDScript *scr = obj->cast_to<GDScript>();
|
||||
if (scr) {
|
||||
while (scr) {
|
||||
|
||||
for (const Map<StringName,GDFunction>::Element *E=scr->get_member_functions().front();E;E=E->next()) {
|
||||
if (E->get().is_static() && p_method==E->get().get_name()) {
|
||||
arghint="static func "+String(p_method)+"(";
|
||||
for(int i=0;i<E->get().get_argument_count();i++) {
|
||||
if (i>0)
|
||||
arghint+=", ";
|
||||
else
|
||||
arghint+=" ";
|
||||
if (i==p_argidx) {
|
||||
arghint+=String::chr(0xFFFF);
|
||||
}
|
||||
arghint+="var "+E->get().get_argument_name(i);
|
||||
int deffrom = E->get().get_argument_count()-E->get().get_default_argument_count();
|
||||
if (i>=deffrom) {
|
||||
int defidx = deffrom-i;
|
||||
if (defidx>=0 && defidx<E->get().get_default_argument_count()) {
|
||||
arghint+="="+E->get().get_default_argument(defidx).get_construct_string();
|
||||
}
|
||||
}
|
||||
if (i==p_argidx) {
|
||||
arghint+=String::chr(0xFFFF);
|
||||
}
|
||||
}
|
||||
arghint+=")";
|
||||
return; //found
|
||||
}
|
||||
}
|
||||
|
||||
if (scr->get_base().is_valid())
|
||||
scr=scr->get_base().ptr();
|
||||
else
|
||||
scr=NULL;
|
||||
}
|
||||
} else {
|
||||
on_script=obj->get_script();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//print_line("but it has a script?");
|
||||
if (!on_script.is_valid() && id.script.is_valid()) {
|
||||
//print_line("yes");
|
||||
on_script=id.script;
|
||||
}
|
||||
|
||||
if (on_script.is_valid()) {
|
||||
|
||||
GDScript *scr = on_script.ptr();
|
||||
if (scr) {
|
||||
while (scr) {
|
||||
|
||||
String code = scr->get_source_code();
|
||||
//print_line("has source code!");
|
||||
|
||||
if (code!="") {
|
||||
//if there is code, parse it. This way is slower but updates in real-time
|
||||
GDParser p;
|
||||
//Error parse(const String& p_code, const String& p_base_path="", bool p_just_validate=false,const String& p_self_path="",bool p_for_completion=false);
|
||||
|
||||
Error err = p.parse(scr->get_source_code(),scr->get_path().get_base_dir(),true,"",false);
|
||||
|
||||
if (err==OK) {
|
||||
//print_line("checking the functions...");
|
||||
//only if ok, otherwise use what is cached on the script
|
||||
//GDParser::ClassNode *base = p.
|
||||
const GDParser::Node *root = p.get_parse_tree();
|
||||
ERR_FAIL_COND(root->type!=GDParser::Node::TYPE_CLASS);
|
||||
|
||||
const GDParser::ClassNode *cl = static_cast<const GDParser::ClassNode*>(root);
|
||||
|
||||
const GDParser::FunctionNode* func=NULL;
|
||||
bool st=false;
|
||||
|
||||
for(int i=0;i<cl->functions.size();i++) {
|
||||
//print_line(String(cl->functions[i]->name)+" vs "+String(p_method));
|
||||
if (cl->functions[i]->name==p_method) {
|
||||
func=cl->functions[i];
|
||||
}
|
||||
}
|
||||
|
||||
for(int i=0;i<cl->static_functions.size();i++) {
|
||||
|
||||
//print_line(String(cl->static_functions[i]->name)+" vs "+String(p_method));
|
||||
if (cl->static_functions[i]->name==p_method) {
|
||||
func=cl->static_functions[i];
|
||||
st=true;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
if (func) {
|
||||
|
||||
arghint="func "+String(p_method)+"(";
|
||||
if (st)
|
||||
arghint="static "+arghint;
|
||||
for(int i=0;i<func->arguments.size();i++) {
|
||||
if (i>0)
|
||||
arghint+=", ";
|
||||
else
|
||||
arghint+=" ";
|
||||
if (i==p_argidx) {
|
||||
arghint+=String::chr(0xFFFF);
|
||||
}
|
||||
arghint+="var "+String(func->arguments[i]);
|
||||
int deffrom = func->arguments.size()-func->default_values.size();
|
||||
if (i>=deffrom) {
|
||||
|
||||
int defidx = deffrom-i;
|
||||
|
||||
if (defidx>=0 && defidx<func->default_values.size() && func->default_values[defidx]->type==GDParser::Node::TYPE_OPERATOR) {
|
||||
const GDParser::OperatorNode *op=static_cast<const GDParser::OperatorNode *>(func->default_values[defidx]);
|
||||
if (op->op==GDParser::OperatorNode::OP_ASSIGN) {
|
||||
const GDParser::ConstantNode *cn=static_cast<const GDParser::ConstantNode *>(op->arguments[1]);
|
||||
arghint+="="+cn->value.get_construct_string();
|
||||
}
|
||||
}
|
||||
}
|
||||
if (i==p_argidx) {
|
||||
arghint+=String::chr(0xFFFF);
|
||||
}
|
||||
}
|
||||
|
||||
arghint+=" )";
|
||||
return;
|
||||
}
|
||||
} else {
|
||||
//print_line("failed parsing?");
|
||||
code="";
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
if (code=="") {
|
||||
|
||||
for (const Map<StringName,GDFunction>::Element *E=scr->get_member_functions().front();E;E=E->next()) {
|
||||
if (p_method==E->get().get_name()) {
|
||||
arghint="func "+String(p_method)+"(";
|
||||
for(int i=0;i<E->get().get_argument_count();i++) {
|
||||
if (i>0)
|
||||
arghint+=", ";
|
||||
else
|
||||
arghint+=" ";
|
||||
if (i==p_argidx) {
|
||||
arghint+=String::chr(0xFFFF);
|
||||
}
|
||||
arghint+="var "+E->get().get_argument_name(i);
|
||||
int deffrom = E->get().get_argument_count()-E->get().get_default_argument_count();
|
||||
if (i>=deffrom) {
|
||||
int defidx = deffrom-i;
|
||||
if (defidx>=0 && defidx<E->get().get_default_argument_count()) {
|
||||
arghint+="="+E->get().get_default_argument(defidx).get_construct_string();
|
||||
}
|
||||
}
|
||||
if (i==p_argidx) {
|
||||
arghint+=String::chr(0xFFFF);
|
||||
}
|
||||
}
|
||||
arghint+=")";
|
||||
return; //found
|
||||
}
|
||||
}
|
||||
#if 0
|
||||
//use class directly, no code was found
|
||||
if (!isfunction) {
|
||||
for (const Map<StringName,Variant>::Element *E=scr->get_constants().front();E;E=E->next()) {
|
||||
options.insert(E->key());
|
||||
}
|
||||
}
|
||||
for (const Map<StringName,GDFunction>::Element *E=scr->get_member_functions().front();E;E=E->next()) {
|
||||
options.insert(String(E->key())+"(");
|
||||
}
|
||||
|
||||
for (const Set<StringName>::Element *E=scr->get_members().front();E;E=E->next()) {
|
||||
options.insert(E->get());
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
if (scr->get_base().is_valid())
|
||||
scr=scr->get_base().ptr();
|
||||
else
|
||||
scr=NULL;
|
||||
}
|
||||
}
|
||||
}
|
||||
/*if (p_argidx==2) {
|
||||
|
||||
ERR_FAIL_COND(p_node->type!=GDParser::Node::TYPE_OPERATOR);
|
||||
const GDParser::OperatorNode *op=static_cast<const GDParser::OperatorNode *>(p_node);
|
||||
if (op->arguments.size()>)
|
||||
|
||||
}*/
|
||||
} else {
|
||||
//regular method
|
||||
|
||||
Object *obj=id.value;
|
||||
if (obj) {
|
||||
List<String> options;
|
||||
obj->get_argument_options(p_method,p_argidx,&options);
|
||||
if (obj->is_type("Node") && p_argidx==0 && (String(p_method)=="get_node" || String(p_method)=="has_node")) {
|
||||
if (p_method.operator String()=="connect") {
|
||||
|
||||
|
||||
if (p_argidx==0) {
|
||||
List<MethodInfo> sigs;
|
||||
ObjectTypeDB::get_signal_list(id.obj_type,&sigs);
|
||||
for (List<MethodInfo>::Element *E=sigs.front();E;E=E->next()) {
|
||||
result.insert("\""+E->get().name+"\"");
|
||||
}
|
||||
}
|
||||
/*if (p_argidx==2) {
|
||||
|
||||
ERR_FAIL_COND(p_node->type!=GDParser::Node::TYPE_OPERATOR);
|
||||
const GDParser::OperatorNode *op=static_cast<const GDParser::OperatorNode *>(p_node);
|
||||
if (op->arguments.size()>)
|
||||
|
||||
}*/
|
||||
} else {
|
||||
|
||||
if (p_argidx==0 && (String(p_method)=="get_node" || String(p_method)=="has_node") && ObjectTypeDB::is_type(id.obj_type,"Node")) {
|
||||
|
||||
List<PropertyInfo> props;
|
||||
Globals::get_singleton()->get_property_list(&props);
|
||||
@ -1339,55 +1607,62 @@ static void _find_type_arguments(const GDParser::Node*p_node,int p_line,const St
|
||||
continue;
|
||||
// print_line("found "+s);
|
||||
String name = s.get_slice("/",1);
|
||||
options.push_back("\"/root/"+name+"\"");
|
||||
result.insert("\"/root/"+name+"\"");
|
||||
}
|
||||
}
|
||||
for(List<String>::Element *E=options.front();E;E=E->next()) {
|
||||
|
||||
result.insert(E->get());
|
||||
Object *obj=id.value;
|
||||
if (obj) {
|
||||
List<String> options;
|
||||
obj->get_argument_options(p_method,p_argidx,&options);
|
||||
|
||||
for(List<String>::Element *E=options.front();E;E=E->next()) {
|
||||
|
||||
result.insert(E->get());
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
arghint = _get_visual_datatype(m->get_argument_info(-1),false)+" "+p_method.operator String()+String("(");
|
||||
|
||||
arghint = _get_visual_datatype(m->get_argument_info(-1),false)+" "+p_method.operator String()+String("(");
|
||||
for(int i=0;i<m->get_argument_count();i++) {
|
||||
if (i>0)
|
||||
arghint+=", ";
|
||||
else
|
||||
arghint+=" ";
|
||||
|
||||
for(int i=0;i<m->get_argument_count();i++) {
|
||||
if (i>0)
|
||||
arghint+=", ";
|
||||
else
|
||||
if (i==p_argidx) {
|
||||
arghint+=String::chr(0xFFFF);
|
||||
}
|
||||
String n = m->get_argument_info(i).name;
|
||||
int dp = n.find(":");
|
||||
if (dp!=-1)
|
||||
n=n.substr(0,dp);
|
||||
arghint+=_get_visual_datatype(m->get_argument_info(i))+" "+n;
|
||||
int deffrom = m->get_argument_count()-m->get_default_argument_count();
|
||||
|
||||
|
||||
if (i>=deffrom) {
|
||||
int defidx = i-deffrom;
|
||||
|
||||
if (defidx>=0 && defidx<m->get_default_argument_count()) {
|
||||
Variant v= m->get_default_argument(i);
|
||||
arghint+="="+v.get_construct_string();
|
||||
}
|
||||
}
|
||||
|
||||
if (i==p_argidx) {
|
||||
arghint+=String::chr(0xFFFF);
|
||||
}
|
||||
|
||||
}
|
||||
if (m->get_argument_count()>0)
|
||||
arghint+=" ";
|
||||
|
||||
if (i==p_argidx) {
|
||||
arghint+=String::chr(0xFFFF);
|
||||
}
|
||||
String n = m->get_argument_info(i).name;
|
||||
int dp = n.find(":");
|
||||
if (dp!=-1)
|
||||
n=n.substr(0,dp);
|
||||
arghint+=_get_visual_datatype(m->get_argument_info(i))+" "+n;
|
||||
int deffrom = m->get_argument_count()-m->get_default_argument_count();
|
||||
|
||||
|
||||
if (i>=deffrom) {
|
||||
int defidx = i-deffrom;
|
||||
|
||||
if (defidx>=0 && defidx<m->get_default_argument_count()) {
|
||||
Variant v= m->get_default_argument(i);
|
||||
arghint+="="+v.get_construct_string();
|
||||
}
|
||||
}
|
||||
|
||||
if (i==p_argidx) {
|
||||
arghint+=String::chr(0xFFFF);
|
||||
}
|
||||
|
||||
arghint+=")";
|
||||
}
|
||||
if (m->get_argument_count()>0)
|
||||
arghint+=" ";
|
||||
|
||||
|
||||
arghint+=")";
|
||||
|
||||
}
|
||||
}
|
||||
@ -1434,7 +1709,7 @@ static void _find_call_arguments(GDCompletionContext& context,const GDParser::No
|
||||
arghint+=")";
|
||||
|
||||
} else if (op->arguments[0]->type==GDParser::Node::TYPE_TYPE) {
|
||||
//complete built-in function
|
||||
//complete constructor
|
||||
const GDParser::TypeNode *tn = static_cast<const GDParser::TypeNode*>(op->arguments[0]);
|
||||
|
||||
List<MethodInfo> mil;
|
||||
@ -1569,7 +1844,7 @@ static void _find_call_arguments(GDCompletionContext& context,const GDParser::No
|
||||
|
||||
}
|
||||
} else {
|
||||
|
||||
//indexed lookup
|
||||
|
||||
GDCompletionIdentifier ci;
|
||||
if (_guess_expression_type(context,op->arguments[0],p_line,ci)) {
|
||||
@ -1735,20 +2010,123 @@ Error GDScriptLanguage::complete_code(const String& p_code, const String& p_base
|
||||
|
||||
if (t.type==Variant::OBJECT && t.obj_type!=StringName()) {
|
||||
|
||||
Ref<GDScript> on_script;
|
||||
|
||||
if (t.value.get_type()) {
|
||||
Object *obj=t.value;
|
||||
|
||||
|
||||
if (obj) {
|
||||
|
||||
|
||||
GDScript *scr = obj->cast_to<GDScript>();
|
||||
if (scr) {
|
||||
while (scr) {
|
||||
|
||||
if (!isfunction) {
|
||||
for (const Map<StringName,Variant>::Element *E=scr->get_constants().front();E;E=E->next()) {
|
||||
options.insert(E->key());
|
||||
}
|
||||
}
|
||||
for (const Map<StringName,GDFunction>::Element *E=scr->get_member_functions().front();E;E=E->next()) {
|
||||
if (E->get().is_static())
|
||||
options.insert(E->key());
|
||||
}
|
||||
|
||||
if (scr->get_base().is_valid())
|
||||
scr=scr->get_base().ptr();
|
||||
else
|
||||
scr=NULL;
|
||||
}
|
||||
} else {
|
||||
on_script=obj->get_script();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
if (!on_script.is_valid() && t.script.is_valid()) {
|
||||
on_script=t.script;
|
||||
}
|
||||
|
||||
if (on_script.is_valid()) {
|
||||
|
||||
GDScript *scr = on_script.ptr();
|
||||
if (scr) {
|
||||
while (scr) {
|
||||
|
||||
if (!isfunction) {
|
||||
for (const Map<StringName,Variant>::Element *E=scr->get_constants().front();E;E=E->next()) {
|
||||
options.insert(E->key());
|
||||
String code = scr->get_source_code();
|
||||
|
||||
if (code!="") {
|
||||
//if there is code, parse it. This way is slower but updates in real-time
|
||||
GDParser p;
|
||||
//Error parse(const String& p_code, const String& p_base_path="", bool p_just_validate=false,const String& p_self_path="",bool p_for_completion=false);
|
||||
|
||||
Error err = p.parse(scr->get_source_code(),scr->get_path().get_base_dir(),true,"",false);
|
||||
|
||||
if (err==OK) {
|
||||
//only if ok, otherwise use what is cached on the script
|
||||
//GDParser::ClassNode *base = p.
|
||||
const GDParser::Node *root = p.get_parse_tree();
|
||||
ERR_FAIL_COND_V(root->type!=GDParser::Node::TYPE_CLASS,ERR_PARSE_ERROR);
|
||||
|
||||
const GDParser::ClassNode *cl = static_cast<const GDParser::ClassNode*>(root);
|
||||
|
||||
for(int i=0;i<cl->functions.size();i++) {
|
||||
|
||||
if (cl->functions[i]->arguments.size())
|
||||
options.insert(String(cl->functions[i]->name)+"(");
|
||||
else
|
||||
options.insert(String(cl->functions[i]->name)+"()");
|
||||
}
|
||||
|
||||
for(int i=0;i<cl->static_functions.size();i++) {
|
||||
|
||||
if (cl->static_functions[i]->arguments.size())
|
||||
options.insert(String(cl->static_functions[i]->name)+"(");
|
||||
else
|
||||
options.insert(String(cl->static_functions[i]->name)+"()");
|
||||
|
||||
}
|
||||
|
||||
if (!isfunction) {
|
||||
for(int i=0;i<cl->variables.size();i++) {
|
||||
|
||||
options.insert(String(cl->variables[i].identifier));
|
||||
}
|
||||
|
||||
for(int i=0;i<cl->constant_expressions.size();i++) {
|
||||
|
||||
options.insert(String(cl->constant_expressions[i].identifier));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
} else {
|
||||
code=""; //well, then no code
|
||||
}
|
||||
|
||||
}
|
||||
for (const Map<StringName,GDFunction>::Element *E=scr->get_member_functions().front();E;E=E->next()) {
|
||||
options.insert(E->key());
|
||||
|
||||
if (code=="") {
|
||||
//use class directly, no code was found
|
||||
if (!isfunction) {
|
||||
for (const Map<StringName,Variant>::Element *E=scr->get_constants().front();E;E=E->next()) {
|
||||
options.insert(E->key());
|
||||
}
|
||||
}
|
||||
for (const Map<StringName,GDFunction>::Element *E=scr->get_member_functions().front();E;E=E->next()) {
|
||||
if (E->get().get_argument_count())
|
||||
options.insert(String(E->key())+"()");
|
||||
else
|
||||
options.insert(String(E->key())+"(");
|
||||
|
||||
}
|
||||
|
||||
for (const Set<StringName>::Element *E=scr->get_members().front();E;E=E->next()) {
|
||||
options.insert(E->get());
|
||||
}
|
||||
}
|
||||
|
||||
if (scr->get_base().is_valid())
|
||||
@ -1760,6 +2138,10 @@ Error GDScriptLanguage::complete_code(const String& p_code, const String& p_base
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
if (!isfunction) {
|
||||
ObjectTypeDB::get_integer_constant_list(t.obj_type,r_options);
|
||||
}
|
||||
|
@ -2315,6 +2315,17 @@ void GDParser::_parse_class(ClassNode *p_class) {
|
||||
|
||||
case Variant::INT: {
|
||||
|
||||
if (tokenizer->get_token()==GDTokenizer::TK_IDENTIFIER && tokenizer->get_token_identifier()=="FLAGS") {
|
||||
|
||||
current_export.hint=PROPERTY_HINT_ALL_FLAGS;
|
||||
tokenizer->advance();
|
||||
if (tokenizer->get_token()!=GDTokenizer::TK_PARENTHESIS_CLOSE) {
|
||||
_set_error("Expected ')' in hint.");
|
||||
return;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
if (tokenizer->get_token()==GDTokenizer::TK_CONSTANT && tokenizer->get_token_constant().get_type()==Variant::STRING) {
|
||||
//enumeration
|
||||
current_export.hint=PROPERTY_HINT_ENUM;
|
||||
@ -2542,16 +2553,23 @@ void GDParser::_parse_class(ClassNode *p_class) {
|
||||
} else if (tokenizer->get_token()==GDTokenizer::TK_IDENTIFIER) {
|
||||
|
||||
String identifier = tokenizer->get_token_identifier();
|
||||
if (!ObjectTypeDB::is_type(identifier,"Resource")) {
|
||||
|
||||
current_export=PropertyInfo();
|
||||
_set_error("Export hint not a type or resource.");
|
||||
if (identifier == "flag") {
|
||||
current_export.type=Variant::INT;
|
||||
current_export.hint=PROPERTY_HINT_ALL_FLAGS;
|
||||
}else if (identifier == "multiline"){
|
||||
current_export.type=Variant::STRING;
|
||||
current_export.hint=PROPERTY_HINT_MULTILINE_TEXT;
|
||||
} else {
|
||||
if (!ObjectTypeDB::is_type(identifier,"Resource")) {
|
||||
|
||||
current_export=PropertyInfo();
|
||||
_set_error("Export hint not a type or resource.");
|
||||
}
|
||||
|
||||
current_export.type=Variant::OBJECT;
|
||||
current_export.hint=PROPERTY_HINT_RESOURCE_TYPE;
|
||||
current_export.hint_string=identifier;
|
||||
}
|
||||
|
||||
current_export.type=Variant::OBJECT;
|
||||
current_export.hint=PROPERTY_HINT_RESOURCE_TYPE;
|
||||
current_export.hint_string=identifier;
|
||||
|
||||
tokenizer->advance();
|
||||
}
|
||||
|
||||
|
@ -1977,9 +1977,17 @@ void GDScript::_bind_methods() {
|
||||
|
||||
ObjectTypeDB::bind_native_method(METHOD_FLAGS_DEFAULT,"new",&GDScript::_new,MethodInfo("new"));
|
||||
|
||||
ObjectTypeDB::bind_method(_MD("get_as_byte_code"),&GDScript::get_as_byte_code);
|
||||
|
||||
}
|
||||
|
||||
|
||||
Vector<uint8_t> GDScript::get_as_byte_code() const {
|
||||
|
||||
GDTokenizerBuffer tokenizer;
|
||||
return tokenizer.parse_code_string(source);
|
||||
};
|
||||
|
||||
|
||||
Error GDScript::load_byte_code(const String& p_path) {
|
||||
|
||||
@ -2556,9 +2564,9 @@ void GDScriptLanguage::init() {
|
||||
|
||||
//populate native classes
|
||||
|
||||
List<String> class_list;
|
||||
List<StringName> class_list;
|
||||
ObjectTypeDB::get_type_list(&class_list);
|
||||
for(List<String>::Element *E=class_list.front();E;E=E->next()) {
|
||||
for(List<StringName>::Element *E=class_list.front();E;E=E->next()) {
|
||||
|
||||
StringName n = E->get();
|
||||
String s = String(n);
|
||||
|
@ -349,6 +349,8 @@ public:
|
||||
Error load_source_code(const String& p_path);
|
||||
Error load_byte_code(const String& p_path);
|
||||
|
||||
Vector<uint8_t> get_as_byte_code() const;
|
||||
|
||||
virtual ScriptLanguage *get_language() const;
|
||||
|
||||
GDScript();
|
||||
@ -473,6 +475,19 @@ public:
|
||||
}
|
||||
|
||||
|
||||
virtual Vector<StackInfo> debug_get_current_stack_info() {
|
||||
if (Thread::get_main_ID()!=Thread::get_caller_ID())
|
||||
return Vector<StackInfo>();
|
||||
|
||||
Vector<StackInfo> csi;
|
||||
csi.resize(_debug_call_stack_pos);
|
||||
for(int i=0;i<_debug_call_stack_pos;i++) {
|
||||
csi[_debug_call_stack_pos-i-1].line=_call_stack[i].line?*_call_stack[i].line:0;
|
||||
csi[_debug_call_stack_pos-i-1].script=Ref<GDScript>(_call_stack[i].function->get_script());
|
||||
}
|
||||
return csi;
|
||||
}
|
||||
|
||||
struct {
|
||||
|
||||
StringName _init;
|
||||
|
@ -97,6 +97,7 @@ const char* GDTokenizer::token_names[TK_MAX]={
|
||||
"preload",
|
||||
"assert",
|
||||
"yield",
|
||||
"signal",
|
||||
"'['",
|
||||
"']'",
|
||||
"'{'",
|
||||
@ -642,6 +643,11 @@ void GDTokenizerText::_advance() {
|
||||
str+=res;
|
||||
|
||||
} else {
|
||||
if (CharType(GETCHAR(i))=='\n') {
|
||||
line++;
|
||||
column=0;
|
||||
}
|
||||
|
||||
str+=CharType(GETCHAR(i));
|
||||
}
|
||||
i++;
|
||||
@ -1040,7 +1046,7 @@ void GDTokenizerText::advance(int p_amount) {
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#define BYTECODE_VERSION 4
|
||||
#define BYTECODE_VERSION 5
|
||||
|
||||
Error GDTokenizerBuffer::set_code_buffer(const Vector<uint8_t> & p_buffer) {
|
||||
|
||||
|
@ -130,8 +130,8 @@ bool GridMap::_set(const StringName& p_name, const Variant& p_value) {
|
||||
|
||||
|
||||
} else if (name.begins_with("areas/")) {
|
||||
int which = name.get_slice("/",1).to_int();
|
||||
String what=name.get_slice("/",2);
|
||||
int which = name.get_slicec('/',1).to_int();
|
||||
String what=name.get_slicec('/',2);
|
||||
if (what=="bounds") {
|
||||
ERR_FAIL_COND_V(area_map.has(which),false);
|
||||
create_area(which,p_value);
|
||||
@ -215,8 +215,8 @@ bool GridMap::_get(const StringName& p_name,Variant &r_ret) const {
|
||||
|
||||
r_ret= d;
|
||||
} else if (name.begins_with("areas/")) {
|
||||
int which = name.get_slice("/",1).to_int();
|
||||
String what=name.get_slice("/",2);
|
||||
int which = name.get_slicec('/',1).to_int();
|
||||
String what=name.get_slicec('/',2);
|
||||
if (what=="bounds")
|
||||
r_ret= area_get_bounds(which);
|
||||
else if (what=="name")
|
||||
|
@ -54,13 +54,53 @@ def create(env):
|
||||
|
||||
def configure(env):
|
||||
|
||||
# Workaround for MinGW. See:
|
||||
# http://www.scons.org/wiki/LongCmdLinesOnWin32
|
||||
import os
|
||||
if (os.name=="nt"):
|
||||
|
||||
import subprocess
|
||||
|
||||
def mySubProcess(cmdline,env):
|
||||
#print "SPAWNED : " + cmdline
|
||||
startupinfo = subprocess.STARTUPINFO()
|
||||
startupinfo.dwFlags |= subprocess.STARTF_USESHOWWINDOW
|
||||
proc = subprocess.Popen(cmdline, stdin=subprocess.PIPE, stdout=subprocess.PIPE,
|
||||
stderr=subprocess.PIPE, startupinfo=startupinfo, shell = False, env = env)
|
||||
data, err = proc.communicate()
|
||||
rv = proc.wait()
|
||||
if rv:
|
||||
print "====="
|
||||
print err
|
||||
print "====="
|
||||
return rv
|
||||
|
||||
def mySpawn(sh, escape, cmd, args, env):
|
||||
|
||||
newargs = ' '.join(args[1:])
|
||||
cmdline = cmd + " " + newargs
|
||||
|
||||
rv=0
|
||||
if len(cmdline) > 32000 and cmd.endswith("ar") :
|
||||
cmdline = cmd + " " + args[1] + " " + args[2] + " "
|
||||
for i in range(3,len(args)) :
|
||||
rv = mySubProcess( cmdline + args[i], env )
|
||||
if rv :
|
||||
break
|
||||
else:
|
||||
rv = mySubProcess( cmdline, env )
|
||||
|
||||
return rv
|
||||
|
||||
env['SPAWN'] = mySpawn
|
||||
|
||||
if env['x86']=='yes':
|
||||
env['NDK_TARGET']='x86-4.8'
|
||||
|
||||
if env['PLATFORM'] == 'win32':
|
||||
import methods
|
||||
env.Tool('gcc')
|
||||
env['SPAWN'] = methods.win32_spawn
|
||||
#env['SPAWN'] = methods.win32_spawn
|
||||
env['SHLIBSUFFIX'] = '.so'
|
||||
|
||||
# env.android_source_modules.append("../libs/apk_expansion")
|
||||
|
@ -228,7 +228,7 @@ class EditorExportPlatformAndroid : public EditorExportPlatform {
|
||||
String get_package_name();
|
||||
|
||||
String get_project_name() const;
|
||||
void _fix_manifest(Vector<uint8_t>& p_manifest);
|
||||
void _fix_manifest(Vector<uint8_t>& p_manifest, bool p_give_internet);
|
||||
void _fix_resources(Vector<uint8_t>& p_manifest);
|
||||
static Error save_apk_file(void *p_userdata,const String& p_path, const Vector<uint8_t>& p_data,int p_file,int p_total);
|
||||
|
||||
@ -249,11 +249,11 @@ public:
|
||||
virtual int get_device_count() const;
|
||||
virtual String get_device_name(int p_device) const;
|
||||
virtual String get_device_info(int p_device) const;
|
||||
virtual Error run(int p_device,bool p_dumb=false);
|
||||
virtual Error run(int p_device,bool p_dumb=false,bool p_remote_debug=false);
|
||||
|
||||
virtual bool requieres_password(bool p_debug) const { return !p_debug; }
|
||||
virtual String get_binary_extension() const { return "apk"; }
|
||||
virtual Error export_project(const String& p_path,bool p_debug,bool p_dumb=false);
|
||||
virtual Error export_project(const String& p_path, bool p_debug, bool p_dumb=false, bool p_remote_debug=false);
|
||||
|
||||
virtual bool can_export(String *r_error=NULL) const;
|
||||
|
||||
@ -317,7 +317,7 @@ bool EditorExportPlatformAndroid::_set(const StringName& p_name, const Variant&
|
||||
apk_expansion_pkey=p_value;
|
||||
else if (n.begins_with("permissions/")) {
|
||||
|
||||
String what = n.get_slice("/",1).to_upper();
|
||||
String what = n.get_slicec('/',1).to_upper();
|
||||
bool state = p_value;
|
||||
if (state)
|
||||
perms.insert(what);
|
||||
@ -325,7 +325,7 @@ bool EditorExportPlatformAndroid::_set(const StringName& p_name, const Variant&
|
||||
perms.erase(what);
|
||||
} else if (n.begins_with("user_permissions/")) {
|
||||
|
||||
int which = n.get_slice("/",1).to_int();
|
||||
int which = n.get_slicec('/',1).to_int();
|
||||
ERR_FAIL_INDEX_V(which,MAX_USER_PERMISSIONS,false);
|
||||
user_perms[which]=p_value;
|
||||
|
||||
@ -390,11 +390,11 @@ bool EditorExportPlatformAndroid::_get(const StringName& p_name,Variant &r_ret)
|
||||
r_ret=apk_expansion_pkey;
|
||||
else if (n.begins_with("permissions/")) {
|
||||
|
||||
String what = n.get_slice("/",1).to_upper();
|
||||
String what = n.get_slicec('/',1).to_upper();
|
||||
r_ret = perms.has(what);
|
||||
} else if (n.begins_with("user_permissions/")) {
|
||||
|
||||
int which = n.get_slice("/",1).to_int();
|
||||
int which = n.get_slicec('/',1).to_int();
|
||||
ERR_FAIL_INDEX_V(which,MAX_USER_PERMISSIONS,false);
|
||||
r_ret=user_perms[which];
|
||||
} else
|
||||
@ -608,7 +608,7 @@ String EditorExportPlatformAndroid::get_project_name() const {
|
||||
}
|
||||
|
||||
|
||||
void EditorExportPlatformAndroid::_fix_manifest(Vector<uint8_t>& p_manifest) {
|
||||
void EditorExportPlatformAndroid::_fix_manifest(Vector<uint8_t>& p_manifest,bool p_give_internet) {
|
||||
|
||||
|
||||
const int CHUNK_AXML_FILE = 0x00080003;
|
||||
@ -838,7 +838,10 @@ void EditorExportPlatformAndroid::_fix_manifest(Vector<uint8_t>& p_manifest) {
|
||||
|
||||
} else if (value.begins_with("godot.")) {
|
||||
String perm = value.get_slice(".",1);
|
||||
if (perms.has(perm)) {
|
||||
print_line("PERM: "+perm+" HAS: "+itos(perms.has(perm)));
|
||||
|
||||
if (perms.has(perm) || (p_give_internet && perm=="INTERNET")) {
|
||||
|
||||
string_table[attr_value]="android.permission."+perm;
|
||||
}
|
||||
|
||||
@ -1011,7 +1014,7 @@ Error EditorExportPlatformAndroid::save_apk_file(void *p_userdata,const String&
|
||||
|
||||
|
||||
|
||||
Error EditorExportPlatformAndroid::export_project(const String& p_path, bool p_debug, bool p_dumb) {
|
||||
Error EditorExportPlatformAndroid::export_project(const String& p_path, bool p_debug, bool p_dumb,bool p_remote_debug) {
|
||||
|
||||
String src_apk;
|
||||
|
||||
@ -1075,7 +1078,7 @@ Error EditorExportPlatformAndroid::export_project(const String& p_path, bool p_d
|
||||
|
||||
if (file=="AndroidManifest.xml") {
|
||||
|
||||
_fix_manifest(data);
|
||||
_fix_manifest(data,p_dumb || p_remote_debug);
|
||||
}
|
||||
|
||||
if (file=="resources.arsc") {
|
||||
@ -1153,9 +1156,11 @@ Error EditorExportPlatformAndroid::export_project(const String& p_path, bool p_d
|
||||
}
|
||||
}
|
||||
|
||||
gen_export_flags(cl,p_dumb,p_remote_debug);
|
||||
|
||||
if (p_dumb) {
|
||||
|
||||
String host = EditorSettings::get_singleton()->get("file_server/host");
|
||||
/*String host = EditorSettings::get_singleton()->get("file_server/host");
|
||||
int port = EditorSettings::get_singleton()->get("file_server/post");
|
||||
String passwd = EditorSettings::get_singleton()->get("file_server/password");
|
||||
cl.push_back("-rfs");
|
||||
@ -1163,7 +1168,7 @@ Error EditorExportPlatformAndroid::export_project(const String& p_path, bool p_d
|
||||
if (passwd!="") {
|
||||
cl.push_back("-rfs_pass");
|
||||
cl.push_back(passwd);
|
||||
}
|
||||
}*/
|
||||
|
||||
|
||||
} else {
|
||||
@ -1480,7 +1485,7 @@ void EditorExportPlatformAndroid::_device_poll_thread(void *ud) {
|
||||
|
||||
}
|
||||
|
||||
Error EditorExportPlatformAndroid::run(int p_device, bool p_dumb) {
|
||||
Error EditorExportPlatformAndroid::run(int p_device, bool p_dumb, bool p_remote_debug) {
|
||||
|
||||
ERR_FAIL_INDEX_V(p_device,devices.size(),ERR_INVALID_PARAMETER);
|
||||
device_lock->lock();
|
||||
@ -1499,7 +1504,7 @@ Error EditorExportPlatformAndroid::run(int p_device, bool p_dumb) {
|
||||
ep.step("Exporting APK",0);
|
||||
|
||||
String export_to=EditorSettings::get_singleton()->get_settings_path()+"/tmp/tmpexport.apk";
|
||||
Error err = export_project(export_to,true,p_dumb);
|
||||
Error err = export_project(export_to,true,p_dumb,p_remote_debug);
|
||||
if (err) {
|
||||
device_lock->unlock();
|
||||
return err;
|
||||
|
@ -67,11 +67,11 @@ public:
|
||||
virtual int get_device_count() const;
|
||||
virtual String get_device_name(int p_device) const;
|
||||
virtual String get_device_info(int p_device) const;
|
||||
virtual Error run(int p_device,bool p_dumb=false);
|
||||
virtual Error run(int p_device,bool p_dumb=false,bool p_remote_debug=false);
|
||||
|
||||
virtual bool requieres_password(bool p_debug) const { return !p_debug; }
|
||||
virtual String get_binary_extension() const { return "bar"; }
|
||||
virtual Error export_project(const String& p_path,bool p_debug,bool p_dumb=false);
|
||||
virtual Error export_project(const String& p_path,bool p_debug,bool p_dumb=false,bool p_remote_debug=false);
|
||||
|
||||
virtual bool can_export(String *r_error=NULL) const;
|
||||
|
||||
@ -270,7 +270,7 @@ void EditorExportPlatformBB10::_fix_descriptor(Vector<uint8_t>& p_descriptor) {
|
||||
|
||||
|
||||
|
||||
Error EditorExportPlatformBB10::export_project(const String& p_path, bool p_debug, bool p_dumb) {
|
||||
Error EditorExportPlatformBB10::export_project(const String& p_path, bool p_debug, bool p_dumb, bool p_remote_debug) {
|
||||
|
||||
|
||||
EditorProgress ep("export","Exporting for BlackBerry 10",104);
|
||||
@ -619,7 +619,7 @@ void EditorExportPlatformBB10::_device_poll_thread(void *ud) {
|
||||
|
||||
}
|
||||
|
||||
Error EditorExportPlatformBB10::run(int p_device, bool p_dumb) {
|
||||
Error EditorExportPlatformBB10::run(int p_device, bool p_dumb, bool p_remote_debug) {
|
||||
|
||||
ERR_FAIL_INDEX_V(p_device,devices.size(),ERR_INVALID_PARAMETER);
|
||||
|
||||
|
@ -138,6 +138,29 @@ static int frame_count = 0;
|
||||
Main::setup2();
|
||||
++frame_count;
|
||||
|
||||
// this might be necessary before here
|
||||
for (NSString* key in [[NSBundle mainBundle] infoDictionary]) {
|
||||
NSObject* value = [[[NSBundle mainBundle] infoDictionary] objectForKey:key];
|
||||
String ukey = String::utf8([key UTF8String]);
|
||||
|
||||
// we need a NSObject to Variant conversor
|
||||
|
||||
if ([value isKindOfClass:[NSString class]]) {
|
||||
NSString* str = (NSString*)value;
|
||||
String uval = String::utf8([str UTF8String]);
|
||||
|
||||
Globals::get_singleton()->set("Info.plist/"+ukey, uval);
|
||||
|
||||
} else if ([value isKindOfClass:[NSNumber class]]) {
|
||||
|
||||
NSNumber* n = (NSNumber*)value;
|
||||
double dval = [n doubleValue];
|
||||
|
||||
Globals::get_singleton()->set("Info.plist/"+ukey, dval);
|
||||
};
|
||||
// do stuff
|
||||
}
|
||||
|
||||
} break;
|
||||
/*
|
||||
case 3: {
|
||||
|
@ -77,11 +77,11 @@ public:
|
||||
virtual int get_device_count() const { return show_run?1:0; };
|
||||
virtual String get_device_name(int p_device) const { return "Run in Browser"; }
|
||||
virtual String get_device_info(int p_device) const { return "Run exported HTML in the system's default browser."; }
|
||||
virtual Error run(int p_device,bool p_dumb=false);
|
||||
virtual Error run(int p_device,bool p_dumb=false,bool p_remote_debug=false);
|
||||
|
||||
virtual bool requieres_password(bool p_debug) const { return false; }
|
||||
virtual String get_binary_extension() const { return "html"; }
|
||||
virtual Error export_project(const String& p_path,bool p_debug,bool p_dumb=false);
|
||||
virtual Error export_project(const String& p_path,bool p_debug,bool p_dumb=false,bool p_remote_debug=false);
|
||||
|
||||
virtual bool can_export(String *r_error=NULL) const;
|
||||
|
||||
@ -194,7 +194,7 @@ struct JSExportData {
|
||||
|
||||
|
||||
|
||||
Error EditorExportPlatformJavaScript::export_project(const String& p_path, bool p_debug, bool p_dumb) {
|
||||
Error EditorExportPlatformJavaScript::export_project(const String& p_path, bool p_debug, bool p_dumb, bool p_remote_debug) {
|
||||
|
||||
|
||||
String src_template;
|
||||
@ -299,7 +299,7 @@ Error EditorExportPlatformJavaScript::export_project(const String& p_path, bool
|
||||
}
|
||||
|
||||
|
||||
Error EditorExportPlatformJavaScript::run(int p_device, bool p_dumb) {
|
||||
Error EditorExportPlatformJavaScript::run(int p_device, bool p_dumb, bool p_remote_debug) {
|
||||
|
||||
String path = EditorSettings::get_singleton()->get_settings_path()+"/tmp/tmp_export.html";
|
||||
Error err = export_project(path,true,"");
|
||||
|
@ -57,11 +57,11 @@ public:
|
||||
virtual int get_device_count() const { return 0; };
|
||||
virtual String get_device_name(int p_device) const { return String(); }
|
||||
virtual String get_device_info(int p_device) const { return String(); }
|
||||
virtual Error run(int p_device,bool p_dumb=false);
|
||||
virtual Error run(int p_device,bool p_dumb=false,bool p_remote_debug=false);
|
||||
|
||||
virtual bool requieres_password(bool p_debug) const { return false; }
|
||||
virtual String get_binary_extension() const { return "zip"; }
|
||||
virtual Error export_project(const String& p_path,bool p_debug,bool p_dumb=false);
|
||||
virtual Error export_project(const String& p_path,bool p_debug,bool p_dumb=false,bool p_remote_debug=false);
|
||||
|
||||
virtual bool can_export(String *r_error=NULL) const;
|
||||
|
||||
@ -245,7 +245,7 @@ void EditorExportPlatformOSX::_fix_plist(Vector<uint8_t>& plist,const String& p_
|
||||
}
|
||||
}
|
||||
|
||||
Error EditorExportPlatformOSX::export_project(const String& p_path, bool p_debug, bool p_dumb) {
|
||||
Error EditorExportPlatformOSX::export_project(const String& p_path, bool p_debug, bool p_dumb, bool p_remote_debug) {
|
||||
|
||||
String src_pkg;
|
||||
|
||||
@ -437,7 +437,7 @@ Error EditorExportPlatformOSX::export_project(const String& p_path, bool p_debug
|
||||
}
|
||||
|
||||
|
||||
Error EditorExportPlatformOSX::run(int p_device, bool p_dumb) {
|
||||
Error EditorExportPlatformOSX::run(int p_device, bool p_dumb, bool p_remote_debug) {
|
||||
|
||||
return OK;
|
||||
}
|
||||
|
@ -1899,6 +1899,12 @@ uint64_t OS_Windows::get_unix_time() const {
|
||||
return (*(uint64_t*)&ft - *(uint64_t*)&fep) / 10000000;
|
||||
};
|
||||
|
||||
uint64_t OS_Windows::get_system_time_msec() const {
|
||||
SYSTEMTIME st;
|
||||
GetSystemTime(&st);
|
||||
return st.wMilliseconds;
|
||||
}
|
||||
|
||||
void OS_Windows::delay_usec(uint32_t p_usec) const {
|
||||
|
||||
if (p_usec < 1000)
|
||||
|
@ -263,6 +263,7 @@ public:
|
||||
virtual Time get_time(bool utc) const;
|
||||
virtual TimeZoneInfo get_time_zone_info() const;
|
||||
virtual uint64_t get_unix_time() const;
|
||||
virtual uint64_t get_system_time_msec() const;
|
||||
|
||||
virtual bool can_draw() const;
|
||||
virtual Error set_cwd(const String& p_cwd);
|
||||
@ -272,7 +273,7 @@ public:
|
||||
|
||||
virtual Error execute(const String& p_path, const List<String>& p_arguments,bool p_blocking,ProcessID *r_child_id=NULL,String* r_pipe=NULL,int *r_exitcode=NULL);
|
||||
virtual Error kill(const ProcessID& p_pid);
|
||||
|
||||
|
||||
virtual bool has_environment(const String& p_var) const;
|
||||
virtual String get_environment(const String& p_var) const;
|
||||
|
||||
|
@ -267,6 +267,7 @@ void OS_X11::initialize(const VideoMode& p_desired,int p_video_driver,int p_audi
|
||||
for(int i=0;i<AudioDriverManagerSW::get_driver_count();i++) {
|
||||
if (i==p_audio_driver)
|
||||
continue;
|
||||
AudioDriverManagerSW::get_driver(i)->set_singleton();
|
||||
if (AudioDriverManagerSW::get_driver(i)->init()==OK) {
|
||||
success=true;
|
||||
print_line("Audio Driver Failed: "+String(AudioDriverManagerSW::get_driver(p_audio_driver)->get_name()));
|
||||
|
@ -330,11 +330,11 @@ void AnimatedSprite::_bind_methods() {
|
||||
|
||||
ADD_PROPERTYNZ( PropertyInfo( Variant::OBJECT, "frames",PROPERTY_HINT_RESOURCE_TYPE,"SpriteFrames"), _SCS("set_sprite_frames"),_SCS("get_sprite_frames"));
|
||||
ADD_PROPERTYNZ( PropertyInfo( Variant::INT, "frame",PROPERTY_HINT_SPRITE_FRAME), _SCS("set_frame"),_SCS("get_frame"));
|
||||
ADD_PROPERTY( PropertyInfo( Variant::BOOL, "centered"), _SCS("set_centered"),_SCS("is_centered"));
|
||||
ADD_PROPERTYNO( PropertyInfo( Variant::BOOL, "centered"), _SCS("set_centered"),_SCS("is_centered"));
|
||||
ADD_PROPERTYNZ( PropertyInfo( Variant::VECTOR2, "offset"), _SCS("set_offset"),_SCS("get_offset"));
|
||||
ADD_PROPERTY( PropertyInfo( Variant::BOOL, "flip_h"), _SCS("set_flip_h"),_SCS("is_flipped_h"));
|
||||
ADD_PROPERTY( PropertyInfo( Variant::BOOL, "flip_v"), _SCS("set_flip_v"),_SCS("is_flipped_v"));
|
||||
ADD_PROPERTY( PropertyInfo( Variant::COLOR, "modulate"), _SCS("set_modulate"),_SCS("get_modulate"));
|
||||
ADD_PROPERTYNZ( PropertyInfo( Variant::BOOL, "flip_h"), _SCS("set_flip_h"),_SCS("is_flipped_h"));
|
||||
ADD_PROPERTYNZ( PropertyInfo( Variant::BOOL, "flip_v"), _SCS("set_flip_v"),_SCS("is_flipped_v"));
|
||||
ADD_PROPERTYNO( PropertyInfo( Variant::COLOR, "modulate"), _SCS("set_modulate"),_SCS("get_modulate"));
|
||||
|
||||
}
|
||||
|
||||
|
@ -428,8 +428,9 @@ void Area2D::set_enable_monitoring(bool p_enable) {
|
||||
|
||||
if (monitoring) {
|
||||
|
||||
Physics2DServer::get_singleton()->area_set_monitor_callback(get_rid(),this,"_body_inout");
|
||||
Physics2DServer::get_singleton()->area_set_area_monitor_callback(get_rid(),this,"_area_inout");
|
||||
Physics2DServer::get_singleton()->area_set_monitor_callback(get_rid(),this,SceneStringNames::get_singleton()->_body_inout);
|
||||
Physics2DServer::get_singleton()->area_set_area_monitor_callback(get_rid(),this,SceneStringNames::get_singleton()->_area_inout);
|
||||
|
||||
} else {
|
||||
Physics2DServer::get_singleton()->area_set_monitor_callback(get_rid(),NULL,StringName());
|
||||
Physics2DServer::get_singleton()->area_set_area_monitor_callback(get_rid(),NULL,StringName());
|
||||
@ -652,17 +653,17 @@ void Area2D::_bind_methods() {
|
||||
|
||||
|
||||
ADD_PROPERTYNZ( PropertyInfo(Variant::INT,"space_override",PROPERTY_HINT_ENUM,"Disabled,Combine,Replace"),_SCS("set_space_override_mode"),_SCS("get_space_override_mode"));
|
||||
ADD_PROPERTY( PropertyInfo(Variant::BOOL,"gravity_point"),_SCS("set_gravity_is_point"),_SCS("is_gravity_a_point"));
|
||||
ADD_PROPERTY( PropertyInfo(Variant::REAL,"gravity_distance_scale", PROPERTY_HINT_RANGE,"0,1024,0.001"),_SCS("set_gravity_distance_scale"),_SCS("get_gravity_distance_scale"));
|
||||
ADD_PROPERTYNZ( PropertyInfo(Variant::BOOL,"gravity_point"),_SCS("set_gravity_is_point"),_SCS("is_gravity_a_point"));
|
||||
ADD_PROPERTYNZ( PropertyInfo(Variant::REAL,"gravity_distance_scale", PROPERTY_HINT_RANGE,"0,1024,0.001"),_SCS("set_gravity_distance_scale"),_SCS("get_gravity_distance_scale"));
|
||||
ADD_PROPERTY( PropertyInfo(Variant::VECTOR2,"gravity_vec"),_SCS("set_gravity_vector"),_SCS("get_gravity_vector"));
|
||||
ADD_PROPERTY( PropertyInfo(Variant::REAL,"gravity",PROPERTY_HINT_RANGE,"-1024,1024,0.01"),_SCS("set_gravity"),_SCS("get_gravity"));
|
||||
ADD_PROPERTY( PropertyInfo(Variant::REAL,"linear_damp",PROPERTY_HINT_RANGE,"0,1024,0.001"),_SCS("set_linear_damp"),_SCS("get_linear_damp"));
|
||||
ADD_PROPERTY( PropertyInfo(Variant::REAL,"angular_damp",PROPERTY_HINT_RANGE,"0,1024,0.001"),_SCS("set_angular_damp"),_SCS("get_angular_damp"));
|
||||
ADD_PROPERTYNZ( PropertyInfo(Variant::INT,"priority",PROPERTY_HINT_RANGE,"0,128,1"),_SCS("set_priority"),_SCS("get_priority"));
|
||||
ADD_PROPERTY( PropertyInfo(Variant::BOOL,"monitoring"),_SCS("set_enable_monitoring"),_SCS("is_monitoring_enabled"));
|
||||
ADD_PROPERTY( PropertyInfo(Variant::BOOL,"monitorable"),_SCS("set_monitorable"),_SCS("is_monitorable"));
|
||||
ADD_PROPERTY( PropertyInfo(Variant::INT,"collision/layers",PROPERTY_HINT_ALL_FLAGS),_SCS("set_layer_mask"),_SCS("get_layer_mask"));
|
||||
ADD_PROPERTY( PropertyInfo(Variant::INT,"collision/mask",PROPERTY_HINT_ALL_FLAGS),_SCS("set_collision_mask"),_SCS("get_collision_mask"));
|
||||
ADD_PROPERTYNO( PropertyInfo(Variant::BOOL,"monitoring"),_SCS("set_enable_monitoring"),_SCS("is_monitoring_enabled"));
|
||||
ADD_PROPERTYNO( PropertyInfo(Variant::BOOL,"monitorable"),_SCS("set_monitorable"),_SCS("is_monitorable"));
|
||||
ADD_PROPERTYNO( PropertyInfo(Variant::INT,"collision/layers",PROPERTY_HINT_ALL_FLAGS),_SCS("set_layer_mask"),_SCS("get_layer_mask"));
|
||||
ADD_PROPERTYNO( PropertyInfo(Variant::INT,"collision/mask",PROPERTY_HINT_ALL_FLAGS),_SCS("set_collision_mask"),_SCS("get_collision_mask"));
|
||||
|
||||
}
|
||||
|
||||
|
@ -1071,8 +1071,8 @@ void CanvasItem::_bind_methods() {
|
||||
ObjectTypeDB::bind_method(_MD("draw_rect","rect","color"),&CanvasItem::draw_rect);
|
||||
ObjectTypeDB::bind_method(_MD("draw_circle","pos","radius","color"),&CanvasItem::draw_circle);
|
||||
ObjectTypeDB::bind_method(_MD("draw_texture","texture:Texture","pos"),&CanvasItem::draw_texture);
|
||||
ObjectTypeDB::bind_method(_MD("draw_texture_rect","texture:Texture","rect","tile","modulate"),&CanvasItem::draw_texture_rect,DEFVAL(false),DEFVAL(Color(1,1,1)));
|
||||
ObjectTypeDB::bind_method(_MD("draw_texture_rect_region","texture:Texture","rect","src_rect","modulate"),&CanvasItem::draw_texture_rect_region,DEFVAL(Color(1,1,1)));
|
||||
ObjectTypeDB::bind_method(_MD("draw_texture_rect","texture:Texture","rect","tile","modulate","transpose"),&CanvasItem::draw_texture_rect,DEFVAL(Color(1,1,1)),DEFVAL(false));
|
||||
ObjectTypeDB::bind_method(_MD("draw_texture_rect_region","texture:Texture","rect","src_rect","modulate","transpose"),&CanvasItem::draw_texture_rect_region,DEFVAL(Color(1,1,1)),DEFVAL(false));
|
||||
ObjectTypeDB::bind_method(_MD("draw_style_box","style_box:StyleBox","rect"),&CanvasItem::draw_style_box);
|
||||
ObjectTypeDB::bind_method(_MD("draw_primitive","points","colors","uvs","texture:Texture","width"),&CanvasItem::draw_primitive,DEFVAL(Array()),DEFVAL(Ref<Texture>()),DEFVAL(1.0));
|
||||
ObjectTypeDB::bind_method(_MD("draw_polygon","points","colors","uvs","texture:Texture"),&CanvasItem::draw_polygon,DEFVAL(Array()),DEFVAL(Ref<Texture>()));
|
||||
@ -1103,14 +1103,14 @@ void CanvasItem::_bind_methods() {
|
||||
|
||||
BIND_VMETHOD(MethodInfo("_draw"));
|
||||
|
||||
ADD_PROPERTY( PropertyInfo(Variant::BOOL,"visibility/visible"), _SCS("_set_visible_"),_SCS("_is_visible_") );
|
||||
ADD_PROPERTY( PropertyInfo(Variant::REAL,"visibility/opacity",PROPERTY_HINT_RANGE, "0,1,0.01"), _SCS("set_opacity"),_SCS("get_opacity") );
|
||||
ADD_PROPERTY( PropertyInfo(Variant::REAL,"visibility/self_opacity",PROPERTY_HINT_RANGE, "0,1,0.01"), _SCS("set_self_opacity"),_SCS("get_self_opacity") );
|
||||
ADD_PROPERTYNO( PropertyInfo(Variant::BOOL,"visibility/visible"), _SCS("_set_visible_"),_SCS("_is_visible_") );
|
||||
ADD_PROPERTYNO( PropertyInfo(Variant::REAL,"visibility/opacity",PROPERTY_HINT_RANGE, "0,1,0.01"), _SCS("set_opacity"),_SCS("get_opacity") );
|
||||
ADD_PROPERTYNO( PropertyInfo(Variant::REAL,"visibility/self_opacity",PROPERTY_HINT_RANGE, "0,1,0.01"), _SCS("set_self_opacity"),_SCS("get_self_opacity") );
|
||||
ADD_PROPERTYNZ( PropertyInfo(Variant::BOOL,"visibility/behind_parent"), _SCS("set_draw_behind_parent"),_SCS("is_draw_behind_parent_enabled") );
|
||||
ADD_PROPERTY( PropertyInfo(Variant::BOOL,"visibility/on_top",PROPERTY_HINT_NONE,"",0), _SCS("_set_on_top"),_SCS("_is_on_top") ); //compatibility
|
||||
|
||||
ADD_PROPERTYNZ( PropertyInfo(Variant::INT,"visibility/blend_mode",PROPERTY_HINT_ENUM, "Mix,Add,Sub,Mul,PMAlpha"), _SCS("set_blend_mode"),_SCS("get_blend_mode") );
|
||||
ADD_PROPERTYNZ( PropertyInfo(Variant::INT,"visibility/light_mask",PROPERTY_HINT_ALL_FLAGS), _SCS("set_light_mask"),_SCS("get_light_mask") );
|
||||
ADD_PROPERTYNO( PropertyInfo(Variant::INT,"visibility/light_mask",PROPERTY_HINT_ALL_FLAGS), _SCS("set_light_mask"),_SCS("get_light_mask") );
|
||||
ADD_PROPERTYNZ( PropertyInfo(Variant::OBJECT,"material/material",PROPERTY_HINT_RESOURCE_TYPE, "CanvasItemMaterial"), _SCS("set_material"),_SCS("get_material") );
|
||||
ADD_PROPERTYNZ( PropertyInfo(Variant::BOOL,"material/use_parent"), _SCS("set_use_parent_material"),_SCS("get_use_parent_material") );
|
||||
//exporting these two things doesn't really make much sense i think
|
||||
|
@ -115,19 +115,16 @@ void CollisionObject2D::_update_shapes() {
|
||||
bool CollisionObject2D::_set(const StringName& p_name, const Variant& p_value) {
|
||||
String name=p_name;
|
||||
|
||||
if (name=="shape_count") {
|
||||
if (name.begins_with("shapes/")) {
|
||||
|
||||
shapes.resize(p_value);
|
||||
_update_shapes();
|
||||
_change_notify();
|
||||
|
||||
} else if (name.begins_with("shapes/")) {
|
||||
|
||||
int idx=name.get_slice("/",1).to_int();
|
||||
String what=name.get_slice("/",2);
|
||||
if (what=="shape")
|
||||
set_shape(idx,RefPtr(p_value));
|
||||
else if (what=="transform")
|
||||
int idx=name.get_slicec('/',1).to_int();
|
||||
String what=name.get_slicec('/',2);
|
||||
if (what=="shape") {
|
||||
if (idx>=shapes.size())
|
||||
add_shape(RefPtr(p_value));
|
||||
else
|
||||
set_shape(idx,RefPtr(p_value));
|
||||
} else if (what=="transform")
|
||||
set_shape_transform(idx,p_value);
|
||||
else if (what=="trigger")
|
||||
set_shape_as_trigger(idx,p_value);
|
||||
@ -143,12 +140,10 @@ bool CollisionObject2D::_get(const StringName& p_name,Variant &r_ret) const {
|
||||
|
||||
String name=p_name;
|
||||
|
||||
if (name=="shape_count") {
|
||||
r_ret= shapes.size();
|
||||
} else if (name.begins_with("shapes/")) {
|
||||
if (name.begins_with("shapes/")) {
|
||||
|
||||
int idx=name.get_slice("/",1).to_int();
|
||||
String what=name.get_slice("/",2);
|
||||
int idx=name.get_slicec('/',1).to_int();
|
||||
String what=name.get_slicec('/',2);
|
||||
if (what=="shape")
|
||||
r_ret= get_shape(idx);
|
||||
else if (what=="transform")
|
||||
@ -163,7 +158,7 @@ bool CollisionObject2D::_get(const StringName& p_name,Variant &r_ret) const {
|
||||
|
||||
void CollisionObject2D::_get_property_list( List<PropertyInfo> *p_list) const {
|
||||
|
||||
p_list->push_back( PropertyInfo(Variant::INT,"shape_count",PROPERTY_HINT_RANGE,"0,256,1",PROPERTY_USAGE_NOEDITOR|PROPERTY_USAGE_NO_INSTANCE_STATE) );
|
||||
//p_list->push_back( PropertyInfo(Variant::INT,"shape_count",PROPERTY_HINT_RANGE,"0,256,1",PROPERTY_USAGE_NOEDITOR|PROPERTY_USAGE_NO_INSTANCE_STATE) );
|
||||
|
||||
for(int i=0;i<shapes.size();i++) {
|
||||
String path="shapes/"+itos(i)+"/";
|
||||
@ -254,12 +249,19 @@ void CollisionObject2D::_bind_methods() {
|
||||
|
||||
void CollisionObject2D::add_shape(const Ref<Shape2D>& p_shape, const Matrix32& p_transform) {
|
||||
|
||||
ERR_FAIL_COND(p_shape.is_null());
|
||||
|
||||
ShapeData sdata;
|
||||
sdata.shape=p_shape;
|
||||
sdata.xform=p_transform;
|
||||
sdata.trigger=false;
|
||||
shapes.push_back(sdata);
|
||||
_update_shapes();
|
||||
|
||||
if (area)
|
||||
Physics2DServer::get_singleton()->area_add_shape(get_rid(),p_shape->get_rid(),p_transform);
|
||||
else
|
||||
Physics2DServer::get_singleton()->body_add_shape(get_rid(),p_shape->get_rid(),p_transform);
|
||||
|
||||
shapes.push_back(sdata);
|
||||
|
||||
}
|
||||
int CollisionObject2D::get_shape_count() const {
|
||||
@ -270,8 +272,15 @@ int CollisionObject2D::get_shape_count() const {
|
||||
void CollisionObject2D::set_shape(int p_shape_idx, const Ref<Shape2D>& p_shape) {
|
||||
|
||||
ERR_FAIL_INDEX(p_shape_idx,shapes.size());
|
||||
ERR_FAIL_COND(p_shape.is_null());
|
||||
|
||||
shapes[p_shape_idx].shape=p_shape;
|
||||
_update_shapes();
|
||||
if (area)
|
||||
Physics2DServer::get_singleton()->area_set_shape(get_rid(),p_shape_idx,p_shape->get_rid());
|
||||
else
|
||||
Physics2DServer::get_singleton()->body_set_shape(get_rid(),p_shape_idx,p_shape->get_rid());
|
||||
|
||||
// _update_shapes();
|
||||
}
|
||||
|
||||
void CollisionObject2D::set_shape_transform(int p_shape_idx, const Matrix32& p_transform) {
|
||||
@ -279,7 +288,12 @@ void CollisionObject2D::set_shape_transform(int p_shape_idx, const Matrix32& p_t
|
||||
ERR_FAIL_INDEX(p_shape_idx,shapes.size());
|
||||
shapes[p_shape_idx].xform=p_transform;
|
||||
|
||||
_update_shapes();
|
||||
if (area)
|
||||
Physics2DServer::get_singleton()->area_set_shape_transform(get_rid(),p_shape_idx,p_transform);
|
||||
else
|
||||
Physics2DServer::get_singleton()->body_set_shape_transform(get_rid(),p_shape_idx,p_transform);
|
||||
|
||||
// _update_shapes();
|
||||
}
|
||||
|
||||
Ref<Shape2D> CollisionObject2D::get_shape(int p_shape_idx) const {
|
||||
|
@ -398,11 +398,11 @@ void Node2D::_bind_methods() {
|
||||
|
||||
ObjectTypeDB::bind_method(_MD("get_relative_transform"),&Node2D::get_relative_transform);
|
||||
|
||||
ADD_PROPERTY(PropertyInfo(Variant::VECTOR2,"transform/pos"),_SCS("set_pos"),_SCS("get_pos"));
|
||||
ADD_PROPERTY(PropertyInfo(Variant::REAL,"transform/rot",PROPERTY_HINT_RANGE,"-1440,1440,0.1"),_SCS("_set_rotd"),_SCS("_get_rotd"));
|
||||
ADD_PROPERTY(PropertyInfo(Variant::VECTOR2,"transform/scale"),_SCS("set_scale"),_SCS("get_scale"));
|
||||
ADD_PROPERTY(PropertyInfo(Variant::INT,"z/z",PROPERTY_HINT_RANGE,itos(VS::CANVAS_ITEM_Z_MIN)+","+itos(VS::CANVAS_ITEM_Z_MAX)+",1"),_SCS("set_z"),_SCS("get_z"));
|
||||
ADD_PROPERTY(PropertyInfo(Variant::BOOL,"z/relative"),_SCS("set_z_as_relative"),_SCS("is_z_relative"));
|
||||
ADD_PROPERTYNZ(PropertyInfo(Variant::VECTOR2,"transform/pos"),_SCS("set_pos"),_SCS("get_pos"));
|
||||
ADD_PROPERTYNZ(PropertyInfo(Variant::REAL,"transform/rot",PROPERTY_HINT_RANGE,"-1440,1440,0.1"),_SCS("_set_rotd"),_SCS("_get_rotd"));
|
||||
ADD_PROPERTYNO(PropertyInfo(Variant::VECTOR2,"transform/scale"),_SCS("set_scale"),_SCS("get_scale"));
|
||||
ADD_PROPERTYNZ(PropertyInfo(Variant::INT,"z/z",PROPERTY_HINT_RANGE,itos(VS::CANVAS_ITEM_Z_MIN)+","+itos(VS::CANVAS_ITEM_Z_MAX)+",1"),_SCS("set_z"),_SCS("get_z"));
|
||||
ADD_PROPERTYNO(PropertyInfo(Variant::BOOL,"z/relative"),_SCS("set_z_as_relative"),_SCS("is_z_relative"));
|
||||
|
||||
|
||||
}
|
||||
|
@ -1072,19 +1072,19 @@ void Particles2D::_bind_methods() {
|
||||
|
||||
ADD_PROPERTY(PropertyInfo(Variant::INT,"config/amount",PROPERTY_HINT_EXP_RANGE,"1,1024"),_SCS("set_amount"),_SCS("get_amount") );
|
||||
ADD_PROPERTY(PropertyInfo(Variant::REAL,"config/lifetime",PROPERTY_HINT_EXP_RANGE,"0.1,3600,0.1"),_SCS("set_lifetime"),_SCS("get_lifetime") );
|
||||
ADD_PROPERTY(PropertyInfo(Variant::REAL,"config/time_scale",PROPERTY_HINT_EXP_RANGE,"0.01,128,0.01"),_SCS("set_time_scale"),_SCS("get_time_scale") );
|
||||
ADD_PROPERTY(PropertyInfo(Variant::REAL,"config/preprocess",PROPERTY_HINT_EXP_RANGE,"0.1,3600,0.1"),_SCS("set_pre_process_time"),_SCS("get_pre_process_time") );
|
||||
ADD_PROPERTY(PropertyInfo(Variant::REAL,"config/emit_timeout",PROPERTY_HINT_RANGE,"0,3600,0.1"),_SCS("set_emit_timeout"),_SCS("get_emit_timeout") );
|
||||
ADD_PROPERTY(PropertyInfo(Variant::BOOL,"config/emitting"),_SCS("set_emitting"),_SCS("is_emitting") );
|
||||
ADD_PROPERTY(PropertyInfo(Variant::VECTOR2,"config/offset"),_SCS("set_emissor_offset"),_SCS("get_emissor_offset"));
|
||||
ADD_PROPERTY(PropertyInfo(Variant::VECTOR2,"config/half_extents"),_SCS("set_emission_half_extents"),_SCS("get_emission_half_extents"));
|
||||
ADD_PROPERTY(PropertyInfo(Variant::BOOL,"config/local_space"),_SCS("set_use_local_space"),_SCS("is_using_local_space"));
|
||||
ADD_PROPERTY(PropertyInfo(Variant::REAL,"config/explosiveness",PROPERTY_HINT_RANGE,"0,1,0.01"),_SCS("set_explosiveness"),_SCS("get_explosiveness"));
|
||||
ADD_PROPERTY(PropertyInfo(Variant::BOOL,"config/flip_h"),_SCS("set_flip_h"),_SCS("is_flipped_h"));
|
||||
ADD_PROPERTY(PropertyInfo(Variant::BOOL,"config/flip_v"),_SCS("set_flip_v"),_SCS("is_flipped_v"));
|
||||
ADD_PROPERTY(PropertyInfo(Variant::OBJECT,"config/texture",PROPERTY_HINT_RESOURCE_TYPE,"Texture"),_SCS("set_texture"),_SCS("get_texture"));
|
||||
ADD_PROPERTY(PropertyInfo(Variant::INT,"config/h_frames",PROPERTY_HINT_RANGE,"1,512,1"),_SCS("set_h_frames"),_SCS("get_h_frames"));
|
||||
ADD_PROPERTY(PropertyInfo(Variant::INT,"config/v_frames",PROPERTY_HINT_RANGE,"1,512,1"),_SCS("set_v_frames"),_SCS("get_v_frames"));
|
||||
ADD_PROPERTYNO(PropertyInfo(Variant::REAL,"config/time_scale",PROPERTY_HINT_EXP_RANGE,"0.01,128,0.01"),_SCS("set_time_scale"),_SCS("get_time_scale") );
|
||||
ADD_PROPERTYNZ(PropertyInfo(Variant::REAL,"config/preprocess",PROPERTY_HINT_EXP_RANGE,"0.1,3600,0.1"),_SCS("set_pre_process_time"),_SCS("get_pre_process_time") );
|
||||
ADD_PROPERTYNZ(PropertyInfo(Variant::REAL,"config/emit_timeout",PROPERTY_HINT_RANGE,"0,3600,0.1"),_SCS("set_emit_timeout"),_SCS("get_emit_timeout") );
|
||||
ADD_PROPERTYNO(PropertyInfo(Variant::BOOL,"config/emitting"),_SCS("set_emitting"),_SCS("is_emitting") );
|
||||
ADD_PROPERTYNZ(PropertyInfo(Variant::VECTOR2,"config/offset"),_SCS("set_emissor_offset"),_SCS("get_emissor_offset"));
|
||||
ADD_PROPERTYNZ(PropertyInfo(Variant::VECTOR2,"config/half_extents"),_SCS("set_emission_half_extents"),_SCS("get_emission_half_extents"));
|
||||
ADD_PROPERTYNO(PropertyInfo(Variant::BOOL,"config/local_space"),_SCS("set_use_local_space"),_SCS("is_using_local_space"));
|
||||
ADD_PROPERTYNO(PropertyInfo(Variant::REAL,"config/explosiveness",PROPERTY_HINT_RANGE,"0,1,0.01"),_SCS("set_explosiveness"),_SCS("get_explosiveness"));
|
||||
ADD_PROPERTYNZ(PropertyInfo(Variant::BOOL,"config/flip_h"),_SCS("set_flip_h"),_SCS("is_flipped_h"));
|
||||
ADD_PROPERTYNZ(PropertyInfo(Variant::BOOL,"config/flip_v"),_SCS("set_flip_v"),_SCS("is_flipped_v"));
|
||||
ADD_PROPERTYNZ(PropertyInfo(Variant::OBJECT,"config/texture",PROPERTY_HINT_RESOURCE_TYPE,"Texture"),_SCS("set_texture"),_SCS("get_texture"));
|
||||
ADD_PROPERTYNO(PropertyInfo(Variant::INT,"config/h_frames",PROPERTY_HINT_RANGE,"1,512,1"),_SCS("set_h_frames"),_SCS("get_h_frames"));
|
||||
ADD_PROPERTYNO(PropertyInfo(Variant::INT,"config/v_frames",PROPERTY_HINT_RANGE,"1,512,1"),_SCS("set_v_frames"),_SCS("get_v_frames"));
|
||||
|
||||
|
||||
for(int i=0;i<PARAM_MAX;i++) {
|
||||
@ -1092,10 +1092,10 @@ void Particles2D::_bind_methods() {
|
||||
}
|
||||
|
||||
for(int i=0;i<PARAM_MAX;i++) {
|
||||
ADD_PROPERTYI(PropertyInfo(Variant::REAL,_particlesframe_property_rnames[i],PROPERTY_HINT_RANGE,"-1,1,0.01"),_SCS("set_randomness"),_SCS("get_randomness"),i);
|
||||
ADD_PROPERTYINZ(PropertyInfo(Variant::REAL,_particlesframe_property_rnames[i],PROPERTY_HINT_RANGE,"-1,1,0.01"),_SCS("set_randomness"),_SCS("get_randomness"),i);
|
||||
}
|
||||
|
||||
ADD_PROPERTY( PropertyInfo( Variant::INT, "color_phases/count",PROPERTY_HINT_RANGE,"0,4,1", 0), _SCS("set_color_phases"), _SCS("get_color_phases"));
|
||||
ADD_PROPERTYNZ( PropertyInfo( Variant::INT, "color_phases/count",PROPERTY_HINT_RANGE,"0,4,1", 0), _SCS("set_color_phases"), _SCS("get_color_phases"));
|
||||
|
||||
//Backward compatibility. They will be converted to color ramp
|
||||
for(int i=0;i<MAX_COLOR_PHASES;i++) {
|
||||
@ -1104,10 +1104,10 @@ void Particles2D::_bind_methods() {
|
||||
ADD_PROPERTYI( PropertyInfo( Variant::COLOR, phase+"color", PROPERTY_HINT_NONE, "", 0),_SCS("set_color_phase_color"),_SCS("get_color_phase_color"),i );
|
||||
}
|
||||
|
||||
ADD_PROPERTY(PropertyInfo(Variant::COLOR, "color/color"),_SCS("set_color"),_SCS("get_color"));
|
||||
ADD_PROPERTY(PropertyInfo(Variant::OBJECT,"color/color_ramp",PROPERTY_HINT_RESOURCE_TYPE,"ColorRamp"),_SCS("set_color_ramp"),_SCS("get_color_ramp"));
|
||||
ADD_PROPERTYNO(PropertyInfo(Variant::COLOR, "color/color"),_SCS("set_color"),_SCS("get_color"));
|
||||
ADD_PROPERTYNZ(PropertyInfo(Variant::OBJECT,"color/color_ramp",PROPERTY_HINT_RESOURCE_TYPE,"ColorRamp"),_SCS("set_color_ramp"),_SCS("get_color_ramp"));
|
||||
|
||||
ADD_PROPERTY(PropertyInfo(Variant::VECTOR2_ARRAY,"emission_points",PROPERTY_HINT_NONE,"",PROPERTY_USAGE_NOEDITOR),_SCS("set_emission_points"),_SCS("get_emission_points"));
|
||||
ADD_PROPERTYNZ(PropertyInfo(Variant::VECTOR2_ARRAY,"emission_points",PROPERTY_HINT_NONE,"",PROPERTY_USAGE_NOEDITOR),_SCS("set_emission_points"),_SCS("get_emission_points"));
|
||||
|
||||
BIND_CONSTANT( PARAM_DIRECTION );
|
||||
BIND_CONSTANT( PARAM_SPREAD );
|
||||
|
@ -103,14 +103,18 @@ void Sprite::set_texture(const Ref<Texture>& p_texture) {
|
||||
|
||||
if (p_texture==texture)
|
||||
return;
|
||||
#ifdef DEBUG_ENABLED
|
||||
if (texture.is_valid()) {
|
||||
texture->disconnect(CoreStringNames::get_singleton()->changed,this,SceneStringNames::get_singleton()->update);
|
||||
}
|
||||
#endif
|
||||
texture=p_texture;
|
||||
#ifdef DEBUG_ENABLED
|
||||
if (texture.is_valid()) {
|
||||
texture->set_flags(texture->get_flags()); //remove repeat from texture, it looks bad in sprites
|
||||
texture->connect(CoreStringNames::get_singleton()->changed,this,SceneStringNames::get_singleton()->update);
|
||||
}
|
||||
#endif
|
||||
update();
|
||||
item_rect_changed();
|
||||
}
|
||||
@ -313,17 +317,17 @@ void Sprite::_bind_methods() {
|
||||
|
||||
ADD_SIGNAL(MethodInfo("frame_changed"));
|
||||
|
||||
ADD_PROPERTY( PropertyInfo( Variant::OBJECT, "texture", PROPERTY_HINT_RESOURCE_TYPE,"Texture"), _SCS("set_texture"),_SCS("get_texture"));
|
||||
ADD_PROPERTY( PropertyInfo( Variant::BOOL, "centered"), _SCS("set_centered"),_SCS("is_centered"));
|
||||
ADD_PROPERTY( PropertyInfo( Variant::VECTOR2, "offset"), _SCS("set_offset"),_SCS("get_offset"));
|
||||
ADD_PROPERTY( PropertyInfo( Variant::BOOL, "flip_h"), _SCS("set_flip_h"),_SCS("is_flipped_h"));
|
||||
ADD_PROPERTY( PropertyInfo( Variant::BOOL, "flip_v"), _SCS("set_flip_v"),_SCS("is_flipped_v"));
|
||||
ADD_PROPERTY( PropertyInfo( Variant::INT, "vframes"), _SCS("set_vframes"),_SCS("get_vframes"));
|
||||
ADD_PROPERTY( PropertyInfo( Variant::INT, "hframes"), _SCS("set_hframes"),_SCS("get_hframes"));
|
||||
ADD_PROPERTY( PropertyInfo( Variant::INT, "frame",PROPERTY_HINT_SPRITE_FRAME), _SCS("set_frame"),_SCS("get_frame"));
|
||||
ADD_PROPERTY( PropertyInfo( Variant::COLOR, "modulate"), _SCS("set_modulate"),_SCS("get_modulate"));
|
||||
ADD_PROPERTY( PropertyInfo( Variant::BOOL, "region"), _SCS("set_region"),_SCS("is_region"));
|
||||
ADD_PROPERTY( PropertyInfo( Variant::RECT2, "region_rect"), _SCS("set_region_rect"),_SCS("get_region_rect"));
|
||||
ADD_PROPERTYNZ( PropertyInfo( Variant::OBJECT, "texture", PROPERTY_HINT_RESOURCE_TYPE,"Texture"), _SCS("set_texture"),_SCS("get_texture"));
|
||||
ADD_PROPERTYNO( PropertyInfo( Variant::BOOL, "centered"), _SCS("set_centered"),_SCS("is_centered"));
|
||||
ADD_PROPERTYNZ( PropertyInfo( Variant::VECTOR2, "offset"), _SCS("set_offset"),_SCS("get_offset"));
|
||||
ADD_PROPERTYNZ( PropertyInfo( Variant::BOOL, "flip_h"), _SCS("set_flip_h"),_SCS("is_flipped_h"));
|
||||
ADD_PROPERTYNZ( PropertyInfo( Variant::BOOL, "flip_v"), _SCS("set_flip_v"),_SCS("is_flipped_v"));
|
||||
ADD_PROPERTYNO( PropertyInfo( Variant::INT, "vframes"), _SCS("set_vframes"),_SCS("get_vframes"));
|
||||
ADD_PROPERTYNO( PropertyInfo( Variant::INT, "hframes"), _SCS("set_hframes"),_SCS("get_hframes"));
|
||||
ADD_PROPERTYNZ( PropertyInfo( Variant::INT, "frame",PROPERTY_HINT_SPRITE_FRAME), _SCS("set_frame"),_SCS("get_frame"));
|
||||
ADD_PROPERTYNO( PropertyInfo( Variant::COLOR, "modulate"), _SCS("set_modulate"),_SCS("get_modulate"));
|
||||
ADD_PROPERTYNZ( PropertyInfo( Variant::BOOL, "region"), _SCS("set_region"),_SCS("is_region"));
|
||||
ADD_PROPERTYNZ( PropertyInfo( Variant::RECT2, "region_rect"), _SCS("set_region_rect"),_SCS("get_region_rect"));
|
||||
|
||||
}
|
||||
|
||||
@ -530,10 +534,10 @@ void ViewportSprite::_bind_methods() {
|
||||
ObjectTypeDB::bind_method(_MD("set_modulate","modulate"),&ViewportSprite::set_modulate);
|
||||
ObjectTypeDB::bind_method(_MD("get_modulate"),&ViewportSprite::get_modulate);
|
||||
|
||||
ADD_PROPERTY( PropertyInfo( Variant::NODE_PATH, "viewport"), _SCS("set_viewport_path"),_SCS("get_viewport_path"));
|
||||
ADD_PROPERTY( PropertyInfo( Variant::BOOL, "centered"), _SCS("set_centered"),_SCS("is_centered"));
|
||||
ADD_PROPERTY( PropertyInfo( Variant::VECTOR2, "offset"), _SCS("set_offset"),_SCS("get_offset"));
|
||||
ADD_PROPERTY( PropertyInfo( Variant::COLOR, "modulate"), _SCS("set_modulate"),_SCS("get_modulate"));
|
||||
ADD_PROPERTYNZ( PropertyInfo( Variant::NODE_PATH, "viewport"), _SCS("set_viewport_path"),_SCS("get_viewport_path"));
|
||||
ADD_PROPERTYNO( PropertyInfo( Variant::BOOL, "centered"), _SCS("set_centered"),_SCS("is_centered"));
|
||||
ADD_PROPERTYNZ( PropertyInfo( Variant::VECTOR2, "offset"), _SCS("set_offset"),_SCS("get_offset"));
|
||||
ADD_PROPERTYNO( PropertyInfo( Variant::COLOR, "modulate"), _SCS("set_modulate"),_SCS("get_modulate"));
|
||||
|
||||
}
|
||||
|
||||
|
@ -579,6 +579,10 @@ void TileMap::_make_quadrant_dirty(Map<PosKey,Quadrant>::Element *Q) {
|
||||
call_deferred("_update_dirty_quadrants");
|
||||
}
|
||||
|
||||
void TileMap::set_cellv(const Vector2& p_pos,int p_tile,bool p_flip_x,bool p_flip_y,bool p_transpose) {
|
||||
|
||||
set_cell(p_pos.x,p_pos.y,p_tile,p_flip_x,p_flip_y,p_transpose);
|
||||
}
|
||||
|
||||
void TileMap::set_cell(int p_x,int p_y,int p_tile,bool p_flip_x,bool p_flip_y,bool p_transpose) {
|
||||
|
||||
@ -1106,6 +1110,7 @@ void TileMap::_bind_methods() {
|
||||
ObjectTypeDB::bind_method(_MD("get_collision_bounce"),&TileMap::get_collision_bounce);
|
||||
|
||||
ObjectTypeDB::bind_method(_MD("set_cell","x","y","tile","flip_x","flip_y","transpose"),&TileMap::set_cell,DEFVAL(false),DEFVAL(false),DEFVAL(false));
|
||||
ObjectTypeDB::bind_method(_MD("set_cellv","pos","tile","flip_x","flip_y","transpose"),&TileMap::set_cellv,DEFVAL(false),DEFVAL(false),DEFVAL(false));
|
||||
ObjectTypeDB::bind_method(_MD("get_cell","x","y"),&TileMap::get_cell);
|
||||
ObjectTypeDB::bind_method(_MD("is_cell_x_flipped","x","y"),&TileMap::is_cell_x_flipped);
|
||||
ObjectTypeDB::bind_method(_MD("is_cell_y_flipped","x","y"),&TileMap::is_cell_y_flipped);
|
||||
|
@ -207,6 +207,8 @@ public:
|
||||
bool is_cell_y_flipped(int p_x,int p_y) const;
|
||||
bool is_cell_transposed(int p_x,int p_y) const;
|
||||
|
||||
void set_cellv(const Vector2& p_pos,int p_tile,bool p_flip_x=false,bool p_flip_y=false,bool p_transpose=false);
|
||||
|
||||
Rect2 get_item_rect() const;
|
||||
|
||||
void set_collision_layer(uint32_t p_layer);
|
||||
|
@ -299,8 +299,8 @@ void Area::set_enable_monitoring(bool p_enable) {
|
||||
|
||||
if (monitoring) {
|
||||
|
||||
PhysicsServer::get_singleton()->area_set_monitor_callback(get_rid(),this,"_body_inout");
|
||||
PhysicsServer::get_singleton()->area_set_area_monitor_callback(get_rid(),this,"_area_inout");
|
||||
PhysicsServer::get_singleton()->area_set_monitor_callback(get_rid(),this,SceneStringNames::get_singleton()->_body_inout);
|
||||
PhysicsServer::get_singleton()->area_set_area_monitor_callback(get_rid(),this,SceneStringNames::get_singleton()->_area_inout);
|
||||
} else {
|
||||
PhysicsServer::get_singleton()->area_set_monitor_callback(get_rid(),NULL,StringName());
|
||||
PhysicsServer::get_singleton()->area_set_area_monitor_callback(get_rid(),NULL,StringName());
|
||||
|
@ -122,8 +122,8 @@ bool CollisionObject::_set(const StringName& p_name, const Variant& p_value) {
|
||||
|
||||
} else if (name.begins_with("shapes/")) {
|
||||
|
||||
int idx=name.get_slice("/",1).to_int();
|
||||
String what=name.get_slice("/",2);
|
||||
int idx=name.get_slicec('/',1).to_int();
|
||||
String what=name.get_slicec('/',2);
|
||||
if (what=="shape")
|
||||
set_shape(idx,RefPtr(p_value));
|
||||
else if (what=="transform")
|
||||
@ -148,8 +148,8 @@ bool CollisionObject::_get(const StringName& p_name,Variant &r_ret) const {
|
||||
r_ret= shapes.size();
|
||||
} else if (name.begins_with("shapes/")) {
|
||||
|
||||
int idx=name.get_slice("/",1).to_int();
|
||||
String what=name.get_slice("/",2);
|
||||
int idx=name.get_slicec('/',1).to_int();
|
||||
String what=name.get_slicec('/',2);
|
||||
if (what=="shape")
|
||||
r_ret= get_shape(idx);
|
||||
else if (what=="transform")
|
||||
|
@ -41,8 +41,8 @@ bool Skeleton::_set(const StringName& p_path, const Variant& p_value) {
|
||||
if (!path.begins_with("bones/"))
|
||||
return false;
|
||||
|
||||
int which=path.get_slice("/",1).to_int();
|
||||
String what=path.get_slice("/",2);
|
||||
int which=path.get_slicec('/',1).to_int();
|
||||
String what=path.get_slicec('/',2);
|
||||
|
||||
|
||||
if (which==bones.size() && what=="name") {
|
||||
@ -88,8 +88,8 @@ bool Skeleton::_get(const StringName& p_name,Variant &r_ret) const {
|
||||
if (!path.begins_with("bones/"))
|
||||
return false;
|
||||
|
||||
int which=path.get_slice("/",1).to_int();
|
||||
String what=path.get_slice("/",2);
|
||||
int which=path.get_slicec('/',1).to_int();
|
||||
String what=path.get_slicec('/',2);
|
||||
|
||||
ERR_FAIL_INDEX_V( which, bones.size(), false );
|
||||
|
||||
|
@ -758,7 +758,7 @@ void Spatial::_bind_methods() {
|
||||
ADD_PROPERTY( PropertyInfo(Variant::VECTOR3,"transform/rotation",PROPERTY_HINT_NONE,"",PROPERTY_USAGE_EDITOR), _SCS("_set_rotation_deg"), _SCS("_get_rotation_deg") );
|
||||
ADD_PROPERTY( PropertyInfo(Variant::VECTOR3,"transform/rotation_rad",PROPERTY_HINT_NONE,"",0), _SCS("set_rotation"), _SCS("get_rotation") );
|
||||
ADD_PROPERTY( PropertyInfo(Variant::VECTOR3,"transform/scale",PROPERTY_HINT_NONE,"",PROPERTY_USAGE_EDITOR), _SCS("set_scale"), _SCS("get_scale") );
|
||||
ADD_PROPERTY( PropertyInfo(Variant::BOOL,"visibility/visible"), _SCS("_set_visible_"), _SCS("_is_visible_") );
|
||||
ADD_PROPERTYNO( PropertyInfo(Variant::BOOL,"visibility/visible"), _SCS("_set_visible_"), _SCS("_is_visible_") );
|
||||
//ADD_PROPERTY( PropertyInfo(Variant::TRANSFORM,"transform/local"), _SCS("set_transform"), _SCS("get_transform") );
|
||||
|
||||
ADD_SIGNAL( MethodInfo("visibility_changed" ) );
|
||||
|
@ -35,10 +35,10 @@ bool AnimationPlayer::_set(const StringName& p_name, const Variant& p_value) {
|
||||
|
||||
String name=p_name;
|
||||
|
||||
if (name=="playback/speed" || name=="speed") { //bw compatibility
|
||||
if (p_name==SceneStringNames::get_singleton()->playback_speed || p_name==SceneStringNames::get_singleton()->speed) { //bw compatibility
|
||||
set_speed(p_value);
|
||||
|
||||
} else if (name=="playback/active") {
|
||||
} else if (p_name==SceneStringNames::get_singleton()->playback_active) {
|
||||
set_active(p_value);
|
||||
} else if (name.begins_with("playback/play")) {
|
||||
|
||||
@ -52,16 +52,16 @@ bool AnimationPlayer::_set(const StringName& p_name, const Variant& p_value) {
|
||||
} else if (name.begins_with("anims/")) {
|
||||
|
||||
|
||||
String which=name.get_slice("/",1);
|
||||
String which=name.get_slicec('/',1);
|
||||
|
||||
add_animation(which,p_value);
|
||||
} else if (name.begins_with("next/")) {
|
||||
|
||||
|
||||
String which=name.get_slice("/",1);
|
||||
String which=name.get_slicec('/',1);
|
||||
animation_set_next(which,p_value);
|
||||
|
||||
} else if (name=="blend_times") {
|
||||
} else if (p_name==SceneStringNames::get_singleton()->blend_times) {
|
||||
|
||||
Array array=p_value;
|
||||
int len = array.size();
|
||||
@ -77,7 +77,7 @@ bool AnimationPlayer::_set(const StringName& p_name, const Variant& p_value) {
|
||||
set_blend_time(from,to,time);
|
||||
}
|
||||
|
||||
} else if (name=="autoplay") {
|
||||
} else if (p_name==SceneStringNames::get_singleton()->autoplay) {
|
||||
autoplay=p_value;
|
||||
|
||||
} else
|
||||
@ -106,12 +106,12 @@ bool AnimationPlayer::_get(const StringName& p_name,Variant &r_ret) const {
|
||||
|
||||
} else if (name.begins_with("anims/")) {
|
||||
|
||||
String which=name.get_slice("/",1);
|
||||
String which=name.get_slicec('/',1);
|
||||
|
||||
r_ret= get_animation(which).get_ref_ptr();
|
||||
} else if (name.begins_with("next/")) {
|
||||
|
||||
String which=name.get_slice("/",1);
|
||||
String which=name.get_slicec('/',1);
|
||||
|
||||
r_ret= animation_get_next(which);
|
||||
|
||||
@ -661,8 +661,11 @@ void AnimationPlayer::_animation_process(float p_delta) {
|
||||
|
||||
Error AnimationPlayer::add_animation(const StringName& p_name, const Ref<Animation>& p_animation) {
|
||||
|
||||
#ifdef DEBUG_ENABLED
|
||||
ERR_EXPLAIN("Invalid animation name: "+String(p_name));
|
||||
ERR_FAIL_COND_V( String(p_name).find("/")!=-1 || String(p_name).find(":")!=-1 || String(p_name).find(",")!=-1 || String(p_name).find("[")!=-1, ERR_INVALID_PARAMETER );
|
||||
#endif
|
||||
|
||||
ERR_FAIL_COND_V( p_animation.is_null() , ERR_INVALID_PARAMETER );
|
||||
|
||||
//print_line("Add anim: "+String(p_name)+" name: "+p_animation->get_name());
|
||||
@ -1271,7 +1274,7 @@ AnimationPlayer::AnimationPlayer() {
|
||||
animation_process_mode=ANIMATION_PROCESS_IDLE;
|
||||
processing=false;
|
||||
default_blend_time=0;
|
||||
root=NodePath("..");
|
||||
root=SceneStringNames::get_singleton()->path_pp;
|
||||
playing = false;
|
||||
active=true;
|
||||
}
|
||||
|
@ -102,7 +102,7 @@ bool SamplePlayer::_get(const StringName& p_name,Variant &r_ret) const {
|
||||
r_ret= get_sample_library();
|
||||
} else if (name.begins_with("default/")) {
|
||||
|
||||
String what=name.get_slice("/",1);
|
||||
String what=name.get_slicec('/',1);
|
||||
|
||||
if (what=="volume_db")
|
||||
r_ret= get_default_volume_db();
|
||||
|
@ -390,10 +390,10 @@ void BaseButton::_bind_methods() {
|
||||
ADD_SIGNAL( MethodInfo("pressed" ) );
|
||||
ADD_SIGNAL( MethodInfo("released" ) );
|
||||
ADD_SIGNAL( MethodInfo("toggled", PropertyInfo( Variant::BOOL,"pressed") ) );
|
||||
ADD_PROPERTY( PropertyInfo( Variant::BOOL, "disabled"), _SCS("set_disabled"), _SCS("is_disabled"));
|
||||
ADD_PROPERTYNZ( PropertyInfo( Variant::BOOL, "disabled"), _SCS("set_disabled"), _SCS("is_disabled"));
|
||||
ADD_PROPERTY( PropertyInfo( Variant::BOOL, "toggle_mode"), _SCS("set_toggle_mode"), _SCS("is_toggle_mode"));
|
||||
ADD_PROPERTY( PropertyInfo( Variant::BOOL, "is_pressed"), _SCS("set_pressed"), _SCS("is_pressed"));
|
||||
ADD_PROPERTY( PropertyInfo( Variant::BOOL, "click_on_press"), _SCS("set_click_on_press"), _SCS("get_click_on_press"));
|
||||
ADD_PROPERTYNZ( PropertyInfo( Variant::BOOL, "is_pressed"), _SCS("set_pressed"), _SCS("is_pressed"));
|
||||
ADD_PROPERTYNZ( PropertyInfo( Variant::BOOL, "click_on_press"), _SCS("set_click_on_press"), _SCS("get_click_on_press"));
|
||||
|
||||
|
||||
BIND_CONSTANT( DRAW_NORMAL );
|
||||
|
@ -225,11 +225,11 @@ void Button::_bind_methods() {
|
||||
ObjectTypeDB::bind_method(_MD("get_text_align"),&Button::get_text_align);
|
||||
ObjectTypeDB::bind_method(_MD("is_flat"),&Button::is_flat);
|
||||
|
||||
ADD_PROPERTY( PropertyInfo( Variant::STRING, "text", PROPERTY_HINT_NONE,"",PROPERTY_USAGE_DEFAULT_INTL ), _SCS("set_text"),_SCS("get_text") );
|
||||
ADD_PROPERTY( PropertyInfo( Variant::OBJECT, "icon", PROPERTY_HINT_RESOURCE_TYPE, "Texture" ), _SCS("set_button_icon"),_SCS("get_button_icon") );
|
||||
ADD_PROPERTYNZ( PropertyInfo( Variant::STRING, "text", PROPERTY_HINT_NONE,"",PROPERTY_USAGE_DEFAULT_INTL ), _SCS("set_text"),_SCS("get_text") );
|
||||
ADD_PROPERTYNZ( PropertyInfo( Variant::OBJECT, "icon", PROPERTY_HINT_RESOURCE_TYPE, "Texture" ), _SCS("set_button_icon"),_SCS("get_button_icon") );
|
||||
ADD_PROPERTY( PropertyInfo( Variant::BOOL, "flat" ), _SCS("set_flat"),_SCS("is_flat") );
|
||||
ADD_PROPERTY( PropertyInfo( Variant::BOOL, "clip_text" ), _SCS("set_clip_text"),_SCS("get_clip_text") );
|
||||
ADD_PROPERTY( PropertyInfo( Variant::INT, "align",PROPERTY_HINT_ENUM,"Left,Center,Right" ), _SCS("set_text_align"),_SCS("get_text_align") );
|
||||
ADD_PROPERTYNZ( PropertyInfo( Variant::BOOL, "clip_text" ), _SCS("set_clip_text"),_SCS("get_clip_text") );
|
||||
ADD_PROPERTYNO( PropertyInfo( Variant::INT, "align",PROPERTY_HINT_ENUM,"Left,Center,Right" ), _SCS("set_text_align"),_SCS("get_text_align") );
|
||||
|
||||
}
|
||||
|
||||
|
@ -34,7 +34,7 @@ bool ButtonArray::_set(const StringName& p_name, const Variant& p_value) {
|
||||
String n=String(p_name);
|
||||
if (n.begins_with("button/")) {
|
||||
|
||||
String what = n.get_slice("/",1);
|
||||
String what = n.get_slicec('/',1);
|
||||
if (what=="count") {
|
||||
int new_size=p_value;
|
||||
if (new_size>0 && buttons.size()==0) {
|
||||
@ -57,7 +57,7 @@ bool ButtonArray::_set(const StringName& p_name, const Variant& p_value) {
|
||||
} else {
|
||||
int idx=what.to_int();
|
||||
ERR_FAIL_INDEX_V(idx,buttons.size(),false);
|
||||
String f = n.get_slice("/",2);
|
||||
String f = n.get_slicec('/',2);
|
||||
if (f=="text")
|
||||
buttons[idx].text=p_value;
|
||||
else if (f=="icon")
|
||||
@ -80,7 +80,7 @@ bool ButtonArray::_get(const StringName& p_name,Variant &r_ret) const {
|
||||
String n=String(p_name);
|
||||
if (n.begins_with("button/")) {
|
||||
|
||||
String what = n.get_slice("/",1);
|
||||
String what = n.get_slicec('/',1);
|
||||
if (what=="count") {
|
||||
r_ret=buttons.size();
|
||||
} else if (what=="align") {
|
||||
@ -92,7 +92,7 @@ bool ButtonArray::_get(const StringName& p_name,Variant &r_ret) const {
|
||||
} else {
|
||||
int idx=what.to_int();
|
||||
ERR_FAIL_INDEX_V(idx,buttons.size(),false);
|
||||
String f = n.get_slice("/",2);
|
||||
String f = n.get_slicec('/',2);
|
||||
if (f=="text")
|
||||
r_ret=buttons[idx].text;
|
||||
else if (f=="icon")
|
||||
|
@ -136,27 +136,27 @@ bool Control::_set(const StringName& p_name, const Variant& p_value) {
|
||||
if (p_value.get_type()==Variant::NIL) {
|
||||
|
||||
if (name.begins_with("custom_icons/")) {
|
||||
String dname = name.get_slice("/",1);
|
||||
String dname = name.get_slicec('/',1);
|
||||
data.icon_override.erase(dname);
|
||||
notification(NOTIFICATION_THEME_CHANGED);
|
||||
update();
|
||||
} else if (name.begins_with("custom_styles/")) {
|
||||
String dname = name.get_slice("/",1);
|
||||
String dname = name.get_slicec('/',1);
|
||||
data.style_override.erase(dname);
|
||||
notification(NOTIFICATION_THEME_CHANGED);
|
||||
update();
|
||||
} else if (name.begins_with("custom_fonts/")) {
|
||||
String dname = name.get_slice("/",1);
|
||||
String dname = name.get_slicec('/',1);
|
||||
data.font_override.erase(dname);
|
||||
notification(NOTIFICATION_THEME_CHANGED);
|
||||
update();
|
||||
} else if (name.begins_with("custom_colors/")) {
|
||||
String dname = name.get_slice("/",1);
|
||||
String dname = name.get_slicec('/',1);
|
||||
data.color_override.erase(dname);
|
||||
notification(NOTIFICATION_THEME_CHANGED);
|
||||
update();
|
||||
} else if (name.begins_with("custom_constants/")) {
|
||||
String dname = name.get_slice("/",1);
|
||||
String dname = name.get_slicec('/',1);
|
||||
data.constant_override.erase(dname);
|
||||
notification(NOTIFICATION_THEME_CHANGED);
|
||||
update();
|
||||
@ -165,23 +165,23 @@ bool Control::_set(const StringName& p_name, const Variant& p_value) {
|
||||
|
||||
} else {
|
||||
if (name.begins_with("custom_icons/")) {
|
||||
String dname = name.get_slice("/",1);
|
||||
String dname = name.get_slicec('/',1);
|
||||
notification(NOTIFICATION_THEME_CHANGED);
|
||||
add_icon_override(dname,p_value);
|
||||
} else if (name.begins_with("custom_styles/")) {
|
||||
String dname = name.get_slice("/",1);
|
||||
String dname = name.get_slicec('/',1);
|
||||
add_style_override(dname,p_value);
|
||||
notification(NOTIFICATION_THEME_CHANGED);
|
||||
} else if (name.begins_with("custom_fonts/")) {
|
||||
String dname = name.get_slice("/",1);
|
||||
String dname = name.get_slicec('/',1);
|
||||
add_font_override(dname,p_value);
|
||||
notification(NOTIFICATION_THEME_CHANGED);
|
||||
} else if (name.begins_with("custom_colors/")) {
|
||||
String dname = name.get_slice("/",1);
|
||||
String dname = name.get_slicec('/',1);
|
||||
add_color_override(dname,p_value);
|
||||
notification(NOTIFICATION_THEME_CHANGED);
|
||||
} else if (name.begins_with("custom_constants/")) {
|
||||
String dname = name.get_slice("/",1);
|
||||
String dname = name.get_slicec('/',1);
|
||||
add_constant_override(dname,p_value);
|
||||
notification(NOTIFICATION_THEME_CHANGED);
|
||||
} else
|
||||
@ -217,22 +217,22 @@ bool Control::_get(const StringName& p_name,Variant &r_ret) const {
|
||||
return false;
|
||||
|
||||
if (sname.begins_with("custom_icons/")) {
|
||||
String name = sname.get_slice("/",1);
|
||||
String name = sname.get_slicec('/',1);
|
||||
|
||||
r_ret= data.icon_override.has(name)?Variant(data.icon_override[name]):Variant();
|
||||
} else if (sname.begins_with("custom_styles/")) {
|
||||
String name = sname.get_slice("/",1);
|
||||
String name = sname.get_slicec('/',1);
|
||||
|
||||
r_ret= data.style_override.has(name)?Variant(data.style_override[name]):Variant();
|
||||
} else if (sname.begins_with("custom_fonts/")) {
|
||||
String name = sname.get_slice("/",1);
|
||||
String name = sname.get_slicec('/',1);
|
||||
|
||||
r_ret= data.font_override.has(name)?Variant(data.font_override[name]):Variant();
|
||||
} else if (sname.begins_with("custom_colors/")) {
|
||||
String name = sname.get_slice("/",1);
|
||||
String name = sname.get_slicec('/',1);
|
||||
r_ret= data.color_override.has(name)?Variant(data.color_override[name]):Variant();
|
||||
} else if (sname.begins_with("custom_constants/")) {
|
||||
String name = sname.get_slice("/",1);
|
||||
String name = sname.get_slicec('/',1);
|
||||
|
||||
r_ret= data.constant_override.has(name)?Variant(data.constant_override[name]):Variant();
|
||||
} else
|
||||
@ -2832,16 +2832,16 @@ void Control::_bind_methods() {
|
||||
ADD_PROPERTYNZ( PropertyInfo(Variant::VECTOR2,"rect/size", PROPERTY_HINT_NONE, "",PROPERTY_USAGE_EDITOR), _SCS("set_size"),_SCS("get_size") );
|
||||
ADD_PROPERTYNZ( PropertyInfo(Variant::VECTOR2,"rect/min_size"), _SCS("set_custom_minimum_size"),_SCS("get_custom_minimum_size") );
|
||||
ADD_PROPERTYNZ( PropertyInfo(Variant::STRING,"hint/tooltip", PROPERTY_HINT_MULTILINE_TEXT), _SCS("set_tooltip"),_SCS("_get_tooltip") );
|
||||
ADD_PROPERTYI( PropertyInfo(Variant::NODE_PATH,"focus_neighbour/left" ), _SCS("set_focus_neighbour"),_SCS("get_focus_neighbour"),MARGIN_LEFT );
|
||||
ADD_PROPERTYI( PropertyInfo(Variant::NODE_PATH,"focus_neighbour/top" ), _SCS("set_focus_neighbour"),_SCS("get_focus_neighbour"),MARGIN_TOP );
|
||||
ADD_PROPERTYI( PropertyInfo(Variant::NODE_PATH,"focus_neighbour/right" ), _SCS("set_focus_neighbour"),_SCS("get_focus_neighbour"),MARGIN_RIGHT );
|
||||
ADD_PROPERTYI( PropertyInfo(Variant::NODE_PATH,"focus_neighbour/bottom" ), _SCS("set_focus_neighbour"),_SCS("get_focus_neighbour"),MARGIN_BOTTOM );
|
||||
ADD_PROPERTYINZ( PropertyInfo(Variant::NODE_PATH,"focus_neighbour/left" ), _SCS("set_focus_neighbour"),_SCS("get_focus_neighbour"),MARGIN_LEFT );
|
||||
ADD_PROPERTYINZ( PropertyInfo(Variant::NODE_PATH,"focus_neighbour/top" ), _SCS("set_focus_neighbour"),_SCS("get_focus_neighbour"),MARGIN_TOP );
|
||||
ADD_PROPERTYINZ( PropertyInfo(Variant::NODE_PATH,"focus_neighbour/right" ), _SCS("set_focus_neighbour"),_SCS("get_focus_neighbour"),MARGIN_RIGHT );
|
||||
ADD_PROPERTYINZ( PropertyInfo(Variant::NODE_PATH,"focus_neighbour/bottom" ), _SCS("set_focus_neighbour"),_SCS("get_focus_neighbour"),MARGIN_BOTTOM );
|
||||
ADD_PROPERTY( PropertyInfo(Variant::BOOL,"focus/ignore_mouse"), _SCS("set_ignore_mouse"),_SCS("is_ignoring_mouse") );
|
||||
ADD_PROPERTY( PropertyInfo(Variant::BOOL,"focus/stop_mouse"), _SCS("set_stop_mouse"),_SCS("is_stopping_mouse") );
|
||||
|
||||
ADD_PROPERTYNZ( PropertyInfo(Variant::INT,"size_flags/horizontal", PROPERTY_HINT_FLAGS, "Expand,Fill"), _SCS("set_h_size_flags"),_SCS("get_h_size_flags") );
|
||||
ADD_PROPERTYNZ( PropertyInfo(Variant::INT,"size_flags/vertical", PROPERTY_HINT_FLAGS, "Expand,Fill"), _SCS("set_v_size_flags"),_SCS("get_v_size_flags") );
|
||||
ADD_PROPERTY( PropertyInfo(Variant::INT,"size_flags/stretch_ratio", PROPERTY_HINT_RANGE, "1,128,0.01"), _SCS("set_stretch_ratio"),_SCS("get_stretch_ratio") );
|
||||
ADD_PROPERTYNO( PropertyInfo(Variant::INT,"size_flags/stretch_ratio", PROPERTY_HINT_RANGE, "1,128,0.01"), _SCS("set_stretch_ratio"),_SCS("get_stretch_ratio") );
|
||||
ADD_PROPERTYNZ( PropertyInfo(Variant::OBJECT,"theme/theme", PROPERTY_HINT_RESOURCE_TYPE, "Theme"), _SCS("set_theme"),_SCS("get_theme") );
|
||||
|
||||
BIND_CONSTANT( ANCHOR_BEGIN );
|
||||
|
@ -613,11 +613,11 @@ void Label::_bind_methods() {
|
||||
BIND_CONSTANT( VALIGN_BOTTOM );
|
||||
BIND_CONSTANT( VALIGN_FILL );
|
||||
|
||||
ADD_PROPERTY( PropertyInfo( Variant::STRING, "text",PROPERTY_HINT_MULTILINE_TEXT,"",PROPERTY_USAGE_DEFAULT_INTL), _SCS("set_text"),_SCS("get_text") );
|
||||
ADD_PROPERTY( PropertyInfo( Variant::INT, "align", PROPERTY_HINT_ENUM,"Left,Center,Right,Fill" ),_SCS("set_align"),_SCS("get_align") );
|
||||
ADD_PROPERTY( PropertyInfo( Variant::INT, "valign", PROPERTY_HINT_ENUM,"Top,Center,Bottom,Fill" ),_SCS("set_valign"),_SCS("get_valign") );
|
||||
ADD_PROPERTY( PropertyInfo( Variant::BOOL, "autowrap"),_SCS("set_autowrap"),_SCS("has_autowrap") );
|
||||
ADD_PROPERTY( PropertyInfo( Variant::BOOL, "uppercase"),_SCS("set_uppercase"),_SCS("is_uppercase") );
|
||||
ADD_PROPERTYNZ( PropertyInfo( Variant::STRING, "text",PROPERTY_HINT_MULTILINE_TEXT,"",PROPERTY_USAGE_DEFAULT_INTL), _SCS("set_text"),_SCS("get_text") );
|
||||
ADD_PROPERTYNZ( PropertyInfo( Variant::INT, "align", PROPERTY_HINT_ENUM,"Left,Center,Right,Fill" ),_SCS("set_align"),_SCS("get_align") );
|
||||
ADD_PROPERTYNZ( PropertyInfo( Variant::INT, "valign", PROPERTY_HINT_ENUM,"Top,Center,Bottom,Fill" ),_SCS("set_valign"),_SCS("get_valign") );
|
||||
ADD_PROPERTYNZ( PropertyInfo( Variant::BOOL, "autowrap"),_SCS("set_autowrap"),_SCS("has_autowrap") );
|
||||
ADD_PROPERTYNZ( PropertyInfo( Variant::BOOL, "uppercase"),_SCS("set_uppercase"),_SCS("is_uppercase") );
|
||||
ADD_PROPERTY( PropertyInfo( Variant::REAL, "percent_visible", PROPERTY_HINT_RANGE,"0,1,0.001"),_SCS("set_percent_visible"),_SCS("get_percent_visible") );
|
||||
|
||||
}
|
||||
|
@ -56,7 +56,14 @@ Size2 Tabs::get_minimum_size() const {
|
||||
else
|
||||
ms.width+=tab_bg->get_minimum_size().width;
|
||||
|
||||
if (tabs[i].right_button.is_valid()) {
|
||||
Ref<Texture> rb=tabs[i].right_button;
|
||||
Size2 bms = rb->get_size()+get_stylebox("button")->get_minimum_size();
|
||||
bms.width+=get_constant("hseparation");
|
||||
|
||||
ms.width+=bms.width;
|
||||
ms.height=MAX(bms.height+tab_bg->get_minimum_size().height,ms.height);
|
||||
}
|
||||
}
|
||||
|
||||
return ms;
|
||||
@ -66,6 +73,39 @@ Size2 Tabs::get_minimum_size() const {
|
||||
|
||||
void Tabs::_input_event(const InputEvent& p_event) {
|
||||
|
||||
if (p_event.type==InputEvent::MOUSE_MOTION) {
|
||||
|
||||
Point2 pos( p_event.mouse_motion.x, p_event.mouse_motion.y );
|
||||
|
||||
int hover=-1;
|
||||
for(int i=0;i<tabs.size();i++) {
|
||||
|
||||
if (tabs[i].rb_rect.has_point(pos)) {
|
||||
hover=i;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (hover!=rb_hover) {
|
||||
rb_hover=hover;
|
||||
update();
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
if (rb_pressing && p_event.type==InputEvent::MOUSE_BUTTON &&
|
||||
!p_event.mouse_button.pressed &&
|
||||
p_event.mouse_button.button_index==BUTTON_LEFT) {
|
||||
|
||||
if (rb_hover!=-1) {
|
||||
//pressed
|
||||
emit_signal("right_button_pressed",rb_hover);
|
||||
}
|
||||
|
||||
rb_pressing=false;
|
||||
update();
|
||||
}
|
||||
|
||||
if (p_event.type==InputEvent::MOUSE_BUTTON &&
|
||||
p_event.mouse_button.pressed &&
|
||||
p_event.mouse_button.button_index==BUTTON_LEFT) {
|
||||
@ -76,6 +116,12 @@ void Tabs::_input_event(const InputEvent& p_event) {
|
||||
int found=-1;
|
||||
for(int i=0;i<tabs.size();i++) {
|
||||
|
||||
if (tabs[i].rb_rect.has_point(pos)) {
|
||||
rb_pressing=true;
|
||||
update();
|
||||
return;
|
||||
}
|
||||
|
||||
int ofs=tabs[i].ofs_cache;
|
||||
int size = tabs[i].ofs_cache;
|
||||
if (pos.x >=tabs[i].ofs_cache && pos.x<tabs[i].ofs_cache+tabs[i].size_cache) {
|
||||
@ -100,7 +146,10 @@ void Tabs::_notification(int p_what) {
|
||||
|
||||
switch(p_what) {
|
||||
|
||||
|
||||
case NOTIFICATION_MOUSE_EXIT: {
|
||||
rb_hover=-1;
|
||||
update();
|
||||
} break;
|
||||
case NOTIFICATION_DRAW: {
|
||||
|
||||
RID ci = get_canvas_item();
|
||||
@ -142,7 +191,7 @@ void Tabs::_notification(int p_what) {
|
||||
|
||||
Ref<Texture> icon;
|
||||
if (tabs[i].icon.is_valid()) {
|
||||
Ref<Texture> icon = tabs[i].icon;
|
||||
icon = tabs[i].icon;
|
||||
if (icon.is_valid()) {
|
||||
lsize+=icon->get_width();
|
||||
if (s!="")
|
||||
@ -151,6 +200,16 @@ void Tabs::_notification(int p_what) {
|
||||
}
|
||||
}
|
||||
|
||||
if (tabs[i].right_button.is_valid()) {
|
||||
Ref<StyleBox> style = get_stylebox("button");
|
||||
Ref<Texture> rb=tabs[i].right_button;
|
||||
|
||||
lsize+=get_constant("hseparation");
|
||||
lsize+=style->get_margin(MARGIN_LEFT);
|
||||
lsize+=rb->get_width();
|
||||
lsize+=style->get_margin(MARGIN_RIGHT);
|
||||
|
||||
}
|
||||
|
||||
Ref<StyleBox> sb;
|
||||
int va;
|
||||
@ -184,7 +243,37 @@ void Tabs::_notification(int p_what) {
|
||||
|
||||
font->draw(ci, Point2i( w, sb->get_margin(MARGIN_TOP)+((sb_rect.size.y-sb_ms.y)-font->get_height())/2+font->get_ascent() ), s, col );
|
||||
|
||||
w+=slen+sb->get_margin(MARGIN_RIGHT);
|
||||
w+=slen;
|
||||
|
||||
if (tabs[i].right_button.is_valid()) {
|
||||
Ref<StyleBox> style = get_stylebox("button");
|
||||
Ref<Texture> rb=tabs[i].right_button;
|
||||
|
||||
w+=get_constant("hseparation");
|
||||
|
||||
Rect2 rb_rect;
|
||||
rb_rect.size=style->get_minimum_size()+rb->get_size();
|
||||
rb_rect.pos.x=w;
|
||||
rb_rect.pos.y=sb->get_margin(MARGIN_TOP)+((sb_rect.size.y-sb_ms.y)-(rb_rect.size.y))/2;
|
||||
|
||||
if (rb_hover==i) {
|
||||
if (rb_pressing)
|
||||
get_stylebox("button_pressed")->draw(ci,rb_rect);
|
||||
else
|
||||
style->draw(ci,rb_rect);
|
||||
}
|
||||
|
||||
w+=style->get_margin(MARGIN_LEFT);
|
||||
|
||||
rb->draw(ci,Point2i( w,rb_rect.pos.y+style->get_margin(MARGIN_TOP) ));
|
||||
w+=rb->get_width();
|
||||
w+=style->get_margin(MARGIN_RIGHT);
|
||||
tabs[i].rb_rect=rb_rect;
|
||||
|
||||
|
||||
}
|
||||
|
||||
w+=sb->get_margin(MARGIN_RIGHT);
|
||||
|
||||
tabs[i].size_cache=w-tabs[i].ofs_cache;
|
||||
|
||||
@ -252,6 +341,23 @@ Ref<Texture> Tabs::get_tab_icon(int p_tab) const{
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
void Tabs::set_tab_right_button(int p_tab,const Ref<Texture>& p_right_button){
|
||||
|
||||
ERR_FAIL_INDEX(p_tab,tabs.size());
|
||||
tabs[p_tab].right_button=p_right_button;
|
||||
update();
|
||||
minimum_size_changed();
|
||||
|
||||
}
|
||||
Ref<Texture> Tabs::get_tab_right_button(int p_tab) const{
|
||||
|
||||
ERR_FAIL_INDEX_V(p_tab,tabs.size(),Ref<Texture>());
|
||||
return tabs[p_tab].right_button;
|
||||
|
||||
}
|
||||
|
||||
void Tabs::add_tab(const String& p_str,const Ref<Texture>& p_icon) {
|
||||
|
||||
Tab t;
|
||||
@ -316,6 +422,7 @@ void Tabs::_bind_methods() {
|
||||
ObjectTypeDB::bind_method(_MD("get_tab_align"),&Tabs::get_tab_align);
|
||||
|
||||
ADD_SIGNAL(MethodInfo("tab_changed",PropertyInfo(Variant::INT,"tab")));
|
||||
ADD_SIGNAL(MethodInfo("right_button_pressed",PropertyInfo(Variant::INT,"tab")));
|
||||
|
||||
ADD_PROPERTY( PropertyInfo(Variant::INT, "current_tab", PROPERTY_HINT_RANGE,"-1,4096,1",PROPERTY_USAGE_EDITOR), _SCS("set_current_tab"), _SCS("get_current_tab") );
|
||||
|
||||
@ -328,5 +435,7 @@ Tabs::Tabs() {
|
||||
|
||||
current=0;
|
||||
tab_align=ALIGN_CENTER;
|
||||
rb_hover=-1;
|
||||
rb_pressing=false;
|
||||
|
||||
}
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user