diff options
Diffstat (limited to 'core/os')
33 files changed, 498 insertions, 3554 deletions
diff --git a/core/os/SCsub b/core/os/SCsub index 1c5f954470..19a6549225 100644 --- a/core/os/SCsub +++ b/core/os/SCsub @@ -1,5 +1,5 @@ #!/usr/bin/env python -Import('env') +Import("env") env.add_source_files(env.core_sources, "*.cpp") diff --git a/core/os/copymem.h b/core/os/copymem.h index 1d6631ddb8..04ea3caeff 100644 --- a/core/os/copymem.h +++ b/core/os/copymem.h @@ -47,4 +47,4 @@ #endif -#endif +#endif // COPYMEM_H diff --git a/core/os/dir_access.cpp b/core/os/dir_access.cpp index 0477db82be..5e1cb8ea29 100644 --- a/core/os/dir_access.cpp +++ b/core/os/dir_access.cpp @@ -36,51 +36,56 @@ #include "core/project_settings.h" String DirAccess::_get_root_path() const { - switch (_access_type) { - - case ACCESS_RESOURCES: return ProjectSettings::get_singleton()->get_resource_path(); - case ACCESS_USERDATA: return OS::get_singleton()->get_user_data_dir(); - default: return ""; + case ACCESS_RESOURCES: + return ProjectSettings::get_singleton()->get_resource_path(); + case ACCESS_USERDATA: + return OS::get_singleton()->get_user_data_dir(); + default: + return ""; } } -String DirAccess::_get_root_string() const { +String DirAccess::_get_root_string() const { switch (_access_type) { - - case ACCESS_RESOURCES: return "res://"; - case ACCESS_USERDATA: return "user://"; - default: return ""; + case ACCESS_RESOURCES: + return "res://"; + case ACCESS_USERDATA: + return "user://"; + default: + return ""; } } int DirAccess::get_current_drive() { - String path = get_current_dir().to_lower(); for (int i = 0; i < get_drive_count(); i++) { String d = get_drive(i).to_lower(); - if (path.begins_with(d)) + if (path.begins_with(d)) { return i; + } } return 0; } -static Error _erase_recursive(DirAccess *da) { +bool DirAccess::drives_are_shortcuts() { + return false; +} +static Error _erase_recursive(DirAccess *da) { List<String> dirs; List<String> files; da->list_dir_begin(); String n = da->get_next(); while (n != String()) { - if (n != "." && n != "..") { - - if (da->current_is_dir()) + if (da->current_is_dir()) { dirs.push_back(n); - else + } else { files.push_back(n); + } } n = da->get_next(); @@ -89,10 +94,8 @@ static Error _erase_recursive(DirAccess *da) { da->list_dir_end(); for (List<String>::Element *E = dirs.front(); E; E = E->next()) { - Error err = da->change_dir(E->get()); if (err == OK) { - err = _erase_recursive(da); if (err) { da->change_dir(".."); @@ -112,7 +115,6 @@ static Error _erase_recursive(DirAccess *da) { } for (List<String>::Element *E = files.front(); E; E = E->next()) { - Error err = da->remove(da->get_current_dir().plus_file(E->get())); if (err) { return err; @@ -123,15 +125,13 @@ static Error _erase_recursive(DirAccess *da) { } Error DirAccess::erase_contents_recursive() { - return _erase_recursive(this); } Error DirAccess::make_dir_recursive(String p_dir) { - if (p_dir.length() < 1) { return OK; - }; + } String full_dir; @@ -149,13 +149,13 @@ Error DirAccess::make_dir_recursive(String p_dir) { String base; - if (full_dir.begins_with("res://")) + if (full_dir.begins_with("res://")) { base = "res://"; - else if (full_dir.begins_with("user://")) + } else if (full_dir.begins_with("user://")) { base = "user://"; - else if (full_dir.begins_with("/")) + } else if (full_dir.begins_with("/")) { base = "/"; - else if (full_dir.find(":/") != -1) { + } else if (full_dir.find(":/") != -1) { base = full_dir.substr(0, full_dir.find(":/") + 2); } else { ERR_FAIL_V(ERR_INVALID_PARAMETER); @@ -167,11 +167,9 @@ Error DirAccess::make_dir_recursive(String p_dir) { String curpath = base; for (int i = 0; i < subdirs.size(); i++) { - curpath = curpath.plus_file(subdirs[i]); Error err = make_dir(curpath); if (err != OK && err != ERR_ALREADY_EXISTS) { - ERR_FAIL_V(err); } } @@ -180,60 +178,48 @@ Error DirAccess::make_dir_recursive(String p_dir) { } String DirAccess::fix_path(String p_path) const { - switch (_access_type) { - case ACCESS_RESOURCES: { - if (ProjectSettings::get_singleton()) { if (p_path.begins_with("res://")) { - String resource_path = ProjectSettings::get_singleton()->get_resource_path(); if (resource_path != "") { - return p_path.replace_first("res:/", resource_path); - }; + } return p_path.replace_first("res://", ""); } } } break; case ACCESS_USERDATA: { - if (p_path.begins_with("user://")) { - String data_dir = OS::get_singleton()->get_user_data_dir(); if (data_dir != "") { - return p_path.replace_first("user:/", data_dir); - }; + } return p_path.replace_first("user://", ""); } } break; case ACCESS_FILESYSTEM: { - return p_path; } break; - case ACCESS_MAX: break; // Can't happen, but silences warning + case ACCESS_MAX: + break; // Can't happen, but silences warning } return p_path; } -DirAccess::CreateFunc DirAccess::create_func[ACCESS_MAX] = { 0, 0, 0 }; +DirAccess::CreateFunc DirAccess::create_func[ACCESS_MAX] = { nullptr, nullptr, nullptr }; DirAccess *DirAccess::create_for_path(const String &p_path) { - - DirAccess *da = NULL; + DirAccess *da = nullptr; if (p_path.begins_with("res://")) { - da = create(ACCESS_RESOURCES); } else if (p_path.begins_with("user://")) { - da = create(ACCESS_USERDATA); } else { - da = create(ACCESS_FILESYSTEM); } @@ -241,36 +227,35 @@ DirAccess *DirAccess::create_for_path(const String &p_path) { } DirAccess *DirAccess::open(const String &p_path, Error *r_error) { - DirAccess *da = create_for_path(p_path); - ERR_FAIL_COND_V_MSG(!da, NULL, "Cannot create DirAccess for path '" + p_path + "'."); + ERR_FAIL_COND_V_MSG(!da, nullptr, "Cannot create DirAccess for path '" + p_path + "'."); Error err = da->change_dir(p_path); - if (r_error) + if (r_error) { *r_error = err; + } if (err != OK) { memdelete(da); - return NULL; + return nullptr; } return da; } DirAccess *DirAccess::create(AccessType p_access) { - - DirAccess *da = create_func[p_access] ? create_func[p_access]() : NULL; + DirAccess *da = create_func[p_access] ? create_func[p_access]() : nullptr; if (da) { da->_access_type = p_access; } return da; -}; +} String DirAccess::get_full_path(const String &p_path, AccessType p_access) { - DirAccess *d = DirAccess::create(p_access); - if (!d) + if (!d) { return p_path; + } d->change_dir(p_path); String full = d->get_current_dir(); @@ -279,22 +264,20 @@ String DirAccess::get_full_path(const String &p_path, AccessType p_access) { } Error DirAccess::copy(String p_from, String p_to, int p_chmod_flags) { - //printf("copy %s -> %s\n",p_from.ascii().get_data(),p_to.ascii().get_data()); Error err; FileAccess *fsrc = FileAccess::open(p_from, FileAccess::READ, &err); if (err) { - ERR_PRINTS("Failed to open " + p_from); + ERR_PRINT("Failed to open " + p_from); return err; } FileAccess *fdst = FileAccess::open(p_to, FileAccess::WRITE, &err); if (err) { - fsrc->close(); memdelete(fsrc); - ERR_PRINTS("Failed to open " + p_to); + ERR_PRINT("Failed to open " + p_to); return err; } @@ -303,7 +286,6 @@ Error DirAccess::copy(String p_from, String p_to, int p_chmod_flags) { fsrc->seek(0); err = OK; while (size--) { - if (fsrc->get_error() != OK) { err = fsrc->get_error(); break; @@ -320,8 +302,9 @@ Error DirAccess::copy(String p_from, String p_to, int p_chmod_flags) { fdst->close(); err = FileAccess::set_unix_permissions(p_to, p_chmod_flags); // If running on a platform with no chmod support (i.e., Windows), don't fail - if (err == ERR_UNAVAILABLE) + if (err == ERR_UNAVAILABLE) { err = OK; + } } memdelete(fsrc); @@ -355,12 +338,10 @@ Error DirAccess::_copy_dir(DirAccess *p_target_da, String p_to, int p_chmod_flag list_dir_begin(); String n = get_next(); while (n != String()) { - if (n != "." && n != "..") { - - if (current_is_dir()) + if (current_is_dir()) { dirs.push_back(n); - else { + } else { const String &rel_path = n; if (!n.is_rel_path()) { list_dir_end(); @@ -428,17 +409,8 @@ Error DirAccess::copy_dir(String p_from, String p_to, int p_chmod_flags) { } bool DirAccess::exists(String p_dir) { - DirAccess *da = DirAccess::create_for_path(p_dir); bool valid = da->change_dir(p_dir) == OK; memdelete(da); return valid; } - -DirAccess::DirAccess() { - - _access_type = ACCESS_FILESYSTEM; -} - -DirAccess::~DirAccess() { -} diff --git a/core/os/dir_access.h b/core/os/dir_access.h index 55a6d53f72..6bce9a4c12 100644 --- a/core/os/dir_access.h +++ b/core/os/dir_access.h @@ -47,7 +47,7 @@ public: typedef DirAccess *(*CreateFunc)(); private: - AccessType _access_type; + AccessType _access_type = ACCESS_FILESYSTEM; static CreateFunc create_func[ACCESS_MAX]; ///< set this to instance a filesystem object Error _copy_dir(DirAccess *p_target_da, String p_to, int p_chmod_flags); @@ -61,7 +61,6 @@ protected: template <class T> static DirAccess *_create_builtin() { - return memnew(T); } @@ -76,9 +75,10 @@ public: virtual int get_drive_count() = 0; virtual String get_drive(int p_drive) = 0; virtual int get_current_drive(); + virtual bool drives_are_shortcuts(); virtual Error change_dir(String p_dir) = 0; ///< can be relative or absolute, return false on success - virtual String get_current_dir() = 0; ///< return current dir location + virtual String get_current_dir(bool p_include_drive = true) = 0; ///< return current dir location virtual Error make_dir(String p_dir) = 0; virtual Error make_dir_recursive(String p_dir); virtual Error erase_contents_recursive(); //super dangerous, use with care! @@ -109,43 +109,34 @@ public: static String get_full_path(const String &p_path, AccessType p_access); static DirAccess *create_for_path(const String &p_path); - /* - enum DirType { - - FILE_TYPE_INVALID, - FILE_TYPE_FILE, - FILE_TYPE_DIR, - }; - - //virtual DirType get_file_type() const=0; -*/ static DirAccess *create(AccessType p_access); template <class T> static void make_default(AccessType p_access) { - create_func[p_access] = _create_builtin<T>; } - static DirAccess *open(const String &p_path, Error *r_error = NULL); + static DirAccess *open(const String &p_path, Error *r_error = nullptr); - DirAccess(); - virtual ~DirAccess(); + DirAccess() {} + virtual ~DirAccess() {} }; struct DirAccessRef { - _FORCE_INLINE_ DirAccess *operator->() { - return f; } - operator bool() const { return f != NULL; } + operator bool() const { return f != nullptr; } + DirAccess *f; + DirAccessRef(DirAccess *fa) { f = fa; } ~DirAccessRef() { - if (f) memdelete(f); + if (f) { + memdelete(f); + } } }; -#endif +#endif // DIR_ACCESS_H diff --git a/core/os/file_access.cpp b/core/os/file_access.cpp index 2917351a2f..9dbb2952f7 100644 --- a/core/os/file_access.cpp +++ b/core/os/file_access.cpp @@ -36,15 +36,14 @@ #include "core/os/os.h" #include "core/project_settings.h" -FileAccess::CreateFunc FileAccess::create_func[ACCESS_MAX] = { 0, 0 }; +FileAccess::CreateFunc FileAccess::create_func[ACCESS_MAX] = { nullptr, nullptr }; -FileAccess::FileCloseFailNotify FileAccess::close_fail_notify = NULL; +FileAccess::FileCloseFailNotify FileAccess::close_fail_notify = nullptr; bool FileAccess::backup_save = false; FileAccess *FileAccess::create(AccessType p_access) { - - ERR_FAIL_INDEX_V(p_access, ACCESS_MAX, 0); + ERR_FAIL_INDEX_V(p_access, ACCESS_MAX, nullptr); FileAccess *ret = create_func[p_access](); ret->_set_access_type(p_access); @@ -52,34 +51,30 @@ FileAccess *FileAccess::create(AccessType p_access) { } bool FileAccess::exists(const String &p_name) { - - if (PackedData::get_singleton() && PackedData::get_singleton()->has_path(p_name)) + if (PackedData::get_singleton() && PackedData::get_singleton()->has_path(p_name)) { return true; + } FileAccess *f = open(p_name, READ); - if (!f) + if (!f) { return false; + } memdelete(f); return true; } void FileAccess::_set_access_type(AccessType p_access) { - _access_type = p_access; -}; +} FileAccess *FileAccess::create_for_path(const String &p_path) { - - FileAccess *ret = NULL; + FileAccess *ret = nullptr; if (p_path.begins_with("res://")) { - ret = create(ACCESS_RESOURCES); } else if (p_path.begins_with("user://")) { - ret = create(ACCESS_USERDATA); } else { - ret = create(ACCESS_FILESYSTEM); } @@ -87,20 +82,19 @@ FileAccess *FileAccess::create_for_path(const String &p_path) { } Error FileAccess::reopen(const String &p_path, int p_mode_flags) { - return _open(p_path, p_mode_flags); -}; +} FileAccess *FileAccess::open(const String &p_path, int p_mode_flags, Error *r_error) { - //try packed data first - FileAccess *ret = NULL; + FileAccess *ret = nullptr; if (!(p_mode_flags & WRITE) && PackedData::get_singleton() && !PackedData::get_singleton()->is_disabled()) { ret = PackedData::get_singleton()->try_open_path(p_path); if (ret) { - if (r_error) + if (r_error) { *r_error = OK; + } return ret; } } @@ -108,21 +102,20 @@ FileAccess *FileAccess::open(const String &p_path, int p_mode_flags, Error *r_er ret = create_for_path(p_path); Error err = ret->_open(p_path, p_mode_flags); - if (r_error) + if (r_error) { *r_error = err; + } if (err != OK) { - memdelete(ret); - ret = NULL; + ret = nullptr; } return ret; } FileAccess::CreateFunc FileAccess::get_create_func(AccessType p_access) { - return create_func[p_access]; -}; +} String FileAccess::fix_path(const String &p_path) const { //helper used by file accesses that use a single filesystem @@ -130,40 +123,33 @@ String FileAccess::fix_path(const String &p_path) const { String r_path = p_path.replace("\\", "/"); switch (_access_type) { - case ACCESS_RESOURCES: { - if (ProjectSettings::get_singleton()) { if (r_path.begins_with("res://")) { - String resource_path = ProjectSettings::get_singleton()->get_resource_path(); if (resource_path != "") { - return r_path.replace("res:/", resource_path); - }; + } return r_path.replace("res://", ""); } } } break; case ACCESS_USERDATA: { - if (r_path.begins_with("user://")) { - String data_dir = OS::get_singleton()->get_user_data_dir(); if (data_dir != "") { - return r_path.replace("user:/", data_dir); - }; + } return r_path.replace("user://", ""); } } break; case ACCESS_FILESYSTEM: { - return r_path; } break; - case ACCESS_MAX: break; // Can't happen, but silences warning + case ACCESS_MAX: + break; // Can't happen, but silences warning } return r_path; @@ -172,7 +158,6 @@ String FileAccess::fix_path(const String &p_path) const { /* these are all implemented for ease of porting, then can later be optimized */ uint16_t FileAccess::get_16() const { - uint16_t res; uint8_t a, b; @@ -180,7 +165,6 @@ uint16_t FileAccess::get_16() const { b = get_8(); if (endian_swap) { - SWAP(a, b); } @@ -190,8 +174,8 @@ uint16_t FileAccess::get_16() const { return res; } -uint32_t FileAccess::get_32() const { +uint32_t FileAccess::get_32() const { uint32_t res; uint16_t a, b; @@ -199,7 +183,6 @@ uint32_t FileAccess::get_32() const { b = get_16(); if (endian_swap) { - SWAP(a, b); } @@ -209,8 +192,8 @@ uint32_t FileAccess::get_32() const { return res; } -uint64_t FileAccess::get_64() const { +uint64_t FileAccess::get_64() const { uint64_t res; uint32_t a, b; @@ -218,7 +201,6 @@ uint64_t FileAccess::get_64() const { b = get_32(); if (endian_swap) { - SWAP(a, b); } @@ -230,38 +212,35 @@ uint64_t FileAccess::get_64() const { } float FileAccess::get_float() const { - MarshallFloat m; m.i = get_32(); return m.f; -}; +} real_t FileAccess::get_real() const { - - if (real_is_double) + if (real_is_double) { return get_double(); - else + } else { return get_float(); + } } double FileAccess::get_double() const { - MarshallDouble m; m.l = get_64(); return m.d; -}; +} String FileAccess::get_token() const { - CharString token; - CharType c = get_8(); + char32_t c = get_8(); while (!eof_reached()) { - if (c <= ' ') { - if (token.length()) + if (token.length()) { break; + } } else { token += c; } @@ -277,19 +256,16 @@ class CharBuffer { char *buffer; int capacity; - int written; + int written = 0; bool grow() { - if (vector.resize(next_power_of_2(1 + written)) != OK) { - return false; } if (buffer == stack_buffer) { // first chunk? for (int i = 0; i < written; i++) { - vector.write[i] = stack_buffer[i]; } } @@ -304,14 +280,11 @@ class CharBuffer { public: _FORCE_INLINE_ CharBuffer() : buffer(stack_buffer), - capacity(sizeof(stack_buffer) / sizeof(char)), - written(0) { + capacity(sizeof(stack_buffer) / sizeof(char)) { } _FORCE_INLINE_ void push_back(char c) { - if (written >= capacity) { - ERR_FAIL_COND(!grow()); } @@ -319,24 +292,22 @@ public: } _FORCE_INLINE_ const char *get_data() const { - return buffer; } }; String FileAccess::get_line() const { - CharBuffer line; - CharType c = get_8(); + char32_t c = get_8(); while (!eof_reached()) { - if (c == '\n' || c == '\0') { line.push_back(0); return String::utf8(line.get_data()); - } else if (c != '\r') + } else if (c != '\r') { line.push_back(c); + } c = get_8(); } @@ -345,21 +316,21 @@ String FileAccess::get_line() const { } Vector<String> FileAccess::get_csv_line(const String &p_delim) const { - ERR_FAIL_COND_V(p_delim.length() != 1, Vector<String>()); String l; int qc = 0; do { - if (eof_reached()) + if (eof_reached()) { break; + } l += get_line() + "\n"; qc = 0; for (int i = 0; i < l.length(); i++) { - - if (l[i] == '"') + if (l[i] == '"') { qc++; + } } } while (qc % 2); @@ -371,9 +342,8 @@ Vector<String> FileAccess::get_csv_line(const String &p_delim) const { bool in_quote = false; String current; for (int i = 0; i < l.length(); i++) { - - CharType c = l[i]; - CharType s[2] = { 0, 0 }; + char32_t c = l[i]; + char32_t s[2] = { 0, 0 }; if (!in_quote && c == p_delim[0]) { strings.push_back(current); @@ -384,7 +354,6 @@ Vector<String> FileAccess::get_csv_line(const String &p_delim) const { current += s; i++; } else { - in_quote = !in_quote; } } else { @@ -399,70 +368,66 @@ Vector<String> FileAccess::get_csv_line(const String &p_delim) const { } int FileAccess::get_buffer(uint8_t *p_dst, int p_length) const { - int i = 0; - for (i = 0; i < p_length && !eof_reached(); i++) + for (i = 0; i < p_length && !eof_reached(); i++) { p_dst[i] = get_8(); + } return i; } String FileAccess::get_as_utf8_string() const { - PoolVector<uint8_t> sourcef; + Vector<uint8_t> sourcef; int len = get_len(); sourcef.resize(len + 1); - PoolVector<uint8_t>::Write w = sourcef.write(); - int r = get_buffer(w.ptr(), len); + uint8_t *w = sourcef.ptrw(); + int r = get_buffer(w, len); ERR_FAIL_COND_V(r != len, String()); w[len] = 0; String s; - if (s.parse_utf8((const char *)w.ptr())) { + if (s.parse_utf8((const char *)w)) { return String(); } return s; } void FileAccess::store_16(uint16_t p_dest) { - uint8_t a, b; a = p_dest & 0xFF; b = p_dest >> 8; if (endian_swap) { - SWAP(a, b); } store_8(a); store_8(b); } -void FileAccess::store_32(uint32_t p_dest) { +void FileAccess::store_32(uint32_t p_dest) { uint16_t a, b; a = p_dest & 0xFFFF; b = p_dest >> 16; if (endian_swap) { - SWAP(a, b); } store_16(a); store_16(b); } -void FileAccess::store_64(uint64_t p_dest) { +void FileAccess::store_64(uint64_t p_dest) { uint32_t a, b; a = p_dest & 0xFFFFFFFF; b = p_dest >> 32; if (endian_swap) { - SWAP(a, b); } @@ -471,31 +436,29 @@ void FileAccess::store_64(uint64_t p_dest) { } void FileAccess::store_real(real_t p_real) { - - if (sizeof(real_t) == 4) + if (sizeof(real_t) == 4) { store_float(p_real); - else + } else { store_double(p_real); + } } void FileAccess::store_float(float p_dest) { - MarshallFloat m; m.f = p_dest; store_32(m.i); -}; +} void FileAccess::store_double(double p_dest) { - MarshallDouble m; m.d = p_dest; store_64(m.l); -}; +} uint64_t FileAccess::get_modified_time(const String &p_file) { - - if (PackedData::get_singleton() && !PackedData::get_singleton()->is_disabled() && PackedData::get_singleton()->has_path(p_file)) + if (PackedData::get_singleton() && !PackedData::get_singleton()->is_disabled() && PackedData::get_singleton()->has_path(p_file)) { return 0; + } FileAccess *fa = create_for_path(p_file); ERR_FAIL_COND_V_MSG(!fa, 0, "Cannot create FileAccess for path '" + p_file + "'."); @@ -506,9 +469,9 @@ uint64_t FileAccess::get_modified_time(const String &p_file) { } uint32_t FileAccess::get_unix_permissions(const String &p_file) { - - if (PackedData::get_singleton() && !PackedData::get_singleton()->is_disabled() && PackedData::get_singleton()->has_path(p_file)) + if (PackedData::get_singleton() && !PackedData::get_singleton()->is_disabled() && PackedData::get_singleton()->has_path(p_file)) { return 0; + } FileAccess *fa = create_for_path(p_file); ERR_FAIL_COND_V_MSG(!fa, 0, "Cannot create FileAccess for path '" + p_file + "'."); @@ -519,7 +482,6 @@ uint32_t FileAccess::get_unix_permissions(const String &p_file) { } Error FileAccess::set_unix_permissions(const String &p_file, uint32_t p_permissions) { - FileAccess *fa = create_for_path(p_file); ERR_FAIL_COND_V_MSG(!fa, ERR_CANT_CREATE, "Cannot create FileAccess for path '" + p_file + "'."); @@ -529,23 +491,21 @@ Error FileAccess::set_unix_permissions(const String &p_file, uint32_t p_permissi } void FileAccess::store_string(const String &p_string) { - - if (p_string.length() == 0) + if (p_string.length() == 0) { return; + } CharString cs = p_string.utf8(); store_buffer((uint8_t *)&cs[0], cs.length()); } void FileAccess::store_pascal_string(const String &p_string) { - CharString cs = p_string.utf8(); store_32(cs.length()); store_buffer((uint8_t *)&cs[0], cs.length()); -}; +} String FileAccess::get_pascal_string() { - uint32_t sl = get_32(); CharString cs; cs.resize(sl + 1); @@ -556,16 +516,14 @@ String FileAccess::get_pascal_string() { ret.parse_utf8(cs.ptr()); return ret; -}; +} void FileAccess::store_line(const String &p_line) { - store_string(p_line); store_8('\n'); } void FileAccess::store_csv_line(const Vector<String> &p_values, const String &p_delim) { - ERR_FAIL_COND(p_delim.length() != 1); String line = ""; @@ -587,13 +545,12 @@ void FileAccess::store_csv_line(const Vector<String> &p_values, const String &p_ } void FileAccess::store_buffer(const uint8_t *p_src, int p_length) { - - for (int i = 0; i < p_length; i++) + for (int i = 0; i < p_length; i++) { store_8(p_src[i]); + } } Vector<uint8_t> FileAccess::get_file_as_array(const String &p_path, Error *r_error) { - FileAccess *f = FileAccess::open(p_path, READ, r_error); if (!f) { if (r_error) { // if error requested, do not throw error @@ -609,7 +566,6 @@ Vector<uint8_t> FileAccess::get_file_as_array(const String &p_path, Error *r_err } String FileAccess::get_file_as_string(const String &p_path, Error *r_error) { - Error err; Vector<uint8_t> array = get_file_as_array(p_path, &err); if (r_error) { @@ -628,10 +584,10 @@ String FileAccess::get_file_as_string(const String &p_path, Error *r_error) { } String FileAccess::get_md5(const String &p_file) { - FileAccess *f = FileAccess::open(p_file, READ); - if (!f) + if (!f) { return String(); + } CryptoCore::MD5Context ctx; ctx.start(); @@ -639,14 +595,13 @@ String FileAccess::get_md5(const String &p_file) { unsigned char step[32768]; while (true) { - int br = f->get_buffer(step, 32768); if (br > 0) { - ctx.update(step, br); } - if (br < 4096) + if (br < 4096) { break; + } } unsigned char hash[16]; @@ -658,7 +613,6 @@ String FileAccess::get_md5(const String &p_file) { } String FileAccess::get_multiple_md5(const Vector<String> &p_file) { - CryptoCore::MD5Context ctx; ctx.start(); @@ -669,14 +623,13 @@ String FileAccess::get_multiple_md5(const Vector<String> &p_file) { unsigned char step[32768]; while (true) { - int br = f->get_buffer(step, 32768); if (br > 0) { - ctx.update(step, br); } - if (br < 4096) + if (br < 4096) { break; + } } memdelete(f); } @@ -688,10 +641,10 @@ String FileAccess::get_multiple_md5(const Vector<String> &p_file) { } String FileAccess::get_sha256(const String &p_file) { - FileAccess *f = FileAccess::open(p_file, READ); - if (!f) + if (!f) { return String(); + } CryptoCore::SHA256Context ctx; ctx.start(); @@ -699,14 +652,13 @@ String FileAccess::get_sha256(const String &p_file) { unsigned char step[32768]; while (true) { - int br = f->get_buffer(step, 32768); if (br > 0) { - ctx.update(step, br); } - if (br < 4096) + if (br < 4096) { break; + } } unsigned char hash[32]; @@ -715,10 +667,3 @@ String FileAccess::get_sha256(const String &p_file) { memdelete(f); return String::hex_encode_buffer(hash, 32); } - -FileAccess::FileAccess() { - - endian_swap = false; - real_is_double = false; - _access_type = ACCESS_FILESYSTEM; -}; diff --git a/core/os/file_access.h b/core/os/file_access.h index 36a947c691..48b9ee4269 100644 --- a/core/os/file_access.h +++ b/core/os/file_access.h @@ -41,7 +41,6 @@ */ class FileAccess { - public: enum AccessType { ACCESS_RESOURCES, @@ -53,8 +52,8 @@ public: typedef void (*FileCloseFailNotify)(const String &); typedef FileAccess *(*CreateFunc)(); - bool endian_swap; - bool real_is_double; + bool endian_swap = false; + bool real_is_double = false; virtual uint32_t _get_unix_permissions(const String &p_file) = 0; virtual Error _set_unix_permissions(const String &p_file, uint32_t p_permissions) = 0; @@ -69,11 +68,10 @@ protected: private: static bool backup_save; - AccessType _access_type; + AccessType _access_type = ACCESS_FILESYSTEM; static CreateFunc create_func[ACCESS_MAX]; /** default file access creation function for a platform */ template <class T> static FileAccess *_create_builtin() { - return memnew(T); } @@ -153,7 +151,7 @@ public: static FileAccess *create(AccessType p_access); /// Create a file access (for the current platform) this is the only portable way of accessing files. static FileAccess *create_for_path(const String &p_path); - static FileAccess *open(const String &p_path, int p_mode_flags, Error *r_error = NULL); /// Create a file access (for the current platform) this is the only portable way of accessing files. + static FileAccess *open(const String &p_path, int p_mode_flags, Error *r_error = nullptr); /// Create a file access (for the current platform) this is the only portable way of accessing files. static CreateFunc get_create_func(AccessType p_access); static bool exists(const String &p_name); ///< return true if a file exists static uint64_t get_modified_time(const String &p_file); @@ -167,33 +165,35 @@ public: static String get_sha256(const String &p_file); static String get_multiple_md5(const Vector<String> &p_file); - static Vector<uint8_t> get_file_as_array(const String &p_path, Error *r_error = NULL); - static String get_file_as_string(const String &p_path, Error *r_error = NULL); + static Vector<uint8_t> get_file_as_array(const String &p_path, Error *r_error = nullptr); + static String get_file_as_string(const String &p_path, Error *r_error = nullptr); template <class T> static void make_default(AccessType p_access) { - create_func[p_access] = _create_builtin<T>; } - FileAccess(); + FileAccess() {} virtual ~FileAccess() {} }; struct FileAccessRef { - _FORCE_INLINE_ FileAccess *operator->() { - return f; } - operator bool() const { return f != NULL; } + operator bool() const { return f != nullptr; } + FileAccess *f; + operator FileAccess *() { return f; } + FileAccessRef(FileAccess *fa) { f = fa; } ~FileAccessRef() { - if (f) memdelete(f); + if (f) { + memdelete(f); + } } }; -#endif +#endif // FILE_ACCESS_H diff --git a/core/os/input.cpp b/core/os/input.cpp deleted file mode 100644 index 6f0392fec9..0000000000 --- a/core/os/input.cpp +++ /dev/null @@ -1,157 +0,0 @@ -/*************************************************************************/ -/* input.cpp */ -/*************************************************************************/ -/* This file is part of: */ -/* GODOT ENGINE */ -/* https://godotengine.org */ -/*************************************************************************/ -/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */ -/* */ -/* Permission is hereby granted, free of charge, to any person obtaining */ -/* a copy of this software and associated documentation files (the */ -/* "Software"), to deal in the Software without restriction, including */ -/* without limitation the rights to use, copy, modify, merge, publish, */ -/* distribute, sublicense, and/or sell copies of the Software, and to */ -/* permit persons to whom the Software is furnished to do so, subject to */ -/* the following conditions: */ -/* */ -/* The above copyright notice and this permission notice shall be */ -/* included in all copies or substantial portions of the Software. */ -/* */ -/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */ -/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */ -/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/ -/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */ -/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */ -/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */ -/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ -/*************************************************************************/ - -#include "input.h" - -#include "core/input_map.h" -#include "core/os/os.h" -#include "core/project_settings.h" - -#ifdef TOOLS_ENABLED -#include "editor/editor_settings.h" -#endif - -Input *Input::singleton = NULL; - -Input *Input::get_singleton() { - - return singleton; -} - -void Input::set_mouse_mode(MouseMode p_mode) { - ERR_FAIL_INDEX((int)p_mode, 4); - OS::get_singleton()->set_mouse_mode((OS::MouseMode)p_mode); -} - -Input::MouseMode Input::get_mouse_mode() const { - - return (MouseMode)OS::get_singleton()->get_mouse_mode(); -} - -void Input::_bind_methods() { - - ClassDB::bind_method(D_METHOD("is_key_pressed", "scancode"), &Input::is_key_pressed); - ClassDB::bind_method(D_METHOD("is_mouse_button_pressed", "button"), &Input::is_mouse_button_pressed); - ClassDB::bind_method(D_METHOD("is_joy_button_pressed", "device", "button"), &Input::is_joy_button_pressed); - ClassDB::bind_method(D_METHOD("is_action_pressed", "action"), &Input::is_action_pressed); - ClassDB::bind_method(D_METHOD("is_action_just_pressed", "action"), &Input::is_action_just_pressed); - ClassDB::bind_method(D_METHOD("is_action_just_released", "action"), &Input::is_action_just_released); - ClassDB::bind_method(D_METHOD("get_action_strength", "action"), &Input::get_action_strength); - ClassDB::bind_method(D_METHOD("add_joy_mapping", "mapping", "update_existing"), &Input::add_joy_mapping, DEFVAL(false)); - ClassDB::bind_method(D_METHOD("remove_joy_mapping", "guid"), &Input::remove_joy_mapping); - ClassDB::bind_method(D_METHOD("joy_connection_changed", "device", "connected", "name", "guid"), &Input::joy_connection_changed); - ClassDB::bind_method(D_METHOD("is_joy_known", "device"), &Input::is_joy_known); - ClassDB::bind_method(D_METHOD("get_joy_axis", "device", "axis"), &Input::get_joy_axis); - ClassDB::bind_method(D_METHOD("get_joy_name", "device"), &Input::get_joy_name); - ClassDB::bind_method(D_METHOD("get_joy_guid", "device"), &Input::get_joy_guid); - ClassDB::bind_method(D_METHOD("get_connected_joypads"), &Input::get_connected_joypads); - ClassDB::bind_method(D_METHOD("get_joy_vibration_strength", "device"), &Input::get_joy_vibration_strength); - ClassDB::bind_method(D_METHOD("get_joy_vibration_duration", "device"), &Input::get_joy_vibration_duration); - ClassDB::bind_method(D_METHOD("get_joy_button_string", "button_index"), &Input::get_joy_button_string); - ClassDB::bind_method(D_METHOD("get_joy_button_index_from_string", "button"), &Input::get_joy_button_index_from_string); - ClassDB::bind_method(D_METHOD("get_joy_axis_string", "axis_index"), &Input::get_joy_axis_string); - ClassDB::bind_method(D_METHOD("get_joy_axis_index_from_string", "axis"), &Input::get_joy_axis_index_from_string); - ClassDB::bind_method(D_METHOD("start_joy_vibration", "device", "weak_magnitude", "strong_magnitude", "duration"), &Input::start_joy_vibration, DEFVAL(0)); - ClassDB::bind_method(D_METHOD("stop_joy_vibration", "device"), &Input::stop_joy_vibration); - ClassDB::bind_method(D_METHOD("vibrate_handheld", "duration_ms"), &Input::vibrate_handheld, DEFVAL(500)); - ClassDB::bind_method(D_METHOD("get_gravity"), &Input::get_gravity); - ClassDB::bind_method(D_METHOD("get_accelerometer"), &Input::get_accelerometer); - ClassDB::bind_method(D_METHOD("get_magnetometer"), &Input::get_magnetometer); - ClassDB::bind_method(D_METHOD("get_gyroscope"), &Input::get_gyroscope); - //ClassDB::bind_method(D_METHOD("get_mouse_position"),&Input::get_mouse_position); - this is not the function you want - ClassDB::bind_method(D_METHOD("get_last_mouse_speed"), &Input::get_last_mouse_speed); - ClassDB::bind_method(D_METHOD("get_mouse_button_mask"), &Input::get_mouse_button_mask); - ClassDB::bind_method(D_METHOD("set_mouse_mode", "mode"), &Input::set_mouse_mode); - ClassDB::bind_method(D_METHOD("get_mouse_mode"), &Input::get_mouse_mode); - ClassDB::bind_method(D_METHOD("warp_mouse_position", "to"), &Input::warp_mouse_position); - ClassDB::bind_method(D_METHOD("action_press", "action", "strength"), &Input::action_press, DEFVAL(1.f)); - ClassDB::bind_method(D_METHOD("action_release", "action"), &Input::action_release); - ClassDB::bind_method(D_METHOD("set_default_cursor_shape", "shape"), &Input::set_default_cursor_shape, DEFVAL(CURSOR_ARROW)); - ClassDB::bind_method(D_METHOD("get_current_cursor_shape"), &Input::get_current_cursor_shape); - ClassDB::bind_method(D_METHOD("set_custom_mouse_cursor", "image", "shape", "hotspot"), &Input::set_custom_mouse_cursor, DEFVAL(CURSOR_ARROW), DEFVAL(Vector2())); - ClassDB::bind_method(D_METHOD("parse_input_event", "event"), &Input::parse_input_event); - ClassDB::bind_method(D_METHOD("set_use_accumulated_input", "enable"), &Input::set_use_accumulated_input); - - BIND_ENUM_CONSTANT(MOUSE_MODE_VISIBLE); - BIND_ENUM_CONSTANT(MOUSE_MODE_HIDDEN); - BIND_ENUM_CONSTANT(MOUSE_MODE_CAPTURED); - BIND_ENUM_CONSTANT(MOUSE_MODE_CONFINED); - - BIND_ENUM_CONSTANT(CURSOR_ARROW); - BIND_ENUM_CONSTANT(CURSOR_IBEAM); - BIND_ENUM_CONSTANT(CURSOR_POINTING_HAND); - BIND_ENUM_CONSTANT(CURSOR_CROSS); - BIND_ENUM_CONSTANT(CURSOR_WAIT); - BIND_ENUM_CONSTANT(CURSOR_BUSY); - BIND_ENUM_CONSTANT(CURSOR_DRAG); - BIND_ENUM_CONSTANT(CURSOR_CAN_DROP); - BIND_ENUM_CONSTANT(CURSOR_FORBIDDEN); - BIND_ENUM_CONSTANT(CURSOR_VSIZE); - BIND_ENUM_CONSTANT(CURSOR_HSIZE); - BIND_ENUM_CONSTANT(CURSOR_BDIAGSIZE); - BIND_ENUM_CONSTANT(CURSOR_FDIAGSIZE); - BIND_ENUM_CONSTANT(CURSOR_MOVE); - BIND_ENUM_CONSTANT(CURSOR_VSPLIT); - BIND_ENUM_CONSTANT(CURSOR_HSPLIT); - BIND_ENUM_CONSTANT(CURSOR_HELP); - - ADD_SIGNAL(MethodInfo("joy_connection_changed", PropertyInfo(Variant::INT, "device"), PropertyInfo(Variant::BOOL, "connected"))); -} - -void Input::get_argument_options(const StringName &p_function, int p_idx, List<String> *r_options) const { -#ifdef TOOLS_ENABLED - - const String quote_style = EDITOR_DEF("text_editor/completion/use_single_quotes", 0) ? "'" : "\""; - - String pf = p_function; - if (p_idx == 0 && (pf == "is_action_pressed" || pf == "action_press" || pf == "action_release" || pf == "is_action_just_pressed" || pf == "is_action_just_released" || pf == "get_action_strength")) { - - List<PropertyInfo> pinfo; - ProjectSettings::get_singleton()->get_property_list(&pinfo); - - for (List<PropertyInfo>::Element *E = pinfo.front(); E; E = E->next()) { - const PropertyInfo &pi = E->get(); - - if (!pi.name.begins_with("input/")) - continue; - - String name = pi.name.substr(pi.name.find("/") + 1, pi.name.length()); - r_options->push_back(quote_style + name + quote_style); - } - } -#endif -} - -Input::Input() { - - singleton = this; -} - -////////////////////////////////////////////////////////// diff --git a/core/os/input.h b/core/os/input.h deleted file mode 100644 index 8df3b1c5a9..0000000000 --- a/core/os/input.h +++ /dev/null @@ -1,146 +0,0 @@ -/*************************************************************************/ -/* input.h */ -/*************************************************************************/ -/* This file is part of: */ -/* GODOT ENGINE */ -/* https://godotengine.org */ -/*************************************************************************/ -/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */ -/* */ -/* Permission is hereby granted, free of charge, to any person obtaining */ -/* a copy of this software and associated documentation files (the */ -/* "Software"), to deal in the Software without restriction, including */ -/* without limitation the rights to use, copy, modify, merge, publish, */ -/* distribute, sublicense, and/or sell copies of the Software, and to */ -/* permit persons to whom the Software is furnished to do so, subject to */ -/* the following conditions: */ -/* */ -/* The above copyright notice and this permission notice shall be */ -/* included in all copies or substantial portions of the Software. */ -/* */ -/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */ -/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */ -/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/ -/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */ -/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */ -/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */ -/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ -/*************************************************************************/ - -#ifndef INPUT_H -#define INPUT_H - -#include "core/object.h" -#include "core/os/main_loop.h" -#include "core/os/thread_safe.h" - -class Input : public Object { - - GDCLASS(Input, Object); - - static Input *singleton; - -protected: - static void _bind_methods(); - -public: - enum MouseMode { - MOUSE_MODE_VISIBLE, - MOUSE_MODE_HIDDEN, - MOUSE_MODE_CAPTURED, - MOUSE_MODE_CONFINED - }; - -#undef CursorShape - enum CursorShape { - CURSOR_ARROW, - CURSOR_IBEAM, - CURSOR_POINTING_HAND, - CURSOR_CROSS, - CURSOR_WAIT, - CURSOR_BUSY, - CURSOR_DRAG, - CURSOR_CAN_DROP, - CURSOR_FORBIDDEN, - CURSOR_VSIZE, - CURSOR_HSIZE, - CURSOR_BDIAGSIZE, - CURSOR_FDIAGSIZE, - CURSOR_MOVE, - CURSOR_VSPLIT, - CURSOR_HSPLIT, - CURSOR_HELP, - CURSOR_MAX - }; - - void set_mouse_mode(MouseMode p_mode); - MouseMode get_mouse_mode() const; - - static Input *get_singleton(); - - virtual bool is_key_pressed(int p_scancode) const = 0; - virtual bool is_mouse_button_pressed(int p_button) const = 0; - virtual bool is_joy_button_pressed(int p_device, int p_button) const = 0; - virtual bool is_action_pressed(const StringName &p_action) const = 0; - virtual bool is_action_just_pressed(const StringName &p_action) const = 0; - virtual bool is_action_just_released(const StringName &p_action) const = 0; - virtual float get_action_strength(const StringName &p_action) const = 0; - - virtual float get_joy_axis(int p_device, int p_axis) const = 0; - virtual String get_joy_name(int p_idx) = 0; - virtual Array get_connected_joypads() = 0; - virtual void joy_connection_changed(int p_idx, bool p_connected, String p_name, String p_guid) = 0; - virtual void add_joy_mapping(String p_mapping, bool p_update_existing = false) = 0; - virtual void remove_joy_mapping(String p_guid) = 0; - virtual bool is_joy_known(int p_device) = 0; - virtual String get_joy_guid(int p_device) const = 0; - virtual Vector2 get_joy_vibration_strength(int p_device) = 0; - virtual float get_joy_vibration_duration(int p_device) = 0; - virtual uint64_t get_joy_vibration_timestamp(int p_device) = 0; - virtual void start_joy_vibration(int p_device, float p_weak_magnitude, float p_strong_magnitude, float p_duration = 0) = 0; - virtual void stop_joy_vibration(int p_device) = 0; - virtual void vibrate_handheld(int p_duration_ms = 500) = 0; - - virtual Point2 get_mouse_position() const = 0; - virtual Point2 get_last_mouse_speed() const = 0; - virtual int get_mouse_button_mask() const = 0; - - virtual void warp_mouse_position(const Vector2 &p_to) = 0; - virtual Point2i warp_mouse_motion(const Ref<InputEventMouseMotion> &p_motion, const Rect2 &p_rect) = 0; - - virtual Vector3 get_gravity() const = 0; - virtual Vector3 get_accelerometer() const = 0; - virtual Vector3 get_magnetometer() const = 0; - virtual Vector3 get_gyroscope() const = 0; - - virtual void action_press(const StringName &p_action, float p_strength = 1.f) = 0; - virtual void action_release(const StringName &p_action) = 0; - - void get_argument_options(const StringName &p_function, int p_idx, List<String> *r_options) const; - - virtual bool is_emulating_touch_from_mouse() const = 0; - virtual bool is_emulating_mouse_from_touch() const = 0; - - virtual CursorShape get_default_cursor_shape() const = 0; - virtual void set_default_cursor_shape(CursorShape p_shape) = 0; - virtual CursorShape get_current_cursor_shape() const = 0; - virtual void set_custom_mouse_cursor(const RES &p_cursor, CursorShape p_shape = CURSOR_ARROW, const Vector2 &p_hotspot = Vector2()) = 0; - - virtual String get_joy_button_string(int p_button) = 0; - virtual String get_joy_axis_string(int p_axis) = 0; - virtual int get_joy_button_index_from_string(String p_button) = 0; - virtual int get_joy_axis_index_from_string(String p_axis) = 0; - - virtual void parse_input_event(const Ref<InputEvent> &p_event) = 0; - virtual void accumulate_input_event(const Ref<InputEvent> &p_event) = 0; - virtual void flush_accumulated_events() = 0; - virtual void set_use_accumulated_input(bool p_enable) = 0; - - Input(); -}; - -VARIANT_ENUM_CAST(Input::MouseMode); -VARIANT_ENUM_CAST(Input::CursorShape); - -#endif // INPUT_H diff --git a/core/os/input_event.cpp b/core/os/input_event.cpp deleted file mode 100644 index 2e863c9c76..0000000000 --- a/core/os/input_event.cpp +++ /dev/null @@ -1,1332 +0,0 @@ -/*************************************************************************/ -/* input_event.cpp */ -/*************************************************************************/ -/* This file is part of: */ -/* GODOT ENGINE */ -/* https://godotengine.org */ -/*************************************************************************/ -/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */ -/* */ -/* Permission is hereby granted, free of charge, to any person obtaining */ -/* a copy of this software and associated documentation files (the */ -/* "Software"), to deal in the Software without restriction, including */ -/* without limitation the rights to use, copy, modify, merge, publish, */ -/* distribute, sublicense, and/or sell copies of the Software, and to */ -/* permit persons to whom the Software is furnished to do so, subject to */ -/* the following conditions: */ -/* */ -/* The above copyright notice and this permission notice shall be */ -/* included in all copies or substantial portions of the Software. */ -/* */ -/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */ -/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */ -/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/ -/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */ -/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */ -/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */ -/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ -/*************************************************************************/ - -#include "input_event.h" - -#include "core/input_map.h" -#include "core/os/keyboard.h" - -const int InputEvent::DEVICE_ID_TOUCH_MOUSE = -1; -const int InputEvent::DEVICE_ID_INTERNAL = -2; - -void InputEvent::set_device(int p_device) { - device = p_device; -} - -int InputEvent::get_device() const { - return device; -} - -bool InputEvent::is_action(const StringName &p_action) const { - - return InputMap::get_singleton()->event_is_action(Ref<InputEvent>((InputEvent *)this), p_action); -} - -bool InputEvent::is_action_pressed(const StringName &p_action, bool p_allow_echo) const { - - bool pressed; - bool valid = InputMap::get_singleton()->event_get_action_status(Ref<InputEvent>((InputEvent *)this), p_action, &pressed); - return valid && pressed && (p_allow_echo || !is_echo()); -} - -bool InputEvent::is_action_released(const StringName &p_action) const { - - bool pressed; - bool valid = InputMap::get_singleton()->event_get_action_status(Ref<InputEvent>((InputEvent *)this), p_action, &pressed); - return valid && !pressed; -} - -float InputEvent::get_action_strength(const StringName &p_action) const { - - bool pressed; - float strength; - bool valid = InputMap::get_singleton()->event_get_action_status(Ref<InputEvent>((InputEvent *)this), p_action, &pressed, &strength); - return valid ? strength : 0.0f; -} - -bool InputEvent::is_pressed() const { - - return false; -} - -bool InputEvent::is_echo() const { - - return false; -} - -Ref<InputEvent> InputEvent::xformed_by(const Transform2D &p_xform, const Vector2 &p_local_ofs) const { - - return Ref<InputEvent>((InputEvent *)this); -} - -String InputEvent::as_text() const { - - return String(); -} - -bool InputEvent::action_match(const Ref<InputEvent> &p_event, bool *p_pressed, float *p_strength, float p_deadzone) const { - - return false; -} - -bool InputEvent::shortcut_match(const Ref<InputEvent> &p_event) const { - - return false; -} - -bool InputEvent::is_action_type() const { - - return false; -} - -void InputEvent::_bind_methods() { - - ClassDB::bind_method(D_METHOD("set_device", "device"), &InputEvent::set_device); - ClassDB::bind_method(D_METHOD("get_device"), &InputEvent::get_device); - - ClassDB::bind_method(D_METHOD("is_action", "action"), &InputEvent::is_action); - ClassDB::bind_method(D_METHOD("is_action_pressed", "action", "allow_echo"), &InputEvent::is_action_pressed, DEFVAL(false)); - ClassDB::bind_method(D_METHOD("is_action_released", "action"), &InputEvent::is_action_released); - ClassDB::bind_method(D_METHOD("get_action_strength", "action"), &InputEvent::get_action_strength); - - ClassDB::bind_method(D_METHOD("is_pressed"), &InputEvent::is_pressed); - ClassDB::bind_method(D_METHOD("is_echo"), &InputEvent::is_echo); - - ClassDB::bind_method(D_METHOD("as_text"), &InputEvent::as_text); - - ClassDB::bind_method(D_METHOD("shortcut_match", "event"), &InputEvent::shortcut_match); - - ClassDB::bind_method(D_METHOD("is_action_type"), &InputEvent::is_action_type); - - ClassDB::bind_method(D_METHOD("accumulate", "with_event"), &InputEvent::accumulate); - - ClassDB::bind_method(D_METHOD("xformed_by", "xform", "local_ofs"), &InputEvent::xformed_by, DEFVAL(Vector2())); - - ADD_PROPERTY(PropertyInfo(Variant::INT, "device"), "set_device", "get_device"); -} - -InputEvent::InputEvent() { - - device = 0; -} - -////////////////// - -void InputEventWithModifiers::set_shift(bool p_enabled) { - - shift = p_enabled; -} - -bool InputEventWithModifiers::get_shift() const { - - return shift; -} - -void InputEventWithModifiers::set_alt(bool p_enabled) { - - alt = p_enabled; -} -bool InputEventWithModifiers::get_alt() const { - - return alt; -} - -void InputEventWithModifiers::set_control(bool p_enabled) { - - control = p_enabled; -} -bool InputEventWithModifiers::get_control() const { - - return control; -} - -void InputEventWithModifiers::set_metakey(bool p_enabled) { - - meta = p_enabled; -} -bool InputEventWithModifiers::get_metakey() const { - - return meta; -} - -void InputEventWithModifiers::set_command(bool p_enabled) { - - command = p_enabled; -} -bool InputEventWithModifiers::get_command() const { - - return command; -} - -void InputEventWithModifiers::set_modifiers_from_event(const InputEventWithModifiers *event) { - - set_alt(event->get_alt()); - set_shift(event->get_shift()); - set_control(event->get_control()); - set_metakey(event->get_metakey()); -} - -void InputEventWithModifiers::_bind_methods() { - - ClassDB::bind_method(D_METHOD("set_alt", "enable"), &InputEventWithModifiers::set_alt); - ClassDB::bind_method(D_METHOD("get_alt"), &InputEventWithModifiers::get_alt); - - ClassDB::bind_method(D_METHOD("set_shift", "enable"), &InputEventWithModifiers::set_shift); - ClassDB::bind_method(D_METHOD("get_shift"), &InputEventWithModifiers::get_shift); - - ClassDB::bind_method(D_METHOD("set_control", "enable"), &InputEventWithModifiers::set_control); - ClassDB::bind_method(D_METHOD("get_control"), &InputEventWithModifiers::get_control); - - ClassDB::bind_method(D_METHOD("set_metakey", "enable"), &InputEventWithModifiers::set_metakey); - ClassDB::bind_method(D_METHOD("get_metakey"), &InputEventWithModifiers::get_metakey); - - ClassDB::bind_method(D_METHOD("set_command", "enable"), &InputEventWithModifiers::set_command); - ClassDB::bind_method(D_METHOD("get_command"), &InputEventWithModifiers::get_command); - - ADD_PROPERTY(PropertyInfo(Variant::BOOL, "alt"), "set_alt", "get_alt"); - ADD_PROPERTY(PropertyInfo(Variant::BOOL, "shift"), "set_shift", "get_shift"); - ADD_PROPERTY(PropertyInfo(Variant::BOOL, "control"), "set_control", "get_control"); - ADD_PROPERTY(PropertyInfo(Variant::BOOL, "meta"), "set_metakey", "get_metakey"); - ADD_PROPERTY(PropertyInfo(Variant::BOOL, "command"), "set_command", "get_command"); -} - -InputEventWithModifiers::InputEventWithModifiers() { - - alt = false; - shift = false; - control = false; - meta = false; -} - -////////////////////////////////// - -void InputEventKey::set_pressed(bool p_pressed) { - - pressed = p_pressed; -} - -bool InputEventKey::is_pressed() const { - - return pressed; -} - -void InputEventKey::set_scancode(uint32_t p_scancode) { - - scancode = p_scancode; -} -uint32_t InputEventKey::get_scancode() const { - - return scancode; -} - -void InputEventKey::set_unicode(uint32_t p_unicode) { - - unicode = p_unicode; -} -uint32_t InputEventKey::get_unicode() const { - - return unicode; -} - -void InputEventKey::set_echo(bool p_enable) { - - echo = p_enable; -} -bool InputEventKey::is_echo() const { - - return echo; -} - -uint32_t InputEventKey::get_scancode_with_modifiers() const { - - uint32_t sc = scancode; - if (get_control()) - sc |= KEY_MASK_CTRL; - if (get_alt()) - sc |= KEY_MASK_ALT; - if (get_shift()) - sc |= KEY_MASK_SHIFT; - if (get_metakey()) - sc |= KEY_MASK_META; - - return sc; -} - -String InputEventKey::as_text() const { - - String kc = keycode_get_string(scancode); - if (kc == String()) - return kc; - - if (get_metakey()) { - kc = find_keycode_name(KEY_META) + ("+" + kc); - } - if (get_alt()) { - kc = find_keycode_name(KEY_ALT) + ("+" + kc); - } - if (get_shift()) { - kc = find_keycode_name(KEY_SHIFT) + ("+" + kc); - } - if (get_control()) { - kc = find_keycode_name(KEY_CONTROL) + ("+" + kc); - } - return kc; -} - -bool InputEventKey::action_match(const Ref<InputEvent> &p_event, bool *p_pressed, float *p_strength, float p_deadzone) const { - - Ref<InputEventKey> key = p_event; - if (key.is_null()) - return false; - - uint32_t code = get_scancode_with_modifiers(); - uint32_t event_code = key->get_scancode_with_modifiers(); - - bool match = get_scancode() == key->get_scancode() && (!key->is_pressed() || (code & event_code) == code); - if (match) { - if (p_pressed != NULL) - *p_pressed = key->is_pressed(); - if (p_strength != NULL) - *p_strength = (p_pressed != NULL && *p_pressed) ? 1.0f : 0.0f; - } - return match; -} - -bool InputEventKey::shortcut_match(const Ref<InputEvent> &p_event) const { - - Ref<InputEventKey> key = p_event; - if (key.is_null()) - return false; - - uint32_t code = get_scancode_with_modifiers(); - uint32_t event_code = key->get_scancode_with_modifiers(); - - return code == event_code; -} - -void InputEventKey::_bind_methods() { - - ClassDB::bind_method(D_METHOD("set_pressed", "pressed"), &InputEventKey::set_pressed); - - ClassDB::bind_method(D_METHOD("set_scancode", "scancode"), &InputEventKey::set_scancode); - ClassDB::bind_method(D_METHOD("get_scancode"), &InputEventKey::get_scancode); - - ClassDB::bind_method(D_METHOD("set_unicode", "unicode"), &InputEventKey::set_unicode); - ClassDB::bind_method(D_METHOD("get_unicode"), &InputEventKey::get_unicode); - - ClassDB::bind_method(D_METHOD("set_echo", "echo"), &InputEventKey::set_echo); - - ClassDB::bind_method(D_METHOD("get_scancode_with_modifiers"), &InputEventKey::get_scancode_with_modifiers); - - ADD_PROPERTY(PropertyInfo(Variant::BOOL, "pressed"), "set_pressed", "is_pressed"); - ADD_PROPERTY(PropertyInfo(Variant::INT, "scancode"), "set_scancode", "get_scancode"); - ADD_PROPERTY(PropertyInfo(Variant::INT, "unicode"), "set_unicode", "get_unicode"); - ADD_PROPERTY(PropertyInfo(Variant::INT, "echo"), "set_echo", "is_echo"); -} - -InputEventKey::InputEventKey() { - - pressed = false; - scancode = 0; - unicode = 0; ///unicode - echo = false; -} - -//////////////////////////////////////// - -void InputEventMouse::set_button_mask(int p_mask) { - - button_mask = p_mask; -} -int InputEventMouse::get_button_mask() const { - - return button_mask; -} - -void InputEventMouse::set_position(const Vector2 &p_pos) { - - pos = p_pos; -} -Vector2 InputEventMouse::get_position() const { - - return pos; -} - -void InputEventMouse::set_global_position(const Vector2 &p_global_pos) { - - global_pos = p_global_pos; -} -Vector2 InputEventMouse::get_global_position() const { - - return global_pos; -} - -void InputEventMouse::_bind_methods() { - - ClassDB::bind_method(D_METHOD("set_button_mask", "button_mask"), &InputEventMouse::set_button_mask); - ClassDB::bind_method(D_METHOD("get_button_mask"), &InputEventMouse::get_button_mask); - - ClassDB::bind_method(D_METHOD("set_position", "position"), &InputEventMouse::set_position); - ClassDB::bind_method(D_METHOD("get_position"), &InputEventMouse::get_position); - - ClassDB::bind_method(D_METHOD("set_global_position", "global_position"), &InputEventMouse::set_global_position); - ClassDB::bind_method(D_METHOD("get_global_position"), &InputEventMouse::get_global_position); - - ADD_PROPERTY(PropertyInfo(Variant::INT, "button_mask"), "set_button_mask", "get_button_mask"); - ADD_PROPERTY(PropertyInfo(Variant::VECTOR2, "position"), "set_position", "get_position"); - ADD_PROPERTY(PropertyInfo(Variant::VECTOR2, "global_position"), "set_global_position", "get_global_position"); -} - -InputEventMouse::InputEventMouse() { - - button_mask = 0; -} - -/////////////////////////////////////// - -void InputEventMouseButton::set_factor(float p_factor) { - - factor = p_factor; -} - -float InputEventMouseButton::get_factor() { - - return factor; -} - -void InputEventMouseButton::set_button_index(int p_index) { - - button_index = p_index; -} -int InputEventMouseButton::get_button_index() const { - - return button_index; -} - -void InputEventMouseButton::set_pressed(bool p_pressed) { - - pressed = p_pressed; -} -bool InputEventMouseButton::is_pressed() const { - - return pressed; -} - -void InputEventMouseButton::set_doubleclick(bool p_doubleclick) { - - doubleclick = p_doubleclick; -} -bool InputEventMouseButton::is_doubleclick() const { - - return doubleclick; -} - -Ref<InputEvent> InputEventMouseButton::xformed_by(const Transform2D &p_xform, const Vector2 &p_local_ofs) const { - - Vector2 g = get_global_position(); - Vector2 l = p_xform.xform(get_position() + p_local_ofs); - - Ref<InputEventMouseButton> mb; - mb.instance(); - - mb->set_device(get_device()); - - mb->set_modifiers_from_event(this); - - mb->set_position(l); - mb->set_global_position(g); - - mb->set_button_mask(get_button_mask()); - mb->set_pressed(pressed); - mb->set_doubleclick(doubleclick); - mb->set_factor(factor); - mb->set_button_index(button_index); - - return mb; -} - -bool InputEventMouseButton::action_match(const Ref<InputEvent> &p_event, bool *p_pressed, float *p_strength, float p_deadzone) const { - - Ref<InputEventMouseButton> mb = p_event; - if (mb.is_null()) - return false; - - bool match = mb->button_index == button_index; - if (match) { - if (p_pressed != NULL) - *p_pressed = mb->is_pressed(); - if (p_strength != NULL) - *p_strength = (p_pressed != NULL && *p_pressed) ? 1.0f : 0.0f; - } - - return match; -} - -String InputEventMouseButton::as_text() const { - - String button_index_string = ""; - switch (get_button_index()) { - case BUTTON_LEFT: - button_index_string = "BUTTON_LEFT"; - break; - case BUTTON_RIGHT: - button_index_string = "BUTTON_RIGHT"; - break; - case BUTTON_MIDDLE: - button_index_string = "BUTTON_MIDDLE"; - break; - case BUTTON_WHEEL_UP: - button_index_string = "BUTTON_WHEEL_UP"; - break; - case BUTTON_WHEEL_DOWN: - button_index_string = "BUTTON_WHEEL_DOWN"; - break; - case BUTTON_WHEEL_LEFT: - button_index_string = "BUTTON_WHEEL_LEFT"; - break; - case BUTTON_WHEEL_RIGHT: - button_index_string = "BUTTON_WHEEL_RIGHT"; - break; - case BUTTON_XBUTTON1: - button_index_string = "BUTTON_XBUTTON1"; - break; - case BUTTON_XBUTTON2: - button_index_string = "BUTTON_XBUTTON2"; - break; - default: - button_index_string = itos(get_button_index()); - break; - } - return "InputEventMouseButton : button_index=" + button_index_string + ", pressed=" + (pressed ? "true" : "false") + ", position=(" + String(get_position()) + "), button_mask=" + itos(get_button_mask()) + ", doubleclick=" + (doubleclick ? "true" : "false"); -} - -void InputEventMouseButton::_bind_methods() { - - ClassDB::bind_method(D_METHOD("set_factor", "factor"), &InputEventMouseButton::set_factor); - ClassDB::bind_method(D_METHOD("get_factor"), &InputEventMouseButton::get_factor); - - ClassDB::bind_method(D_METHOD("set_button_index", "button_index"), &InputEventMouseButton::set_button_index); - ClassDB::bind_method(D_METHOD("get_button_index"), &InputEventMouseButton::get_button_index); - - ClassDB::bind_method(D_METHOD("set_pressed", "pressed"), &InputEventMouseButton::set_pressed); - // ClassDB::bind_method(D_METHOD("is_pressed"), &InputEventMouseButton::is_pressed); - - ClassDB::bind_method(D_METHOD("set_doubleclick", "doubleclick"), &InputEventMouseButton::set_doubleclick); - ClassDB::bind_method(D_METHOD("is_doubleclick"), &InputEventMouseButton::is_doubleclick); - - ADD_PROPERTY(PropertyInfo(Variant::REAL, "factor"), "set_factor", "get_factor"); - ADD_PROPERTY(PropertyInfo(Variant::INT, "button_index"), "set_button_index", "get_button_index"); - ADD_PROPERTY(PropertyInfo(Variant::BOOL, "pressed"), "set_pressed", "is_pressed"); - ADD_PROPERTY(PropertyInfo(Variant::BOOL, "doubleclick"), "set_doubleclick", "is_doubleclick"); -} - -InputEventMouseButton::InputEventMouseButton() { - - factor = 1; - button_index = 0; - pressed = false; - doubleclick = false; -} - -//////////////////////////////////////////// - -void InputEventMouseMotion::set_tilt(const Vector2 &p_tilt) { - - tilt = p_tilt; -} - -Vector2 InputEventMouseMotion::get_tilt() const { - - return tilt; -} - -void InputEventMouseMotion::set_pressure(float p_pressure) { - - pressure = p_pressure; -} - -float InputEventMouseMotion::get_pressure() const { - - return pressure; -} - -void InputEventMouseMotion::set_relative(const Vector2 &p_relative) { - - relative = p_relative; -} - -Vector2 InputEventMouseMotion::get_relative() const { - - return relative; -} - -void InputEventMouseMotion::set_speed(const Vector2 &p_speed) { - - speed = p_speed; -} - -Vector2 InputEventMouseMotion::get_speed() const { - - return speed; -} - -Ref<InputEvent> InputEventMouseMotion::xformed_by(const Transform2D &p_xform, const Vector2 &p_local_ofs) const { - - Vector2 g = get_global_position(); - Vector2 l = p_xform.xform(get_position() + p_local_ofs); - Vector2 r = p_xform.basis_xform(get_relative()); - Vector2 s = p_xform.basis_xform(get_speed()); - - Ref<InputEventMouseMotion> mm; - mm.instance(); - - mm->set_device(get_device()); - - mm->set_modifiers_from_event(this); - - mm->set_position(l); - mm->set_pressure(get_pressure()); - mm->set_tilt(get_tilt()); - mm->set_global_position(g); - - mm->set_button_mask(get_button_mask()); - mm->set_relative(r); - mm->set_speed(s); - - return mm; -} - -String InputEventMouseMotion::as_text() const { - - String button_mask_string = ""; - switch (get_button_mask()) { - case BUTTON_MASK_LEFT: - button_mask_string = "BUTTON_MASK_LEFT"; - break; - case BUTTON_MASK_MIDDLE: - button_mask_string = "BUTTON_MASK_MIDDLE"; - break; - case BUTTON_MASK_RIGHT: - button_mask_string = "BUTTON_MASK_RIGHT"; - break; - case BUTTON_MASK_XBUTTON1: - button_mask_string = "BUTTON_MASK_XBUTTON1"; - break; - case BUTTON_MASK_XBUTTON2: - button_mask_string = "BUTTON_MASK_XBUTTON2"; - break; - default: - button_mask_string = itos(get_button_mask()); - break; - } - return "InputEventMouseMotion : button_mask=" + button_mask_string + ", position=(" + String(get_position()) + "), relative=(" + String(get_relative()) + "), speed=(" + String(get_speed()) + ")"; -} - -bool InputEventMouseMotion::accumulate(const Ref<InputEvent> &p_event) { - - Ref<InputEventMouseMotion> motion = p_event; - if (motion.is_null()) - return false; - - if (is_pressed() != motion->is_pressed()) { - return false; - } - - if (get_button_mask() != motion->get_button_mask()) { - return false; - } - - if (get_shift() != motion->get_shift()) { - return false; - } - - if (get_control() != motion->get_control()) { - return false; - } - - if (get_alt() != motion->get_alt()) { - return false; - } - - if (get_metakey() != motion->get_metakey()) { - return false; - } - - set_position(motion->get_position()); - set_global_position(motion->get_global_position()); - set_speed(motion->get_speed()); - relative += motion->get_relative(); - - return true; -} - -void InputEventMouseMotion::_bind_methods() { - - ClassDB::bind_method(D_METHOD("set_tilt", "tilt"), &InputEventMouseMotion::set_tilt); - ClassDB::bind_method(D_METHOD("get_tilt"), &InputEventMouseMotion::get_tilt); - - ClassDB::bind_method(D_METHOD("set_pressure", "pressure"), &InputEventMouseMotion::set_pressure); - ClassDB::bind_method(D_METHOD("get_pressure"), &InputEventMouseMotion::get_pressure); - - ClassDB::bind_method(D_METHOD("set_relative", "relative"), &InputEventMouseMotion::set_relative); - ClassDB::bind_method(D_METHOD("get_relative"), &InputEventMouseMotion::get_relative); - - ClassDB::bind_method(D_METHOD("set_speed", "speed"), &InputEventMouseMotion::set_speed); - ClassDB::bind_method(D_METHOD("get_speed"), &InputEventMouseMotion::get_speed); - - ADD_PROPERTY(PropertyInfo(Variant::VECTOR2, "tilt"), "set_tilt", "get_tilt"); - ADD_PROPERTY(PropertyInfo(Variant::REAL, "pressure"), "set_pressure", "get_pressure"); - ADD_PROPERTY(PropertyInfo(Variant::VECTOR2, "relative"), "set_relative", "get_relative"); - ADD_PROPERTY(PropertyInfo(Variant::VECTOR2, "speed"), "set_speed", "get_speed"); -} - -InputEventMouseMotion::InputEventMouseMotion() { - - pressure = 0; -} - -//////////////////////////////////////// - -void InputEventJoypadMotion::set_axis(int p_axis) { - - axis = p_axis; -} - -int InputEventJoypadMotion::get_axis() const { - - return axis; -} - -void InputEventJoypadMotion::set_axis_value(float p_value) { - - axis_value = p_value; -} - -float InputEventJoypadMotion::get_axis_value() const { - - return axis_value; -} - -bool InputEventJoypadMotion::is_pressed() const { - - return Math::abs(axis_value) >= 0.5f; -} - -bool InputEventJoypadMotion::action_match(const Ref<InputEvent> &p_event, bool *p_pressed, float *p_strength, float p_deadzone) const { - - Ref<InputEventJoypadMotion> jm = p_event; - if (jm.is_null()) - return false; - - bool match = (axis == jm->axis); // Matches even if not in the same direction, but returns a "not pressed" event. - if (match) { - bool same_direction = (((axis_value < 0) == (jm->axis_value < 0)) || jm->axis_value == 0); - bool pressed = same_direction ? Math::abs(jm->get_axis_value()) >= p_deadzone : false; - if (p_pressed != NULL) - *p_pressed = pressed; - if (p_strength != NULL) { - if (pressed) { - if (p_deadzone == 1.0f) { - *p_strength = 1.0f; - } else { - *p_strength = CLAMP(Math::inverse_lerp(p_deadzone, 1.0f, Math::abs(jm->get_axis_value())), 0.0f, 1.0f); - } - } else { - *p_strength = 0.0f; - } - } - } - return match; -} - -String InputEventJoypadMotion::as_text() const { - - return "InputEventJoypadMotion : axis=" + itos(axis) + ", axis_value=" + String(Variant(axis_value)); -} - -void InputEventJoypadMotion::_bind_methods() { - - ClassDB::bind_method(D_METHOD("set_axis", "axis"), &InputEventJoypadMotion::set_axis); - ClassDB::bind_method(D_METHOD("get_axis"), &InputEventJoypadMotion::get_axis); - - ClassDB::bind_method(D_METHOD("set_axis_value", "axis_value"), &InputEventJoypadMotion::set_axis_value); - ClassDB::bind_method(D_METHOD("get_axis_value"), &InputEventJoypadMotion::get_axis_value); - - ADD_PROPERTY(PropertyInfo(Variant::INT, "axis"), "set_axis", "get_axis"); - ADD_PROPERTY(PropertyInfo(Variant::REAL, "axis_value"), "set_axis_value", "get_axis_value"); -} - -InputEventJoypadMotion::InputEventJoypadMotion() { - - axis = 0; - axis_value = 0; -} -///////////////////////////////// - -void InputEventJoypadButton::set_button_index(int p_index) { - - button_index = p_index; -} - -int InputEventJoypadButton::get_button_index() const { - - return button_index; -} - -void InputEventJoypadButton::set_pressed(bool p_pressed) { - - pressed = p_pressed; -} -bool InputEventJoypadButton::is_pressed() const { - - return pressed; -} - -void InputEventJoypadButton::set_pressure(float p_pressure) { - - pressure = p_pressure; -} -float InputEventJoypadButton::get_pressure() const { - - return pressure; -} - -bool InputEventJoypadButton::action_match(const Ref<InputEvent> &p_event, bool *p_pressed, float *p_strength, float p_deadzone) const { - - Ref<InputEventJoypadButton> jb = p_event; - if (jb.is_null()) - return false; - - bool match = button_index == jb->button_index; - if (match) { - if (p_pressed != NULL) - *p_pressed = jb->is_pressed(); - if (p_strength != NULL) - *p_strength = (p_pressed != NULL && *p_pressed) ? 1.0f : 0.0f; - } - - return match; -} - -bool InputEventJoypadButton::shortcut_match(const Ref<InputEvent> &p_event) const { - - Ref<InputEventJoypadButton> button = p_event; - if (button.is_null()) - return false; - - return button_index == button->button_index; -} - -String InputEventJoypadButton::as_text() const { - - return "InputEventJoypadButton : button_index=" + itos(button_index) + ", pressed=" + (pressed ? "true" : "false") + ", pressure=" + String(Variant(pressure)); -} - -void InputEventJoypadButton::_bind_methods() { - - ClassDB::bind_method(D_METHOD("set_button_index", "button_index"), &InputEventJoypadButton::set_button_index); - ClassDB::bind_method(D_METHOD("get_button_index"), &InputEventJoypadButton::get_button_index); - - ClassDB::bind_method(D_METHOD("set_pressure", "pressure"), &InputEventJoypadButton::set_pressure); - ClassDB::bind_method(D_METHOD("get_pressure"), &InputEventJoypadButton::get_pressure); - - ClassDB::bind_method(D_METHOD("set_pressed", "pressed"), &InputEventJoypadButton::set_pressed); - // ClassDB::bind_method(D_METHOD("is_pressed"), &InputEventJoypadButton::is_pressed); - - ADD_PROPERTY(PropertyInfo(Variant::INT, "button_index"), "set_button_index", "get_button_index"); - ADD_PROPERTY(PropertyInfo(Variant::REAL, "pressure"), "set_pressure", "get_pressure"); - ADD_PROPERTY(PropertyInfo(Variant::BOOL, "pressed"), "set_pressed", "is_pressed"); -} - -InputEventJoypadButton::InputEventJoypadButton() { - - button_index = 0; - pressure = 0; - pressed = false; -} - -////////////////////////////////////////////// - -void InputEventScreenTouch::set_index(int p_index) { - - index = p_index; -} -int InputEventScreenTouch::get_index() const { - - return index; -} - -void InputEventScreenTouch::set_position(const Vector2 &p_pos) { - - pos = p_pos; -} -Vector2 InputEventScreenTouch::get_position() const { - - return pos; -} - -void InputEventScreenTouch::set_pressed(bool p_pressed) { - - pressed = p_pressed; -} -bool InputEventScreenTouch::is_pressed() const { - - return pressed; -} - -Ref<InputEvent> InputEventScreenTouch::xformed_by(const Transform2D &p_xform, const Vector2 &p_local_ofs) const { - - Ref<InputEventScreenTouch> st; - st.instance(); - st->set_device(get_device()); - st->set_index(index); - st->set_position(p_xform.xform(pos + p_local_ofs)); - st->set_pressed(pressed); - - return st; -} - -String InputEventScreenTouch::as_text() const { - - return "InputEventScreenTouch : index=" + itos(index) + ", pressed=" + (pressed ? "true" : "false") + ", position=(" + String(get_position()) + ")"; -} - -void InputEventScreenTouch::_bind_methods() { - - ClassDB::bind_method(D_METHOD("set_index", "index"), &InputEventScreenTouch::set_index); - ClassDB::bind_method(D_METHOD("get_index"), &InputEventScreenTouch::get_index); - - ClassDB::bind_method(D_METHOD("set_position", "position"), &InputEventScreenTouch::set_position); - ClassDB::bind_method(D_METHOD("get_position"), &InputEventScreenTouch::get_position); - - ClassDB::bind_method(D_METHOD("set_pressed", "pressed"), &InputEventScreenTouch::set_pressed); - //ClassDB::bind_method(D_METHOD("is_pressed"),&InputEventScreenTouch::is_pressed); - - ADD_PROPERTY(PropertyInfo(Variant::INT, "index"), "set_index", "get_index"); - ADD_PROPERTY(PropertyInfo(Variant::VECTOR2, "position"), "set_position", "get_position"); - ADD_PROPERTY(PropertyInfo(Variant::BOOL, "pressed"), "set_pressed", "is_pressed"); -} - -InputEventScreenTouch::InputEventScreenTouch() { - - index = 0; - pressed = false; -} - -///////////////////////////// - -void InputEventScreenDrag::set_index(int p_index) { - - index = p_index; -} - -int InputEventScreenDrag::get_index() const { - - return index; -} - -void InputEventScreenDrag::set_position(const Vector2 &p_pos) { - - pos = p_pos; -} -Vector2 InputEventScreenDrag::get_position() const { - - return pos; -} - -void InputEventScreenDrag::set_relative(const Vector2 &p_relative) { - - relative = p_relative; -} -Vector2 InputEventScreenDrag::get_relative() const { - - return relative; -} - -void InputEventScreenDrag::set_speed(const Vector2 &p_speed) { - - speed = p_speed; -} -Vector2 InputEventScreenDrag::get_speed() const { - - return speed; -} - -Ref<InputEvent> InputEventScreenDrag::xformed_by(const Transform2D &p_xform, const Vector2 &p_local_ofs) const { - - Ref<InputEventScreenDrag> sd; - - sd.instance(); - - sd->set_device(get_device()); - - sd->set_index(index); - sd->set_position(p_xform.xform(pos + p_local_ofs)); - sd->set_relative(p_xform.basis_xform(relative)); - sd->set_speed(p_xform.basis_xform(speed)); - - return sd; -} - -String InputEventScreenDrag::as_text() const { - - return "InputEventScreenDrag : index=" + itos(index) + ", position=(" + String(get_position()) + "), relative=(" + String(get_relative()) + "), speed=(" + String(get_speed()) + ")"; -} - -void InputEventScreenDrag::_bind_methods() { - - ClassDB::bind_method(D_METHOD("set_index", "index"), &InputEventScreenDrag::set_index); - ClassDB::bind_method(D_METHOD("get_index"), &InputEventScreenDrag::get_index); - - ClassDB::bind_method(D_METHOD("set_position", "position"), &InputEventScreenDrag::set_position); - ClassDB::bind_method(D_METHOD("get_position"), &InputEventScreenDrag::get_position); - - ClassDB::bind_method(D_METHOD("set_relative", "relative"), &InputEventScreenDrag::set_relative); - ClassDB::bind_method(D_METHOD("get_relative"), &InputEventScreenDrag::get_relative); - - ClassDB::bind_method(D_METHOD("set_speed", "speed"), &InputEventScreenDrag::set_speed); - ClassDB::bind_method(D_METHOD("get_speed"), &InputEventScreenDrag::get_speed); - - ADD_PROPERTY(PropertyInfo(Variant::INT, "index"), "set_index", "get_index"); - ADD_PROPERTY(PropertyInfo(Variant::VECTOR2, "position"), "set_position", "get_position"); - ADD_PROPERTY(PropertyInfo(Variant::VECTOR2, "relative"), "set_relative", "get_relative"); - ADD_PROPERTY(PropertyInfo(Variant::VECTOR2, "speed"), "set_speed", "get_speed"); -} - -InputEventScreenDrag::InputEventScreenDrag() { - - index = 0; -} -///////////////////////////// - -void InputEventAction::set_action(const StringName &p_action) { - - action = p_action; -} -StringName InputEventAction::get_action() const { - - return action; -} - -void InputEventAction::set_pressed(bool p_pressed) { - - pressed = p_pressed; -} -bool InputEventAction::is_pressed() const { - - return pressed; -} - -void InputEventAction::set_strength(float p_strength) { - strength = CLAMP(p_strength, 0.0f, 1.0f); -} - -float InputEventAction::get_strength() const { - return strength; -} - -bool InputEventAction::shortcut_match(const Ref<InputEvent> &p_event) const { - if (p_event.is_null()) - return false; - - return p_event->is_action(action); -} - -bool InputEventAction::is_action(const StringName &p_action) const { - - return action == p_action; -} - -bool InputEventAction::action_match(const Ref<InputEvent> &p_event, bool *p_pressed, float *p_strength, float p_deadzone) const { - - Ref<InputEventAction> act = p_event; - if (act.is_null()) - return false; - - bool match = action == act->action; - if (match) { - if (p_pressed != NULL) - *p_pressed = act->pressed; - if (p_strength != NULL) - *p_strength = (p_pressed != NULL && *p_pressed) ? 1.0f : 0.0f; - } - return match; -} - -String InputEventAction::as_text() const { - - return "InputEventAction : action=" + action + ", pressed=(" + (pressed ? "true" : "false"); -} - -void InputEventAction::_bind_methods() { - - ClassDB::bind_method(D_METHOD("set_action", "action"), &InputEventAction::set_action); - ClassDB::bind_method(D_METHOD("get_action"), &InputEventAction::get_action); - - ClassDB::bind_method(D_METHOD("set_pressed", "pressed"), &InputEventAction::set_pressed); - //ClassDB::bind_method(D_METHOD("is_pressed"), &InputEventAction::is_pressed); - - ClassDB::bind_method(D_METHOD("set_strength", "strength"), &InputEventAction::set_strength); - ClassDB::bind_method(D_METHOD("get_strength"), &InputEventAction::get_strength); - - // ClassDB::bind_method(D_METHOD("is_action", "name"), &InputEventAction::is_action); - - ADD_PROPERTY(PropertyInfo(Variant::STRING, "action"), "set_action", "get_action"); - ADD_PROPERTY(PropertyInfo(Variant::BOOL, "pressed"), "set_pressed", "is_pressed"); - ADD_PROPERTY(PropertyInfo(Variant::REAL, "strength", PROPERTY_HINT_RANGE, "0,1,0.01"), "set_strength", "get_strength"); -} - -InputEventAction::InputEventAction() { - pressed = false; - strength = 1.0f; -} -///////////////////////////// - -void InputEventGesture::set_position(const Vector2 &p_pos) { - - pos = p_pos; -} - -void InputEventGesture::_bind_methods() { - - ClassDB::bind_method(D_METHOD("set_position", "position"), &InputEventGesture::set_position); - ClassDB::bind_method(D_METHOD("get_position"), &InputEventGesture::get_position); - - ADD_PROPERTY(PropertyInfo(Variant::VECTOR2, "position"), "set_position", "get_position"); -} - -Vector2 InputEventGesture::get_position() const { - - return pos; -} -///////////////////////////// - -void InputEventMagnifyGesture::set_factor(real_t p_factor) { - - factor = p_factor; -} - -real_t InputEventMagnifyGesture::get_factor() const { - - return factor; -} - -Ref<InputEvent> InputEventMagnifyGesture::xformed_by(const Transform2D &p_xform, const Vector2 &p_local_ofs) const { - - Ref<InputEventMagnifyGesture> ev; - ev.instance(); - - ev->set_device(get_device()); - ev->set_modifiers_from_event(this); - - ev->set_position(p_xform.xform(get_position() + p_local_ofs)); - ev->set_factor(get_factor()); - - return ev; -} - -String InputEventMagnifyGesture::as_text() const { - - return "InputEventMagnifyGesture : factor=" + rtos(get_factor()) + ", position=(" + String(get_position()) + ")"; -} - -void InputEventMagnifyGesture::_bind_methods() { - - ClassDB::bind_method(D_METHOD("set_factor", "factor"), &InputEventMagnifyGesture::set_factor); - ClassDB::bind_method(D_METHOD("get_factor"), &InputEventMagnifyGesture::get_factor); - - ADD_PROPERTY(PropertyInfo(Variant::REAL, "factor"), "set_factor", "get_factor"); -} - -InputEventMagnifyGesture::InputEventMagnifyGesture() { - - factor = 1.0; -} -///////////////////////////// - -void InputEventPanGesture::set_delta(const Vector2 &p_delta) { - - delta = p_delta; -} - -Vector2 InputEventPanGesture::get_delta() const { - return delta; -} - -Ref<InputEvent> InputEventPanGesture::xformed_by(const Transform2D &p_xform, const Vector2 &p_local_ofs) const { - - Ref<InputEventPanGesture> ev; - ev.instance(); - - ev->set_device(get_device()); - ev->set_modifiers_from_event(this); - - ev->set_position(p_xform.xform(get_position() + p_local_ofs)); - ev->set_delta(get_delta()); - - return ev; -} - -String InputEventPanGesture::as_text() const { - - return "InputEventPanGesture : delta=(" + String(get_delta()) + "), position=(" + String(get_position()) + ")"; -} - -void InputEventPanGesture::_bind_methods() { - - ClassDB::bind_method(D_METHOD("set_delta", "delta"), &InputEventPanGesture::set_delta); - ClassDB::bind_method(D_METHOD("get_delta"), &InputEventPanGesture::get_delta); - - ADD_PROPERTY(PropertyInfo(Variant::VECTOR2, "delta"), "set_delta", "get_delta"); -} - -InputEventPanGesture::InputEventPanGesture() { - - delta = Vector2(0, 0); -} -///////////////////////////// - -void InputEventMIDI::set_channel(const int p_channel) { - - channel = p_channel; -} - -int InputEventMIDI::get_channel() const { - return channel; -} - -void InputEventMIDI::set_message(const int p_message) { - - message = p_message; -} - -int InputEventMIDI::get_message() const { - return message; -} - -void InputEventMIDI::set_pitch(const int p_pitch) { - - pitch = p_pitch; -} - -int InputEventMIDI::get_pitch() const { - return pitch; -} - -void InputEventMIDI::set_velocity(const int p_velocity) { - - velocity = p_velocity; -} - -int InputEventMIDI::get_velocity() const { - return velocity; -} - -void InputEventMIDI::set_instrument(const int p_instrument) { - - instrument = p_instrument; -} - -int InputEventMIDI::get_instrument() const { - return instrument; -} - -void InputEventMIDI::set_pressure(const int p_pressure) { - - pressure = p_pressure; -} - -int InputEventMIDI::get_pressure() const { - return pressure; -} - -void InputEventMIDI::set_controller_number(const int p_controller_number) { - - controller_number = p_controller_number; -} - -int InputEventMIDI::get_controller_number() const { - return controller_number; -} - -void InputEventMIDI::set_controller_value(const int p_controller_value) { - - controller_value = p_controller_value; -} - -int InputEventMIDI::get_controller_value() const { - return controller_value; -} - -String InputEventMIDI::as_text() const { - - return "InputEventMIDI : channel=(" + itos(get_channel()) + "), message=(" + itos(get_message()) + ")"; -} - -void InputEventMIDI::_bind_methods() { - - ClassDB::bind_method(D_METHOD("set_channel", "channel"), &InputEventMIDI::set_channel); - ClassDB::bind_method(D_METHOD("get_channel"), &InputEventMIDI::get_channel); - ClassDB::bind_method(D_METHOD("set_message", "message"), &InputEventMIDI::set_message); - ClassDB::bind_method(D_METHOD("get_message"), &InputEventMIDI::get_message); - ClassDB::bind_method(D_METHOD("set_pitch", "pitch"), &InputEventMIDI::set_pitch); - ClassDB::bind_method(D_METHOD("get_pitch"), &InputEventMIDI::get_pitch); - ClassDB::bind_method(D_METHOD("set_velocity", "velocity"), &InputEventMIDI::set_velocity); - ClassDB::bind_method(D_METHOD("get_velocity"), &InputEventMIDI::get_velocity); - ClassDB::bind_method(D_METHOD("set_instrument", "instrument"), &InputEventMIDI::set_instrument); - ClassDB::bind_method(D_METHOD("get_instrument"), &InputEventMIDI::get_instrument); - ClassDB::bind_method(D_METHOD("set_pressure", "pressure"), &InputEventMIDI::set_pressure); - ClassDB::bind_method(D_METHOD("get_pressure"), &InputEventMIDI::get_pressure); - ClassDB::bind_method(D_METHOD("set_controller_number", "controller_number"), &InputEventMIDI::set_controller_number); - ClassDB::bind_method(D_METHOD("get_controller_number"), &InputEventMIDI::get_controller_number); - ClassDB::bind_method(D_METHOD("set_controller_value", "controller_value"), &InputEventMIDI::set_controller_value); - ClassDB::bind_method(D_METHOD("get_controller_value"), &InputEventMIDI::get_controller_value); - - ADD_PROPERTY(PropertyInfo(Variant::INT, "channel"), "set_channel", "get_channel"); - ADD_PROPERTY(PropertyInfo(Variant::INT, "message"), "set_message", "get_message"); - ADD_PROPERTY(PropertyInfo(Variant::INT, "pitch"), "set_pitch", "get_pitch"); - ADD_PROPERTY(PropertyInfo(Variant::INT, "velocity"), "set_velocity", "get_velocity"); - ADD_PROPERTY(PropertyInfo(Variant::INT, "instrument"), "set_instrument", "get_instrument"); - ADD_PROPERTY(PropertyInfo(Variant::INT, "pressure"), "set_pressure", "get_pressure"); - ADD_PROPERTY(PropertyInfo(Variant::INT, "controller_number"), "set_controller_number", "get_controller_number"); - ADD_PROPERTY(PropertyInfo(Variant::INT, "controller_value"), "set_controller_value", "get_controller_value"); -} - -InputEventMIDI::InputEventMIDI() { - - channel = 0; - message = 0; - pitch = 0; - velocity = 0; - instrument = 0; - pressure = 0; - controller_number = 0; - controller_value = 0; -} diff --git a/core/os/input_event.h b/core/os/input_event.h deleted file mode 100644 index c6b04bcfa5..0000000000 --- a/core/os/input_event.h +++ /dev/null @@ -1,620 +0,0 @@ -/*************************************************************************/ -/* input_event.h */ -/*************************************************************************/ -/* This file is part of: */ -/* GODOT ENGINE */ -/* https://godotengine.org */ -/*************************************************************************/ -/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */ -/* */ -/* Permission is hereby granted, free of charge, to any person obtaining */ -/* a copy of this software and associated documentation files (the */ -/* "Software"), to deal in the Software without restriction, including */ -/* without limitation the rights to use, copy, modify, merge, publish, */ -/* distribute, sublicense, and/or sell copies of the Software, and to */ -/* permit persons to whom the Software is furnished to do so, subject to */ -/* the following conditions: */ -/* */ -/* The above copyright notice and this permission notice shall be */ -/* included in all copies or substantial portions of the Software. */ -/* */ -/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */ -/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */ -/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/ -/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */ -/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */ -/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */ -/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ -/*************************************************************************/ - -#ifndef INPUT_EVENT_H -#define INPUT_EVENT_H - -#include "core/math/transform_2d.h" -#include "core/os/copymem.h" -#include "core/resource.h" -#include "core/typedefs.h" -#include "core/ustring.h" - -/** - * Input Event classes. These are used in the main loop. - * The events are pretty obvious. - */ - -enum ButtonList { - BUTTON_LEFT = 1, - BUTTON_RIGHT = 2, - BUTTON_MIDDLE = 3, - BUTTON_WHEEL_UP = 4, - BUTTON_WHEEL_DOWN = 5, - BUTTON_WHEEL_LEFT = 6, - BUTTON_WHEEL_RIGHT = 7, - BUTTON_XBUTTON1 = 8, - BUTTON_XBUTTON2 = 9, - BUTTON_MASK_LEFT = (1 << (BUTTON_LEFT - 1)), - BUTTON_MASK_RIGHT = (1 << (BUTTON_RIGHT - 1)), - BUTTON_MASK_MIDDLE = (1 << (BUTTON_MIDDLE - 1)), - BUTTON_MASK_XBUTTON1 = (1 << (BUTTON_XBUTTON1 - 1)), - BUTTON_MASK_XBUTTON2 = (1 << (BUTTON_XBUTTON2 - 1)) -}; - -enum JoystickList { - - JOY_BUTTON_0 = 0, - JOY_BUTTON_1 = 1, - JOY_BUTTON_2 = 2, - JOY_BUTTON_3 = 3, - JOY_BUTTON_4 = 4, - JOY_BUTTON_5 = 5, - JOY_BUTTON_6 = 6, - JOY_BUTTON_7 = 7, - JOY_BUTTON_8 = 8, - JOY_BUTTON_9 = 9, - JOY_BUTTON_10 = 10, - JOY_BUTTON_11 = 11, - JOY_BUTTON_12 = 12, - JOY_BUTTON_13 = 13, - JOY_BUTTON_14 = 14, - JOY_BUTTON_15 = 15, - JOY_BUTTON_MAX = 16, - - JOY_L = JOY_BUTTON_4, - JOY_R = JOY_BUTTON_5, - JOY_L2 = JOY_BUTTON_6, - JOY_R2 = JOY_BUTTON_7, - JOY_L3 = JOY_BUTTON_8, - JOY_R3 = JOY_BUTTON_9, - JOY_SELECT = JOY_BUTTON_10, - JOY_START = JOY_BUTTON_11, - JOY_DPAD_UP = JOY_BUTTON_12, - JOY_DPAD_DOWN = JOY_BUTTON_13, - JOY_DPAD_LEFT = JOY_BUTTON_14, - JOY_DPAD_RIGHT = JOY_BUTTON_15, - - JOY_SONY_CIRCLE = JOY_BUTTON_1, - JOY_SONY_X = JOY_BUTTON_0, - JOY_SONY_SQUARE = JOY_BUTTON_2, - JOY_SONY_TRIANGLE = JOY_BUTTON_3, - - JOY_XBOX_A = JOY_BUTTON_0, - JOY_XBOX_B = JOY_BUTTON_1, - JOY_XBOX_X = JOY_BUTTON_2, - JOY_XBOX_Y = JOY_BUTTON_3, - - JOY_DS_A = JOY_BUTTON_1, - JOY_DS_B = JOY_BUTTON_0, - JOY_DS_X = JOY_BUTTON_3, - JOY_DS_Y = JOY_BUTTON_2, - - JOY_WII_C = JOY_BUTTON_5, - JOY_WII_Z = JOY_BUTTON_6, - - JOY_WII_MINUS = JOY_BUTTON_10, - JOY_WII_PLUS = JOY_BUTTON_11, - - JOY_VR_GRIP = JOY_BUTTON_2, - JOY_VR_PAD = JOY_BUTTON_14, - JOY_VR_TRIGGER = JOY_BUTTON_15, - - JOY_OCULUS_AX = JOY_BUTTON_7, - JOY_OCULUS_BY = JOY_BUTTON_1, - JOY_OCULUS_MENU = JOY_BUTTON_3, - - JOY_OPENVR_MENU = JOY_BUTTON_1, - - // end of history - - JOY_AXIS_0 = 0, - JOY_AXIS_1 = 1, - JOY_AXIS_2 = 2, - JOY_AXIS_3 = 3, - JOY_AXIS_4 = 4, - JOY_AXIS_5 = 5, - JOY_AXIS_6 = 6, - JOY_AXIS_7 = 7, - JOY_AXIS_8 = 8, - JOY_AXIS_9 = 9, - JOY_AXIS_MAX = 10, - - JOY_ANALOG_LX = JOY_AXIS_0, - JOY_ANALOG_LY = JOY_AXIS_1, - - JOY_ANALOG_RX = JOY_AXIS_2, - JOY_ANALOG_RY = JOY_AXIS_3, - - JOY_ANALOG_L2 = JOY_AXIS_6, - JOY_ANALOG_R2 = JOY_AXIS_7, - - JOY_VR_ANALOG_TRIGGER = JOY_AXIS_2, - JOY_VR_ANALOG_GRIP = JOY_AXIS_4, - - JOY_OPENVR_TOUCHPADX = JOY_AXIS_0, - JOY_OPENVR_TOUCHPADY = JOY_AXIS_1, -}; - -enum MidiMessageList { - MIDI_MESSAGE_NOTE_OFF = 0x8, - MIDI_MESSAGE_NOTE_ON = 0x9, - MIDI_MESSAGE_AFTERTOUCH = 0xA, - MIDI_MESSAGE_CONTROL_CHANGE = 0xB, - MIDI_MESSAGE_PROGRAM_CHANGE = 0xC, - MIDI_MESSAGE_CHANNEL_PRESSURE = 0xD, - MIDI_MESSAGE_PITCH_BEND = 0xE, -}; - -/** - * Input Modifier Status - * for keyboard/mouse events. - */ - -class InputEvent : public Resource { - GDCLASS(InputEvent, Resource); - - int device; - -protected: - static void _bind_methods(); - -public: - static const int DEVICE_ID_TOUCH_MOUSE; - static const int DEVICE_ID_INTERNAL; - - void set_device(int p_device); - int get_device() const; - - bool is_action(const StringName &p_action) const; - bool is_action_pressed(const StringName &p_action, bool p_allow_echo = false) const; - bool is_action_released(const StringName &p_action) const; - float get_action_strength(const StringName &p_action) const; - - // To be removed someday, since they do not make sense for all events - virtual bool is_pressed() const; - virtual bool is_echo() const; - // ...-. - - virtual String as_text() const; - - virtual Ref<InputEvent> xformed_by(const Transform2D &p_xform, const Vector2 &p_local_ofs = Vector2()) const; - - virtual bool action_match(const Ref<InputEvent> &p_event, bool *p_pressed, float *p_strength, float p_deadzone) const; - virtual bool shortcut_match(const Ref<InputEvent> &p_event) const; - virtual bool is_action_type() const; - - virtual bool accumulate(const Ref<InputEvent> &p_event) { return false; } - InputEvent(); -}; - -class InputEventWithModifiers : public InputEvent { - GDCLASS(InputEventWithModifiers, InputEvent); - - bool shift; - bool alt; -#ifdef APPLE_STYLE_KEYS - union { - bool command; - bool meta; //< windows/mac key - }; - - bool control; -#else - union { - bool command; //< windows/mac key - bool control; - }; - bool meta; //< windows/mac key - -#endif - -protected: - static void _bind_methods(); - -public: - void set_shift(bool p_enabled); - bool get_shift() const; - - void set_alt(bool p_enabled); - bool get_alt() const; - - void set_control(bool p_enabled); - bool get_control() const; - - void set_metakey(bool p_enabled); - bool get_metakey() const; - - void set_command(bool p_enabled); - bool get_command() const; - - void set_modifiers_from_event(const InputEventWithModifiers *event); - - InputEventWithModifiers(); -}; - -class InputEventKey : public InputEventWithModifiers { - - GDCLASS(InputEventKey, InputEventWithModifiers); - - bool pressed; /// otherwise release - - uint32_t scancode; ///< check keyboard.h , KeyCode enum, without modifier masks - uint32_t unicode; ///unicode - - bool echo; /// true if this is an echo key - -protected: - static void _bind_methods(); - -public: - void set_pressed(bool p_pressed); - virtual bool is_pressed() const; - - void set_scancode(uint32_t p_scancode); - uint32_t get_scancode() const; - - void set_unicode(uint32_t p_unicode); - uint32_t get_unicode() const; - - void set_echo(bool p_enable); - virtual bool is_echo() const; - - uint32_t get_scancode_with_modifiers() const; - - virtual bool action_match(const Ref<InputEvent> &p_event, bool *p_pressed, float *p_strength, float p_deadzone) const; - virtual bool shortcut_match(const Ref<InputEvent> &p_event) const; - - virtual bool is_action_type() const { return true; } - - virtual String as_text() const; - - InputEventKey(); -}; - -class InputEventMouse : public InputEventWithModifiers { - - GDCLASS(InputEventMouse, InputEventWithModifiers); - - int button_mask; - - Vector2 pos; - Vector2 global_pos; - -protected: - static void _bind_methods(); - -public: - void set_button_mask(int p_mask); - int get_button_mask() const; - - void set_position(const Vector2 &p_pos); - Vector2 get_position() const; - - void set_global_position(const Vector2 &p_global_pos); - Vector2 get_global_position() const; - - InputEventMouse(); -}; - -class InputEventMouseButton : public InputEventMouse { - - GDCLASS(InputEventMouseButton, InputEventMouse); - - float factor; - int button_index; - bool pressed; //otherwise released - bool doubleclick; //last even less than doubleclick time - -protected: - static void _bind_methods(); - -public: - void set_factor(float p_factor); - float get_factor(); - - void set_button_index(int p_index); - int get_button_index() const; - - void set_pressed(bool p_pressed); - virtual bool is_pressed() const; - - void set_doubleclick(bool p_doubleclick); - bool is_doubleclick() const; - - virtual Ref<InputEvent> xformed_by(const Transform2D &p_xform, const Vector2 &p_local_ofs = Vector2()) const; - virtual bool action_match(const Ref<InputEvent> &p_event, bool *p_pressed, float *p_strength, float p_deadzone) const; - - virtual bool is_action_type() const { return true; } - virtual String as_text() const; - - InputEventMouseButton(); -}; - -class InputEventMouseMotion : public InputEventMouse { - - GDCLASS(InputEventMouseMotion, InputEventMouse); - - Vector2 tilt; - float pressure; - Vector2 relative; - Vector2 speed; - -protected: - static void _bind_methods(); - -public: - void set_tilt(const Vector2 &p_tilt); - Vector2 get_tilt() const; - - void set_pressure(float p_pressure); - float get_pressure() const; - - void set_relative(const Vector2 &p_relative); - Vector2 get_relative() const; - - void set_speed(const Vector2 &p_speed); - Vector2 get_speed() const; - - virtual Ref<InputEvent> xformed_by(const Transform2D &p_xform, const Vector2 &p_local_ofs = Vector2()) const; - virtual String as_text() const; - - virtual bool accumulate(const Ref<InputEvent> &p_event); - - InputEventMouseMotion(); -}; - -class InputEventJoypadMotion : public InputEvent { - - GDCLASS(InputEventJoypadMotion, InputEvent); - int axis; ///< Joypad axis - float axis_value; ///< -1 to 1 - -protected: - static void _bind_methods(); - -public: - void set_axis(int p_axis); - int get_axis() const; - - void set_axis_value(float p_value); - float get_axis_value() const; - - virtual bool is_pressed() const; - - virtual bool action_match(const Ref<InputEvent> &p_event, bool *p_pressed, float *p_strength, float p_deadzone) const; - - virtual bool is_action_type() const { return true; } - virtual String as_text() const; - - InputEventJoypadMotion(); -}; - -class InputEventJoypadButton : public InputEvent { - GDCLASS(InputEventJoypadButton, InputEvent); - - int button_index; - bool pressed; - float pressure; //0 to 1 -protected: - static void _bind_methods(); - -public: - void set_button_index(int p_index); - int get_button_index() const; - - void set_pressed(bool p_pressed); - virtual bool is_pressed() const; - - void set_pressure(float p_pressure); - float get_pressure() const; - - virtual bool action_match(const Ref<InputEvent> &p_event, bool *p_pressed, float *p_strength, float p_deadzone) const; - virtual bool shortcut_match(const Ref<InputEvent> &p_event) const; - - virtual bool is_action_type() const { return true; } - virtual String as_text() const; - - InputEventJoypadButton(); -}; - -class InputEventScreenTouch : public InputEvent { - GDCLASS(InputEventScreenTouch, InputEvent); - int index; - Vector2 pos; - bool pressed; - -protected: - static void _bind_methods(); - -public: - void set_index(int p_index); - int get_index() const; - - void set_position(const Vector2 &p_pos); - Vector2 get_position() const; - - void set_pressed(bool p_pressed); - virtual bool is_pressed() const; - - virtual Ref<InputEvent> xformed_by(const Transform2D &p_xform, const Vector2 &p_local_ofs = Vector2()) const; - virtual String as_text() const; - - InputEventScreenTouch(); -}; - -class InputEventScreenDrag : public InputEvent { - - GDCLASS(InputEventScreenDrag, InputEvent); - int index; - Vector2 pos; - Vector2 relative; - Vector2 speed; - -protected: - static void _bind_methods(); - -public: - void set_index(int p_index); - int get_index() const; - - void set_position(const Vector2 &p_pos); - Vector2 get_position() const; - - void set_relative(const Vector2 &p_relative); - Vector2 get_relative() const; - - void set_speed(const Vector2 &p_speed); - Vector2 get_speed() const; - - virtual Ref<InputEvent> xformed_by(const Transform2D &p_xform, const Vector2 &p_local_ofs = Vector2()) const; - virtual String as_text() const; - - InputEventScreenDrag(); -}; - -class InputEventAction : public InputEvent { - - GDCLASS(InputEventAction, InputEvent); - - StringName action; - bool pressed; - float strength; - -protected: - static void _bind_methods(); - -public: - void set_action(const StringName &p_action); - StringName get_action() const; - - void set_pressed(bool p_pressed); - virtual bool is_pressed() const; - - void set_strength(float p_strength); - float get_strength() const; - - virtual bool is_action(const StringName &p_action) const; - - virtual bool action_match(const Ref<InputEvent> &p_event, bool *p_pressed, float *p_strength, float p_deadzone) const; - - virtual bool shortcut_match(const Ref<InputEvent> &p_event) const; - virtual bool is_action_type() const { return true; } - virtual String as_text() const; - - InputEventAction(); -}; - -class InputEventGesture : public InputEventWithModifiers { - - GDCLASS(InputEventGesture, InputEventWithModifiers); - - Vector2 pos; - -protected: - static void _bind_methods(); - -public: - void set_position(const Vector2 &p_pos); - Vector2 get_position() const; -}; - -class InputEventMagnifyGesture : public InputEventGesture { - - GDCLASS(InputEventMagnifyGesture, InputEventGesture); - real_t factor; - -protected: - static void _bind_methods(); - -public: - void set_factor(real_t p_factor); - real_t get_factor() const; - - virtual Ref<InputEvent> xformed_by(const Transform2D &p_xform, const Vector2 &p_local_ofs = Vector2()) const; - virtual String as_text() const; - - InputEventMagnifyGesture(); -}; - -class InputEventPanGesture : public InputEventGesture { - - GDCLASS(InputEventPanGesture, InputEventGesture); - Vector2 delta; - -protected: - static void _bind_methods(); - -public: - void set_delta(const Vector2 &p_delta); - Vector2 get_delta() const; - - virtual Ref<InputEvent> xformed_by(const Transform2D &p_xform, const Vector2 &p_local_ofs = Vector2()) const; - virtual String as_text() const; - - InputEventPanGesture(); -}; - -class InputEventMIDI : public InputEvent { - GDCLASS(InputEventMIDI, InputEvent); - - int channel; - int message; - int pitch; - int velocity; - int instrument; - int pressure; - int controller_number; - int controller_value; - -protected: - static void _bind_methods(); - -public: - void set_channel(const int p_channel); - int get_channel() const; - - void set_message(const int p_message); - int get_message() const; - - void set_pitch(const int p_pitch); - int get_pitch() const; - - void set_velocity(const int p_velocity); - int get_velocity() const; - - void set_instrument(const int p_instrument); - int get_instrument() const; - - void set_pressure(const int p_pressure); - int get_pressure() const; - - void set_controller_number(const int p_controller_number); - int get_controller_number() const; - - void set_controller_value(const int p_controller_value); - int get_controller_value() const; - - virtual String as_text() const; - - InputEventMIDI(); -}; - -#endif diff --git a/core/os/keyboard.cpp b/core/os/keyboard.cpp index 7141423c77..d088151a6d 100644 --- a/core/os/keyboard.cpp +++ b/core/os/keyboard.cpp @@ -288,14 +288,12 @@ static const _KeyCodeText _keycodes[] = { {KEY_DIVISION ,"Division"}, {KEY_YDIAERESIS ,"Ydiaeresis"}, - {0 ,0} + {0 ,nullptr} /* clang-format on */ }; bool keycode_has_unicode(uint32_t p_keycode) { - switch (p_keycode) { - case KEY_ESCAPE: case KEY_TAB: case KEY_BACKTAB: @@ -394,7 +392,6 @@ bool keycode_has_unicode(uint32_t p_keycode) { } String keycode_get_string(uint32_t p_code) { - String codestr; if (p_code & KEY_MASK_SHIFT) { codestr += find_keycode_name(KEY_SHIFT); @@ -418,9 +415,7 @@ String keycode_get_string(uint32_t p_code) { const _KeyCodeText *kct = &_keycodes[0]; while (kct->text) { - if (kct->code == (int)p_code) { - codestr += kct->text; return codestr; } @@ -433,11 +428,9 @@ String keycode_get_string(uint32_t p_code) { } int find_keycode(const String &p_code) { - const _KeyCodeText *kct = &_keycodes[0]; while (kct->text) { - if (p_code.nocasecmp_to(kct->text) == 0) { return kct->code; } @@ -448,11 +441,9 @@ int find_keycode(const String &p_code) { } const char *find_keycode_name(int p_keycode) { - const _KeyCodeText *kct = &_keycodes[0]; while (kct->text) { - if (kct->code == p_keycode) { return kct->text; } @@ -463,12 +454,10 @@ const char *find_keycode_name(int p_keycode) { } int keycode_get_count() { - const _KeyCodeText *kct = &_keycodes[0]; int count = 0; while (kct->text) { - count++; kct++; } diff --git a/core/os/keyboard.h b/core/os/keyboard.h index bac32e01dd..5d11e6a378 100644 --- a/core/os/keyboard.h +++ b/core/os/keyboard.h @@ -325,4 +325,4 @@ int keycode_get_count(); int keycode_get_value_by_index(int p_index); const char *keycode_get_name_by_index(int p_index); -#endif +#endif // KEYBOARD_H diff --git a/core/os/main_loop.cpp b/core/os/main_loop.cpp index 5ecdd74a4b..434f6fa300 100644 --- a/core/os/main_loop.cpp +++ b/core/os/main_loop.cpp @@ -33,104 +33,62 @@ #include "core/script_language.h" void MainLoop::_bind_methods() { - - ClassDB::bind_method(D_METHOD("input_event", "event"), &MainLoop::input_event); - ClassDB::bind_method(D_METHOD("input_text", "text"), &MainLoop::input_text); ClassDB::bind_method(D_METHOD("init"), &MainLoop::init); ClassDB::bind_method(D_METHOD("iteration", "delta"), &MainLoop::iteration); ClassDB::bind_method(D_METHOD("idle", "delta"), &MainLoop::idle); ClassDB::bind_method(D_METHOD("finish"), &MainLoop::finish); - BIND_VMETHOD(MethodInfo("_input_event", PropertyInfo(Variant::OBJECT, "event", PROPERTY_HINT_RESOURCE_TYPE, "InputEvent"))); - BIND_VMETHOD(MethodInfo("_input_text", PropertyInfo(Variant::STRING, "text"))); BIND_VMETHOD(MethodInfo("_initialize")); - BIND_VMETHOD(MethodInfo(Variant::BOOL, "_iteration", PropertyInfo(Variant::REAL, "delta"))); - BIND_VMETHOD(MethodInfo(Variant::BOOL, "_idle", PropertyInfo(Variant::REAL, "delta"))); - BIND_VMETHOD(MethodInfo("_drop_files", PropertyInfo(Variant::POOL_STRING_ARRAY, "files"), PropertyInfo(Variant::INT, "from_screen"))); + BIND_VMETHOD(MethodInfo(Variant::BOOL, "_iteration", PropertyInfo(Variant::FLOAT, "delta"))); + BIND_VMETHOD(MethodInfo(Variant::BOOL, "_idle", PropertyInfo(Variant::FLOAT, "delta"))); BIND_VMETHOD(MethodInfo("_finalize")); - BIND_VMETHOD(MethodInfo("_global_menu_action", PropertyInfo(Variant::NIL, "id"), PropertyInfo(Variant::NIL, "meta"))); - - BIND_CONSTANT(NOTIFICATION_WM_MOUSE_ENTER); - BIND_CONSTANT(NOTIFICATION_WM_MOUSE_EXIT); - BIND_CONSTANT(NOTIFICATION_WM_FOCUS_IN); - BIND_CONSTANT(NOTIFICATION_WM_FOCUS_OUT); - BIND_CONSTANT(NOTIFICATION_WM_QUIT_REQUEST); - BIND_CONSTANT(NOTIFICATION_WM_GO_BACK_REQUEST); - BIND_CONSTANT(NOTIFICATION_WM_UNFOCUS_REQUEST); BIND_CONSTANT(NOTIFICATION_OS_MEMORY_WARNING); BIND_CONSTANT(NOTIFICATION_TRANSLATION_CHANGED); BIND_CONSTANT(NOTIFICATION_WM_ABOUT); BIND_CONSTANT(NOTIFICATION_CRASH); BIND_CONSTANT(NOTIFICATION_OS_IME_UPDATE); - BIND_CONSTANT(NOTIFICATION_APP_RESUMED); - BIND_CONSTANT(NOTIFICATION_APP_PAUSED); + BIND_CONSTANT(NOTIFICATION_APPLICATION_RESUMED); + BIND_CONSTANT(NOTIFICATION_APPLICATION_PAUSED); + BIND_CONSTANT(NOTIFICATION_APPLICATION_FOCUS_IN); + BIND_CONSTANT(NOTIFICATION_APPLICATION_FOCUS_OUT); ADD_SIGNAL(MethodInfo("on_request_permissions_result", PropertyInfo(Variant::STRING, "permission"), PropertyInfo(Variant::BOOL, "granted"))); }; void MainLoop::set_init_script(const Ref<Script> &p_init_script) { - init_script = p_init_script; } -MainLoop::MainLoop() { -} - -MainLoop::~MainLoop() { -} - -void MainLoop::input_text(const String &p_text) { - - if (get_script_instance()) - get_script_instance()->call("_input_text", p_text); -} - -void MainLoop::input_event(const Ref<InputEvent> &p_event) { - - if (get_script_instance()) - get_script_instance()->call("_input_event", p_event); -} - void MainLoop::init() { + if (init_script.is_valid()) { + set_script(init_script); + } - if (init_script.is_valid()) - set_script(init_script.get_ref_ptr()); - - if (get_script_instance()) + if (get_script_instance()) { get_script_instance()->call("_initialize"); + } } -bool MainLoop::iteration(float p_time) { - if (get_script_instance()) +bool MainLoop::iteration(float p_time) { + if (get_script_instance()) { return get_script_instance()->call("_iteration", p_time); + } return false; } -bool MainLoop::idle(float p_time) { - if (get_script_instance()) +bool MainLoop::idle(float p_time) { + if (get_script_instance()) { return get_script_instance()->call("_idle", p_time); + } return false; } -void MainLoop::drop_files(const Vector<String> &p_files, int p_from_screen) { - - if (get_script_instance()) - get_script_instance()->call("_drop_files", p_files, p_from_screen); -} - -void MainLoop::global_menu_action(const Variant &p_id, const Variant &p_meta) { - - if (get_script_instance()) - get_script_instance()->call("_global_menu_action", p_id, p_meta); -} - void MainLoop::finish() { - if (get_script_instance()) { get_script_instance()->call("_finalize"); - set_script(RefPtr()); //clear script + set_script(Variant()); //clear script } } diff --git a/core/os/main_loop.h b/core/os/main_loop.h index b1120aee8a..2c34cf193c 100644 --- a/core/os/main_loop.h +++ b/core/os/main_loop.h @@ -31,12 +31,11 @@ #ifndef MAIN_LOOP_H #define MAIN_LOOP_H -#include "core/os/input_event.h" +#include "core/input/input_event.h" #include "core/reference.h" #include "core/script_language.h" class MainLoop : public Object { - GDCLASS(MainLoop, Object); OBJ_CATEGORY("Main Loop"); @@ -48,37 +47,26 @@ protected: public: enum { //make sure these are replicated in Node - NOTIFICATION_WM_MOUSE_ENTER = 1002, - NOTIFICATION_WM_MOUSE_EXIT = 1003, - NOTIFICATION_WM_FOCUS_IN = 1004, - NOTIFICATION_WM_FOCUS_OUT = 1005, - NOTIFICATION_WM_QUIT_REQUEST = 1006, - NOTIFICATION_WM_GO_BACK_REQUEST = 1007, - NOTIFICATION_WM_UNFOCUS_REQUEST = 1008, - NOTIFICATION_OS_MEMORY_WARNING = 1009, - NOTIFICATION_TRANSLATION_CHANGED = 1010, - NOTIFICATION_WM_ABOUT = 1011, - NOTIFICATION_CRASH = 1012, - NOTIFICATION_OS_IME_UPDATE = 1013, - NOTIFICATION_APP_RESUMED = 1014, - NOTIFICATION_APP_PAUSED = 1015, + NOTIFICATION_OS_MEMORY_WARNING = 2009, + NOTIFICATION_TRANSLATION_CHANGED = 2010, + NOTIFICATION_WM_ABOUT = 2011, + NOTIFICATION_CRASH = 2012, + NOTIFICATION_OS_IME_UPDATE = 2013, + NOTIFICATION_APPLICATION_RESUMED = 2014, + NOTIFICATION_APPLICATION_PAUSED = 2015, + NOTIFICATION_APPLICATION_FOCUS_IN = 2016, + NOTIFICATION_APPLICATION_FOCUS_OUT = 2017, }; - virtual void input_event(const Ref<InputEvent> &p_event); - virtual void input_text(const String &p_text); - virtual void init(); virtual bool iteration(float p_time); virtual bool idle(float p_time); virtual void finish(); - virtual void drop_files(const Vector<String> &p_files, int p_from_screen = 0); - virtual void global_menu_action(const Variant &p_id, const Variant &p_meta); - void set_init_script(const Ref<Script> &p_init_script); - MainLoop(); - virtual ~MainLoop(); + MainLoop() {} + virtual ~MainLoop() {} }; -#endif +#endif // MAIN_LOOP_H diff --git a/core/os/memory.cpp b/core/os/memory.cpp index 39d3fce910..8457c52092 100644 --- a/core/os/memory.cpp +++ b/core/os/memory.cpp @@ -38,28 +38,23 @@ #include <stdlib.h> void *operator new(size_t p_size, const char *p_description) { - return Memory::alloc_static(p_size, false); } void *operator new(size_t p_size, void *(*p_allocfunc)(size_t p_size)) { - return p_allocfunc(p_size); } #ifdef _MSC_VER void operator delete(void *p_mem, const char *p_description) { - CRASH_NOW_MSG("Call to placement delete should not happen."); } void operator delete(void *p_mem, void *(*p_allocfunc)(size_t p_size)) { - CRASH_NOW_MSG("Call to placement delete should not happen."); } void operator delete(void *p_mem, void *p_pointer, size_t check, const char *p_description) { - CRASH_NOW_MSG("Call to placement delete should not happen."); } #endif @@ -72,7 +67,6 @@ uint64_t Memory::max_usage = 0; uint64_t Memory::alloc_count = 0; void *Memory::alloc_static(size_t p_bytes, bool p_pad_align) { - #ifdef DEBUG_ENABLED bool prepad = true; #else @@ -81,7 +75,7 @@ void *Memory::alloc_static(size_t p_bytes, bool p_pad_align) { void *mem = malloc(p_bytes + (prepad ? PAD_ALIGN : 0)); - ERR_FAIL_COND_V(!mem, NULL); + ERR_FAIL_COND_V(!mem, nullptr); atomic_increment(&alloc_count); @@ -102,8 +96,7 @@ void *Memory::alloc_static(size_t p_bytes, bool p_pad_align) { } void *Memory::realloc_static(void *p_memory, size_t p_bytes, bool p_pad_align) { - - if (p_memory == NULL) { + if (p_memory == nullptr) { return alloc_static(p_bytes, p_pad_align); } @@ -130,12 +123,12 @@ void *Memory::realloc_static(void *p_memory, size_t p_bytes, bool p_pad_align) { if (p_bytes == 0) { free(mem); - return NULL; + return nullptr; } else { *s = p_bytes; mem = (uint8_t *)realloc(mem, p_bytes + PAD_ALIGN); - ERR_FAIL_COND_V(!mem, NULL); + ERR_FAIL_COND_V(!mem, nullptr); s = (uint64_t *)mem; @@ -144,18 +137,16 @@ void *Memory::realloc_static(void *p_memory, size_t p_bytes, bool p_pad_align) { return mem + PAD_ALIGN; } } else { - mem = (uint8_t *)realloc(mem, p_bytes); - ERR_FAIL_COND_V(mem == NULL && p_bytes > 0, NULL); + ERR_FAIL_COND_V(mem == nullptr && p_bytes > 0, nullptr); return mem; } } void Memory::free_static(void *p_ptr, bool p_pad_align) { - - ERR_FAIL_COND(p_ptr == NULL); + ERR_FAIL_COND(p_ptr == nullptr); uint8_t *mem = (uint8_t *)p_ptr; @@ -177,13 +168,11 @@ void Memory::free_static(void *p_ptr, bool p_pad_align) { free(mem); } else { - free(mem); } } uint64_t Memory::get_mem_available() { - return -1; // 0xFFFF... } @@ -204,8 +193,6 @@ uint64_t Memory::get_mem_max_usage() { } _GlobalNil::_GlobalNil() { - - color = 1; left = this; right = this; parent = this; diff --git a/core/os/memory.h b/core/os/memory.h index e45f97e0c8..46ffb4124b 100644 --- a/core/os/memory.h +++ b/core/os/memory.h @@ -41,7 +41,6 @@ #endif class Memory { - Memory(); #ifdef DEBUG_ENABLED static uint64_t mem_usage; @@ -87,7 +86,6 @@ _ALWAYS_INLINE_ void postinitialize_handler(void *) {} template <class T> _ALWAYS_INLINE_ T *_post_initialize(T *p_obj) { - postinitialize_handler(p_obj); return p_obj; } @@ -110,44 +108,48 @@ _ALWAYS_INLINE_ bool predelete_handler(void *) { template <class T> void memdelete(T *p_class) { - - if (!predelete_handler(p_class)) + if (!predelete_handler(p_class)) { return; // doesn't want to be deleted - if (!__has_trivial_destructor(T)) + } + if (!__has_trivial_destructor(T)) { p_class->~T(); + } Memory::free_static(p_class, false); } template <class T, class A> void memdelete_allocator(T *p_class) { - - if (!predelete_handler(p_class)) + if (!predelete_handler(p_class)) { return; // doesn't want to be deleted - if (!__has_trivial_destructor(T)) + } + if (!__has_trivial_destructor(T)) { p_class->~T(); + } A::free(p_class); } -#define memdelete_notnull(m_v) \ - { \ - if (m_v) memdelete(m_v); \ +#define memdelete_notnull(m_v) \ + { \ + if (m_v) { \ + memdelete(m_v); \ + } \ } #define memnew_arr(m_class, m_count) memnew_arr_template<m_class>(m_count) template <typename T> T *memnew_arr_template(size_t p_elements, const char *p_descr = "") { - - if (p_elements == 0) - return 0; + if (p_elements == 0) { + return nullptr; + } /** overloading operator new[] cannot be done , because it may not return the real allocated address (it may pad the 'element count' before the actual array). Because of that, it must be done by hand. This is the - same strategy used by std::vector, and the PoolVector class, so it should be safe.*/ + same strategy used by std::vector, and the Vector class, so it should be safe.*/ size_t len = sizeof(T) * p_elements; uint64_t *mem = (uint64_t *)Memory::alloc_static(len, true); - T *failptr = 0; //get rid of a warning + T *failptr = nullptr; //get rid of a warning ERR_FAIL_COND_V(!mem, failptr); *(mem - 1) = p_elements; @@ -170,14 +172,12 @@ T *memnew_arr_template(size_t p_elements, const char *p_descr = "") { template <typename T> size_t memarr_len(const T *p_class) { - uint64_t *ptr = (uint64_t *)p_class; return *(ptr - 1); } template <typename T> void memdelete_arr(T *p_class) { - uint64_t *ptr = (uint64_t *)p_class; if (!__has_trivial_destructor(T)) { @@ -192,8 +192,7 @@ void memdelete_arr(T *p_class) { } struct _GlobalNil { - - int color; + int color = 1; _GlobalNil *right; _GlobalNil *left; _GlobalNil *parent; @@ -202,8 +201,7 @@ struct _GlobalNil { }; struct _GlobalNilClass { - static _GlobalNil _nil; }; -#endif +#endif // MEMORY_H diff --git a/core/os/midi_driver.cpp b/core/os/midi_driver.cpp index 3e020a1585..e9919aeb86 100644 --- a/core/os/midi_driver.cpp +++ b/core/os/midi_driver.cpp @@ -30,23 +30,20 @@ #include "midi_driver.h" +#include "core/input/input.h" #include "core/os/os.h" -#include "main/input_default.h" uint8_t MIDIDriver::last_received_message = 0x00; -MIDIDriver *MIDIDriver::singleton = NULL; +MIDIDriver *MIDIDriver::singleton = nullptr; MIDIDriver *MIDIDriver::get_singleton() { - return singleton; } void MIDIDriver::set_singleton() { - singleton = this; } void MIDIDriver::receive_input_packet(uint64_t timestamp, uint8_t *data, uint32_t length) { - Ref<InputEventMIDI> event; event.instance(); uint32_t param_position = 1; @@ -117,17 +114,15 @@ void MIDIDriver::receive_input_packet(uint64_t timestamp, uint8_t *data, uint32_ break; } - InputDefault *id = Object::cast_to<InputDefault>(Input::get_singleton()); + Input *id = Input::get_singleton(); id->parse_input_event(event); } -PoolStringArray MIDIDriver::get_connected_inputs() { - - PoolStringArray list; +PackedStringArray MIDIDriver::get_connected_inputs() { + PackedStringArray list; return list; } MIDIDriver::MIDIDriver() { - set_singleton(); } diff --git a/core/os/midi_driver.h b/core/os/midi_driver.h index 26dbdce151..bc922e1fcf 100644 --- a/core/os/midi_driver.h +++ b/core/os/midi_driver.h @@ -39,7 +39,6 @@ */ class MIDIDriver { - static MIDIDriver *singleton; static uint8_t last_received_message; @@ -50,7 +49,7 @@ public: virtual Error open() = 0; virtual void close() = 0; - virtual PoolStringArray get_connected_inputs(); + virtual PackedStringArray get_connected_inputs(); static void receive_input_packet(uint64_t timestamp, uint8_t *data, uint32_t length); @@ -58,4 +57,4 @@ public: virtual ~MIDIDriver() {} }; -#endif +#endif // MIDI_DRIVER_H diff --git a/core/os/mutex.cpp b/core/os/mutex.cpp index f099b4319a..31a0dc2bfa 100644 --- a/core/os/mutex.cpp +++ b/core/os/mutex.cpp @@ -30,31 +30,21 @@ #include "mutex.h" -#include "core/error_macros.h" +static Mutex _global_mutex; -#include <stddef.h> - -Mutex *(*Mutex::create_func)(bool) = 0; - -Mutex *Mutex::create(bool p_recursive) { - - ERR_FAIL_COND_V(!create_func, 0); - - return create_func(p_recursive); +void _global_lock() { + _global_mutex.lock(); } -Mutex::~Mutex() { +void _global_unlock() { + _global_mutex.unlock(); } -Mutex *_global_mutex = NULL; +#ifndef NO_THREADS -void _global_lock() { +template class MutexImpl<std::recursive_mutex>; +template class MutexImpl<std::mutex>; +template class MutexLock<MutexImpl<std::recursive_mutex>>; +template class MutexLock<MutexImpl<std::mutex>>; - if (_global_mutex) - _global_mutex->lock(); -} -void _global_unlock() { - - if (_global_mutex) - _global_mutex->unlock(); -} +#endif diff --git a/core/os/mutex.h b/core/os/mutex.h index db82eb64f5..d42cbed821 100644 --- a/core/os/mutex.h +++ b/core/os/mutex.h @@ -32,42 +32,76 @@ #define MUTEX_H #include "core/error_list.h" +#include "core/typedefs.h" -/** - * @class Mutex - * @author Juan Linietsky - * Portable Mutex (thread-safe locking) implementation. - * Mutexes are always recursive ( they don't self-lock in a single thread ). - * Mutexes can be used with a Lockp object like this, to avoid having to worry about unlocking: - * Lockp( mutex ); - */ +#if !defined(NO_THREADS) -class Mutex { -protected: - static Mutex *(*create_func)(bool); +#include <mutex> + +template <class StdMutexT> +class MutexImpl { + mutable StdMutexT mutex; public: - virtual void lock() = 0; ///< Lock the mutex, block if locked by someone else - virtual void unlock() = 0; ///< Unlock the mutex, let other threads continue - virtual Error try_lock() = 0; ///< Attempt to lock the mutex, OK on success, ERROR means it can't lock. + _ALWAYS_INLINE_ void lock() const { + mutex.lock(); + } - static Mutex *create(bool p_recursive = true); ///< Create a mutex + _ALWAYS_INLINE_ void unlock() const { + mutex.unlock(); + } - virtual ~Mutex(); + _ALWAYS_INLINE_ Error try_lock() const { + return mutex.try_lock() ? OK : ERR_BUSY; + } }; +template <class MutexT> class MutexLock { - - Mutex *mutex; + const MutexT &mutex; public: - MutexLock(Mutex *p_mutex) { - mutex = p_mutex; - if (mutex) mutex->lock(); + _ALWAYS_INLINE_ explicit MutexLock(const MutexT &p_mutex) : + mutex(p_mutex) { + mutex.lock(); } - ~MutexLock() { - if (mutex) mutex->unlock(); + + _ALWAYS_INLINE_ ~MutexLock() { + mutex.unlock(); } }; -#endif +using Mutex = MutexImpl<std::recursive_mutex>; // Recursive, for general use +using BinaryMutex = MutexImpl<std::mutex>; // Non-recursive, handle with care + +extern template class MutexImpl<std::recursive_mutex>; +extern template class MutexImpl<std::mutex>; +extern template class MutexLock<MutexImpl<std::recursive_mutex>>; +extern template class MutexLock<MutexImpl<std::mutex>>; + +#else + +class FakeMutex { + FakeMutex() {} +}; + +template <class MutexT> +class MutexImpl { +public: + _ALWAYS_INLINE_ void lock() const {} + _ALWAYS_INLINE_ void unlock() const {} + _ALWAYS_INLINE_ Error try_lock() const { return OK; } +}; + +template <class MutexT> +class MutexLock { +public: + explicit MutexLock(const MutexT &p_mutex) {} +}; + +using Mutex = MutexImpl<FakeMutex>; +using BinaryMutex = MutexImpl<FakeMutex>; // Non-recursive, handle with care + +#endif // !NO_THREADS + +#endif // MUTEX_H diff --git a/core/os/os.cpp b/core/os/os.cpp index 1ed9484208..dc8bd5ee69 100644 --- a/core/os/os.cpp +++ b/core/os/os.cpp @@ -30,9 +30,9 @@ #include "os.h" +#include "core/input/input.h" #include "core/os/dir_access.h" #include "core/os/file_access.h" -#include "core/os/input.h" #include "core/os/midi_driver.h" #include "core/project_settings.h" #include "core/version_generated.gen.h" @@ -40,10 +40,10 @@ #include <stdarg.h> -OS *OS::singleton = NULL; +OS *OS::singleton = nullptr; +uint64_t OS::target_ticks = 0; OS *OS::get_singleton() { - return singleton; } @@ -83,20 +83,14 @@ String OS::get_iso_date_time(bool local) const { uint64_t OS::get_splash_tick_msec() const { return _msec_splash; } -uint64_t OS::get_unix_time() const { - return 0; -}; -uint64_t OS::get_system_time_secs() const { - return 0; -} -uint64_t OS::get_system_time_msecs() const { +double OS::get_unix_time() const { return 0; } -void OS::debug_break(){ +void OS::debug_break() { // something -}; +} void OS::_set_logger(CompositeLogger *p_logger) { if (_logger) { @@ -116,19 +110,17 @@ void OS::add_logger(Logger *p_logger) { } void OS::print_error(const char *p_function, const char *p_file, int p_line, const char *p_code, const char *p_rationale, Logger::ErrorType p_type) { - _logger->log_error(p_function, p_file, p_line, p_code, p_rationale, p_type); } void OS::print(const char *p_format, ...) { - va_list argp; va_start(argp, p_format); _logger->logv(p_format, argp, false); va_end(argp); -}; +} void OS::printerr(const char *p_format, ...) { va_list argp; @@ -137,119 +129,71 @@ void OS::printerr(const char *p_format, ...) { _logger->logv(p_format, argp, true); va_end(argp); -}; - -void OS::set_keep_screen_on(bool p_enabled) { - _keep_screen_on = p_enabled; -} - -bool OS::is_keep_screen_on() const { - return _keep_screen_on; } void OS::set_low_processor_usage_mode(bool p_enabled) { - low_processor_usage_mode = p_enabled; } bool OS::is_in_low_processor_usage_mode() const { - return low_processor_usage_mode; } void OS::set_low_processor_usage_mode_sleep_usec(int p_usec) { - low_processor_usage_mode_sleep_usec = p_usec; } int OS::get_low_processor_usage_mode_sleep_usec() const { - return low_processor_usage_mode_sleep_usec; } -void OS::set_clipboard(const String &p_text) { - - _local_clipboard = p_text; -} -String OS::get_clipboard() const { - - return _local_clipboard; -} - String OS::get_executable_path() const { - return _execpath; } int OS::get_process_id() const { - return -1; -}; +} void OS::vibrate_handheld(int p_duration_ms) { - - WARN_PRINTS("vibrate_handheld() only works with Android and iOS"); + WARN_PRINT("vibrate_handheld() only works with Android and iOS"); } bool OS::is_stdout_verbose() const { - return _verbose_stdout; } -void OS::dump_memory_to_file(const char *p_file) { +bool OS::is_stdout_debug_enabled() const { + return _debug_stdout; +} +void OS::dump_memory_to_file(const char *p_file) { //Memory::dump_static_mem_to_file(p_file); } -static FileAccess *_OSPRF = NULL; +static FileAccess *_OSPRF = nullptr; static void _OS_printres(Object *p_obj) { - Resource *res = Object::cast_to<Resource>(p_obj); - if (!res) + if (!res) { return; + } String str = itos(res->get_instance_id()) + String(res->get_class()) + ":" + String(res->get_name()) + " - " + res->get_path(); - if (_OSPRF) + if (_OSPRF) { _OSPRF->store_line(str); - else + } else { print_line(str); -} - -bool OS::has_virtual_keyboard() const { - - return false; -} - -void OS::show_virtual_keyboard(const String &p_existing_text, const Rect2 &p_screen_rect, int p_max_input_length) { -} - -void OS::hide_virtual_keyboard() { -} - -int OS::get_virtual_keyboard_height() const { - return 0; -} - -void OS::set_cursor_shape(CursorShape p_shape) { -} - -OS::CursorShape OS::get_cursor_shape() const { - return CURSOR_ARROW; -} - -void OS::set_custom_mouse_cursor(const RES &p_cursor, CursorShape p_shape, const Vector2 &p_hotspot) { + } } void OS::print_all_resources(String p_to_file) { - ERR_FAIL_COND(p_to_file != "" && _OSPRF); if (p_to_file != "") { - Error err; _OSPRF = FileAccess::open(p_to_file, FileAccess::WRITE, &err); if (err != OK) { - _OSPRF = NULL; + _OSPRF = nullptr; ERR_FAIL_MSG("Can't print all resources to file: " + String(p_to_file) + "."); } } @@ -257,50 +201,43 @@ void OS::print_all_resources(String p_to_file) { ObjectDB::debug_objects(_OS_printres); if (p_to_file != "") { - - if (_OSPRF) + if (_OSPRF) { memdelete(_OSPRF); - _OSPRF = NULL; + } + _OSPRF = nullptr; } } void OS::print_resources_in_use(bool p_short) { - - ResourceCache::dump(NULL, p_short); + ResourceCache::dump(nullptr, p_short); } void OS::dump_resources_to_file(const char *p_file) { - ResourceCache::dump(p_file); } void OS::set_no_window_mode(bool p_enable) { - _no_window = p_enable; } bool OS::is_no_window_mode_enabled() const { - return _no_window; } int OS::get_exit_code() const { - return _exit_code; } -void OS::set_exit_code(int p_code) { +void OS::set_exit_code(int p_code) { _exit_code = p_code; } String OS::get_locale() const { - return "en"; } // Helper function to ensure that a dir name/path will be valid on the OS String OS::get_safe_dir_name(const String &p_dir_name, bool p_allow_dir_separator) const { - Vector<String> invalid_chars = String(": * ? \" < > |").split(" "); if (p_allow_dir_separator) { // Dir separators are allowed, but disallow ".." to avoid going up the filesystem @@ -320,143 +257,71 @@ String OS::get_safe_dir_name(const String &p_dir_name, bool p_allow_dir_separato // Get properly capitalized engine name for system paths String OS::get_godot_dir_name() const { - // Default to lowercase, so only override when different case is needed return String(VERSION_SHORT_NAME).to_lower(); } // OS equivalent of XDG_DATA_HOME String OS::get_data_path() const { - return "."; } // OS equivalent of XDG_CONFIG_HOME String OS::get_config_path() const { - return "."; } // OS equivalent of XDG_CACHE_HOME String OS::get_cache_path() const { - return "."; } // Path to macOS .app bundle resources String OS::get_bundle_resource_dir() const { - return "."; -}; +} // OS specific path for user:// String OS::get_user_data_dir() const { - return "."; -}; +} // Absolute path to res:// String OS::get_resource_dir() const { - return ProjectSettings::get_singleton()->get_resource_path(); } // Access system-specific dirs like Documents, Downloads, etc. String OS::get_system_dir(SystemDir p_dir) const { - return "."; } Error OS::shell_open(String p_uri) { return ERR_UNAVAILABLE; -}; +} // implement these with the canvas? -Error OS::dialog_show(String p_title, String p_description, Vector<String> p_buttons, Object *p_obj, String p_callback) { - - while (true) { - - print("%ls\n--------\n%ls\n", p_title.c_str(), p_description.c_str()); - for (int i = 0; i < p_buttons.size(); i++) { - if (i > 0) print(", "); - print("%i=%ls", i + 1, p_buttons[i].c_str()); - }; - print("\n"); - String res = get_stdin_string().strip_edges(); - if (!res.is_numeric()) - continue; - int n = res.to_int(); - if (n < 0 || n >= p_buttons.size()) - continue; - if (p_obj && p_callback != "") - p_obj->call_deferred(p_callback, n); - break; - }; - return OK; -}; - -Error OS::dialog_input_text(String p_title, String p_description, String p_partial, Object *p_obj, String p_callback) { - - ERR_FAIL_COND_V(!p_obj, FAILED); - ERR_FAIL_COND_V(p_callback == "", FAILED); - print("%ls\n---------\n%ls\n[%ls]:\n", p_title.c_str(), p_description.c_str(), p_partial.c_str()); - - String res = get_stdin_string().strip_edges(); - bool success = true; - if (res == "") { - res = p_partial; - }; - - p_obj->call_deferred(p_callback, success, res); - - return OK; -}; uint64_t OS::get_static_memory_usage() const { - return Memory::get_mem_usage(); } -uint64_t OS::get_dynamic_memory_usage() const { - - return MemoryPool::total_memory; -} uint64_t OS::get_static_memory_peak_usage() const { - return Memory::get_mem_max_usage(); } Error OS::set_cwd(const String &p_cwd) { - return ERR_CANT_OPEN; } -bool OS::has_touchscreen_ui_hint() const { - - //return false; - return Input::get_singleton() && Input::get_singleton()->is_emulating_touch_from_mouse(); -} - uint64_t OS::get_free_static_memory() const { - return Memory::get_mem_available(); } void OS::yield() { } -void OS::set_screen_orientation(ScreenOrientation p_orientation) { - - _orientation = p_orientation; -} - -OS::ScreenOrientation OS::get_screen_orientation() const { - - return (OS::ScreenOrientation)_orientation; -} - -void OS::_ensure_user_data_dir() { - +void OS::ensure_user_data_dir() { String dd = get_user_data_dir(); DirAccess *da = DirAccess::open(dd); if (da) { @@ -471,69 +336,24 @@ void OS::_ensure_user_data_dir() { memdelete(da); } -void OS::set_native_icon(const String &p_filename) { -} - -void OS::set_icon(const Ref<Image> &p_icon) { -} - String OS::get_model_name() const { - return "GenericDevice"; } void OS::set_cmdline(const char *p_execpath, const List<String> &p_args) { - _execpath = p_execpath; _cmdline = p_args; -}; - -void OS::release_rendering_thread() { -} - -void OS::make_rendering_thread() { -} - -void OS::swap_buffers() { } String OS::get_unique_id() const { - ERR_FAIL_V(""); } int OS::get_processor_count() const { - return 1; } -Error OS::native_video_play(String p_path, float p_volume, String p_audio_track, String p_subtitle_track) { - - return FAILED; -}; - -bool OS::native_video_is_playing() const { - - return false; -}; - -void OS::native_video_pause(){ - -}; - -void OS::native_video_unpause(){ - -}; - -void OS::native_video_stop(){ - -}; - -void OS::set_mouse_mode(MouseMode p_mode) { -} - bool OS::can_use_threads() const { - #ifdef NO_THREADS return false; #else @@ -541,80 +361,26 @@ bool OS::can_use_threads() const { #endif } -OS::MouseMode OS::get_mouse_mode() const { - - return MOUSE_MODE_VISIBLE; -} - -OS::LatinKeyboardVariant OS::get_latin_keyboard_variant() const { - - return LATIN_KEYBOARD_QWERTY; -} - -bool OS::is_joy_known(int p_device) { - return true; -} - -String OS::get_joy_guid(int p_device) const { - return "Default Joypad"; -} - -void OS::set_context(int p_context) { -} - -OS::SwitchVSyncCallbackInThread OS::switch_vsync_function = NULL; - -void OS::set_use_vsync(bool p_enable) { - _use_vsync = p_enable; - if (switch_vsync_function) { //if a function was set, use function - switch_vsync_function(p_enable); - } else { //otherwise just call here - _set_use_vsync(p_enable); - } -} - -bool OS::is_vsync_enabled() const { - - return _use_vsync; -} - -void OS::set_vsync_via_compositor(bool p_enable) { - _vsync_via_compositor = p_enable; -} - -bool OS::is_vsync_via_compositor_enabled() const { - return _vsync_via_compositor; -} - -OS::PowerState OS::get_power_state() { - return POWERSTATE_UNKNOWN; -} -int OS::get_power_seconds_left() { - return -1; -} -int OS::get_power_percent_left() { - return -1; -} - void OS::set_has_server_feature_callback(HasServerFeatureCallback p_callback) { - has_server_feature_callback = p_callback; } bool OS::has_feature(const String &p_feature) { - - if (p_feature == get_name()) + if (p_feature == get_name()) { return true; + } #ifdef DEBUG_ENABLED - if (p_feature == "debug") + if (p_feature == "debug") { return true; + } #else if (p_feature == "release") return true; #endif #ifdef TOOLS_ENABLED - if (p_feature == "editor") + if (p_feature == "editor") { return true; + } #else if (p_feature == "standalone") return true; @@ -654,59 +420,19 @@ bool OS::has_feature(const String &p_feature) { } #endif - if (_check_internal_feature_support(p_feature)) + if (_check_internal_feature_support(p_feature)) { return true; + } if (has_server_feature_callback && has_server_feature_callback(p_feature)) { return true; } - if (ProjectSettings::get_singleton()->has_custom_feature(p_feature)) + if (ProjectSettings::get_singleton()->has_custom_feature(p_feature)) { return true; - - return false; -} - -void OS::center_window() { - - if (is_window_fullscreen()) return; - - Point2 sp = get_screen_position(get_current_screen()); - Size2 scr = get_screen_size(get_current_screen()); - Size2 wnd = get_real_window_size(); - - int x = sp.width + (scr.width - wnd.width) / 2; - int y = sp.height + (scr.height - wnd.height) / 2; - - set_window_position(Vector2(x, y)); -} - -int OS::get_video_driver_count() const { - - return 2; -} - -const char *OS::get_video_driver_name(int p_driver) const { - - switch (p_driver) { - case VIDEO_DRIVER_GLES2: - return "GLES2"; - case VIDEO_DRIVER_GLES3: - default: - return "GLES3"; } -} - -int OS::get_audio_driver_count() const { - - return AudioDriverManager::get_driver_count(); -} -const char *OS::get_audio_driver_name(int p_driver) const { - - AudioDriver *driver = AudioDriverManager::get_driver(p_driver); - ERR_FAIL_COND_V_MSG(!driver, "", "Cannot get audio driver at index '" + itos(p_driver) + "'."); - return AudioDriverManager::get_driver(p_driver)->get_name(); + return false; } void OS::set_restart_on_exit(bool p_restart, const List<String> &p_restart_arguments) { @@ -722,49 +448,72 @@ List<String> OS::get_restart_on_exit_arguments() const { return restart_commandline; } -PoolStringArray OS::get_connected_midi_inputs() { - - if (MIDIDriver::get_singleton()) +PackedStringArray OS::get_connected_midi_inputs() { + if (MIDIDriver::get_singleton()) { return MIDIDriver::get_singleton()->get_connected_inputs(); + } - PoolStringArray list; - return list; + PackedStringArray list; + ERR_FAIL_V_MSG(list, vformat("MIDI input isn't supported on %s.", OS::get_singleton()->get_name())); } void OS::open_midi_inputs() { - - if (MIDIDriver::get_singleton()) + if (MIDIDriver::get_singleton()) { MIDIDriver::get_singleton()->open(); + } else { + ERR_PRINT(vformat("MIDI input isn't supported on %s.", OS::get_singleton()->get_name())); + } } void OS::close_midi_inputs() { - - if (MIDIDriver::get_singleton()) + if (MIDIDriver::get_singleton()) { MIDIDriver::get_singleton()->close(); + } else { + ERR_PRINT(vformat("MIDI input isn't supported on %s.", OS::get_singleton()->get_name())); + } +} + +void OS::add_frame_delay(bool p_can_draw) { + const uint32_t frame_delay = Engine::get_singleton()->get_frame_delay(); + if (frame_delay) { + // Add fixed frame delay to decrease CPU/GPU usage. This doesn't take + // the actual frame time into account. + // Due to the high fluctuation of the actual sleep duration, it's not recommended + // to use this as a FPS limiter. + delay_usec(frame_delay * 1000); + } + + // Add a dynamic frame delay to decrease CPU/GPU usage. This takes the + // previous frame time into account for a smoother result. + uint64_t dynamic_delay = 0; + if (is_in_low_processor_usage_mode() || !p_can_draw) { + dynamic_delay = get_low_processor_usage_mode_sleep_usec(); + } + const int target_fps = Engine::get_singleton()->get_target_fps(); + if (target_fps > 0 && !Engine::get_singleton()->is_editor_hint()) { + // Override the low processor usage mode sleep delay if the target FPS is lower. + dynamic_delay = MAX(dynamic_delay, (uint64_t)(1000000 / target_fps)); + } + + if (dynamic_delay > 0) { + target_ticks += dynamic_delay; + uint64_t current_ticks = get_ticks_usec(); + + if (current_ticks < target_ticks) { + delay_usec(target_ticks - current_ticks); + } + + current_ticks = get_ticks_usec(); + target_ticks = MIN(MAX(target_ticks, current_ticks - dynamic_delay), current_ticks + dynamic_delay); + } } OS::OS() { void *volatile stack_bottom; - restart_on_exit = false; singleton = this; - _keep_screen_on = true; // set default value to true, because this had been true before godot 2.0. - low_processor_usage_mode = false; - low_processor_usage_mode_sleep_usec = 10000; - _verbose_stdout = false; - _no_window = false; - _exit_code = 0; - _orientation = SCREEN_LANDSCAPE; - - _render_thread_mode = RENDER_THREAD_SAFE; - - _allow_hidpi = false; - _allow_layered = false; - _stack_bottom = (void *)(&stack_bottom); - - _logger = NULL; - has_server_feature_callback = NULL; + _stack_bottom = (void *)(&stack_bottom); Vector<Logger *> loggers; loggers.push_back(memnew(StdLogger)); @@ -773,5 +522,5 @@ OS::OS() { OS::~OS() { memdelete(_logger); - singleton = NULL; + singleton = nullptr; } diff --git a/core/os/os.h b/core/os/os.h index 89b3414b3e..8e5c0c26e0 100644 --- a/core/os/os.h +++ b/core/os/os.h @@ -41,24 +41,23 @@ #include <stdarg.h> -class Mutex; - class OS { - static OS *singleton; + static uint64_t target_ticks; String _execpath; List<String> _cmdline; - bool _keep_screen_on; - bool low_processor_usage_mode; - int low_processor_usage_mode_sleep_usec; - bool _verbose_stdout; + bool _keep_screen_on = true; // set default value to true, because this had been true before godot 2.0. + bool low_processor_usage_mode = false; + int low_processor_usage_mode_sleep_usec = 10000; + bool _verbose_stdout = false; + bool _debug_stdout = false; String _local_clipboard; uint64_t _msec_splash; - bool _no_window; - int _exit_code; + bool _no_window = false; + int _exit_code = 0; int _orientation; - bool _allow_hidpi; - bool _allow_layered; + bool _allow_hidpi = false; + bool _allow_layered = false; bool _use_vsync; bool _vsync_via_compositor; @@ -66,9 +65,9 @@ class OS { void *_stack_bottom; - CompositeLogger *_logger; + CompositeLogger *_logger = nullptr; - bool restart_on_exit; + bool restart_on_exit = false; List<String> restart_commandline; protected: @@ -78,57 +77,26 @@ public: typedef void (*ImeCallback)(void *p_inp, String p_text, Point2 p_selection); typedef bool (*HasServerFeatureCallback)(const String &p_feature); - enum PowerState { - POWERSTATE_UNKNOWN, /**< cannot determine power status */ - POWERSTATE_ON_BATTERY, /**< Not plugged in, running on the battery */ - POWERSTATE_NO_BATTERY, /**< Plugged in, no battery available */ - POWERSTATE_CHARGING, /**< Plugged in, charging battery */ - POWERSTATE_CHARGED /**< Plugged in, battery charged */ - }; - enum RenderThreadMode { RENDER_THREAD_UNSAFE, RENDER_THREAD_SAFE, RENDER_SEPARATE_THREAD }; - struct VideoMode { - - int width, height; - bool fullscreen; - bool resizable; - bool borderless_window; - bool maximized; - bool always_on_top; - bool use_vsync; - bool vsync_via_compositor; - bool layered; - float get_aspect() const { return (float)width / (float)height; } - VideoMode(int p_width = 1024, int p_height = 600, bool p_fullscreen = false, bool p_resizable = true, bool p_borderless_window = false, bool p_maximized = false, bool p_always_on_top = false, bool p_use_vsync = false, bool p_vsync_via_compositor = false) { - width = p_width; - height = p_height; - fullscreen = p_fullscreen; - resizable = p_resizable; - borderless_window = p_borderless_window; - maximized = p_maximized; - always_on_top = p_always_on_top; - use_vsync = p_use_vsync; - vsync_via_compositor = p_vsync_via_compositor; - layered = false; - } - }; protected: friend class Main; + // Needed by tests to setup command-line args. + friend int test_main(int argc, char *argv[]); - HasServerFeatureCallback has_server_feature_callback; - RenderThreadMode _render_thread_mode; + HasServerFeatureCallback has_server_feature_callback = nullptr; + RenderThreadMode _render_thread_mode = RENDER_THREAD_SAFE; - // functions used by main to initialize/deinitialize the OS + // Functions used by Main to initialize/deinitialize the OS. void add_logger(Logger *p_logger); - virtual void initialize_core() = 0; - virtual Error initialize(const VideoMode &p_desired, int p_video_driver, int p_audio_driver) = 0; + virtual void initialize() = 0; + virtual void initialize_joypads() = 0; virtual void set_main_loop(MainLoop *p_main_loop) = 0; virtual void delete_main_loop() = 0; @@ -138,7 +106,6 @@ protected: virtual void set_cmdline(const char *p_execpath, const List<String> &p_args); - void _ensure_user_data_dir(); virtual bool _check_internal_feature_support(const String &p_feature) = 0; public: @@ -146,128 +113,27 @@ public: static OS *get_singleton(); - virtual void global_menu_add_item(const String &p_menu, const String &p_label, const Variant &p_signal, const Variant &p_meta){}; - virtual void global_menu_add_separator(const String &p_menu){}; - virtual void global_menu_remove_item(const String &p_menu, int p_idx){}; - virtual void global_menu_clear(const String &p_menu){}; - void print_error(const char *p_function, const char *p_file, int p_line, const char *p_code, const char *p_rationale, Logger::ErrorType p_type = Logger::ERR_ERROR); void print(const char *p_format, ...) _PRINTF_FORMAT_ATTRIBUTE_2_3; void printerr(const char *p_format, ...) _PRINTF_FORMAT_ATTRIBUTE_2_3; - virtual void alert(const String &p_alert, const String &p_title = "ALERT!") = 0; virtual String get_stdin_string(bool p_block = true) = 0; - enum MouseMode { - MOUSE_MODE_VISIBLE, - MOUSE_MODE_HIDDEN, - MOUSE_MODE_CAPTURED, - MOUSE_MODE_CONFINED - }; - - virtual void set_mouse_mode(MouseMode p_mode); - virtual MouseMode get_mouse_mode() const; - - virtual void warp_mouse_position(const Point2 &p_to) {} - virtual Point2 get_mouse_position() const = 0; - virtual int get_mouse_button_state() const = 0; - virtual void set_window_title(const String &p_title) = 0; - - virtual void set_clipboard(const String &p_text); - virtual String get_clipboard() const; - - virtual void set_video_mode(const VideoMode &p_video_mode, int p_screen = 0) = 0; - virtual VideoMode get_video_mode(int p_screen = 0) const = 0; - virtual void get_fullscreen_mode_list(List<VideoMode> *p_list, int p_screen = 0) const = 0; - - enum VideoDriver { - VIDEO_DRIVER_GLES3, - VIDEO_DRIVER_GLES2, - VIDEO_DRIVER_MAX, - }; - - virtual int get_video_driver_count() const; - virtual const char *get_video_driver_name(int p_driver) const; - virtual int get_current_video_driver() const = 0; - - virtual int get_audio_driver_count() const; - virtual const char *get_audio_driver_name(int p_driver) const; - - virtual PoolStringArray get_connected_midi_inputs(); + virtual PackedStringArray get_connected_midi_inputs(); virtual void open_midi_inputs(); virtual void close_midi_inputs(); - virtual int get_screen_count() const { return 1; } - virtual int get_current_screen() const { return 0; } - virtual void set_current_screen(int p_screen) {} - virtual Point2 get_screen_position(int p_screen = -1) const { return Point2(); } - virtual Size2 get_screen_size(int p_screen = -1) const { return get_window_size(); } - virtual int get_screen_dpi(int p_screen = -1) const { return 72; } - virtual Point2 get_window_position() const { return Vector2(); } - virtual void set_window_position(const Point2 &p_position) {} - virtual Size2 get_max_window_size() const { return Size2(); }; - virtual Size2 get_min_window_size() const { return Size2(); }; - virtual Size2 get_window_size() const = 0; - virtual Size2 get_real_window_size() const { return get_window_size(); } - virtual void set_min_window_size(const Size2 p_size) {} - virtual void set_max_window_size(const Size2 p_size) {} - virtual void set_window_size(const Size2 p_size) {} - virtual void set_window_fullscreen(bool p_enabled) {} - virtual bool is_window_fullscreen() const { return true; } - virtual void set_window_resizable(bool p_enabled) {} - virtual bool is_window_resizable() const { return false; } - virtual void set_window_minimized(bool p_enabled) {} - virtual bool is_window_minimized() const { return false; } - virtual void set_window_maximized(bool p_enabled) {} - virtual bool is_window_maximized() const { return true; } - virtual void set_window_always_on_top(bool p_enabled) {} - virtual bool is_window_always_on_top() const { return false; } - virtual bool is_window_focused() const { return true; } - virtual void set_console_visible(bool p_enabled) {} - virtual bool is_console_visible() const { return false; } - virtual void request_attention() {} - virtual void center_window(); - - // Returns window area free of hardware controls and other obstacles. - // The application should use this to determine where to place UI elements. - // - // Keep in mind the area returned is in window coordinates rather than - // viewport coordinates - you should perform the conversion on your own. - // - // The maximum size of the area is Rect2(0, 0, window_size.width, window_size.height). - virtual Rect2 get_window_safe_area() const { - Size2 window_size = get_window_size(); - return Rect2(0, 0, window_size.width, window_size.height); - } - - virtual void set_borderless_window(bool p_borderless) {} - virtual bool get_borderless_window() { return 0; } - - virtual bool get_window_per_pixel_transparency_enabled() const { return false; } - virtual void set_window_per_pixel_transparency_enabled(bool p_enabled) {} - - virtual uint8_t *get_layered_buffer_data() { return NULL; } - virtual Size2 get_layered_buffer_size() { return Size2(0, 0); } - virtual void swap_layered_buffer() {} - - virtual void set_ime_active(const bool p_active) {} - virtual void set_ime_position(const Point2 &p_pos) {} - virtual Point2 get_ime_selection() const { return Point2(); } - virtual String get_ime_text() const { return String(); } - virtual Error open_dynamic_library(const String p_path, void *&p_library_handle, bool p_also_set_library_path = false) { return ERR_UNAVAILABLE; } virtual Error close_dynamic_library(void *p_library_handle) { return ERR_UNAVAILABLE; } virtual Error get_dynamic_library_symbol_handle(void *p_library_handle, const String p_name, void *&p_symbol_handle, bool p_optional = false) { return ERR_UNAVAILABLE; } - virtual void set_keep_screen_on(bool p_enabled); - virtual bool is_keep_screen_on() const; virtual void set_low_processor_usage_mode(bool p_enabled); virtual bool is_in_low_processor_usage_mode() const; virtual void set_low_processor_usage_mode_sleep_usec(int p_usec); virtual int get_low_processor_usage_mode_sleep_usec() const; virtual String get_executable_path() const; - virtual Error execute(const String &p_path, const List<String> &p_arguments, bool p_blocking = true, ProcessID *r_child_id = NULL, String *r_pipe = NULL, int *r_exitcode = NULL, bool read_stderr = false, Mutex *p_pipe_mutex = NULL) = 0; + virtual Error execute(const String &p_path, const List<String> &p_arguments, bool p_blocking = true, ProcessID *r_child_id = nullptr, String *r_pipe = nullptr, int *r_exitcode = nullptr, bool read_stderr = false, Mutex *p_pipe_mutex = nullptr) = 0; virtual Error kill(const ProcessID &p_pid) = 0; virtual int get_process_id() const; virtual void vibrate_handheld(int p_duration_ms = 500); @@ -283,6 +149,16 @@ public: virtual List<String> get_cmdline_args() const { return _cmdline; } virtual String get_model_name() const; + bool is_layered_allowed() const { return _allow_layered; } + bool is_hidpi_allowed() const { return _allow_hidpi; } + + virtual int get_tablet_driver_count() const { return 0; }; + virtual String get_tablet_driver_name(int p_driver) const { return ""; }; + virtual String get_current_tablet_driver() const { return ""; }; + virtual void set_current_tablet_driver(const String &p_driver){}; + + void ensure_user_data_dir(); + virtual MainLoop *get_main_loop() const = 0; virtual void yield(); @@ -315,7 +191,6 @@ public: }; struct Date { - int year; Month month; int day; @@ -324,7 +199,6 @@ public: }; struct Time { - int hour; int min; int sec; @@ -339,58 +213,24 @@ public: virtual Time get_time(bool local = false) const = 0; virtual TimeZoneInfo get_time_zone_info() const = 0; virtual String get_iso_date_time(bool local = false) const; - virtual uint64_t get_unix_time() const; - virtual uint64_t get_system_time_secs() const; - virtual uint64_t get_system_time_msecs() const; + virtual double get_unix_time() const; virtual void delay_usec(uint32_t p_usec) const = 0; + virtual void add_frame_delay(bool p_can_draw); + virtual uint64_t get_ticks_usec() const = 0; uint32_t get_ticks_msec() const; uint64_t get_splash_tick_msec() const; - virtual bool can_draw() const = 0; - virtual bool is_userfs_persistent() const { return true; } bool is_stdout_verbose() const; + bool is_stdout_debug_enabled() const; virtual void disable_crash_handler() {} virtual bool is_disable_crash_handler() const { return false; } virtual void initialize_debugging() {} - enum CursorShape { - CURSOR_ARROW, - CURSOR_IBEAM, - CURSOR_POINTING_HAND, - CURSOR_CROSS, - CURSOR_WAIT, - CURSOR_BUSY, - CURSOR_DRAG, - CURSOR_CAN_DROP, - CURSOR_FORBIDDEN, - CURSOR_VSIZE, - CURSOR_HSIZE, - CURSOR_BDIAGSIZE, - CURSOR_FDIAGSIZE, - CURSOR_MOVE, - CURSOR_VSPLIT, - CURSOR_HSPLIT, - CURSOR_HELP, - CURSOR_MAX - }; - - virtual bool has_virtual_keyboard() const; - virtual void show_virtual_keyboard(const String &p_existing_text, const Rect2 &p_screen_rect = Rect2(), int p_max_input_length = -1); - virtual void hide_virtual_keyboard(); - - // returns height of the currently shown virtual keyboard (0 if keyboard is hidden) - virtual int get_virtual_keyboard_height() const; - - virtual void set_cursor_shape(CursorShape p_shape); - virtual CursorShape get_cursor_shape() const; - virtual void set_custom_mouse_cursor(const RES &p_cursor, CursorShape p_shape, const Vector2 &p_hotspot); - - virtual bool get_swap_ok_cancel() { return false; } virtual void dump_memory_to_file(const char *p_file); virtual void dump_resources_to_file(const char *p_file); virtual void print_resources_in_use(bool p_short = false); @@ -398,7 +238,6 @@ public: virtual uint64_t get_static_memory_usage() const; virtual uint64_t get_static_memory_peak_usage() const; - virtual uint64_t get_dynamic_memory_usage() const; virtual uint64_t get_free_static_memory() const; RenderThreadMode get_render_thread_mode() const { return _render_thread_mode; } @@ -434,34 +273,8 @@ public: virtual void set_no_window_mode(bool p_enable); virtual bool is_no_window_mode_enabled() const; - virtual bool has_touchscreen_ui_hint() const; - - enum ScreenOrientation { - - SCREEN_LANDSCAPE, - SCREEN_PORTRAIT, - SCREEN_REVERSE_LANDSCAPE, - SCREEN_REVERSE_PORTRAIT, - SCREEN_SENSOR_LANDSCAPE, - SCREEN_SENSOR_PORTRAIT, - SCREEN_SENSOR, - }; - - virtual void set_screen_orientation(ScreenOrientation p_orientation); - ScreenOrientation get_screen_orientation() const; - - virtual void enable_for_stealing_focus(ProcessID pid) {} - virtual void move_window_to_foreground() {} - virtual void debug_break(); - virtual void release_rendering_thread(); - virtual void make_rendering_thread(); - virtual void swap_buffers(); - - virtual void set_native_icon(const String &p_filename); - virtual void set_icon(const Ref<Image> &p_icon); - virtual int get_exit_code() const; virtual void set_exit_code(int p_code); @@ -469,66 +282,12 @@ public: virtual String get_unique_id() const; - virtual Error native_video_play(String p_path, float p_volume, String p_audio_track, String p_subtitle_track); - virtual bool native_video_is_playing() const; - virtual void native_video_pause(); - virtual void native_video_unpause(); - virtual void native_video_stop(); - virtual bool can_use_threads() const; - virtual Error dialog_show(String p_title, String p_description, Vector<String> p_buttons, Object *p_obj, String p_callback); - virtual Error dialog_input_text(String p_title, String p_description, String p_partial, Object *p_obj, String p_callback); - - enum LatinKeyboardVariant { - LATIN_KEYBOARD_QWERTY, - LATIN_KEYBOARD_QWERTZ, - LATIN_KEYBOARD_AZERTY, - LATIN_KEYBOARD_QZERTY, - LATIN_KEYBOARD_DVORAK, - LATIN_KEYBOARD_NEO, - LATIN_KEYBOARD_COLEMAK, - }; - - virtual LatinKeyboardVariant get_latin_keyboard_variant() const; - - virtual bool is_joy_known(int p_device); - virtual String get_joy_guid(int p_device) const; - - enum EngineContext { - CONTEXT_EDITOR, - CONTEXT_PROJECTMAN, - CONTEXT_ENGINE, - }; - - virtual void set_context(int p_context); - - //amazing hack because OpenGL needs this to be set on a separate thread.. - //also core can't access servers, so a callback must be used - typedef void (*SwitchVSyncCallbackInThread)(bool); - - static SwitchVSyncCallbackInThread switch_vsync_function; - void set_use_vsync(bool p_enable); - bool is_vsync_enabled() const; - - //real, actual overridable function to switch vsync, which needs to be called from graphics thread if needed - virtual void _set_use_vsync(bool p_enable) {} - - void set_vsync_via_compositor(bool p_enable); - bool is_vsync_via_compositor_enabled() const; - - virtual OS::PowerState get_power_state(); - virtual int get_power_seconds_left(); - virtual int get_power_percent_left(); - - virtual void force_process_input(){}; bool has_feature(const String &p_feature); void set_has_server_feature_callback(HasServerFeatureCallback p_callback); - bool is_layered_allowed() const { return _allow_layered; } - bool is_hidpi_allowed() const { return _allow_hidpi; } - void set_restart_on_exit(bool p_restart, const List<String> &p_restart_arguments); bool is_restart_on_exit_set() const; List<String> get_restart_on_exit_arguments() const; @@ -542,6 +301,4 @@ public: virtual ~OS(); }; -VARIANT_ENUM_CAST(OS::PowerState); - -#endif +#endif // OS_H diff --git a/core/os/rw_lock.cpp b/core/os/rw_lock.cpp index 75683962af..a668fe2b4c 100644 --- a/core/os/rw_lock.cpp +++ b/core/os/rw_lock.cpp @@ -34,14 +34,10 @@ #include <stddef.h> -RWLock *(*RWLock::create_func)() = 0; +RWLock *(*RWLock::create_func)() = nullptr; RWLock *RWLock::create() { - - ERR_FAIL_COND_V(!create_func, 0); + ERR_FAIL_COND_V(!create_func, nullptr); return create_func(); } - -RWLock::~RWLock() { -} diff --git a/core/os/rw_lock.h b/core/os/rw_lock.h index 21648b6cbc..1035072cce 100644 --- a/core/os/rw_lock.h +++ b/core/os/rw_lock.h @@ -28,8 +28,8 @@ /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /*************************************************************************/ -#ifndef RWLOCK_H -#define RWLOCK_H +#ifndef RW_LOCK_H +#define RW_LOCK_H #include "core/error_list.h" @@ -48,35 +48,41 @@ public: static RWLock *create(); ///< Create a rwlock - virtual ~RWLock(); + virtual ~RWLock() {} }; class RWLockRead { - RWLock *lock; public: RWLockRead(const RWLock *p_lock) { lock = const_cast<RWLock *>(p_lock); - if (lock) lock->read_lock(); + if (lock) { + lock->read_lock(); + } } ~RWLockRead() { - if (lock) lock->read_unlock(); + if (lock) { + lock->read_unlock(); + } } }; class RWLockWrite { - RWLock *lock; public: RWLockWrite(RWLock *p_lock) { lock = p_lock; - if (lock) lock->write_lock(); + if (lock) { + lock->write_lock(); + } } ~RWLockWrite() { - if (lock) lock->write_unlock(); + if (lock) { + lock->write_unlock(); + } } }; -#endif // RWLOCK_H +#endif // RW_LOCK_H diff --git a/core/os/semaphore.cpp b/core/os/semaphore.cpp deleted file mode 100644 index b2ba9716f0..0000000000 --- a/core/os/semaphore.cpp +++ /dev/null @@ -1,45 +0,0 @@ -/*************************************************************************/ -/* semaphore.cpp */ -/*************************************************************************/ -/* This file is part of: */ -/* GODOT ENGINE */ -/* https://godotengine.org */ -/*************************************************************************/ -/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */ -/* */ -/* Permission is hereby granted, free of charge, to any person obtaining */ -/* a copy of this software and associated documentation files (the */ -/* "Software"), to deal in the Software without restriction, including */ -/* without limitation the rights to use, copy, modify, merge, publish, */ -/* distribute, sublicense, and/or sell copies of the Software, and to */ -/* permit persons to whom the Software is furnished to do so, subject to */ -/* the following conditions: */ -/* */ -/* The above copyright notice and this permission notice shall be */ -/* included in all copies or substantial portions of the Software. */ -/* */ -/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */ -/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */ -/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/ -/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */ -/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */ -/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */ -/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ -/*************************************************************************/ - -#include "semaphore.h" - -#include "core/error_macros.h" - -Semaphore *(*Semaphore::create_func)() = 0; - -Semaphore *Semaphore::create() { - - ERR_FAIL_COND_V(!create_func, 0); - - return create_func(); -} - -Semaphore::~Semaphore() { -} diff --git a/core/os/semaphore.h b/core/os/semaphore.h index 9f3c0f549c..077e04704b 100644 --- a/core/os/semaphore.h +++ b/core/os/semaphore.h @@ -32,19 +32,53 @@ #define SEMAPHORE_H #include "core/error_list.h" +#include "core/typedefs.h" + +#if !defined(NO_THREADS) + +#include <condition_variable> +#include <mutex> class Semaphore { -protected: - static Semaphore *(*create_func)(); +private: + mutable std::mutex mutex_; + mutable std::condition_variable condition_; + mutable unsigned long count_ = 0; // Initialized as locked. public: - virtual Error wait() = 0; ///< wait until semaphore has positive value, then decrement and pass - virtual Error post() = 0; ///< unlock the semaphore, incrementing the value - virtual int get() const = 0; ///< get semaphore value + _ALWAYS_INLINE_ void post() const { + std::lock_guard<decltype(mutex_)> lock(mutex_); + ++count_; + condition_.notify_one(); + } + + _ALWAYS_INLINE_ void wait() const { + std::unique_lock<decltype(mutex_)> lock(mutex_); + while (!count_) { // Handle spurious wake-ups. + condition_.wait(lock); + } + --count_; + } + + _ALWAYS_INLINE_ bool try_wait() const { + std::lock_guard<decltype(mutex_)> lock(mutex_); + if (count_) { + --count_; + return true; + } + return false; + } +}; - static Semaphore *create(); ///< Create a mutex +#else - virtual ~Semaphore(); +class Semaphore { +public: + _ALWAYS_INLINE_ void post() const {} + _ALWAYS_INLINE_ void wait() const {} + _ALWAYS_INLINE_ bool try_wait() const { return true; } }; #endif + +#endif // SEMAPHORE_H diff --git a/core/os/thread.cpp b/core/os/thread.cpp index 7f6148057d..fc0ce3c9b4 100644 --- a/core/os/thread.cpp +++ b/core/os/thread.cpp @@ -30,45 +30,37 @@ #include "thread.h" -Thread *(*Thread::create_func)(ThreadCreateCallback, void *, const Settings &) = NULL; -Thread::ID (*Thread::get_thread_id_func)() = NULL; -void (*Thread::wait_to_finish_func)(Thread *) = NULL; -Error (*Thread::set_name_func)(const String &) = NULL; +Thread *(*Thread::create_func)(ThreadCreateCallback, void *, const Settings &) = nullptr; +Thread::ID (*Thread::get_thread_id_func)() = nullptr; +void (*Thread::wait_to_finish_func)(Thread *) = nullptr; +Error (*Thread::set_name_func)(const String &) = nullptr; Thread::ID Thread::_main_thread_id = 0; Thread::ID Thread::get_caller_id() { - - if (get_thread_id_func) + if (get_thread_id_func) { return get_thread_id_func(); + } return 0; } Thread *Thread::create(ThreadCreateCallback p_callback, void *p_user, const Settings &p_settings) { - if (create_func) { - return create_func(p_callback, p_user, p_settings); } - return NULL; + return nullptr; } void Thread::wait_to_finish(Thread *p_thread) { - - if (wait_to_finish_func) + if (wait_to_finish_func) { wait_to_finish_func(p_thread); + } } Error Thread::set_name(const String &p_name) { - - if (set_name_func) + if (set_name_func) { return set_name_func(p_name); + } return ERR_UNAVAILABLE; -}; - -Thread::Thread() { -} - -Thread::~Thread() { } diff --git a/core/os/thread.h b/core/os/thread.h index 0803fd1190..f761d4ca43 100644 --- a/core/os/thread.h +++ b/core/os/thread.h @@ -46,7 +46,6 @@ public: }; struct Settings { - Priority priority; Settings() { priority = PRIORITY_NORMAL; } }; @@ -63,7 +62,7 @@ protected: static ID _main_thread_id; - Thread(); + Thread() {} public: virtual ID get_id() const = 0; @@ -74,7 +73,7 @@ public: static void wait_to_finish(Thread *p_thread); ///< waits until thread is finished, and deallocates it. static Thread *create(ThreadCreateCallback p_callback, void *p_user, const Settings &p_settings = Settings()); ///< Static function to create a thread, will call p_callback - virtual ~Thread(); + virtual ~Thread() {} }; -#endif +#endif // THREAD_H diff --git a/core/os/thread_dummy.cpp b/core/os/thread_dummy.cpp index d4f65b0312..2672cd7ad9 100644 --- a/core/os/thread_dummy.cpp +++ b/core/os/thread_dummy.cpp @@ -34,32 +34,16 @@ Thread *ThreadDummy::create(ThreadCreateCallback p_callback, void *p_user, const Thread::Settings &p_settings) { return memnew(ThreadDummy); -}; +} void ThreadDummy::make_default() { Thread::create_func = &ThreadDummy::create; -}; - -Mutex *MutexDummy::create(bool p_recursive) { - return memnew(MutexDummy); -}; - -void MutexDummy::make_default() { - Mutex::create_func = &MutexDummy::create; -}; - -Semaphore *SemaphoreDummy::create() { - return memnew(SemaphoreDummy); -}; - -void SemaphoreDummy::make_default() { - Semaphore::create_func = &SemaphoreDummy::create; -}; +} RWLock *RWLockDummy::create() { return memnew(RWLockDummy); -}; +} void RWLockDummy::make_default() { RWLock::create_func = &RWLockDummy::create; -}; +} diff --git a/core/os/thread_dummy.h b/core/os/thread_dummy.h index c8b52ae4dd..37d9ee0846 100644 --- a/core/os/thread_dummy.h +++ b/core/os/thread_dummy.h @@ -31,13 +31,11 @@ #ifndef THREAD_DUMMY_H #define THREAD_DUMMY_H -#include "core/os/mutex.h" #include "core/os/rw_lock.h" #include "core/os/semaphore.h" #include "core/os/thread.h" class ThreadDummy : public Thread { - static Thread *create(ThreadCreateCallback p_callback, void *p_user, const Settings &p_settings = Settings()); public: @@ -46,32 +44,7 @@ public: static void make_default(); }; -class MutexDummy : public Mutex { - - static Mutex *create(bool p_recursive); - -public: - virtual void lock(){}; - virtual void unlock(){}; - virtual Error try_lock() { return OK; }; - - static void make_default(); -}; - -class SemaphoreDummy : public Semaphore { - - static Semaphore *create(); - -public: - virtual Error wait() { return OK; }; - virtual Error post() { return OK; }; - virtual int get() const { return 0; }; ///< get semaphore value - - static void make_default(); -}; - class RWLockDummy : public RWLock { - static RWLock *create(); public: @@ -86,4 +59,4 @@ public: static void make_default(); }; -#endif +#endif // THREAD_DUMMY_H diff --git a/core/os/thread_safe.cpp b/core/os/thread_safe.cpp deleted file mode 100644 index d8d783ae16..0000000000 --- a/core/os/thread_safe.cpp +++ /dev/null @@ -1,49 +0,0 @@ -/*************************************************************************/ -/* thread_safe.cpp */ -/*************************************************************************/ -/* This file is part of: */ -/* GODOT ENGINE */ -/* https://godotengine.org */ -/*************************************************************************/ -/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */ -/* */ -/* Permission is hereby granted, free of charge, to any person obtaining */ -/* a copy of this software and associated documentation files (the */ -/* "Software"), to deal in the Software without restriction, including */ -/* without limitation the rights to use, copy, modify, merge, publish, */ -/* distribute, sublicense, and/or sell copies of the Software, and to */ -/* permit persons to whom the Software is furnished to do so, subject to */ -/* the following conditions: */ -/* */ -/* The above copyright notice and this permission notice shall be */ -/* included in all copies or substantial portions of the Software. */ -/* */ -/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */ -/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */ -/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/ -/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */ -/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */ -/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */ -/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ -/*************************************************************************/ - -#include "thread_safe.h" - -#include "core/error_macros.h" -#include "core/os/memory.h" - -ThreadSafe::ThreadSafe() { - - mutex = Mutex::create(); - if (!mutex) { - - WARN_PRINT("THREAD_SAFE defined, but no default mutex type"); - } -} - -ThreadSafe::~ThreadSafe() { - - if (mutex) - memdelete(mutex); -} diff --git a/core/os/thread_safe.h b/core/os/thread_safe.h index a4238a9225..670ee8b125 100644 --- a/core/os/thread_safe.h +++ b/core/os/thread_safe.h @@ -33,50 +33,9 @@ #include "core/os/mutex.h" -class ThreadSafe { +#define _THREAD_SAFE_CLASS_ mutable Mutex _thread_safe_; +#define _THREAD_SAFE_METHOD_ MutexLock _thread_safe_method_(_thread_safe_); +#define _THREAD_SAFE_LOCK_ _thread_safe_.lock(); +#define _THREAD_SAFE_UNLOCK_ _thread_safe_.unlock(); - Mutex *mutex; - -public: - inline void lock() const { - if (mutex) mutex->lock(); - } - inline void unlock() const { - if (mutex) mutex->unlock(); - } - - ThreadSafe(); - ~ThreadSafe(); -}; - -class ThreadSafeMethod { - - const ThreadSafe *_ts; - -public: - ThreadSafeMethod(const ThreadSafe *p_ts) { - - _ts = p_ts; - _ts->lock(); - } - - ~ThreadSafeMethod() { _ts->unlock(); } -}; - -#ifndef NO_THREADS - -#define _THREAD_SAFE_CLASS_ ThreadSafe __thread__safe__; -#define _THREAD_SAFE_METHOD_ ThreadSafeMethod __thread_safe_method__(&__thread__safe__); -#define _THREAD_SAFE_LOCK_ __thread__safe__.lock(); -#define _THREAD_SAFE_UNLOCK_ __thread__safe__.unlock(); - -#else - -#define _THREAD_SAFE_CLASS_ -#define _THREAD_SAFE_METHOD_ -#define _THREAD_SAFE_LOCK_ -#define _THREAD_SAFE_UNLOCK_ - -#endif - -#endif +#endif // THREAD_SAFE_H diff --git a/core/os/threaded_array_processor.h b/core/os/threaded_array_processor.h index 9dcd6ceece..d27399e4cc 100644 --- a/core/os/threaded_array_processor.h +++ b/core/os/threaded_array_processor.h @@ -54,19 +54,18 @@ struct ThreadArrayProcessData { template <class T> void process_array_thread(void *ud) { - T &data = *(T *)ud; while (true) { uint32_t index = atomic_increment(&data.index); - if (index >= data.elements) + if (index >= data.elements) { break; + } data.process(index); } } template <class C, class M, class U> void thread_process_array(uint32_t p_elements, C *p_instance, M p_method, U p_userdata) { - ThreadArrayProcessData<C, U> data; data.method = p_method; data.instance = p_instance; @@ -80,7 +79,7 @@ void thread_process_array(uint32_t p_elements, C *p_instance, M p_method, U p_us threads.resize(OS::get_singleton()->get_processor_count()); for (int i = 0; i < threads.size(); i++) { - threads.write[i] = Thread::create(process_array_thread<ThreadArrayProcessData<C, U> >, &data); + threads.write[i] = Thread::create(process_array_thread<ThreadArrayProcessData<C, U>>, &data); } for (int i = 0; i < threads.size(); i++) { @@ -93,7 +92,6 @@ void thread_process_array(uint32_t p_elements, C *p_instance, M p_method, U p_us template <class C, class M, class U> void thread_process_array(uint32_t p_elements, C *p_instance, M p_method, U p_userdata) { - ThreadArrayProcessData<C, U> data; data.method = p_method; data.instance = p_instance; |