Bring that Whole New World to the Old Continent too

Applies the clang-format style to the 2.1 branch as done for master in
5dbf1809c6.
This commit is contained in:
Rémi Verschelde 2017-03-19 00:36:26 +01:00
parent 1d418afe86
commit f8db8a3faa
1308 changed files with 147754 additions and 174357 deletions

View File

@ -30,13 +30,13 @@
#define ALLOCATORS_H
#include "os/memory.h"
template<int PREALLOC_COUNT=64, int MAX_HANDS=8>
template <int PREALLOC_COUNT = 64, int MAX_HANDS = 8>
class BalloonAllocator {
enum {
USED_FLAG=(1<<30),
USED_MASK=USED_FLAG-1
USED_FLAG = (1 << 30),
USED_MASK = USED_FLAG - 1
};
struct Balloon {
@ -46,7 +46,6 @@ class BalloonAllocator {
uint32_t hand;
};
struct Hand {
int used;
@ -55,136 +54,132 @@ class BalloonAllocator {
Balloon *last;
};
Hand hands[MAX_HANDS];
public:
void *alloc(size_t p_size) {
void* alloc(size_t p_size) {
size_t max = (1 << MAX_HANDS);
ERR_FAIL_COND_V(p_size > max, NULL);
size_t max=(1<<MAX_HANDS);
ERR_FAIL_COND_V( p_size>max, NULL );
unsigned int hand = 0;
unsigned int hand=0;
while (p_size > (size_t)(1 << hand))
++hand;
while(p_size>(size_t)(1<<hand)) ++hand;
Hand &h = hands[hand];
Hand &h=hands[hand];
if (h.used == h.allocated) {
if (h.used==h.allocated) {
for (int i = 0; i < PREALLOC_COUNT; i++) {
for(int i=0;i<PREALLOC_COUNT;i++) {
Balloon *b = (Balloon*)memalloc(sizeof(Balloon)+(1<<hand));
b->hand=hand;
Balloon *b = (Balloon *)memalloc(sizeof(Balloon) + (1 << hand));
b->hand = hand;
if (h.last) {
b->prev=h.last;
h.last->next=b;
h.last=b;
b->prev = h.last;
h.last->next = b;
h.last = b;
} else {
b->prev=NULL;
h.last=b;
h.first=b;
b->prev = NULL;
h.last = b;
h.first = b;
}
}
h.last->next=NULL;
h.allocated+=PREALLOC_COUNT;
h.last->next = NULL;
h.allocated += PREALLOC_COUNT;
}
Balloon *pick=h.last;
Balloon *pick = h.last;
ERR_FAIL_COND_V( (pick->hand&USED_FLAG), NULL );
ERR_FAIL_COND_V((pick->hand & USED_FLAG), NULL);
// remove last
h.last=h.last->prev;
h.last->next=NULL;
h.last = h.last->prev;
h.last->next = NULL;
pick->next=h.first;
h.first->prev=pick;
pick->prev=NULL;
h.first=pick;
pick->next = h.first;
h.first->prev = pick;
pick->prev = NULL;
h.first = pick;
h.used++;
pick->hand|=USED_FLAG;
pick->hand |= USED_FLAG;
return (void*)(pick+1);
return (void *)(pick + 1);
}
void free(void* p_ptr) {
void free(void *p_ptr) {
Balloon *b=(Balloon*)p_ptr;
b-=1;
Balloon *b = (Balloon *)p_ptr;
b -= 1;
ERR_FAIL_COND(!(b->hand&USED_FLAG) );
ERR_FAIL_COND(!(b->hand & USED_FLAG));
b->hand=b->hand&USED_MASK; // not used
int hand=b->hand;
b->hand = b->hand & USED_MASK; // not used
int hand = b->hand;
Hand &h=hands[hand];
Hand &h = hands[hand];
if (b==h.first)
h.first=b->next;
if (b == h.first)
h.first = b->next;
if (b->prev)
b->prev->next=b->next;
b->prev->next = b->next;
if (b->next)
b->next->prev=b->prev;
b->next->prev = b->prev;
if (h.last!=b) {
h.last->next=b;
b->prev=h.last;
b->next=NULL;
h.last=b;
if (h.last != b) {
h.last->next = b;
b->prev = h.last;
b->next = NULL;
h.last = b;
}
h.used--;
if (h.used<=(h.allocated-(PREALLOC_COUNT*2))) { // this is done to ensure no alloc/free is done constantly
if (h.used <= (h.allocated - (PREALLOC_COUNT * 2))) { // this is done to ensure no alloc/free is done constantly
for(int i=0;i<PREALLOC_COUNT;i++) {
ERR_CONTINUE( h.last->hand& USED_FLAG );
for (int i = 0; i < PREALLOC_COUNT; i++) {
ERR_CONTINUE(h.last->hand & USED_FLAG);
Balloon *new_last=h.last->prev;
Balloon *new_last = h.last->prev;
if (new_last)
new_last->next=NULL;
memfree( h.last );
h.last=new_last;
new_last->next = NULL;
memfree(h.last);
h.last = new_last;
}
h.allocated-=PREALLOC_COUNT;
h.allocated -= PREALLOC_COUNT;
}
}
BalloonAllocator() {
for(int i=0;i<MAX_HANDS;i++) {
for (int i = 0; i < MAX_HANDS; i++) {
hands[i].allocated=0;
hands[i].used=0;
hands[i].first=NULL;
hands[i].last=NULL;
hands[i].allocated = 0;
hands[i].used = 0;
hands[i].first = NULL;
hands[i].last = NULL;
}
}
void clear() {
for(int i=0;i<MAX_HANDS;i++) {
for (int i = 0; i < MAX_HANDS; i++) {
while(hands[i].first) {
while (hands[i].first) {
Balloon *b=hands[i].first;
hands[i].first=b->next;
Balloon *b = hands[i].first;
hands[i].first = b->next;
memfree(b);
}
hands[i].allocated=0;
hands[i].used=0;
hands[i].first=NULL;
hands[i].last=NULL;
hands[i].allocated = 0;
hands[i].used = 0;
hands[i].first = NULL;
hands[i].last = NULL;
}
}
@ -194,5 +189,4 @@ public:
}
};
#endif // ALLOCATORS_H

View File

@ -27,10 +27,10 @@
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
/*************************************************************************/
#include "array.h"
#include "vector.h"
#include "hashfuncs.h"
#include "variant.h"
#include "object.h"
#include "variant.h"
#include "vector.h"
struct ArrayPrivate {
@ -39,7 +39,7 @@ struct ArrayPrivate {
bool shared;
};
void Array::_ref(const Array& p_from) const {
void Array::_ref(const Array &p_from) const {
ArrayPrivate *_fp = p_from._p;
@ -60,10 +60,10 @@ void Array::_ref(const Array& p_from) const {
} else {
_p = memnew( ArrayPrivate );
_p->shared=false;
_p = memnew(ArrayPrivate);
_p->shared = false;
_p->refcount.init();
_p->array=_fp->array;
_p->array = _fp->array;
if (_fp->refcount.unref())
memdelete(_fp);
@ -78,19 +78,17 @@ void Array::_unref() const {
if (_p->refcount.unref()) {
memdelete(_p);
}
_p=NULL;
_p = NULL;
}
Variant& Array::operator[](int p_idx) {
Variant &Array::operator[](int p_idx) {
return _p->array[p_idx];
}
const Variant& Array::operator[](int p_idx) const {
const Variant &Array::operator[](int p_idx) const {
return _p->array[p_idx];
}
int Array::size() const {
@ -108,29 +106,29 @@ void Array::clear() {
bool Array::is_shared() const {
return _p->shared;
return _p->shared;
}
bool Array::operator==(const Array& p_array) const {
bool Array::operator==(const Array &p_array) const {
return _p==p_array._p;
return _p == p_array._p;
}
uint32_t Array::hash() const {
uint32_t h=hash_djb2_one_32(0);
uint32_t h = hash_djb2_one_32(0);
for (int i=0;i<_p->array.size();i++) {
for (int i = 0; i < _p->array.size(); i++) {
h = hash_djb2_one_32( _p->array[i].hash(), h);
h = hash_djb2_one_32(_p->array[i].hash(), h);
}
return h;
}
void Array::operator=(const Array& p_array) {
void Array::operator=(const Array &p_array) {
_ref(p_array);
}
void Array::push_back(const Variant& p_value) {
void Array::push_back(const Variant &p_value) {
_p->array.push_back(p_value);
}
@ -140,12 +138,12 @@ Error Array::resize(int p_new_size) {
return _p->array.resize(p_new_size);
}
void Array::insert(int p_pos, const Variant& p_value) {
void Array::insert(int p_pos, const Variant &p_value) {
_p->array.insert(p_pos,p_value);
_p->array.insert(p_pos, p_value);
}
void Array::erase(const Variant& p_value) {
void Array::erase(const Variant &p_value) {
_p->array.erase(p_value);
}
@ -160,12 +158,12 @@ Variant Array::back() const {
return operator[](_p->array.size() - 1);
}
int Array::find(const Variant& p_value, int p_from) const {
int Array::find(const Variant &p_value, int p_from) const {
return _p->array.find(p_value, p_from);
}
int Array::rfind(const Variant& p_value, int p_from) const {
int Array::rfind(const Variant &p_value, int p_from) const {
if (_p->array.size() == 0)
return -1;
@ -179,9 +177,9 @@ int Array::rfind(const Variant& p_value, int p_from) const {
p_from = _p->array.size() - 1;
}
for (int i=p_from; i>=0; i--) {
for (int i = p_from; i >= 0; i--) {
if(_p->array[i] == p_value){
if (_p->array[i] == p_value) {
return i;
};
};
@ -189,20 +187,20 @@ int Array::rfind(const Variant& p_value, int p_from) const {
return -1;
}
int Array::find_last(const Variant& p_value) const {
int Array::find_last(const Variant &p_value) const {
return rfind(p_value);
}
int Array::count(const Variant& p_value) const {
int Array::count(const Variant &p_value) const {
if(_p->array.size() == 0)
if (_p->array.size() == 0)
return 0;
int amount=0;
for (int i=0; i<_p->array.size(); i++) {
int amount = 0;
for (int i = 0; i < _p->array.size(); i++) {
if(_p->array[i] == p_value){
if (_p->array[i] == p_value) {
amount++;
};
};
@ -210,7 +208,7 @@ int Array::count(const Variant& p_value) const {
return amount;
}
bool Array::has(const Variant& p_value) const {
bool Array::has(const Variant &p_value) const {
return _p->array.find(p_value, 0) != -1;
}
@ -219,25 +217,24 @@ void Array::remove(int p_pos) {
_p->array.remove(p_pos);
}
void Array::set(int p_idx, const Variant &p_value) {
void Array::set(int p_idx,const Variant& p_value) {
operator[](p_idx)=p_value;
operator[](p_idx) = p_value;
}
const Variant& Array::get(int p_idx) const {
const Variant &Array::get(int p_idx) const {
return operator[](p_idx);
}
struct _ArrayVariantSort {
_FORCE_INLINE_ bool operator()(const Variant& p_l, const Variant& p_r) const {
bool valid=false;
_FORCE_INLINE_ bool operator()(const Variant &p_l, const Variant &p_r) const {
bool valid = false;
Variant res;
Variant::evaluate(Variant::OP_LESS,p_l,p_r,res,valid);
Variant::evaluate(Variant::OP_LESS, p_l, p_r, res, valid);
if (!valid)
res=false;
res = false;
return res;
}
};
@ -245,7 +242,6 @@ struct _ArrayVariantSort {
void Array::sort() {
_p->array.sort_custom<_ArrayVariantSort>();
}
struct _ArrayVariantSortCustom {
@ -253,64 +249,57 @@ struct _ArrayVariantSortCustom {
Object *obj;
StringName func;
_FORCE_INLINE_ bool operator()(const Variant& p_l, const Variant& p_r) const {
_FORCE_INLINE_ bool operator()(const Variant &p_l, const Variant &p_r) const {
const Variant*args[2]={&p_l,&p_r};
const Variant *args[2] = { &p_l, &p_r };
Variant::CallError err;
bool res = obj->call(func,args,2,err);
if (err.error!=Variant::CallError::CALL_OK)
res=false;
bool res = obj->call(func, args, 2, err);
if (err.error != Variant::CallError::CALL_OK)
res = false;
return res;
}
};
void Array::sort_custom(Object *p_obj,const StringName& p_function){
void Array::sort_custom(Object *p_obj, const StringName &p_function) {
ERR_FAIL_NULL(p_obj);
SortArray<Variant,_ArrayVariantSortCustom> avs;
avs.compare.obj=p_obj;
avs.compare.func=p_function;
avs.sort(_p->array.ptr(),_p->array.size());
SortArray<Variant, _ArrayVariantSortCustom> avs;
avs.compare.obj = p_obj;
avs.compare.func = p_function;
avs.sort(_p->array.ptr(), _p->array.size());
}
void Array::invert(){
void Array::invert() {
_p->array.invert();
}
void Array::push_front(const Variant &p_value) {
void Array::push_front(const Variant& p_value) {
_p->array.insert(0,p_value);
_p->array.insert(0, p_value);
}
void Array::pop_back(){
void Array::pop_back() {
if (!_p->array.empty())
_p->array.resize( _p->array.size() -1 );
_p->array.resize(_p->array.size() - 1);
}
void Array::pop_front(){
void Array::pop_front() {
if (!_p->array.empty())
_p->array.remove(0);
}
Array::Array(const Array &p_from) {
Array::Array(const Array& p_from) {
_p=NULL;
_p = NULL;
_ref(p_from);
}
Array::Array(bool p_shared) {
_p = memnew( ArrayPrivate );
_p = memnew(ArrayPrivate);
_p->refcount.init();
_p->shared=p_shared;
_p->shared = p_shared;
}
Array::~Array() {

View File

@ -38,16 +38,15 @@ class StringName;
class Array {
mutable ArrayPrivate *_p;
void _ref(const Array& p_from) const;
void _ref(const Array &p_from) const;
void _unref() const;
public:
Variant &operator[](int p_idx);
const Variant &operator[](int p_idx) const;
Variant& operator[](int p_idx);
const Variant& operator[](int p_idx) const;
void set(int p_idx,const Variant& p_value);
const Variant& get(int p_idx) const;
void set(int p_idx, const Variant &p_value);
const Variant &get(int p_idx) const;
int size() const;
bool empty() const;
@ -55,41 +54,40 @@ public:
bool is_shared() const;
bool operator==(const Array& p_array) const;
bool operator==(const Array &p_array) const;
uint32_t hash() const;
void operator=(const Array& p_array);
void operator=(const Array &p_array);
void push_back(const Variant& p_value);
_FORCE_INLINE_ void append(const Variant& p_value) { push_back(p_value); } //for python compatibility
void push_back(const Variant &p_value);
_FORCE_INLINE_ void append(const Variant &p_value) { push_back(p_value); } //for python compatibility
Error resize(int p_new_size);
void insert(int p_pos, const Variant& p_value);
void insert(int p_pos, const Variant &p_value);
void remove(int p_pos);
Variant front() const;
Variant back() const;
void sort();
void sort_custom(Object *p_obj,const StringName& p_function);
void sort_custom(Object *p_obj, const StringName &p_function);
void invert();
int find(const Variant& p_value, int p_from=0) const;
int rfind(const Variant& p_value, int p_from=-1) const;
int find_last(const Variant& p_value) const;
int count(const Variant& p_value) const;
bool has(const Variant& p_value) const;
int find(const Variant &p_value, int p_from = 0) const;
int rfind(const Variant &p_value, int p_from = -1) const;
int find_last(const Variant &p_value) const;
int count(const Variant &p_value) const;
bool has(const Variant &p_value) const;
void erase(const Variant& p_value);
void erase(const Variant &p_value);
void push_front(const Variant& p_value);
void push_front(const Variant &p_value);
void pop_back();
void pop_front();
Array(const Array& p_from);
Array(bool p_shared=false);
Array(const Array &p_from);
Array(bool p_shared = false);
~Array();
};
#endif // ARRAY_H

File diff suppressed because it is too large Load Diff

View File

@ -31,73 +31,67 @@
#include "io/resource_loader.h"
#include "io/resource_saver.h"
#include "os/file_access.h"
#include "os/dir_access.h"
#include "os/thread.h"
#include "os/file_access.h"
#include "os/semaphore.h"
#include "os/thread.h"
class _ResourceLoader : public Object {
OBJ_TYPE(_ResourceLoader,Object);
class _ResourceLoader : public Object {
OBJ_TYPE(_ResourceLoader, Object);
protected:
static void _bind_methods();
static _ResourceLoader *singleton;
public:
static _ResourceLoader *get_singleton() { return singleton; }
Ref<ResourceInteractiveLoader> load_interactive(const String& p_path,const String& p_type_hint="");
RES load(const String &p_path,const String& p_type_hint="", bool p_no_cache = false);
DVector<String> get_recognized_extensions_for_type(const String& p_type);
Ref<ResourceInteractiveLoader> load_interactive(const String &p_path, const String &p_type_hint = "");
RES load(const String &p_path, const String &p_type_hint = "", bool p_no_cache = false);
DVector<String> get_recognized_extensions_for_type(const String &p_type);
void set_abort_on_missing_resources(bool p_abort);
StringArray get_dependencies(const String& p_path);
bool has(const String& p_path);
Ref<ResourceImportMetadata> load_import_metadata(const String& p_path);
StringArray get_dependencies(const String &p_path);
bool has(const String &p_path);
Ref<ResourceImportMetadata> load_import_metadata(const String &p_path);
_ResourceLoader();
};
class _ResourceSaver : public Object {
OBJ_TYPE(_ResourceSaver,Object);
class _ResourceSaver : public Object {
OBJ_TYPE(_ResourceSaver, Object);
protected:
static void _bind_methods();
static _ResourceSaver *singleton;
public:
public:
enum SaverFlags {
FLAG_RELATIVE_PATHS=1,
FLAG_BUNDLE_RESOURCES=2,
FLAG_CHANGE_PATH=4,
FLAG_OMIT_EDITOR_PROPERTIES=8,
FLAG_SAVE_BIG_ENDIAN=16,
FLAG_COMPRESS=32,
FLAG_RELATIVE_PATHS = 1,
FLAG_BUNDLE_RESOURCES = 2,
FLAG_CHANGE_PATH = 4,
FLAG_OMIT_EDITOR_PROPERTIES = 8,
FLAG_SAVE_BIG_ENDIAN = 16,
FLAG_COMPRESS = 32,
};
static _ResourceSaver *get_singleton() { return singleton; }
Error save(const String &p_path,const RES& p_resource, uint32_t p_flags);
DVector<String> get_recognized_extensions(const RES& p_resource);
Error save(const String &p_path, const RES &p_resource, uint32_t p_flags);
DVector<String> get_recognized_extensions(const RES &p_resource);
_ResourceSaver();
};
class MainLoop;
class _OS : public Object {
OBJ_TYPE(_OS,Object);
class _OS : public Object {
OBJ_TYPE(_OS, Object);
protected:
static void _bind_methods();
static _OS *singleton;
public:
public:
enum Weekday {
DAY_SUNDAY,
DAY_MONDAY,
@ -126,30 +120,28 @@ public:
};
Point2 get_mouse_pos() const;
void set_window_title(const String& p_title);
void set_window_title(const String &p_title);
int get_mouse_button_state() const;
void set_clipboard(const String& p_text);
void set_clipboard(const String &p_text);
String get_clipboard() const;
void set_video_mode(const Size2& p_size, bool p_fullscreen,bool p_resizeable,int p_screen=0);
Size2 get_video_mode(int p_screen=0) const;
bool is_video_mode_fullscreen(int p_screen=0) const;
bool is_video_mode_resizable(int p_screen=0) const;
Array get_fullscreen_mode_list(int p_screen=0) const;
void set_video_mode(const Size2 &p_size, bool p_fullscreen, bool p_resizeable, int p_screen = 0);
Size2 get_video_mode(int p_screen = 0) const;
bool is_video_mode_fullscreen(int p_screen = 0) const;
bool is_video_mode_resizable(int p_screen = 0) const;
Array get_fullscreen_mode_list(int p_screen = 0) const;
virtual int get_screen_count() const;
virtual int get_current_screen() const;
virtual void set_current_screen(int p_screen);
virtual Point2 get_screen_position(int p_screen=0) const;
virtual Size2 get_screen_size(int p_screen=0) const;
virtual int get_screen_dpi(int p_screen=0) const;
virtual Point2 get_screen_position(int p_screen = 0) const;
virtual Size2 get_screen_size(int p_screen = 0) const;
virtual int get_screen_dpi(int p_screen = 0) const;
virtual Point2 get_window_position() const;
virtual void set_window_position(const Point2& p_position);
virtual void set_window_position(const Point2 &p_position);
virtual Size2 get_window_size() const;
virtual void set_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;
virtual void set_window_resizable(bool p_enabled);
@ -179,15 +171,15 @@ public:
bool is_in_low_processor_usage_mode() const;
String get_executable_path() const;
int execute(const String& p_path, const Vector<String> & p_arguments,bool p_blocking,Array p_output=Array());
int execute(const String &p_path, const Vector<String> &p_arguments, bool p_blocking, Array p_output = Array());
Error kill(int p_pid);
Error shell_open(String p_uri);
int get_process_ID() const;
bool has_environment(const String& p_var) const;
String get_environment(const String& p_var) const;
bool has_environment(const String &p_var) const;
String get_environment(const String &p_var) const;
String get_name() const;
Vector<String> get_cmdline_args();
@ -202,17 +194,17 @@ public:
float get_frames_per_second() const;
void dump_memory_to_file(const String& p_file);
void dump_resources_to_file(const String& p_file);
void dump_memory_to_file(const String &p_file);
void dump_resources_to_file(const String &p_file);
bool has_virtual_keyboard() const;
void show_virtual_keyboard(const String& p_existing_text="");
void show_virtual_keyboard(const String &p_existing_text = "");
void hide_virtual_keyboard();
void print_resources_in_use(bool p_short=false);
void print_all_resources(const String& p_to_file);
void print_resources_in_use(bool p_short = false);
void print_all_resources(const String &p_to_file);
void print_all_textures_by_size();
void print_resources_by_type(const Vector<String>& p_types);
void print_resources_by_type(const Vector<String> &p_types);
bool has_touchscreen_ui_hint() const;
@ -222,8 +214,7 @@ public:
String get_scancode_string(uint32_t p_code) const;
bool is_scancode_unicode(uint32_t p_unicode) const;
int find_scancode_from_string(const String& p_code) const;
int find_scancode_from_string(const String &p_code) const;
/*
struct Date {
@ -245,7 +236,7 @@ public:
void set_use_file_access_save_and_swap(bool p_enable);
void set_icon(const Image& p_icon);
void set_icon(const Image &p_icon);
int get_exit_code() const;
void set_exit_code(int p_code);
@ -271,7 +262,7 @@ public:
bool can_draw() const;
int get_frames_drawn();
int get_frames_drawn();
bool is_stdout_verbose() const;
@ -301,11 +292,9 @@ public:
String get_system_dir(SystemDir p_dir) const;
String get_data_dir() const;
void alert(const String& p_alert,const String& p_title="ALERT!");
void alert(const String &p_alert, const String &p_title = "ALERT!");
void set_screen_orientation(ScreenOrientation p_orientation);
ScreenOrientation get_screen_orientation() const;
@ -318,7 +307,7 @@ public:
bool is_ok_left_and_cancel_right() const;
Error set_thread_name(const String& p_name);
Error set_thread_name(const String &p_name);
void set_use_vsync(bool p_enable);
bool is_vsync_enabled() const;
@ -333,76 +322,71 @@ public:
VARIANT_ENUM_CAST(_OS::SystemDir);
VARIANT_ENUM_CAST(_OS::ScreenOrientation);
class _Geometry : public Object {
OBJ_TYPE(_Geometry, Object);
static _Geometry *singleton;
protected:
static void _bind_methods();
public:
static _Geometry *get_singleton();
DVector<Plane> build_box_planes(const Vector3& p_extents);
DVector<Plane> build_cylinder_planes(float p_radius, float p_height, int p_sides, Vector3::Axis p_axis=Vector3::AXIS_Z);
DVector<Plane> build_capsule_planes(float p_radius, float p_height, int p_sides, int p_lats, Vector3::Axis p_axis=Vector3::AXIS_Z);
Variant segment_intersects_segment_2d(const Vector2& p_from_a,const Vector2& p_to_a,const Vector2& p_from_b,const Vector2& p_to_b);
DVector<Vector2> get_closest_points_between_segments_2d( const Vector2& p1,const Vector2& q1, const Vector2& p2,const Vector2& q2);
DVector<Vector3> get_closest_points_between_segments(const Vector3& p1,const Vector3& p2,const Vector3& q1,const Vector3& q2);
Vector2 get_closest_point_to_segment_2d(const Vector2& p_point, const Vector2& p_a,const Vector2& p_b);
Vector3 get_closest_point_to_segment(const Vector3& p_point, const Vector3& p_a,const Vector3& p_b);
Vector2 get_closest_point_to_segment_uncapped_2d(const Vector2& p_point, const Vector2& p_a,const Vector2& p_b);
Vector3 get_closest_point_to_segment_uncapped(const Vector3& p_point, const Vector3& p_a,const Vector3& p_b);
Variant ray_intersects_triangle( const Vector3& p_from, const Vector3& p_dir, const Vector3& p_v0,const Vector3& p_v1,const Vector3& p_v2);
Variant segment_intersects_triangle( const Vector3& p_from, const Vector3& p_to, const Vector3& p_v0,const Vector3& p_v1,const Vector3& p_v2);
bool point_is_inside_triangle(const Vector2& s, const Vector2& a, const Vector2& b, const Vector2& c) const;
DVector<Plane> build_box_planes(const Vector3 &p_extents);
DVector<Plane> build_cylinder_planes(float p_radius, float p_height, int p_sides, Vector3::Axis p_axis = Vector3::AXIS_Z);
DVector<Plane> build_capsule_planes(float p_radius, float p_height, int p_sides, int p_lats, Vector3::Axis p_axis = Vector3::AXIS_Z);
Variant segment_intersects_segment_2d(const Vector2 &p_from_a, const Vector2 &p_to_a, const Vector2 &p_from_b, const Vector2 &p_to_b);
DVector<Vector2> get_closest_points_between_segments_2d(const Vector2 &p1, const Vector2 &q1, const Vector2 &p2, const Vector2 &q2);
DVector<Vector3> get_closest_points_between_segments(const Vector3 &p1, const Vector3 &p2, const Vector3 &q1, const Vector3 &q2);
Vector2 get_closest_point_to_segment_2d(const Vector2 &p_point, const Vector2 &p_a, const Vector2 &p_b);
Vector3 get_closest_point_to_segment(const Vector3 &p_point, const Vector3 &p_a, const Vector3 &p_b);
Vector2 get_closest_point_to_segment_uncapped_2d(const Vector2 &p_point, const Vector2 &p_a, const Vector2 &p_b);
Vector3 get_closest_point_to_segment_uncapped(const Vector3 &p_point, const Vector3 &p_a, const Vector3 &p_b);
Variant ray_intersects_triangle(const Vector3 &p_from, const Vector3 &p_dir, const Vector3 &p_v0, const Vector3 &p_v1, const Vector3 &p_v2);
Variant segment_intersects_triangle(const Vector3 &p_from, const Vector3 &p_to, const Vector3 &p_v0, const Vector3 &p_v1, const Vector3 &p_v2);
bool point_is_inside_triangle(const Vector2 &s, const Vector2 &a, const Vector2 &b, const Vector2 &c) const;
DVector<Vector3> segment_intersects_sphere( const Vector3& p_from, const Vector3& p_to, const Vector3& p_sphere_pos,real_t p_sphere_radius);
DVector<Vector3> segment_intersects_cylinder( const Vector3& p_from, const Vector3& p_to, float p_height,float p_radius);
DVector<Vector3> segment_intersects_convex(const Vector3& p_from, const Vector3& p_to,const Vector<Plane>& p_planes);
real_t segment_intersects_circle(const Vector2& p_from, const Vector2& p_to, const Vector2& p_circle_pos, real_t p_circle_radius);
int get_uv84_normal_bit(const Vector3& p_vector);
DVector<Vector3> segment_intersects_sphere(const Vector3 &p_from, const Vector3 &p_to, const Vector3 &p_sphere_pos, real_t p_sphere_radius);
DVector<Vector3> segment_intersects_cylinder(const Vector3 &p_from, const Vector3 &p_to, float p_height, float p_radius);
DVector<Vector3> segment_intersects_convex(const Vector3 &p_from, const Vector3 &p_to, const Vector<Plane> &p_planes);
real_t segment_intersects_circle(const Vector2 &p_from, const Vector2 &p_to, const Vector2 &p_circle_pos, real_t p_circle_radius);
int get_uv84_normal_bit(const Vector3 &p_vector);
Vector<int> triangulate_polygon(const Vector<Vector2>& p_polygon);
Vector<int> triangulate_polygon(const Vector<Vector2> &p_polygon);
Dictionary make_atlas(const Vector<Size2>& p_rects);
Dictionary make_atlas(const Vector<Size2> &p_rects);
_Geometry();
};
class _File : public Reference {
OBJ_TYPE(_File,Reference);
OBJ_TYPE(_File, Reference);
FileAccess *f;
bool eswap;
protected:
static void _bind_methods();
public:
enum ModeFlags {
enum ModeFlags {
READ=1,
WRITE=2,
READ_WRITE=3,
WRITE_READ=7,
READ = 1,
WRITE = 2,
READ_WRITE = 3,
WRITE_READ = 7,
};
Error open_encrypted(const String& p_path, int p_mode_flags,const Vector<uint8_t>& p_key);
Error open_encrypted_pass(const String& p_path, int p_mode_flags,const String& p_pass);
Error open_encrypted(const String &p_path, int p_mode_flags, const Vector<uint8_t> &p_key);
Error open_encrypted_pass(const String &p_path, int p_mode_flags, const String &p_pass);
Error open(const String& p_path, int p_mode_flags); ///< open a file
Error open(const String &p_path, int p_mode_flags); ///< open a file
void close(); ///< close a file
bool is_open() const; ///< true when file is open
void seek(int64_t p_position); ///< seek to a given position
void seek_end(int64_t p_position=0); ///< seek from the end of file
void seek_end(int64_t p_position = 0); ///< seek from the end of file
int64_t get_pos() const; ///< get position in the file
int64_t get_len() const; ///< get size of the file
@ -422,8 +406,8 @@ public:
DVector<uint8_t> get_buffer(int p_length) const; ///< get an array of bytes
String get_line() const;
String get_as_text() const;
String get_md5(const String& p_path) const;
String get_sha256(const String& p_path) const;
String get_md5(const String &p_path) const;
String get_sha256(const String &p_path) const;
/**< use this for files WRITTEN in _big_ endian machines (ie, amiga/mac)
* It's not about the current CPU type but file formats.
@ -444,38 +428,36 @@ public:
void store_double(double p_dest);
void store_real(real_t p_real);
void store_string(const String& p_string);
void store_line(const String& p_string);
void store_string(const String &p_string);
void store_line(const String &p_string);
virtual void store_pascal_string(const String& p_string);
virtual void store_pascal_string(const String &p_string);
virtual String get_pascal_string();
Vector<String> get_csv_line(String delim=",") const;
Vector<String> get_csv_line(String delim = ",") const;
void store_buffer(const DVector<uint8_t> &p_buffer); ///< store an array of bytes
void store_buffer(const DVector<uint8_t>& p_buffer); ///< store an array of bytes
void store_var(const Variant &p_var);
void store_var(const Variant& p_var);
bool file_exists(const String &p_name) const; ///< return true if a file exists
bool file_exists(const String& p_name) const; ///< return true if a file exists
uint64_t get_modified_time(const String& p_file) const;
uint64_t get_modified_time(const String &p_file) const;
_File();
virtual ~_File();
};
class _Directory : public Reference {
OBJ_TYPE(_Directory,Reference);
OBJ_TYPE(_Directory, Reference);
DirAccess *d;
protected:
static void _bind_methods();
public:
Error open(const String& p_path);
public:
Error open(const String &p_path);
bool list_dir_begin(); ///< This starts dir listing
String get_next();
@ -497,48 +479,42 @@ public:
int get_space_left();
Error copy(String p_from,String p_to);
Error copy(String p_from, String p_to);
Error rename(String p_from, String p_to);
Error remove(String p_name);
_Directory();
virtual ~_Directory();
};
class _Marshalls : public Reference {
OBJ_TYPE(_Marshalls,Reference);
OBJ_TYPE(_Marshalls, Reference);
protected:
static void _bind_methods();
public:
String variant_to_base64(const Variant &p_var);
Variant base64_to_variant(const String &p_str);
String variant_to_base64(const Variant& p_var);
Variant base64_to_variant(const String& p_str);
String raw_to_base64(const DVector<uint8_t> &p_arr);
DVector<uint8_t> base64_to_raw(const String &p_str);
String raw_to_base64(const DVector<uint8_t>& p_arr);
DVector<uint8_t> base64_to_raw(const String& p_str);
String utf8_to_base64(const String &p_str);
String base64_to_utf8(const String &p_str);
String utf8_to_base64(const String& p_str);
String base64_to_utf8(const String& p_str);
_Marshalls() {};
_Marshalls(){};
};
class _Mutex : public Reference {
OBJ_TYPE(_Mutex,Reference);
OBJ_TYPE(_Mutex, Reference);
Mutex *mutex;
static void _bind_methods();
public:
public:
void lock();
Error try_lock();
void unlock();
@ -549,12 +525,12 @@ public:
class _Semaphore : public Reference {
OBJ_TYPE(_Semaphore,Reference);
OBJ_TYPE(_Semaphore, Reference);
Semaphore *semaphore;
static void _bind_methods();
public:
public:
Error wait();
Error post();
@ -564,10 +540,9 @@ public:
class _Thread : public Reference {
OBJ_TYPE(_Thread,Reference);
OBJ_TYPE(_Thread, Reference);
protected:
Variant ret;
Variant userdata;
volatile bool active;
@ -576,8 +551,8 @@ protected:
Thread *thread;
static void _bind_methods();
static void _start_func(void *ud);
public:
public:
enum Priority {
PRIORITY_LOW,
@ -585,7 +560,7 @@ public:
PRIORITY_HIGH
};
Error start(Object *p_instance,const StringName& p_method,const Variant& p_userdata=Variant(),int p_priority=PRIORITY_NORMAL);
Error start(Object *p_instance, const StringName &p_method, const Variant &p_userdata = Variant(), int p_priority = PRIORITY_NORMAL);
String get_id() const;
bool is_active() const;
Variant wait_to_finish();

View File

@ -27,82 +27,80 @@
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
/*************************************************************************/
#include "color.h"
#include "color_names.inc"
#include "map.h"
#include "math_funcs.h"
#include "print_string.h"
#include "map.h"
#include "color_names.inc"
uint32_t Color::to_ARGB32() const {
uint32_t c=(uint8_t)(a*255);
c<<=8;
c|=(uint8_t)(r*255);
c<<=8;
c|=(uint8_t)(g*255);
c<<=8;
c|=(uint8_t)(b*255);
uint32_t c = (uint8_t)(a * 255);
c <<= 8;
c |= (uint8_t)(r * 255);
c <<= 8;
c |= (uint8_t)(g * 255);
c <<= 8;
c |= (uint8_t)(b * 255);
return c;
}
uint32_t Color::to_32() const {
uint32_t c=(uint8_t)(a*255);
c<<=8;
c|=(uint8_t)(r*255);
c<<=8;
c|=(uint8_t)(g*255);
c<<=8;
c|=(uint8_t)(b*255);
uint32_t c = (uint8_t)(a * 255);
c <<= 8;
c |= (uint8_t)(r * 255);
c <<= 8;
c |= (uint8_t)(g * 255);
c <<= 8;
c |= (uint8_t)(b * 255);
return c;
}
float Color::get_h() const {
float min = MIN( r, g );
min = MIN( min, b );
float max = MAX( r, g );
max = MAX( max, b );
float min = MIN(r, g);
min = MIN(min, b);
float max = MAX(r, g);
max = MAX(max, b);
float delta = max - min;
if( delta == 0 )
if (delta == 0)
return 0;
float h;
if( r == max )
h = ( g - b ) / delta; // between yellow & magenta
else if( g == max )
h = 2 + ( b - r ) / delta; // between cyan & yellow
if (r == max)
h = (g - b) / delta; // between yellow & magenta
else if (g == max)
h = 2 + (b - r) / delta; // between cyan & yellow
else
h = 4 + ( r - g ) / delta; // between magenta & cyan
h = 4 + (r - g) / delta; // between magenta & cyan
h/=6.0;
if (h<0)
h+=1.0;
h /= 6.0;
if (h < 0)
h += 1.0;
return h;
}
float Color::get_s() const {
float min = MIN( r, g );
min = MIN( min, b );
float max = MAX( r, g );
max = MAX( max, b );
float min = MIN(r, g);
min = MIN(min, b);
float max = MAX(r, g);
max = MAX(max, b);
float delta = max - min;
return (max!=0) ? (delta / max) : 0;
return (max != 0) ? (delta / max) : 0;
}
float Color::get_v() const {
float max = MAX( r, g );
max = MAX( max, b );
float max = MAX(r, g);
max = MAX(max, b);
return max;
}
@ -110,24 +108,24 @@ void Color::set_hsv(float p_h, float p_s, float p_v, float p_alpha) {
int i;
float f, p, q, t;
a=p_alpha;
a = p_alpha;
if( p_s == 0 ) {
if (p_s == 0) {
// acp_hromatic (grey)
r = g = b = p_v;
return;
}
p_h *=6.0;
p_h = Math::fmod(p_h,6);
i = Math::floor( p_h );
p_h *= 6.0;
p_h = Math::fmod(p_h, 6);
i = Math::floor(p_h);
f = p_h - i;
p = p_v * ( 1 - p_s );
q = p_v * ( 1 - p_s * f );
t = p_v * ( 1 - p_s * ( 1 - f ) );
p = p_v * (1 - p_s);
q = p_v * (1 - p_s * f);
t = p_v * (1 - p_s * (1 - f));
switch( i ) {
switch (i) {
case 0: // Red is the dominant color
r = p_v;
g = t;
@ -163,170 +161,166 @@ void Color::set_hsv(float p_h, float p_s, float p_v, float p_alpha) {
void Color::invert() {
r=1.0-r;
g=1.0-g;
b=1.0-b;
r = 1.0 - r;
g = 1.0 - g;
b = 1.0 - b;
}
void Color::contrast() {
r=Math::fmod(r+0.5,1.0);
g=Math::fmod(g+0.5,1.0);
b=Math::fmod(b+0.5,1.0);
r = Math::fmod(r + 0.5, 1.0);
g = Math::fmod(g + 0.5, 1.0);
b = Math::fmod(b + 0.5, 1.0);
}
Color Color::hex(uint32_t p_hex) {
float a = (p_hex&0xFF)/255.0;
p_hex>>=8;
float b = (p_hex&0xFF)/255.0;
p_hex>>=8;
float g = (p_hex&0xFF)/255.0;
p_hex>>=8;
float r = (p_hex&0xFF)/255.0;
float a = (p_hex & 0xFF) / 255.0;
p_hex >>= 8;
float b = (p_hex & 0xFF) / 255.0;
p_hex >>= 8;
float g = (p_hex & 0xFF) / 255.0;
p_hex >>= 8;
float r = (p_hex & 0xFF) / 255.0;
return Color(r,g,b,a);
return Color(r, g, b, a);
}
static float _parse_col(const String& p_str, int p_ofs) {
static float _parse_col(const String &p_str, int p_ofs) {
int ig=0;
int ig = 0;
for(int i=0;i<2;i++) {
for (int i = 0; i < 2; i++) {
int c=p_str[i+p_ofs];
int v=0;
int c = p_str[i + p_ofs];
int v = 0;
if (c>='0' && c<='9') {
v=c-'0';
} else if (c>='a' && c<='f') {
v=c-'a';
v+=10;
} else if (c>='A' && c<='F') {
v=c-'A';
v+=10;
if (c >= '0' && c <= '9') {
v = c - '0';
} else if (c >= 'a' && c <= 'f') {
v = c - 'a';
v += 10;
} else if (c >= 'A' && c <= 'F') {
v = c - 'A';
v += 10;
} else {
return -1;
}
if (i==0)
ig+=v*16;
if (i == 0)
ig += v * 16;
else
ig+=v;
ig += v;
}
return ig;
}
Color Color::inverted() const {
Color c=*this;
Color c = *this;
c.invert();
return c;
}
Color Color::contrasted() const {
Color c=*this;
Color c = *this;
c.contrast();
return c;
}
Color Color::html(const String& p_color) {
Color Color::html(const String &p_color) {
String color = p_color;
if (color.length()==0)
if (color.length() == 0)
return Color();
if (color[0]=='#')
color=color.substr(1,color.length()-1);
if (color[0] == '#')
color = color.substr(1, color.length() - 1);
bool alpha=false;
bool alpha = false;
if (color.length()==8) {
alpha=true;
} else if (color.length()==6) {
alpha=false;
if (color.length() == 8) {
alpha = true;
} else if (color.length() == 6) {
alpha = false;
} else {
ERR_EXPLAIN("Invalid Color Code: "+p_color);
ERR_EXPLAIN("Invalid Color Code: " + p_color);
ERR_FAIL_V(Color());
}
int a=255;
int a = 255;
if (alpha) {
a=_parse_col(color,0);
if (a<0) {
ERR_EXPLAIN("Invalid Color Code: "+p_color);
a = _parse_col(color, 0);
if (a < 0) {
ERR_EXPLAIN("Invalid Color Code: " + p_color);
ERR_FAIL_V(Color());
}
}
int from=alpha?2:0;
int from = alpha ? 2 : 0;
int r=_parse_col(color,from+0);
if (r<0) {
ERR_EXPLAIN("Invalid Color Code: "+p_color);
int r = _parse_col(color, from + 0);
if (r < 0) {
ERR_EXPLAIN("Invalid Color Code: " + p_color);
ERR_FAIL_V(Color());
}
int g=_parse_col(color,from+2);
if (g<0) {
ERR_EXPLAIN("Invalid Color Code: "+p_color);
int g = _parse_col(color, from + 2);
if (g < 0) {
ERR_EXPLAIN("Invalid Color Code: " + p_color);
ERR_FAIL_V(Color());
}
int b=_parse_col(color,from+4);
if (b<0) {
ERR_EXPLAIN("Invalid Color Code: "+p_color);
int b = _parse_col(color, from + 4);
if (b < 0) {
ERR_EXPLAIN("Invalid Color Code: " + p_color);
ERR_FAIL_V(Color());
}
return Color(r/255.0,g/255.0,b/255.0,a/255.0);
return Color(r / 255.0, g / 255.0, b / 255.0, a / 255.0);
}
bool Color::html_is_valid(const String& p_color) {
bool Color::html_is_valid(const String &p_color) {
String color = p_color;
if (color.length()==0)
if (color.length() == 0)
return false;
if (color[0]=='#')
color=color.substr(1,color.length()-1);
if (color[0] == '#')
color = color.substr(1, color.length() - 1);
bool alpha=false;
bool alpha = false;
if (color.length()==8) {
alpha=true;
} else if (color.length()==6) {
alpha=false;
if (color.length() == 8) {
alpha = true;
} else if (color.length() == 6) {
alpha = false;
} else {
return false;
}
int a=255;
int a = 255;
if (alpha) {
a=_parse_col(color,0);
if (a<0) {
a = _parse_col(color, 0);
if (a < 0) {
return false;
}
}
int from=alpha?2:0;
int from = alpha ? 2 : 0;
int r=_parse_col(color,from+0);
if (r<0) {
int r = _parse_col(color, from + 0);
if (r < 0) {
return false;
}
int g=_parse_col(color,from+2);
if (g<0) {
int g = _parse_col(color, from + 2);
if (g < 0) {
return false;
}
int b=_parse_col(color,from+4);
if (b<0) {
int b = _parse_col(color, from + 4);
if (b < 0) {
return false;
}
return true;
}
Color Color::named(const String &p_name) {
@ -339,12 +333,12 @@ Color Color::named(const String &p_name) {
name = name.replace("'", "");
name = name.replace(".", "");
name = name.to_lower();
const Map<String, Color>::Element* color = _named_colors.find(name);
if(color) {
const Map<String, Color>::Element *color = _named_colors.find(name);
if (color) {
return color->value();
} else {
ERR_EXPLAIN("Invalid Color Name: "+p_name);
ERR_EXPLAIN("Invalid Color Name: " + p_name);
ERR_FAIL_V(Color());
}
}
@ -352,48 +346,43 @@ Color Color::named(const String &p_name) {
String _to_hex(float p_val) {
int v = p_val * 255;
v = CLAMP(v,0,255);
v = CLAMP(v, 0, 255);
String ret;
for(int i=0;i<2;i++) {
for (int i = 0; i < 2; i++) {
CharType c[2]={0,0};
int lv = v&0xF;
if (lv<10)
c[0]='0'+lv;
CharType c[2] = { 0, 0 };
int lv = v & 0xF;
if (lv < 10)
c[0] = '0' + lv;
else
c[0]='a'+lv-10;
c[0] = 'a' + lv - 10;
v>>=4;
String cs=(const CharType*)c;
v >>= 4;
String cs = (const CharType *)c;
ret = cs + ret;
}
return ret;
}
String Color::to_html(bool p_alpha) const {
String txt;
txt+=_to_hex(r);
txt+=_to_hex(g);
txt+=_to_hex(b);
txt += _to_hex(r);
txt += _to_hex(g);
txt += _to_hex(b);
if (p_alpha)
txt=_to_hex(a)+txt;
txt = _to_hex(a) + txt;
return txt;
}
float Color::gray() const {
return (r+g+b)/3.0;
return (r + g + b) / 3.0;
}
Color::operator String() const {
return rtos(r)+", "+rtos(g)+", "+rtos(b)+", "+rtos(a);
return rtos(r) + ", " + rtos(g) + ", " + rtos(b) + ", " + rtos(a);
}

View File

@ -29,8 +29,8 @@
#ifndef COLOR_H
#define COLOR_H
#include "ustring.h"
#include "math_funcs.h"
#include "ustring.h"
/**
@author Juan Linietsky <reduzio@gmail.com>
*/
@ -47,8 +47,8 @@ struct Color {
float components[4];
};
bool operator==(const Color &p_color) const { return (r==p_color.r && g==p_color.g && b==p_color.b && a==p_color.a ); }
bool operator!=(const Color &p_color) const { return (r!=p_color.r || g!=p_color.g || b!=p_color.b || a!=p_color.a ); }
bool operator==(const Color &p_color) const { return (r == p_color.r && g == p_color.g && b == p_color.b && a == p_color.a); }
bool operator!=(const Color &p_color) const { return (r != p_color.r || g != p_color.g || b != p_color.b || a != p_color.a); }
uint32_t to_32() const;
uint32_t to_ARGB32() const;
@ -56,12 +56,12 @@ struct Color {
float get_h() const;
float get_s() const;
float get_v() const;
void set_hsv(float p_h, float p_s, float p_v, float p_alpha=1.0);
void set_hsv(float p_h, float p_s, float p_v, float p_alpha = 1.0);
_FORCE_INLINE_ float& operator[](int idx) {
_FORCE_INLINE_ float &operator[](int idx) {
return components[idx];
}
_FORCE_INLINE_ const float& operator[](int idx) const {
_FORCE_INLINE_ const float &operator[](int idx) const {
return components[idx];
}
@ -70,30 +70,29 @@ struct Color {
Color inverted() const;
Color contrasted() const;
_FORCE_INLINE_ Color linear_interpolate(const Color& p_b, float p_t) const {
_FORCE_INLINE_ Color linear_interpolate(const Color &p_b, float p_t) const {
Color res=*this;
Color res = *this;
res.r+= (p_t * (p_b.r-r));
res.g+= (p_t * (p_b.g-g));
res.b+= (p_t * (p_b.b-b));
res.a+= (p_t * (p_b.a-a));
res.r += (p_t * (p_b.r - r));
res.g += (p_t * (p_b.g - g));
res.b += (p_t * (p_b.b - b));
res.a += (p_t * (p_b.a - a));
return res;
}
_FORCE_INLINE_ Color blend(const Color& p_over) const {
_FORCE_INLINE_ Color blend(const Color &p_over) const {
Color res;
float sa = 1.0 - p_over.a;
res.a = a*sa+p_over.a;
if (res.a==0) {
return Color(0,0,0,0);
res.a = a * sa + p_over.a;
if (res.a == 0) {
return Color(0, 0, 0, 0);
} else {
res.r = (r*a*sa + p_over.r * p_over.a)/res.a;
res.g = (g*a*sa + p_over.g * p_over.a)/res.a;
res.b = (b*a*sa + p_over.b * p_over.a)/res.a;
res.r = (r * a * sa + p_over.r * p_over.a) / res.a;
res.g = (g * a * sa + p_over.g * p_over.a) / res.a;
res.b = (b * a * sa + p_over.b * p_over.a) / res.a;
}
return res;
}
@ -101,48 +100,54 @@ struct Color {
_FORCE_INLINE_ Color to_linear() const {
return Color(
r<0.04045 ? r * (1.0 / 12.92) : Math::pow((r + 0.055) * (1.0 / (1 + 0.055)), 2.4),
g<0.04045 ? g * (1.0 / 12.92) : Math::pow((g + 0.055) * (1.0 / (1 + 0.055)), 2.4),
b<0.04045 ? b * (1.0 / 12.92) : Math::pow((b + 0.055) * (1.0 / (1 + 0.055)), 2.4),
a
);
r < 0.04045 ? r * (1.0 / 12.92) : Math::pow((r + 0.055) * (1.0 / (1 + 0.055)), 2.4),
g < 0.04045 ? g * (1.0 / 12.92) : Math::pow((g + 0.055) * (1.0 / (1 + 0.055)), 2.4),
b < 0.04045 ? b * (1.0 / 12.92) : Math::pow((b + 0.055) * (1.0 / (1 + 0.055)), 2.4),
a);
}
static Color hex(uint32_t p_hex);
static Color html(const String& p_color);
static bool html_is_valid(const String& p_color);
static Color named(const String& p_name);
String to_html(bool p_alpha=true) const;
static Color html(const String &p_color);
static bool html_is_valid(const String &p_color);
static Color named(const String &p_name);
String to_html(bool p_alpha = true) const;
_FORCE_INLINE_ bool operator<(const Color& p_color) const; //used in set keys
_FORCE_INLINE_ bool operator<(const Color &p_color) const; //used in set keys
operator String() const;
/**
* No construct parameters, r=0, g=0, b=0. a=255
*/
_FORCE_INLINE_ Color() {
r=0; g=0; b=0; a=1.0;
r = 0;
g = 0;
b = 0;
a = 1.0;
}
/**
* RGB / RGBA construct parameters. Alpha is optional, but defaults to 1.0
*/
_FORCE_INLINE_ Color(float p_r,float p_g,float p_b,float p_a=1.0) { r=p_r; g=p_g; b=p_b; a=p_a; }
_FORCE_INLINE_ Color(float p_r, float p_g, float p_b, float p_a = 1.0) {
r = p_r;
g = p_g;
b = p_b;
a = p_a;
}
};
bool Color::operator<(const Color& p_color) const {
bool Color::operator<(const Color &p_color) const {
if (r==p_color.r) {
if (g==p_color.g) {
if(b==p_color.b) {
return (a<p_color.a);
if (r == p_color.r) {
if (g == p_color.g) {
if (b == p_color.b) {
return (a < p_color.a);
} else
return (b<p_color.b);
return (b < p_color.b);
} else
return g<p_color.g;
return g < p_color.g;
} else
return r<p_color.r;
return r < p_color.r;
}
#endif

View File

@ -47,22 +47,22 @@ void CommandQueueMT::wait_for_flush() {
OS::get_singleton()->delay_usec(1000);
}
CommandQueueMT::SyncSemaphore* CommandQueueMT::_alloc_sync_sem() {
CommandQueueMT::SyncSemaphore *CommandQueueMT::_alloc_sync_sem() {
int idx=-1;
int idx = -1;
while(true) {
while (true) {
for(int i=0;i<SYNC_SEMAPHORES;i++) {
for (int i = 0; i < SYNC_SEMAPHORES; i++) {
if (!sync_sems[i].in_use) {
sync_sems[i].in_use=true;
idx=i;
sync_sems[i].in_use = true;
idx = i;
break;
}
}
if (idx==-1) {
if (idx == -1) {
wait_for_flush();
} else {
break;
@ -72,36 +72,30 @@ CommandQueueMT::SyncSemaphore* CommandQueueMT::_alloc_sync_sem() {
return &sync_sems[idx];
}
CommandQueueMT::CommandQueueMT(bool p_sync) {
CommandQueueMT::CommandQueueMT(bool p_sync){
read_ptr=0;
write_ptr=0;
read_ptr = 0;
write_ptr = 0;
mutex = Mutex::create();
for(int i=0;i<SYNC_SEMAPHORES;i++) {
sync_sems[i].sem=Semaphore::create();
sync_sems[i].in_use=false;
for (int i = 0; i < SYNC_SEMAPHORES; i++) {
sync_sems[i].sem = Semaphore::create();
sync_sems[i].in_use = false;
}
if (p_sync)
sync = Semaphore::create();
else
sync=NULL;
sync = NULL;
}
CommandQueueMT::~CommandQueueMT() {
if (sync)
memdelete(sync);
memdelete(mutex);
for(int i=0;i<SYNC_SEMAPHORES;i++) {
for (int i = 0; i < SYNC_SEMAPHORES; i++) {
memdelete(sync_sems[i].sem);
}
}

File diff suppressed because it is too large Load Diff

View File

@ -45,201 +45,199 @@ Redistribution and use in source and binary forms, with or without modification,
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
/* Our compression codebook, used for compression */
static const char *Smaz_cb[241] = {
"\002s,\266", "\003had\232\002leW", "\003on \216", "", "\001yS",
"\002ma\255\002li\227", "\003or \260", "", "\002ll\230\003s t\277",
"\004fromg\002mel", "", "\003its\332", "\001z\333", "\003ingF", "\001>\336",
"\001 \000\003 (\002nc\344", "\002nd=\003 on\312",
"\002ne\213\003hat\276\003re q", "", "\002ngT\003herz\004have\306\003s o\225",
"", "\003ionk\003s a\254\002ly\352", "\003hisL\003 inN\003 be\252", "",
"\003 fo\325\003 of \003 ha\311", "", "\002of\005",
"\003 co\241\002no\267\003 ma\370", "", "", "\003 cl\356\003enta\003 an7",
"\002ns\300\001\"e", "\003n t\217\002ntP\003s, \205",
"\002pe\320\003 we\351\002om\223", "\002on\037", "", "\002y G", "\003 wa\271",
"\003 re\321\002or*", "", "\002=\"\251\002ot\337", "\003forD\002ou[",
"\003 toR", "\003 th\r", "\003 it\366",
"\003but\261\002ra\202\003 wi\363\002</\361", "\003 wh\237", "\002 4",
"\003nd ?", "\002re!", "", "\003ng c", "",
"\003ly \307\003ass\323\001a\004\002rir", "", "", "", "\002se_", "\003of \"",
"\003div\364\002ros\003ere\240", "", "\002ta\310\001bZ\002si\324", "",
"\003and\a\002rs\335", "\002rt\362", "\002teE", "\003ati\316", "\002so\263",
"\002th\021", "\002tiJ\001c\034\003allp", "\003ate\345", "\002ss\246",
"\002stM", "", "\002><\346", "\002to\024", "\003arew", "\001d\030",
"\002tr\303", "", "\001\n1\003 a \222", "\003f tv\002veo", "\002un\340", "",
"\003e o\242", "\002a \243\002wa\326\001e\002", "\002ur\226\003e a\274",
"\002us\244\003\n\r\n\247", "\002ut\304\003e c\373", "\002we\221", "", "",
"\002wh\302", "\001f,", "", "", "", "\003d t\206", "", "", "\003th \343",
"\001g;", "", "", "\001\r9\003e s\265", "\003e t\234", "", "\003to Y",
"\003e\r\n\236", "\002d \036\001h\022", "", "\001,Q", "\002 a\031", "\002 b^",
"\002\r\n\025\002 cI", "\002 d\245", "\002 e\253", "\002 fh\001i\b\002e \v",
"", "\002 hU\001-\314", "\002 i8", "", "", "\002 l\315", "\002 m{",
"\002f :\002 n\354", "\002 o\035", "\002 p}\001.n\003\r\n\r\250", "",
"\002 r\275", "\002 s>", "\002 t\016", "", "\002g \235\005which+\003whi\367",
"\002 w5", "\001/\305", "\003as \214", "\003at \207", "", "\003who\331", "",
"\001l\026\002h \212", "", "\002, $", "", "\004withV", "", "", "", "\001m-", "",
"", "\002ac\357", "\002ad\350", "\003TheH", "", "", "\004this\233\001n\t",
"", "\002. y", "", "\002alX\003e, \365", "\003tio\215\002be\\",
"\002an\032\003ver\347", "", "\004that0\003tha\313\001o\006", "\003was2",
"\002arO", "\002as.", "\002at'\003the\001\004they\200\005there\322\005theird",
"\002ce\210", "\004were]", "", "\002ch\231\002l \264\001p<", "", "",
"\003one\256", "", "\003he \023\002dej", "\003ter\270", "\002cou", "",
"\002by\177\002di\201\002eax", "", "\002ec\327", "\002edB", "\002ee\353", "",
"", "\001r\f\002n )", "", "", "", "\002el\262", "", "\003in i\002en3", "",
"\002o `\001s\n", "", "\002er\033", "\003is t\002es6", "", "\002ge\371",
"\004.com\375", "\002fo\334\003our\330", "\003ch \301\001t\003", "\002hab", "",
"\003men\374", "", "\002he\020", "", "", "\001u&", "\002hif", "",
"\003not\204\002ic\203", "\003ed @\002id\355", "", "", "\002ho\273",
"\002r K\001vm", "", "", "", "\003t t\257\002il\360", "\002im\342",
"\003en \317\002in\017", "\002io\220", "\002s \027\001wA", "", "\003er |",
"\003es ~\002is%", "\002it/", "", "\002iv\272", "",
"\002t #\ahttp://C\001x\372", "\002la\211", "\001<\341", "\003, a\224"
"\002s,\266", "\003had\232\002leW", "\003on \216", "", "\001yS",
"\002ma\255\002li\227", "\003or \260", "", "\002ll\230\003s t\277",
"\004fromg\002mel", "", "\003its\332", "\001z\333", "\003ingF", "\001>\336",
"\001 \000\003 (\002nc\344", "\002nd=\003 on\312",
"\002ne\213\003hat\276\003re q", "", "\002ngT\003herz\004have\306\003s o\225",
"", "\003ionk\003s a\254\002ly\352", "\003hisL\003 inN\003 be\252", "",
"\003 fo\325\003 of \003 ha\311", "", "\002of\005",
"\003 co\241\002no\267\003 ma\370", "", "", "\003 cl\356\003enta\003 an7",
"\002ns\300\001\"e", "\003n t\217\002ntP\003s, \205",
"\002pe\320\003 we\351\002om\223", "\002on\037", "", "\002y G", "\003 wa\271",
"\003 re\321\002or*", "", "\002=\"\251\002ot\337", "\003forD\002ou[",
"\003 toR", "\003 th\r", "\003 it\366",
"\003but\261\002ra\202\003 wi\363\002</\361", "\003 wh\237", "\002 4",
"\003nd ?", "\002re!", "", "\003ng c", "",
"\003ly \307\003ass\323\001a\004\002rir", "", "", "", "\002se_", "\003of \"",
"\003div\364\002ros\003ere\240", "", "\002ta\310\001bZ\002si\324", "",
"\003and\a\002rs\335", "\002rt\362", "\002teE", "\003ati\316", "\002so\263",
"\002th\021", "\002tiJ\001c\034\003allp", "\003ate\345", "\002ss\246",
"\002stM", "", "\002><\346", "\002to\024", "\003arew", "\001d\030",
"\002tr\303", "", "\001\n1\003 a \222", "\003f tv\002veo", "\002un\340", "",
"\003e o\242", "\002a \243\002wa\326\001e\002", "\002ur\226\003e a\274",
"\002us\244\003\n\r\n\247", "\002ut\304\003e c\373", "\002we\221", "", "",
"\002wh\302", "\001f,", "", "", "", "\003d t\206", "", "", "\003th \343",
"\001g;", "", "", "\001\r9\003e s\265", "\003e t\234", "", "\003to Y",
"\003e\r\n\236", "\002d \036\001h\022", "", "\001,Q", "\002 a\031", "\002 b^",
"\002\r\n\025\002 cI", "\002 d\245", "\002 e\253", "\002 fh\001i\b\002e \v",
"", "\002 hU\001-\314", "\002 i8", "", "", "\002 l\315", "\002 m{",
"\002f :\002 n\354", "\002 o\035", "\002 p}\001.n\003\r\n\r\250", "",
"\002 r\275", "\002 s>", "\002 t\016", "", "\002g \235\005which+\003whi\367",
"\002 w5", "\001/\305", "\003as \214", "\003at \207", "", "\003who\331", "",
"\001l\026\002h \212", "", "\002, $", "", "\004withV", "", "", "", "\001m-", "",
"", "\002ac\357", "\002ad\350", "\003TheH", "", "", "\004this\233\001n\t",
"", "\002. y", "", "\002alX\003e, \365", "\003tio\215\002be\\",
"\002an\032\003ver\347", "", "\004that0\003tha\313\001o\006", "\003was2",
"\002arO", "\002as.", "\002at'\003the\001\004they\200\005there\322\005theird",
"\002ce\210", "\004were]", "", "\002ch\231\002l \264\001p<", "", "",
"\003one\256", "", "\003he \023\002dej", "\003ter\270", "\002cou", "",
"\002by\177\002di\201\002eax", "", "\002ec\327", "\002edB", "\002ee\353", "",
"", "\001r\f\002n )", "", "", "", "\002el\262", "", "\003in i\002en3", "",
"\002o `\001s\n", "", "\002er\033", "\003is t\002es6", "", "\002ge\371",
"\004.com\375", "\002fo\334\003our\330", "\003ch \301\001t\003", "\002hab", "",
"\003men\374", "", "\002he\020", "", "", "\001u&", "\002hif", "",
"\003not\204\002ic\203", "\003ed @\002id\355", "", "", "\002ho\273",
"\002r K\001vm", "", "", "", "\003t t\257\002il\360", "\002im\342",
"\003en \317\002in\017", "\002io\220", "\002s \027\001wA", "", "\003er |",
"\003es ~\002is%", "\002it/", "", "\002iv\272", "",
"\002t #\ahttp://C\001x\372", "\002la\211", "\001<\341", "\003, a\224"
};
/* Reverse compression codebook, used for decompression */
static const char *Smaz_rcb[254] = {
" ", "the", "e", "t", "a", "of", "o", "and", "i", "n", "s", "e ", "r", " th",
" t", "in", "he", "th", "h", "he ", "to", "\r\n", "l", "s ", "d", " a", "an",
"er", "c", " o", "d ", "on", " of", "re", "of ", "t ", ", ", "is", "u", "at",
" ", "n ", "or", "which", "f", "m", "as", "it", "that", "\n", "was", "en",
" ", " w", "es", " an", " i", "\r", "f ", "g", "p", "nd", " s", "nd ", "ed ",
"w", "ed", "http://", "for", "te", "ing", "y ", "The", " c", "ti", "r ", "his",
"st", " in", "ar", "nt", ",", " to", "y", "ng", " h", "with", "le", "al", "to ",
"b", "ou", "be", "were", " b", "se", "o ", "ent", "ha", "ng ", "their", "\"",
"hi", "from", " f", "in ", "de", "ion", "me", "v", ".", "ve", "all", "re ",
"ri", "ro", "is ", "co", "f t", "are", "ea", ". ", "her", " m", "er ", " p",
"es ", "by", "they", "di", "ra", "ic", "not", "s, ", "d t", "at ", "ce", "la",
"h ", "ne", "as ", "tio", "on ", "n t", "io", "we", " a ", "om", ", a", "s o",
"ur", "li", "ll", "ch", "had", "this", "e t", "g ", "e\r\n", " wh", "ere",
" co", "e o", "a ", "us", " d", "ss", "\n\r\n", "\r\n\r", "=\"", " be", " e",
"s a", "ma", "one", "t t", "or ", "but", "el", "so", "l ", "e s", "s,", "no",
"ter", " wa", "iv", "ho", "e a", " r", "hat", "s t", "ns", "ch ", "wh", "tr",
"ut", "/", "have", "ly ", "ta", " ha", " on", "tha", "-", " l", "ati", "en ",
"pe", " re", "there", "ass", "si", " fo", "wa", "ec", "our", "who", "its", "z",
"fo", "rs", ">", "ot", "un", "<", "im", "th ", "nc", "ate", "><", "ver", "ad",
" we", "ly", "ee", " n", "id", " cl", "ac", "il", "</", "rt", " wi", "div",
"e, ", " it", "whi", " ma", "ge", "x", "e c", "men", ".com"
" ", "the", "e", "t", "a", "of", "o", "and", "i", "n", "s", "e ", "r", " th",
" t", "in", "he", "th", "h", "he ", "to", "\r\n", "l", "s ", "d", " a", "an",
"er", "c", " o", "d ", "on", " of", "re", "of ", "t ", ", ", "is", "u", "at",
" ", "n ", "or", "which", "f", "m", "as", "it", "that", "\n", "was", "en",
" ", " w", "es", " an", " i", "\r", "f ", "g", "p", "nd", " s", "nd ", "ed ",
"w", "ed", "http://", "for", "te", "ing", "y ", "The", " c", "ti", "r ", "his",
"st", " in", "ar", "nt", ",", " to", "y", "ng", " h", "with", "le", "al", "to ",
"b", "ou", "be", "were", " b", "se", "o ", "ent", "ha", "ng ", "their", "\"",
"hi", "from", " f", "in ", "de", "ion", "me", "v", ".", "ve", "all", "re ",
"ri", "ro", "is ", "co", "f t", "are", "ea", ". ", "her", " m", "er ", " p",
"es ", "by", "they", "di", "ra", "ic", "not", "s, ", "d t", "at ", "ce", "la",
"h ", "ne", "as ", "tio", "on ", "n t", "io", "we", " a ", "om", ", a", "s o",
"ur", "li", "ll", "ch", "had", "this", "e t", "g ", "e\r\n", " wh", "ere",
" co", "e o", "a ", "us", " d", "ss", "\n\r\n", "\r\n\r", "=\"", " be", " e",
"s a", "ma", "one", "t t", "or ", "but", "el", "so", "l ", "e s", "s,", "no",
"ter", " wa", "iv", "ho", "e a", " r", "hat", "s t", "ns", "ch ", "wh", "tr",
"ut", "/", "have", "ly ", "ta", " ha", " on", "tha", "-", " l", "ati", "en ",
"pe", " re", "there", "ass", "si", " fo", "wa", "ec", "our", "who", "its", "z",
"fo", "rs", ">", "ot", "un", "<", "im", "th ", "nc", "ate", "><", "ver", "ad",
" we", "ly", "ee", " n", "id", " cl", "ac", "il", "</", "rt", " wi", "div",
"e, ", " it", "whi", " ma", "ge", "x", "e c", "men", ".com"
};
static int smaz_compress(const char *in, int inlen, char *out, int outlen) {
unsigned int h1,h2,h3=0;
int verblen = 0, _outlen = outlen;
char verb[256], *_out = out;
unsigned int h1, h2, h3 = 0;
int verblen = 0, _outlen = outlen;
char verb[256], *_out = out;
while(inlen) {
int j = 7, needed;
char *flush = NULL;
const char *slot;
while (inlen) {
int j = 7, needed;
char *flush = NULL;
const char *slot;
h1 = h2 = in[0]<<3;
if (inlen > 1) h2 += in[1];
if (inlen > 2) h3 = h2^in[2];
if (j > inlen) j = inlen;
h1 = h2 = in[0] << 3;
if (inlen > 1) h2 += in[1];
if (inlen > 2) h3 = h2 ^ in[2];
if (j > inlen) j = inlen;
/* Try to lookup substrings into the hash table, starting from the
/* Try to lookup substrings into the hash table, starting from the
* longer to the shorter substrings */
for (; j > 0; j--) {
switch(j) {
case 1: slot = Smaz_cb[h1%241]; break;
case 2: slot = Smaz_cb[h2%241]; break;
default: slot = Smaz_cb[h3%241]; break;
}
while(slot[0]) {
if (slot[0] == j && memcmp(slot+1,in,j) == 0) {
/* Match found in the hash table,
for (; j > 0; j--) {
switch (j) {
case 1: slot = Smaz_cb[h1 % 241]; break;
case 2: slot = Smaz_cb[h2 % 241]; break;
default: slot = Smaz_cb[h3 % 241]; break;
}
while (slot[0]) {
if (slot[0] == j && memcmp(slot + 1, in, j) == 0) {
/* Match found in the hash table,
* prepare a verbatim bytes flush if needed */
if (verblen) {
needed = (verblen == 1) ? 2 : 2+verblen;
if (verblen) {
needed = (verblen == 1) ? 2 : 2 + verblen;
flush = out;
out += needed;
outlen -= needed;
}
/* Emit the byte */
if (outlen <= 0) return _outlen + 1;
out[0] = slot[slot[0] + 1];
out++;
outlen--;
inlen -= j;
in += j;
goto out;
} else {
slot += slot[0] + 2;
}
}
}
/* Match not found - add the byte to the verbatim buffer */
verb[verblen] = in[0];
verblen++;
inlen--;
in++;
out:
/* Prepare a flush if we reached the flush length limit, and there
* is not already a pending flush operation. */
if (!flush && (verblen == 256 || (verblen > 0 && inlen == 0))) {
needed = (verblen == 1) ? 2 : 2 + verblen;
flush = out;
out += needed;
outlen -= needed;
}
/* Emit the byte */
if (outlen <= 0) return _outlen+1;
out[0] = slot[slot[0]+1];
out++;
outlen--;
inlen -= j;
in += j;
goto out;
} else {
slot += slot[0]+2;
if (outlen < 0) return _outlen + 1;
}
/* Perform a verbatim flush if needed */
if (flush) {
if (verblen == 1) {
flush[0] = (signed char)254;
flush[1] = verb[0];
} else {
flush[0] = (signed char)255;
flush[1] = (signed char)(verblen - 1);
memcpy(flush + 2, verb, verblen);
}
flush = NULL;
verblen = 0;
}
}
}
/* Match not found - add the byte to the verbatim buffer */
verb[verblen] = in[0];
verblen++;
inlen--;
in++;
out:
/* Prepare a flush if we reached the flush length limit, and there
* is not already a pending flush operation. */
if (!flush && (verblen == 256 || (verblen > 0 && inlen == 0))) {
needed = (verblen == 1) ? 2 : 2+verblen;
flush = out;
out += needed;
outlen -= needed;
if (outlen < 0) return _outlen+1;
}
/* Perform a verbatim flush if needed */
if (flush) {
if (verblen == 1) {
flush[0] = (signed char)254;
flush[1] = verb[0];
} else {
flush[0] = (signed char)255;
flush[1] = (signed char)(verblen-1);
memcpy(flush+2,verb,verblen);
}
flush = NULL;
verblen = 0;
}
}
return out-_out;
return out - _out;
}
static int smaz_decompress(const char *in, int inlen, char *out, int outlen) {
unsigned char *c = (unsigned char*) in;
char *_out = out;
int _outlen = outlen;
unsigned char *c = (unsigned char *)in;
char *_out = out;
int _outlen = outlen;
while(inlen) {
if (*c == 254) {
/* Verbatim byte */
if (outlen < 1) return _outlen+1;
*out = *(c+1);
out++;
outlen--;
c += 2;
inlen -= 2;
} else if (*c == 255) {
/* Verbatim string */
int len = (*(c+1))+1;
if (outlen < len) return _outlen+1;
memcpy(out,c+2,len);
out += len;
outlen -= len;
c += 2+len;
inlen -= 2+len;
} else {
/* Codebook entry */
const char *s = Smaz_rcb[*c];
int len = strlen(s);
while (inlen) {
if (*c == 254) {
/* Verbatim byte */
if (outlen < 1) return _outlen + 1;
*out = *(c + 1);
out++;
outlen--;
c += 2;
inlen -= 2;
} else if (*c == 255) {
/* Verbatim string */
int len = (*(c + 1)) + 1;
if (outlen < len) return _outlen + 1;
memcpy(out, c + 2, len);
out += len;
outlen -= len;
c += 2 + len;
inlen -= 2 + len;
} else {
/* Codebook entry */
const char *s = Smaz_rcb[*c];
int len = strlen(s);
if (outlen < len) return _outlen+1;
memcpy(out,s,len);
out += len;
outlen -= len;
c++;
inlen--;
if (outlen < len) return _outlen + 1;
memcpy(out, s, len);
out += len;
outlen -= len;
c++;
inlen--;
}
}
}
return out-_out;
return out - _out;
}
/////////// END OF SMAZ /////////////
struct _PHashTranslationCmp {
@ -254,104 +252,100 @@ void PHashTranslation::generate(const Ref<Translation> &p_from) {
List<StringName> keys;
p_from->get_message_list(&keys);
int size=Math::larger_prime(keys.size());
int size = Math::larger_prime(keys.size());
print_line("compressing keys: "+itos(keys.size()));
Vector< Vector< Pair<int,CharString> > > buckets;
Vector< Map< uint32_t, int > > table;
Vector< uint32_t > hfunc_table;
Vector< _PHashTranslationCmp > compressed;
print_line("compressing keys: " + itos(keys.size()));
Vector<Vector<Pair<int, CharString> > > buckets;
Vector<Map<uint32_t, int> > table;
Vector<uint32_t> hfunc_table;
Vector<_PHashTranslationCmp> compressed;
table.resize(size);
hfunc_table.resize(size);
buckets.resize(size);
compressed.resize(keys.size());
int idx=0;
int total_compression_size=0;
int total_string_size=0;
int idx = 0;
int total_compression_size = 0;
int total_string_size = 0;
for(List<StringName>::Element *E=keys.front();E;E=E->next()) {
for (List<StringName>::Element *E = keys.front(); E; E = E->next()) {
//hash string
CharString cs = E->get().operator String().utf8();
uint32_t h = hash(0,cs.get_data());
Pair<int,CharString> p;
p.first=idx;
p.second=cs;
uint32_t h = hash(0, cs.get_data());
Pair<int, CharString> p;
p.first = idx;
p.second = cs;
buckets[h % size].push_back(p);
//compress string
CharString src_s = p_from->get_message(E->get()).operator String().utf8();
_PHashTranslationCmp ps;
ps.orig_len=src_s.size();
ps.offset=total_compression_size;
ps.orig_len = src_s.size();
ps.offset = total_compression_size;
if (ps.orig_len!=0) {
if (ps.orig_len != 0) {
CharString dst_s;
dst_s.resize(src_s.size());
int ret = smaz_compress(src_s.get_data(),src_s.size(),&dst_s[0],src_s.size());
if (ret>=src_s.size()) {
int ret = smaz_compress(src_s.get_data(), src_s.size(), &dst_s[0], src_s.size());
if (ret >= src_s.size()) {
//if compressed is larger than original, just use original
ps.orig_len=src_s.size();
ps.compressed=src_s;
ps.orig_len = src_s.size();
ps.compressed = src_s;
} else {
dst_s.resize(ret);
//ps.orig_len=;
ps.compressed=dst_s;
ps.compressed = dst_s;
}
} else {
ps.orig_len=1;
ps.orig_len = 1;
ps.compressed.resize(1);
ps.compressed[0]=0;
ps.compressed[0] = 0;
}
compressed[idx]=ps;
total_compression_size+=ps.compressed.size();
total_string_size+=src_s.size();
compressed[idx] = ps;
total_compression_size += ps.compressed.size();
total_string_size += src_s.size();
idx++;
}
int bucket_table_size=0;
print_line("total compressed string size: "+itos(total_compression_size)+" ("+itos(total_string_size)+" uncompressed).");
int bucket_table_size = 0;
print_line("total compressed string size: " + itos(total_compression_size) + " (" + itos(total_string_size) + " uncompressed).");
for(int i=0;i<size;i++) {
for (int i = 0; i < size; i++) {
Vector< Pair<int,CharString> > &b = buckets[i];
Map< uint32_t, int > &t=table[i];
Vector<Pair<int, CharString> > &b = buckets[i];
Map<uint32_t, int> &t = table[i];
if (b.size()==0)
if (b.size() == 0)
continue;
//print_line("bucket: "+itos(i)+" - elements: "+itos(b.size()));
int d = 1;
int item =0;
int item = 0;
while(item < b.size()) {
while (item < b.size()) {
uint32_t slot = hash(d,b[item].second.get_data());
uint32_t slot = hash(d, b[item].second.get_data());
if (t.has(slot)) {
item=0;
item = 0;
d++;
t.clear();
} else {
t[slot]=b[item].first;
t[slot] = b[item].first;
item++;
}
}
hfunc_table[i]=d;
bucket_table_size+=2+b.size()*4;
hfunc_table[i] = d;
bucket_table_size += 2 + b.size() * 4;
}
print_line("bucket table size: "+itos(bucket_table_size*4));
print_line("hash table size: "+itos(size*4));
print_line("bucket table size: " + itos(bucket_table_size * 4));
print_line("hash table size: " + itos(size * 4));
hash_table.resize(size);
bucket_table.resize(bucket_table_size);
@ -359,176 +353,166 @@ void PHashTranslation::generate(const Ref<Translation> &p_from) {
DVector<int>::Write htwb = hash_table.write();
DVector<int>::Write btwb = bucket_table.write();
uint32_t *htw = (uint32_t*)&htwb[0];
uint32_t *btw = (uint32_t*)&btwb[0];
uint32_t *htw = (uint32_t *)&htwb[0];
uint32_t *btw = (uint32_t *)&btwb[0];
int btindex=0;
int collisions=0;
int btindex = 0;
int collisions = 0;
for(int i=0;i<size;i++) {
for (int i = 0; i < size; i++) {
Map< uint32_t, int > &t=table[i];
if (t.size()==0) {
htw[i]=0xFFFFFFFF; //nothing
Map<uint32_t, int> &t = table[i];
if (t.size() == 0) {
htw[i] = 0xFFFFFFFF; //nothing
continue;
} else if (t.size()>1) {
collisions+=t.size()-1;
} else if (t.size() > 1) {
collisions += t.size() - 1;
}
htw[i]=btindex;
btw[btindex++]=t.size();
btw[btindex++]=hfunc_table[i];
htw[i] = btindex;
btw[btindex++] = t.size();
btw[btindex++] = hfunc_table[i];
for( Map< uint32_t, int >::Element *E=t.front();E;E=E->next()) {
for (Map<uint32_t, int>::Element *E = t.front(); E; E = E->next()) {
btw[btindex++]=E->key();
btw[btindex++]=compressed[E->get()].offset;
btw[btindex++]=compressed[E->get()].compressed.size();
btw[btindex++]=compressed[E->get()].orig_len;
btw[btindex++] = E->key();
btw[btindex++] = compressed[E->get()].offset;
btw[btindex++] = compressed[E->get()].compressed.size();
btw[btindex++] = compressed[E->get()].orig_len;
}
}
print_line("total collisions: "+itos(collisions));
print_line("total collisions: " + itos(collisions));
strings.resize(total_compression_size);
DVector<uint8_t>::Write cw = strings.write();
for(int i=0;i<compressed.size();i++) {
memcpy(&cw[compressed[i].offset],compressed[i].compressed.get_data(),compressed[i].compressed.size());
for (int i = 0; i < compressed.size(); i++) {
memcpy(&cw[compressed[i].offset], compressed[i].compressed.get_data(), compressed[i].compressed.size());
}
ERR_FAIL_COND(btindex!=bucket_table_size);
ERR_FAIL_COND(btindex != bucket_table_size);
set_locale(p_from->get_locale());
#endif
}
bool PHashTranslation::_set(const StringName& p_name, const Variant& p_value) {
bool PHashTranslation::_set(const StringName &p_name, const Variant &p_value) {
String name = p_name.operator String();
if (name=="hash_table") {
hash_table=p_value;
if (name == "hash_table") {
hash_table = p_value;
//print_line("translation: loaded hash table of size: "+itos(hash_table.size()));
} else if (name=="bucket_table") {
bucket_table=p_value;
} else if (name == "bucket_table") {
bucket_table = p_value;
//print_line("translation: loaded bucket table of size: "+itos(bucket_table.size()));
} else if (name=="strings") {
strings=p_value;
} else if (name == "strings") {
strings = p_value;
//print_line("translation: loaded string table of size: "+itos(strings.size()));
} else if (name=="load_from") {
} else if (name == "load_from") {
//print_line("generating");
generate(p_value);
} else
return false;
return true;
}
bool PHashTranslation::_get(const StringName& p_name,Variant &r_ret) const{
bool PHashTranslation::_get(const StringName &p_name, Variant &r_ret) const {
String name = p_name.operator String();
if (name=="hash_table")
r_ret=hash_table;
else if (name=="bucket_table")
r_ret=bucket_table;
else if (name=="strings")
r_ret=strings;
if (name == "hash_table")
r_ret = hash_table;
else if (name == "bucket_table")
r_ret = bucket_table;
else if (name == "strings")
r_ret = strings;
else
return false;
return true;
}
StringName PHashTranslation::get_message(const StringName& p_src_text) const {
StringName PHashTranslation::get_message(const StringName &p_src_text) const {
int htsize = hash_table.size();
if (htsize==0)
if (htsize == 0)
return StringName();
CharString str = p_src_text.operator String().utf8();
uint32_t h = hash(0,str.get_data());
uint32_t h = hash(0, str.get_data());
DVector<int>::Read htr = hash_table.read();
const uint32_t *htptr = (const uint32_t*)&htr[0];
DVector<int>::Read btr = bucket_table.read();
const uint32_t *btptr = (const uint32_t*)&btr[0];
DVector<int>::Read htr = hash_table.read();
const uint32_t *htptr = (const uint32_t *)&htr[0];
DVector<int>::Read btr = bucket_table.read();
const uint32_t *btptr = (const uint32_t *)&btr[0];
DVector<uint8_t>::Read sr = strings.read();
const char *sptr= (const char*)&sr[0];
const char *sptr = (const char *)&sr[0];
uint32_t p = htptr[ h % htsize];
uint32_t p = htptr[h % htsize];
//print_line("String: "+p_src_text.operator String());
//print_line("Hash: "+itos(p));
if (p==0xFFFFFFFF) {
// print_line("GETMSG: Nothing!");
if (p == 0xFFFFFFFF) {
// print_line("GETMSG: Nothing!");
return StringName(); //nothing
}
const Bucket &bucket = *(const Bucket*)&btptr[p];
const Bucket &bucket = *(const Bucket *)&btptr[p];
h = hash(bucket.func,str.get_data());
h = hash(bucket.func, str.get_data());
int idx=-1;
int idx = -1;
for(int i=0;i<bucket.size;i++) {
for (int i = 0; i < bucket.size; i++) {
if (bucket.elem[i].key==h) {
if (bucket.elem[i].key == h) {
idx=i;
idx = i;
break;
}
}
//print_line("bucket pos: "+itos(idx));
if (idx==-1) {
// print_line("GETMSG: Not in Bucket!");
if (idx == -1) {
// print_line("GETMSG: Not in Bucket!");
return StringName();
}
if (bucket.elem[idx].comp_size == bucket.elem[idx].uncomp_size) {
String rstr;
rstr.parse_utf8(&sptr[ bucket.elem[idx].str_offset ], bucket.elem[idx].uncomp_size );
// print_line("Uncompressed, size: "+itos(bucket.elem[idx].comp_size));
// print_line("Return: "+rstr);
rstr.parse_utf8(&sptr[bucket.elem[idx].str_offset], bucket.elem[idx].uncomp_size);
// print_line("Uncompressed, size: "+itos(bucket.elem[idx].comp_size));
// print_line("Return: "+rstr);
return rstr;
} else {
CharString uncomp;
uncomp.resize( bucket.elem[idx].uncomp_size+1 );
smaz_decompress(&sptr[ bucket.elem[idx].str_offset ], bucket.elem[idx].comp_size,uncomp.ptr(),bucket.elem[idx].uncomp_size );
uncomp.resize(bucket.elem[idx].uncomp_size + 1);
smaz_decompress(&sptr[bucket.elem[idx].str_offset], bucket.elem[idx].comp_size, uncomp.ptr(), bucket.elem[idx].uncomp_size);
String rstr;
rstr.parse_utf8(uncomp.get_data());
// print_line("Compressed, size: "+itos(bucket.elem[idx].comp_size));
// print_line("Return: "+rstr);
// print_line("Compressed, size: "+itos(bucket.elem[idx].comp_size));
// print_line("Return: "+rstr);
return rstr;
}
}
void PHashTranslation::_get_property_list(List<PropertyInfo> *p_list) const {
void PHashTranslation::_get_property_list( List<PropertyInfo> *p_list) const{
p_list->push_back( PropertyInfo(Variant::INT_ARRAY, "hash_table"));
p_list->push_back( PropertyInfo(Variant::INT_ARRAY, "bucket_table"));
p_list->push_back( PropertyInfo(Variant::RAW_ARRAY, "strings"));
p_list->push_back( PropertyInfo(Variant::OBJECT, "load_from",PROPERTY_HINT_RESOURCE_TYPE,"Translation",PROPERTY_USAGE_EDITOR));
p_list->push_back(PropertyInfo(Variant::INT_ARRAY, "hash_table"));
p_list->push_back(PropertyInfo(Variant::INT_ARRAY, "bucket_table"));
p_list->push_back(PropertyInfo(Variant::RAW_ARRAY, "strings"));
p_list->push_back(PropertyInfo(Variant::OBJECT, "load_from", PROPERTY_HINT_RESOURCE_TYPE, "Translation", PROPERTY_USAGE_EDITOR));
}
void PHashTranslation::_bind_methods() {
ObjectTypeDB::bind_method(_MD("generate","from:Translation"),&PHashTranslation::generate);
ObjectTypeDB::bind_method(_MD("generate", "from:Translation"), &PHashTranslation::generate);
}
PHashTranslation::PHashTranslation()
{
PHashTranslation::PHashTranslation() {
}

View File

@ -33,8 +33,7 @@
class PHashTranslation : public Translation {
OBJ_TYPE(PHashTranslation,Translation);
OBJ_TYPE(PHashTranslation, Translation);
//this translation uses a sort of modified perfect hash algorithm
//it requieres hashing strings twice and then does a binary search,
@ -46,7 +45,6 @@ class PHashTranslation : public Translation {
DVector<int> bucket_table;
DVector<uint8_t> strings;
struct Bucket {
int size;
@ -63,11 +61,11 @@ class PHashTranslation : public Translation {
Elem elem[1];
};
_FORCE_INLINE_ uint32_t hash( uint32_t d, const char *p_str ) const {
_FORCE_INLINE_ uint32_t hash(uint32_t d, const char *p_str) const {
if (d==0)
d=0x1000193;
while(*p_str) {
if (d == 0)
d = 0x1000193;
while (*p_str) {
d = (d * 0x1000193) ^ uint32_t(*p_str);
p_str++;
@ -75,16 +73,15 @@ class PHashTranslation : public Translation {
return d;
}
protected:
bool _set(const StringName& p_name, const Variant& p_value);
bool _get(const StringName& p_name,Variant &r_ret) const;
void _get_property_list( List<PropertyInfo> *p_list) const;
protected:
bool _set(const StringName &p_name, const Variant &p_value);
bool _get(const StringName &p_name, Variant &r_ret) const;
void _get_property_list(List<PropertyInfo> *p_list) const;
static void _bind_methods();
public:
virtual StringName get_message(const StringName& p_src_text) const; //overridable for other implementations
virtual StringName get_message(const StringName &p_src_text) const; //overridable for other implementations
void generate(const Ref<Translation> &p_from);
PHashTranslation();

View File

@ -28,21 +28,19 @@
/*************************************************************************/
#include "core_string_names.h"
CoreStringNames* CoreStringNames::singleton=NULL;
CoreStringNames *CoreStringNames::singleton = NULL;
CoreStringNames::CoreStringNames() {
_free=StaticCString::create("free");
changed=StaticCString::create("changed");
_meta=StaticCString::create("__meta__");
_script=StaticCString::create("script/script");
script_changed=StaticCString::create("script_changed");
___pdcdata=StaticCString::create("___pdcdata");
__getvar=StaticCString::create("__getvar");
_iter_init=StaticCString::create("_iter_init");
_iter_next=StaticCString::create("_iter_next");
_iter_get=StaticCString::create("_iter_get");
get_rid=StaticCString::create("get_rid");
_free = StaticCString::create("free");
changed = StaticCString::create("changed");
_meta = StaticCString::create("__meta__");
_script = StaticCString::create("script/script");
script_changed = StaticCString::create("script_changed");
___pdcdata = StaticCString::create("___pdcdata");
__getvar = StaticCString::create("__getvar");
_iter_init = StaticCString::create("_iter_init");
_iter_next = StaticCString::create("_iter_next");
_iter_get = StaticCString::create("_iter_get");
get_rid = StaticCString::create("get_rid");
}

View File

@ -33,18 +33,21 @@
class CoreStringNames {
friend void register_core_types();
friend void unregister_core_types();
friend void register_core_types();
friend void unregister_core_types();
static CoreStringNames* singleton;
static CoreStringNames *singleton;
static void create() { singleton = memnew(CoreStringNames); }
static void free() { memdelete( singleton); singleton=NULL; }
static void free() {
memdelete(singleton);
singleton = NULL;
}
CoreStringNames();
public:
_FORCE_INLINE_ static CoreStringNames* get_singleton() { return singleton; }
public:
_FORCE_INLINE_ static CoreStringNames *get_singleton() { return singleton; }
StringName _free;
StringName changed;
@ -57,7 +60,6 @@ public:
StringName _iter_next;
StringName _iter_get;
StringName get_rid;
};
#endif // SCENE_STRING_NAMES_H

View File

@ -27,26 +27,23 @@
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
/*************************************************************************/
#include "dictionary.h"
#include "io/json.h"
#include "safe_refcount.h"
#include "variant.h"
#include "io/json.h"
struct _DictionaryVariantHash {
static _FORCE_INLINE_ uint32_t hash(const Variant &p_variant) { return p_variant.hash(); }
static _FORCE_INLINE_ uint32_t hash(const Variant &p_variant) { return p_variant.hash(); }
};
struct DictionaryPrivate {
SafeRefCount refcount;
HashMap<Variant,Variant,_DictionaryVariantHash> variant_map;
HashMap<Variant, Variant, _DictionaryVariantHash> variant_map;
bool shared;
};
void Dictionary::get_key_list( List<Variant> *p_keys) const {
void Dictionary::get_key_list(List<Variant> *p_keys) const {
_p->variant_map.get_key_list(p_keys);
}
@ -58,36 +55,35 @@ void Dictionary::_copy_on_write() const {
return;
DictionaryPrivate *p = memnew(DictionaryPrivate);
p->shared=_p->shared;
p->variant_map=_p->variant_map;
p->shared = _p->shared;
p->variant_map = _p->variant_map;
p->refcount.init();
_unref();
_p=p;
_p = p;
}
Variant& Dictionary::operator[](const Variant& p_key) {
Variant &Dictionary::operator[](const Variant &p_key) {
_copy_on_write();
return _p->variant_map[p_key];
}
const Variant& Dictionary::operator[](const Variant& p_key) const {
const Variant &Dictionary::operator[](const Variant &p_key) const {
return _p->variant_map[p_key];
}
const Variant* Dictionary::getptr(const Variant& p_key) const {
const Variant *Dictionary::getptr(const Variant &p_key) const {
return _p->variant_map.getptr(p_key);
}
Variant* Dictionary::getptr(const Variant& p_key) {
Variant *Dictionary::getptr(const Variant &p_key) {
_copy_on_write();
return _p->variant_map.getptr(p_key);
}
Variant Dictionary::get_valid(const Variant& p_key) const {
Variant Dictionary::get_valid(const Variant &p_key) const {
const Variant *v = getptr(p_key);
if (!v)
@ -95,56 +91,53 @@ Variant Dictionary::get_valid(const Variant& p_key) const {
return *v;
}
int Dictionary::size() const {
return _p->variant_map.size();
}
bool Dictionary::empty() const {
return !_p->variant_map.size();
}
bool Dictionary::has(const Variant& p_key) const {
bool Dictionary::has(const Variant &p_key) const {
return _p->variant_map.has(p_key);
}
bool Dictionary::has_all(const Array& p_keys) const {
for (int i=0;i<p_keys.size();i++) {
if( !has(p_keys[i]) ) {
bool Dictionary::has_all(const Array &p_keys) const {
for (int i = 0; i < p_keys.size(); i++) {
if (!has(p_keys[i])) {
return false;
}
}
return true;
}
void Dictionary::erase(const Variant& p_key) {
void Dictionary::erase(const Variant &p_key) {
_copy_on_write();
_p->variant_map.erase(p_key);
}
bool Dictionary::operator==(const Dictionary& p_dictionary) const {
bool Dictionary::operator==(const Dictionary &p_dictionary) const {
return _p==p_dictionary._p;
return _p == p_dictionary._p;
}
void Dictionary::_ref(const Dictionary& p_from) const {
void Dictionary::_ref(const Dictionary &p_from) const {
//make a copy first (thread safe)
if (!p_from._p->refcount.ref())
return; // couldn't copy
//if this is the same, unreference the other one
if (p_from._p==_p) {
if (p_from._p == _p) {
_p->refcount.unref();
return;
}
if (_p)
_unref();
_p=p_from._p;
_p = p_from._p;
}
void Dictionary::clear() {
@ -155,34 +148,30 @@ void Dictionary::clear() {
bool Dictionary::is_shared() const {
return _p->shared;
return _p->shared;
}
void Dictionary::_unref() const {
ERR_FAIL_COND(!_p);
if (_p->refcount.unref()) {
memdelete(_p);
}
_p=NULL;
_p = NULL;
}
uint32_t Dictionary::hash() const {
uint32_t h=hash_djb2_one_32(Variant::DICTIONARY);
uint32_t h = hash_djb2_one_32(Variant::DICTIONARY);
List<Variant> keys;
get_key_list(&keys);
for (List<Variant>::Element *E=keys.front();E;E=E->next()) {
h = hash_djb2_one_32( E->get().hash(), h);
h = hash_djb2_one_32( operator[](E->get()).hash(), h);
for (List<Variant>::Element *E = keys.front(); E; E = E->next()) {
h = hash_djb2_one_32(E->get().hash(), h);
h = hash_djb2_one_32(operator[](E->get()).hash(), h);
}
return h;
}
@ -190,42 +179,40 @@ Array Dictionary::keys() const {
Array karr;
karr.resize(size());
const Variant *K=NULL;
int idx=0;
while((K=next(K))) {
karr[idx++]=(*K);
const Variant *K = NULL;
int idx = 0;
while ((K = next(K))) {
karr[idx++] = (*K);
}
return karr;
}
Array Dictionary::values() const {
Array varr;
varr.resize(size());
const Variant *key=NULL;
int i=0;
while((key=next(key))){
const Variant *key = NULL;
int i = 0;
while ((key = next(key))) {
varr[i++] = _p->variant_map[*key];
}
return varr;
}
const Variant* Dictionary::next(const Variant* p_key) const {
const Variant *Dictionary::next(const Variant *p_key) const {
return _p->variant_map.next(p_key);
}
Error Dictionary::parse_json(const String& p_json) {
Error Dictionary::parse_json(const String &p_json) {
String errstr;
int errline=0;
if (p_json != ""){
Error err = JSON::parse(p_json,*this,errstr,errline);
if (err!=OK) {
ERR_EXPLAIN("Error parsing JSON: "+errstr+" at line: "+itos(errline));
ERR_FAIL_COND_V(err!=OK,err);
int errline = 0;
if (p_json != "") {
Error err = JSON::parse(p_json, *this, errstr, errline);
if (err != OK) {
ERR_EXPLAIN("Error parsing JSON: " + errstr + " at line: " + itos(errline));
ERR_FAIL_COND_V(err != OK, err);
}
}
@ -237,26 +224,21 @@ String Dictionary::to_json() const {
return JSON::print(*this);
}
void Dictionary::operator=(const Dictionary& p_dictionary) {
void Dictionary::operator=(const Dictionary &p_dictionary) {
_ref(p_dictionary);
}
Dictionary::Dictionary(const Dictionary& p_from) {
_p=NULL;
Dictionary::Dictionary(const Dictionary &p_from) {
_p = NULL;
_ref(p_from);
}
Dictionary::Dictionary(bool p_shared) {
_p=memnew( DictionaryPrivate );
_p = memnew(DictionaryPrivate);
_p->refcount.init();
_p->shared=p_shared;
_p->shared = p_shared;
}
Dictionary::~Dictionary() {

View File

@ -29,62 +29,58 @@
#ifndef DICTIONARY_H
#define DICTIONARY_H
#include "list.h"
#include "array.h"
#include "list.h"
#include "ustring.h"
class Variant;
struct DictionaryPrivate;
class Dictionary {
mutable DictionaryPrivate *_p;
void _copy_on_write() const;
void _ref(const Dictionary& p_from) const;
void _ref(const Dictionary &p_from) const;
void _unref() const;
public:
void get_key_list(List<Variant> *p_keys) const;
void get_key_list( List<Variant> *p_keys) const;
Variant &operator[](const Variant &p_key);
const Variant &operator[](const Variant &p_key) const;
Variant& operator[](const Variant& p_key);
const Variant& operator[](const Variant& p_key) const;
const Variant *getptr(const Variant &p_key) const;
Variant *getptr(const Variant &p_key);
const Variant* getptr(const Variant& p_key) const;
Variant* getptr(const Variant& p_key);
Variant get_valid(const Variant& p_key) const;
Variant get_valid(const Variant &p_key) const;
int size() const;
bool empty() const;
void clear();
Error parse_json(const String& p_json);
Error parse_json(const String &p_json);
String to_json() const;
bool is_shared() const;
bool has(const Variant& p_key) const;
bool has_all(const Array& p_keys) const;
bool has(const Variant &p_key) const;
bool has_all(const Array &p_keys) const;
void erase(const Variant& p_key);
void erase(const Variant &p_key);
bool operator==(const Dictionary& p_dictionary) const;
bool operator==(const Dictionary &p_dictionary) const;
uint32_t hash() const;
void operator=(const Dictionary& p_dictionary);
void operator=(const Dictionary &p_dictionary);
const Variant* next(const Variant* p_key=NULL) const;
const Variant *next(const Variant *p_key = NULL) const;
Array keys() const;
Array values() const;
Dictionary(const Dictionary& p_from);
Dictionary(bool p_shared=false);
Dictionary(const Dictionary &p_from);
Dictionary(bool p_shared = false);
~Dictionary();
};

View File

@ -28,5 +28,4 @@
/*************************************************************************/
#include "dvector.h"
Mutex* dvector_lock=NULL;
Mutex *dvector_lock = NULL;

View File

@ -31,20 +31,17 @@
#include "os/memory.h"
/**
@author Juan Linietsky <reduzio@gmail.com>
*/
extern Mutex *dvector_lock;
extern Mutex* dvector_lock;
template<class T>
template <class T>
class DVector {
mutable MID mem;
void copy_on_write() {
if (!mem.is_valid())
@ -53,56 +50,54 @@ class DVector {
if (dvector_lock)
dvector_lock->lock();
MID_Lock lock( mem );
MID_Lock lock(mem);
if ( *(int*)lock.data() == 1 ) {
if (*(int *)lock.data() == 1) {
// one reference, means no refcount changes
if (dvector_lock)
dvector_lock->unlock();
return;
}
MID new_mem= dynalloc( mem.get_size() );
MID new_mem = dynalloc(mem.get_size());
if (!new_mem.is_valid()) {
if (dvector_lock)
dvector_lock->unlock();
ERR_FAIL_COND( new_mem.is_valid() ); // out of memory
ERR_FAIL_COND(new_mem.is_valid()); // out of memory
}
MID_Lock dst_lock( new_mem );
MID_Lock dst_lock(new_mem);
int *rc = (int*)dst_lock.data();
int *rc = (int *)dst_lock.data();
*rc=1;
*rc = 1;
T * dst = (T*)(rc + 1 );
T *dst = (T *)(rc + 1);
T * src =(T*) ((int*)lock.data() + 1 );
T *src = (T *)((int *)lock.data() + 1);
int count = (mem.get_size() - sizeof(int)) / sizeof(T);
for (int i=0;i<count;i++) {
for (int i = 0; i < count; i++) {
memnew_placement( &dst[i], T(src[i]) );
memnew_placement(&dst[i], T(src[i]));
}
(*(int*)lock.data())--;
(*(int *)lock.data())--;
// unlock all
dst_lock=MID_Lock();
lock=MID_Lock();
dst_lock = MID_Lock();
lock = MID_Lock();
mem=new_mem;
mem = new_mem;
if (dvector_lock)
dvector_lock->unlock();
}
void reference( const DVector& p_dvector ) {
void reference(const DVector &p_dvector) {
unreference();
@ -118,18 +113,16 @@ class DVector {
MID_Lock lock(p_dvector.mem);
int * rc = (int*)lock.data();
int *rc = (int *)lock.data();
(*rc)++;
lock = MID_Lock();
mem=p_dvector.mem;
mem = p_dvector.mem;
if (dvector_lock)
dvector_lock->unlock();
}
void unreference() {
if (dvector_lock)
@ -144,65 +137,60 @@ class DVector {
MID_Lock lock(mem);
int * rc = (int*)lock.data();
int *rc = (int *)lock.data();
(*rc)--;
if (*rc==0) {
if (*rc == 0) {
// no one else using it, destruct
T * t= (T*)(rc+1);
T *t = (T *)(rc + 1);
int count = (mem.get_size() - sizeof(int)) / sizeof(T);
for (int i=0;i<count;i++) {
for (int i = 0; i < count; i++) {
t[i].~T();
}
}
lock = MID_Lock();
mem = MID ();
mem = MID();
if (dvector_lock)
dvector_lock->unlock();
}
public:
class Read {
friend class DVector;
friend class DVector;
MID_Lock lock;
const T * mem;
public:
const T *mem;
_FORCE_INLINE_ const T& operator[](int p_index) const { return mem[p_index]; }
public:
_FORCE_INLINE_ const T &operator[](int p_index) const { return mem[p_index]; }
_FORCE_INLINE_ const T *ptr() const { return mem; }
Read() { mem=NULL; }
Read() { mem = NULL; }
};
class Write {
friend class DVector;
friend class DVector;
MID_Lock lock;
T * mem;
public:
T *mem;
_FORCE_INLINE_ T& operator[](int p_index) { return mem[p_index]; }
public:
_FORCE_INLINE_ T &operator[](int p_index) { return mem[p_index]; }
_FORCE_INLINE_ T *ptr() { return mem; }
Write() { mem=NULL; }
Write() { mem = NULL; }
};
Read read() const {
Read r;
if (mem.is_valid()) {
r.lock = MID_Lock( mem );
r.mem = (const T*)((int*)r.lock.data()+1);
r.lock = MID_Lock(mem);
r.mem = (const T *)((int *)r.lock.data() + 1);
}
return r;
}
@ -211,74 +199,70 @@ public:
Write w;
if (mem.is_valid()) {
copy_on_write();
w.lock = MID_Lock( mem );
w.mem = (T*)((int*)w.lock.data()+1);
w.lock = MID_Lock(mem);
w.mem = (T *)((int *)w.lock.data() + 1);
}
return w;
}
template<class MC>
void fill_with(const MC& p_mc) {
template <class MC>
void fill_with(const MC &p_mc) {
int c=p_mc.size();
int c = p_mc.size();
resize(c);
Write w=write();
int idx=0;
for(const typename MC::Element *E=p_mc.front();E;E=E->next()) {
Write w = write();
int idx = 0;
for (const typename MC::Element *E = p_mc.front(); E; E = E->next()) {
w[idx++]=E->get();
w[idx++] = E->get();
}
}
void remove(int p_index) {
int s = size();
ERR_FAIL_INDEX(p_index, s);
Write w = write();
for (int i=p_index; i<s-1; i++) {
for (int i = p_index; i < s - 1; i++) {
w[i]=w[i+1];
w[i] = w[i + 1];
};
w = Write();
resize(s-1);
resize(s - 1);
}
inline int size() const;
T get(int p_index) const;
void set(int p_index, const T& p_val);
void push_back(const T& p_val);
void append(const T& p_val) { push_back(p_val); }
void append_array(const DVector<T>& p_arr) {
void set(int p_index, const T &p_val);
void push_back(const T &p_val);
void append(const T &p_val) { push_back(p_val); }
void append_array(const DVector<T> &p_arr) {
int ds = p_arr.size();
if (ds==0)
if (ds == 0)
return;
int bs = size();
resize( bs + ds);
resize(bs + ds);
Write w = write();
Read r = p_arr.read();
for(int i=0;i<ds;i++)
w[bs+i]=r[i];
for (int i = 0; i < ds; i++)
w[bs + i] = r[i];
}
Error insert(int p_pos, const T &p_val) {
Error insert(int p_pos,const T& p_val) {
int s=size();
ERR_FAIL_INDEX_V(p_pos,s+1,ERR_INVALID_PARAMETER);
resize(s+1);
int s = size();
ERR_FAIL_INDEX_V(p_pos, s + 1, ERR_INVALID_PARAMETER);
resize(s + 1);
{
Write w = write();
for (int i=s;i>p_pos;i--)
w[i]=w[i-1];
w[p_pos]=p_val;
for (int i = s; i > p_pos; i--)
w[i] = w[i - 1];
w[p_pos] = p_val;
}
return OK;
}
bool is_locked() const { return mem.is_locked(); }
inline const T operator[](int p_index) const;
@ -287,49 +271,48 @@ public:
void invert();
void operator=(const DVector& p_dvector) { reference(p_dvector); }
void operator=(const DVector &p_dvector) { reference(p_dvector); }
DVector() {}
DVector(const DVector& p_dvector) { reference(p_dvector); }
DVector(const DVector &p_dvector) { reference(p_dvector); }
~DVector() { unreference(); }
};
template<class T>
template <class T>
int DVector<T>::size() const {
return mem.is_valid() ? ((mem.get_size() - sizeof(int)) / sizeof(T) ) : 0;
return mem.is_valid() ? ((mem.get_size() - sizeof(int)) / sizeof(T)) : 0;
}
template<class T>
template <class T>
T DVector<T>::get(int p_index) const {
return operator[](p_index);
}
template<class T>
void DVector<T>::set(int p_index, const T& p_val) {
template <class T>
void DVector<T>::set(int p_index, const T &p_val) {
if (p_index<0 || p_index>=size()) {
ERR_FAIL_COND(p_index<0 || p_index>=size());
if (p_index < 0 || p_index >= size()) {
ERR_FAIL_COND(p_index < 0 || p_index >= size());
}
Write w = write();
w[p_index]=p_val;
w[p_index] = p_val;
}
template<class T>
void DVector<T>::push_back(const T& p_val) {
template <class T>
void DVector<T>::push_back(const T &p_val) {
resize( size() + 1 );
set( size() -1, p_val );
resize(size() + 1);
set(size() - 1, p_val);
}
template<class T>
template <class T>
const T DVector<T>::operator[](int p_index) const {
if (p_index<0 || p_index>=size()) {
T& aux=*((T*)0); //nullreturn
ERR_FAIL_COND_V(p_index<0 || p_index>=size(),aux);
if (p_index < 0 || p_index >= size()) {
T &aux = *((T *)0); //nullreturn
ERR_FAIL_COND_V(p_index < 0 || p_index >= size(), aux);
}
Read r = read();
@ -337,14 +320,13 @@ const T DVector<T>::operator[](int p_index) const {
return r[p_index];
}
template<class T>
template <class T>
Error DVector<T>::resize(int p_size) {
if (dvector_lock)
dvector_lock->lock();
bool same = p_size==size();
bool same = p_size == size();
if (dvector_lock)
dvector_lock->unlock();
@ -353,89 +335,82 @@ Error DVector<T>::resize(int p_size) {
if (same)
return OK;
if (p_size == 0 ) {
if (p_size == 0) {
unreference();
return OK;
}
copy_on_write(); // make it unique
ERR_FAIL_COND_V( mem.is_locked(), ERR_LOCKED ); // if after copy on write, memory is locked, fail.
ERR_FAIL_COND_V(mem.is_locked(), ERR_LOCKED); // if after copy on write, memory is locked, fail.
if (p_size > size() ) {
if (p_size > size()) {
int oldsize=size();
int oldsize = size();
MID_Lock lock;
if (oldsize==0) {
if (oldsize == 0) {
mem = dynalloc( p_size * sizeof(T) + sizeof(int) );
lock=MID_Lock(mem);
int *rc = ((int*)lock.data());
*rc=1;
mem = dynalloc(p_size * sizeof(T) + sizeof(int));
lock = MID_Lock(mem);
int *rc = ((int *)lock.data());
*rc = 1;
} else {
if (dynrealloc( mem, p_size * sizeof(T) + sizeof(int) )!=OK ) {
if (dynrealloc(mem, p_size * sizeof(T) + sizeof(int)) != OK) {
ERR_FAIL_V(ERR_OUT_OF_MEMORY); // out of memory
}
lock=MID_Lock(mem);
lock = MID_Lock(mem);
}
T *t = (T *)((int *)lock.data() + 1);
for (int i = oldsize; i < p_size; i++) {
T *t = (T*)((int*)lock.data() + 1);
for (int i=oldsize;i<p_size;i++) {
memnew_placement(&t[i], T );
memnew_placement(&t[i], T);
}
lock = MID_Lock(); // clear
} else {
int oldsize=size();
int oldsize = size();
MID_Lock lock(mem);
T *t = (T *)((int *)lock.data() + 1);
T *t = (T*)((int*)lock.data() + 1);
for (int i=p_size;i<oldsize;i++) {
for (int i = p_size; i < oldsize; i++) {
t[i].~T();
}
lock = MID_Lock(); // clear
if (dynrealloc( mem, p_size * sizeof(T) + sizeof(int) )!=OK ) {
if (dynrealloc(mem, p_size * sizeof(T) + sizeof(int)) != OK) {
ERR_FAIL_V(ERR_OUT_OF_MEMORY); // wtf error
}
}
return OK;
}
template<class T>
template <class T>
void DVector<T>::invert() {
T temp;
Write w = write();
int s = size();
int half_s = s/2;
int half_s = s / 2;
for(int i=0;i<half_s;i++) {
for (int i = 0; i < half_s; i++) {
temp = w[i];
w[i] = w[s-i-1];
w[s-i-1] = temp;
w[i] = w[s - i - 1];
w[s - i - 1] = temp;
}
}

View File

@ -47,7 +47,7 @@ enum Error {
ERR_FILE_NOT_FOUND,
ERR_FILE_BAD_DRIVE,
ERR_FILE_BAD_PATH,
ERR_FILE_NO_PERMISSION, // (10)
ERR_FILE_NO_PERMISSION, // (10)
ERR_FILE_ALREADY_IN_USE,
ERR_FILE_CANT_OPEN,
ERR_FILE_CANT_WRITE,
@ -57,15 +57,15 @@ enum Error {
ERR_FILE_MISSING_DEPENDENCIES,
ERR_FILE_EOF,
ERR_CANT_OPEN, ///< Can't open a resource/socket/file
ERR_CANT_CREATE, // (20)
ERR_CANT_CREATE, // (20)
ERROR_QUERY_FAILED,
ERR_ALREADY_IN_USE,
ERR_LOCKED, ///< resource is locked
ERR_TIMEOUT,
ERR_CANT_CONNECT, // (25)
ERR_LOCKED, ///< resource is locked
ERR_TIMEOUT,
ERR_CANT_CONNECT, // (25)
ERR_CANT_RESOLVE,
ERR_CONNECTION_ERROR,
ERR_CANT_AQUIRE_RESOURCE,
ERR_CANT_AQUIRE_RESOURCE,
ERR_CANT_FORK,
ERR_INVALID_DATA, ///< Data passed is invalid (30)
ERR_INVALID_PARAMETER, ///< Parameter passed is invalid
@ -74,15 +74,15 @@ enum Error {
ERR_DATABASE_CANT_READ, ///< database is full
ERR_DATABASE_CANT_WRITE, ///< database is full (35)
ERR_COMPILATION_FAILED,
ERR_METHOD_NOT_FOUND,
ERR_LINK_FAILED,
ERR_METHOD_NOT_FOUND,
ERR_LINK_FAILED,
ERR_SCRIPT_FAILED,
ERR_CYCLIC_LINK, // (40)
ERR_CYCLIC_LINK, // (40)
ERR_INVALID_DECLARATION,
ERR_DUPLICATE_SYMBOL,
ERR_PARSE_ERROR,
ERR_BUSY,
ERR_SKIP, // (45)
ERR_SKIP, // (45)
ERR_HELP, ///< user requested help!!
ERR_BUG, ///< a bug in the software certainly happened, due to a double check failing or unexpected behavior.
ERR_PRINTER_ON_FIRE, /// the parallel port printer is engulfed in flames
@ -90,7 +90,4 @@ enum Error {
ERR_WTF = ERR_OMFG_THIS_IS_VERY_VERY_BAD ///< short version of the above
};
#endif

View File

@ -29,12 +29,11 @@
#include "error_macros.h"
#include "os/os.h"
bool _err_error_exists = false;
bool _err_error_exists=false;
static ErrorHandlerList *error_handler_list = NULL;
static ErrorHandlerList *error_handler_list=NULL;
void _err_set_last_error(const char* p_err) {
void _err_set_last_error(const char *p_err) {
OS::get_singleton()->set_last_error(p_err);
}
@ -47,8 +46,8 @@ void _err_clear_last_error() {
void add_error_handler(ErrorHandlerList *p_handler) {
_global_lock();
p_handler->next=error_handler_list;
error_handler_list=p_handler;
p_handler->next = error_handler_list;
error_handler_list = p_handler;
_global_unlock();
}
@ -59,44 +58,39 @@ void remove_error_handler(ErrorHandlerList *p_handler) {
ErrorHandlerList *prev = NULL;
ErrorHandlerList *l = error_handler_list;
while(l) {
while (l) {
if (l==p_handler) {
if (l == p_handler) {
if (prev)
prev->next=l->next;
prev->next = l->next;
else
error_handler_list=l->next;
error_handler_list = l->next;
break;
}
prev=l;
l=l->next;
prev = l;
l = l->next;
}
_global_unlock();
}
void _err_print_error(const char* p_function, const char* p_file,int p_line,const char *p_error,ErrorHandlerType p_type) {
void _err_print_error(const char *p_function, const char *p_file, int p_line, const char *p_error, ErrorHandlerType p_type) {
OS::get_singleton()->print_error(p_function,p_file,p_line,p_error,_err_error_exists?OS::get_singleton()->get_last_error():"",(OS::ErrorType)p_type);
OS::get_singleton()->print_error(p_function, p_file, p_line, p_error, _err_error_exists ? OS::get_singleton()->get_last_error() : "", (OS::ErrorType)p_type);
_global_lock();
ErrorHandlerList *l = error_handler_list;
while(l) {
while (l) {
l->errfunc(l->userdata,p_function,p_file,p_line,p_error,_err_error_exists?OS::get_singleton()->get_last_error():"",p_type);
l=l->next;
l->errfunc(l->userdata, p_function, p_file, p_line, p_error, _err_error_exists ? OS::get_singleton()->get_last_error() : "", p_type);
l = l->next;
}
_global_unlock();
if (_err_error_exists) {
OS::get_singleton()->clear_last_error();
_err_error_exists=false;
_err_error_exists = false;
}
}

View File

@ -29,7 +29,6 @@
#ifndef ERROR_MACROS_H
#define ERROR_MACROS_H
/**
* Error macros. Unlike exceptions and asserts, these macros try to mantain consistency and stability
* inside the code. It is recommended to always return processable data, so in case of an error, the
@ -52,8 +51,8 @@ enum ErrorHandlerType {
ERR_HANDLER_SCRIPT
};
typedef void (*ErrorHandlerFunc)(void*,const char*,const char*,int p_line,const char *, const char *,ErrorHandlerType p_type);
void _err_set_last_error(const char* p_err);
typedef void (*ErrorHandlerFunc)(void *, const char *, const char *, int p_line, const char *, const char *, ErrorHandlerType p_type);
void _err_set_last_error(const char *p_err);
void _err_clear_last_error();
struct ErrorHandlerList {
@ -61,22 +60,26 @@ struct ErrorHandlerList {
ErrorHandlerFunc errfunc;
void *userdata;
ErrorHandlerList*next;
ErrorHandlerList *next;
ErrorHandlerList() { errfunc=0; next=0; userdata=0; }
ErrorHandlerList() {
errfunc = 0;
next = 0;
userdata = 0;
}
};
void add_error_handler(ErrorHandlerList *p_handler);
void remove_error_handler(ErrorHandlerList *p_handler);
void _err_print_error(const char* p_function,const char* p_file,int p_line,const char *p_error,ErrorHandlerType p_type=ERR_HANDLER_ERROR);
void _err_print_error(const char *p_function, const char *p_file, int p_line, const char *p_error, ErrorHandlerType p_type = ERR_HANDLER_ERROR);
#ifndef _STR
#define _STR(m_x) #m_x
#define _MKSTR(m_x) _STR(m_x)
#endif
#define _FNL __FILE__":"
#define _FNL __FILE__ ":"
/** An index has failed if m_index<0 or m_index >=m_size, the function exists */
@ -85,13 +88,21 @@ extern bool _err_error_exists;
#ifdef DEBUG_ENABLED
/** Print a warning string.
*/
#define ERR_EXPLAINC(m_reason) {_err_set_last_error(m_reason); _err_error_exists=true;}
#define ERR_EXPLAIN(m_string) {_err_set_last_error(String(m_string).utf8().get_data()); _err_error_exists=true;}
#define ERR_EXPLAINC(m_reason) \
{ \
_err_set_last_error(m_reason); \
_err_error_exists = true; \
}
#define ERR_EXPLAIN(m_string) \
{ \
_err_set_last_error(String(m_string).utf8().get_data()); \
_err_error_exists = true; \
}
#else
#define ERR_EXPLAIN( m_text )
#define ERR_EXPLAINC( m_text )
#define ERR_EXPLAIN(m_text)
#define ERR_EXPLAINC(m_text)
#endif
@ -102,49 +113,63 @@ extern bool _err_error_exists;
#define FUNCTION_STR __FUNCTION__
#endif
#define ERR_FAIL_INDEX(m_index,m_size) \
do {if ((m_index)<0 || (m_index)>=(m_size)) { \
_err_print_error(FUNCTION_STR,__FILE__,__LINE__,"Index " _STR(m_index)" out of size (" _STR(m_size)")."); \
return; \
} else _err_error_exists=false; } while(0); \
#define ERR_FAIL_INDEX(m_index, m_size) \
do { \
if ((m_index) < 0 || (m_index) >= (m_size)) { \
_err_print_error(FUNCTION_STR, __FILE__, __LINE__, "Index " _STR(m_index) " out of size (" _STR(m_size) ")."); \
return; \
} else \
_err_error_exists = false; \
} while (0);
/** An index has failed if m_index<0 or m_index >=m_size, the function exists.
* This function returns an error value, if returning Error, please select the most
* appropriate error condition from error_macros.h
*/
#define ERR_FAIL_INDEX_V(m_index,m_size,m_retval) \
do {if ((m_index)<0 || (m_index)>=(m_size)) { \
_err_print_error(FUNCTION_STR,__FILE__,__LINE__,"Index " _STR(m_index)" out of size (" _STR(m_size)")."); \
return m_retval; \
} else _err_error_exists=false;} while (0);
#define ERR_FAIL_INDEX_V(m_index, m_size, m_retval) \
do { \
if ((m_index) < 0 || (m_index) >= (m_size)) { \
_err_print_error(FUNCTION_STR, __FILE__, __LINE__, "Index " _STR(m_index) " out of size (" _STR(m_size) ")."); \
return m_retval; \
} else \
_err_error_exists = false; \
} while (0);
/** An error condition happened (m_cond tested true) (WARNING this is the opposite as assert().
/** An error condition happened (m_cond tested true) (WARNING this is the opposite as assert().
* the function will exit.
*/
#define ERR_FAIL_NULL(m_param) \
{ if ( !m_param ) { \
_err_print_error(FUNCTION_STR,__FILE__,__LINE__,"Parameter ' " _STR(m_param)" ' is null."); \
return; \
}else _err_error_exists=false; } \
#define ERR_FAIL_NULL(m_param) \
{ \
if (!m_param) { \
_err_print_error(FUNCTION_STR, __FILE__, __LINE__, "Parameter ' " _STR(m_param) " ' is null."); \
return; \
} else \
_err_error_exists = false; \
}
#define ERR_FAIL_NULL_V(m_param,m_retval) \
{ if ( !m_param ) { \
_err_print_error(FUNCTION_STR,__FILE__,__LINE__,"Parameter ' " _STR(m_param)" ' is null."); \
return m_retval; \
}else _err_error_exists=false; } \
#define ERR_FAIL_NULL_V(m_param, m_retval) \
{ \
if (!m_param) { \
_err_print_error(FUNCTION_STR, __FILE__, __LINE__, "Parameter ' " _STR(m_param) " ' is null."); \
return m_retval; \
} else \
_err_error_exists = false; \
}
/** An error condition happened (m_cond tested true) (WARNING this is the opposite as assert().
* the function will exit.
*/
#define ERR_FAIL_COND(m_cond) \
{ if ( m_cond ) { \
_err_print_error(FUNCTION_STR,__FILE__,__LINE__,"Condition ' " _STR(m_cond)" ' is true."); \
return; \
}else _err_error_exists=false; } \
#define ERR_FAIL_COND(m_cond) \
{ \
if (m_cond) { \
_err_print_error(FUNCTION_STR, __FILE__, __LINE__, "Condition ' " _STR(m_cond) " ' is true."); \
return; \
} else \
_err_error_exists = false; \
}
/** An error condition happened (m_cond tested true) (WARNING this is the opposite as assert().
* the function will exit.
@ -152,81 +177,89 @@ extern bool _err_error_exists;
* appropriate error condition from error_macros.h
*/
#define ERR_FAIL_COND_V(m_cond,m_retval) \
{ if ( m_cond ) { \
_err_print_error(FUNCTION_STR,__FILE__,__LINE__,"Condition ' " _STR(m_cond)" ' is true. returned: " _STR(m_retval)); \
return m_retval; \
}else _err_error_exists=false; } \
#define ERR_FAIL_COND_V(m_cond, m_retval) \
{ \
if (m_cond) { \
_err_print_error(FUNCTION_STR, __FILE__, __LINE__, "Condition ' " _STR(m_cond) " ' is true. returned: " _STR(m_retval)); \
return m_retval; \
} else \
_err_error_exists = false; \
}
/** An error condition happened (m_cond tested true) (WARNING this is the opposite as assert().
* the loop will skip to the next iteration.
*/
#define ERR_CONTINUE(m_cond) \
{ if ( m_cond ) { \
_err_print_error(FUNCTION_STR,__FILE__,__LINE__,"Condition ' " _STR(m_cond)" ' is true. Continuing..:"); \
continue;\
} else _err_error_exists=false;} \
#define ERR_CONTINUE(m_cond) \
{ \
if (m_cond) { \
_err_print_error(FUNCTION_STR, __FILE__, __LINE__, "Condition ' " _STR(m_cond) " ' is true. Continuing..:"); \
continue; \
} else \
_err_error_exists = false; \
}
/** An error condition happened (m_cond tested true) (WARNING this is the opposite as assert().
* the loop will break
*/
#define ERR_BREAK(m_cond) \
{ if ( m_cond ) { \
_err_print_error(FUNCTION_STR,__FILE__,__LINE__,"Condition ' " _STR(m_cond)" ' is true. Breaking..:"); \
break;\
} else _err_error_exists=false;} \
#define ERR_BREAK(m_cond) \
{ \
if (m_cond) { \
_err_print_error(FUNCTION_STR, __FILE__, __LINE__, "Condition ' " _STR(m_cond) " ' is true. Breaking..:"); \
break; \
} else \
_err_error_exists = false; \
}
/** Print an error string and return
*/
#define ERR_FAIL() \
{ \
_err_print_error(FUNCTION_STR,__FILE__,__LINE__,"Method/Function Failed."); \
_err_error_exists=false;\
return;\
} \
#define ERR_FAIL() \
{ \
_err_print_error(FUNCTION_STR, __FILE__, __LINE__, "Method/Function Failed."); \
_err_error_exists = false; \
return; \
}
/** Print an error string and return with value
*/
#define ERR_FAIL_V(m_value) \
{ \
_err_print_error(FUNCTION_STR,__FILE__,__LINE__,"Method/Function Failed, returning: " __STR(m_value)); \
_err_error_exists=false; \
return m_value;\
} \
#define ERR_FAIL_V(m_value) \
{ \
_err_print_error(FUNCTION_STR, __FILE__, __LINE__, "Method/Function Failed, returning: " __STR(m_value)); \
_err_error_exists = false; \
return m_value; \
}
/** Print an error string.
*/
#define ERR_PRINT(m_string) \
{ \
_err_print_error(FUNCTION_STR,__FILE__,__LINE__,m_string); \
_err_error_exists=false;\
} \
#define ERR_PRINT(m_string) \
{ \
_err_print_error(FUNCTION_STR, __FILE__, __LINE__, m_string); \
_err_error_exists = false; \
}
#define ERR_PRINTS(m_string) \
{ \
_err_print_error(FUNCTION_STR,__FILE__,__LINE__,String(m_string).utf8().get_data()); \
_err_error_exists=false;\
} \
#define ERR_PRINTS(m_string) \
{ \
_err_print_error(FUNCTION_STR, __FILE__, __LINE__, String(m_string).utf8().get_data()); \
_err_error_exists = false; \
}
/** Print a warning string.
*/
#define WARN_PRINT(m_string) \
{ \
_err_print_error(FUNCTION_STR,__FILE__,__LINE__,m_string,ERR_HANDLER_WARNING); \
_err_error_exists=false;\
} \
#define WARN_PRINT(m_string) \
{ \
_err_print_error(FUNCTION_STR, __FILE__, __LINE__, m_string, ERR_HANDLER_WARNING); \
_err_error_exists = false; \
}
#define WARN_PRINTS(m_string) \
{ \
_err_print_error(FUNCTION_STR,__FILE__,__LINE__,String(m_string).utf8().get_data(),ERR_HANDLER_WARNING); \
_err_error_exists=false;\
} \
#define WARN_PRINTS(m_string) \
{ \
_err_print_error(FUNCTION_STR, __FILE__, __LINE__, String(m_string).utf8().get_data(), ERR_HANDLER_WARNING); \
_err_error_exists = false; \
}
#endif

View File

@ -28,134 +28,129 @@
/*************************************************************************/
#include "event_queue.h"
Error EventQueue::push_call(uint32_t p_instance_ID, const StringName &p_method, VARIANT_ARG_DECLARE) {
Error EventQueue::push_call(uint32_t p_instance_ID, const StringName& p_method, VARIANT_ARG_DECLARE) {
uint8_t room_needed=sizeof(Event);
int args=0;
if (p_arg5.get_type()!=Variant::NIL)
args=5;
else if (p_arg4.get_type()!=Variant::NIL)
args=4;
else if (p_arg3.get_type()!=Variant::NIL)
args=3;
else if (p_arg2.get_type()!=Variant::NIL)
args=2;
else if (p_arg1.get_type()!=Variant::NIL)
args=1;
uint8_t room_needed = sizeof(Event);
int args = 0;
if (p_arg5.get_type() != Variant::NIL)
args = 5;
else if (p_arg4.get_type() != Variant::NIL)
args = 4;
else if (p_arg3.get_type() != Variant::NIL)
args = 3;
else if (p_arg2.get_type() != Variant::NIL)
args = 2;
else if (p_arg1.get_type() != Variant::NIL)
args = 1;
else
args=0;
args = 0;
room_needed+=sizeof(Variant)*args;
room_needed += sizeof(Variant) * args;
ERR_FAIL_COND_V( (buffer_end+room_needed) >= buffer_size , ERR_OUT_OF_MEMORY );
Event * ev = memnew_placement( &event_buffer[ buffer_end ], Event );
ev->args=args;
ev->instance_ID=p_instance_ID;
ev->method=p_method;
ERR_FAIL_COND_V((buffer_end + room_needed) >= buffer_size, ERR_OUT_OF_MEMORY);
Event *ev = memnew_placement(&event_buffer[buffer_end], Event);
ev->args = args;
ev->instance_ID = p_instance_ID;
ev->method = p_method;
buffer_end+=sizeof(Event);
buffer_end += sizeof(Event);
if (args>=1) {
if (args >= 1) {
Variant * v = memnew_placement( &event_buffer[ buffer_end ], Variant );
buffer_end+=sizeof(Variant);
*v=p_arg1;
Variant *v = memnew_placement(&event_buffer[buffer_end], Variant);
buffer_end += sizeof(Variant);
*v = p_arg1;
}
if (args>=2) {
if (args >= 2) {
Variant * v = memnew_placement( &event_buffer[ buffer_end ], Variant );
buffer_end+=sizeof(Variant);
*v=p_arg2;
Variant *v = memnew_placement(&event_buffer[buffer_end], Variant);
buffer_end += sizeof(Variant);
*v = p_arg2;
}
if (args>=3) {
Variant * v = memnew_placement( &event_buffer[ buffer_end ], Variant );
buffer_end+=sizeof(Variant);
*v=p_arg3;
if (args >= 3) {
Variant *v = memnew_placement(&event_buffer[buffer_end], Variant);
buffer_end += sizeof(Variant);
*v = p_arg3;
}
if (args>=4) {
if (args >= 4) {
Variant * v = memnew_placement( &event_buffer[ buffer_end ], Variant );
buffer_end+=sizeof(Variant);
*v=p_arg4;
Variant *v = memnew_placement(&event_buffer[buffer_end], Variant);
buffer_end += sizeof(Variant);
*v = p_arg4;
}
if (args>=5) {
if (args >= 5) {
Variant * v = memnew_placement( &event_buffer[ buffer_end ], Variant );
buffer_end+=sizeof(Variant);
*v=p_arg5;
Variant *v = memnew_placement(&event_buffer[buffer_end], Variant);
buffer_end += sizeof(Variant);
*v = p_arg5;
}
if (buffer_end > buffer_max_used)
buffer_max_used=buffer_end;
buffer_max_used = buffer_end;
return OK;
}
void EventQueue::flush_events() {
uint32_t read_pos=0;
uint32_t read_pos = 0;
while (read_pos < buffer_end ) {
while (read_pos < buffer_end) {
Event *event = (Event*)&event_buffer[ read_pos ];
Variant *args= (Variant*)(event+1);
Event *event = (Event *)&event_buffer[read_pos];
Variant *args = (Variant *)(event + 1);
Object *obj = ObjectDB::get_instance(event->instance_ID);
if (obj) {
// events don't expect a return value
obj->call( event->method,
(event->args>=1) ? args[0] : Variant(),
(event->args>=2) ? args[1] : Variant(),
(event->args>=3) ? args[2] : Variant(),
(event->args>=4) ? args[3] : Variant(),
(event->args>=5) ? args[4] : Variant() );
obj->call(event->method,
(event->args >= 1) ? args[0] : Variant(),
(event->args >= 2) ? args[1] : Variant(),
(event->args >= 3) ? args[2] : Variant(),
(event->args >= 4) ? args[3] : Variant(),
(event->args >= 5) ? args[4] : Variant());
}
if (event->args>=1) args[0].~Variant();
if (event->args>=2) args[1].~Variant();
if (event->args>=3) args[2].~Variant();
if (event->args>=4) args[3].~Variant();
if (event->args>=5) args[4].~Variant();
if (event->args >= 1) args[0].~Variant();
if (event->args >= 2) args[1].~Variant();
if (event->args >= 3) args[2].~Variant();
if (event->args >= 4) args[3].~Variant();
if (event->args >= 5) args[4].~Variant();
event->~Event();
read_pos+=sizeof(Event)+sizeof(Variant)*event->args;
read_pos += sizeof(Event) + sizeof(Variant) * event->args;
}
buffer_end=0; // reset buffer
buffer_end = 0; // reset buffer
}
EventQueue::EventQueue(uint32_t p_buffer_size) {
buffer_end=0;
buffer_max_used=0;
buffer_size=p_buffer_size;
event_buffer = memnew_arr( uint8_t, buffer_size );
buffer_end = 0;
buffer_max_used = 0;
buffer_size = p_buffer_size;
event_buffer = memnew_arr(uint8_t, buffer_size);
}
EventQueue::~EventQueue() {
uint32_t read_pos=0;
uint32_t read_pos = 0;
while (read_pos < buffer_end ) {
while (read_pos < buffer_end) {
Event *event = (Event*)&event_buffer[ read_pos ];
Variant *args= (Variant*)(event+1);
for (int i=0;i<event->args;i++)
Event *event = (Event *)&event_buffer[read_pos];
Variant *args = (Variant *)(event + 1);
for (int i = 0; i < event->args; i++)
args[i].~Variant();
event->~Event();
read_pos+=sizeof(Event)+sizeof(Variant)*event->args;
read_pos += sizeof(Event) + sizeof(Variant) * event->args;
}
memdelete_arr(event_buffer);
event_buffer=NULL;
event_buffer = NULL;
}

View File

@ -37,7 +37,7 @@ class EventQueue {
enum {
DEFAULT_EVENT_QUEUE_SIZE_KB=256
DEFAULT_EVENT_QUEUE_SIZE_KB = 256
};
struct Event {
@ -47,20 +47,17 @@ class EventQueue {
int args;
};
uint8_t *event_buffer;
uint32_t buffer_end;
uint32_t buffer_max_used;
uint32_t buffer_size;
public:
Error push_call(uint32_t p_instance_ID, const StringName& p_method, VARIANT_ARG_LIST);
Error push_call(uint32_t p_instance_ID, const StringName &p_method, VARIANT_ARG_LIST);
void flush_events();
EventQueue(uint32_t p_buffer_size=DEFAULT_EVENT_QUEUE_SIZE_KB*1024);
EventQueue(uint32_t p_buffer_size = DEFAULT_EVENT_QUEUE_SIZE_KB * 1024);
~EventQueue();
};
#endif

View File

@ -28,55 +28,50 @@
/*************************************************************************/
#include "func_ref.h"
Variant FuncRef::call_func(const Variant** p_args, int p_argcount, Variant::CallError& r_error) {
Variant FuncRef::call_func(const Variant **p_args, int p_argcount, Variant::CallError &r_error) {
if (id==0) {
r_error.error=Variant::CallError::CALL_ERROR_INSTANCE_IS_NULL;
if (id == 0) {
r_error.error = Variant::CallError::CALL_ERROR_INSTANCE_IS_NULL;
return Variant();
}
Object* obj = ObjectDB::get_instance(id);
Object *obj = ObjectDB::get_instance(id);
if (!obj) {
r_error.error=Variant::CallError::CALL_ERROR_INSTANCE_IS_NULL;
r_error.error = Variant::CallError::CALL_ERROR_INSTANCE_IS_NULL;
return Variant();
}
return obj->call(function,p_args,p_argcount,r_error);
return obj->call(function, p_args, p_argcount, r_error);
}
void FuncRef::set_instance(Object *p_obj){
void FuncRef::set_instance(Object *p_obj) {
ERR_FAIL_NULL(p_obj);
id=p_obj->get_instance_ID();
id = p_obj->get_instance_ID();
}
void FuncRef::set_function(const StringName& p_func){
void FuncRef::set_function(const StringName &p_func) {
function=p_func;
function = p_func;
}
void FuncRef::_bind_methods() {
{
MethodInfo mi;
mi.name="call_func";
mi.name = "call_func";
Vector<Variant> defargs;
for(int i=0;i<10;i++) {
mi.arguments.push_back( PropertyInfo( Variant::NIL, "arg"+itos(i)));
for (int i = 0; i < 10; i++) {
mi.arguments.push_back(PropertyInfo(Variant::NIL, "arg" + itos(i)));
defargs.push_back(Variant());
}
ObjectTypeDB::bind_native_method(METHOD_FLAGS_DEFAULT,"call_func",&FuncRef::call_func,mi,defargs);
ObjectTypeDB::bind_native_method(METHOD_FLAGS_DEFAULT, "call_func", &FuncRef::call_func, mi, defargs);
}
ObjectTypeDB::bind_method(_MD("set_instance","instance"),&FuncRef::set_instance);
ObjectTypeDB::bind_method(_MD("set_function","name"),&FuncRef::set_function);
ObjectTypeDB::bind_method(_MD("set_instance", "instance"), &FuncRef::set_instance);
ObjectTypeDB::bind_method(_MD("set_function", "name"), &FuncRef::set_function);
}
FuncRef::FuncRef() {
FuncRef::FuncRef(){
id=0;
id = 0;
}

View File

@ -31,20 +31,19 @@
#include "reference.h"
class FuncRef : public Reference{
class FuncRef : public Reference {
OBJ_TYPE(FuncRef,Reference);
OBJ_TYPE(FuncRef, Reference);
ObjectID id;
StringName function;
protected:
static void _bind_methods();
public:
Variant call_func(const Variant** p_args, int p_argcount, Variant::CallError& r_error);
public:
Variant call_func(const Variant **p_args, int p_argcount, Variant::CallError &r_error);
void set_instance(Object *p_obj);
void set_function(const StringName& p_func);
void set_function(const StringName &p_func);
FuncRef();
};

View File

@ -27,9 +27,9 @@
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
/*************************************************************************/
#include "global_constants.h"
#include "variant.h"
#include "os/keyboard.h"
#include "object.h"
#include "os/keyboard.h"
#include "variant.h"
struct _GlobalConstant {
@ -37,514 +37,510 @@ struct _GlobalConstant {
int value;
};
#define BIND_GLOBAL_CONSTANT(m_constant) {#m_constant,m_constant}
#define BIND_GLOBAL_CONSTANT(m_constant) \
{ #m_constant, m_constant }
static _GlobalConstant _global_constants[] = {
static _GlobalConstant _global_constants[]={
//{ KEY_BACKSPACE, VK_BACK },// (0x08) // backspace
//{ KEY_BACKSPACE, VK_BACK },// (0x08) // backspace
BIND_GLOBAL_CONSTANT( MARGIN_LEFT ),
BIND_GLOBAL_CONSTANT( MARGIN_TOP ),
BIND_GLOBAL_CONSTANT( MARGIN_RIGHT ),
BIND_GLOBAL_CONSTANT( MARGIN_BOTTOM ),
BIND_GLOBAL_CONSTANT( VERTICAL ),
BIND_GLOBAL_CONSTANT( HORIZONTAL ),
BIND_GLOBAL_CONSTANT( HALIGN_LEFT ),
BIND_GLOBAL_CONSTANT( HALIGN_CENTER ),
BIND_GLOBAL_CONSTANT( HALIGN_RIGHT ),
BIND_GLOBAL_CONSTANT( VALIGN_TOP ),
BIND_GLOBAL_CONSTANT( VALIGN_CENTER ),
BIND_GLOBAL_CONSTANT( VALIGN_BOTTOM ),
BIND_GLOBAL_CONSTANT(MARGIN_LEFT),
BIND_GLOBAL_CONSTANT(MARGIN_TOP),
BIND_GLOBAL_CONSTANT(MARGIN_RIGHT),
BIND_GLOBAL_CONSTANT(MARGIN_BOTTOM),
BIND_GLOBAL_CONSTANT(VERTICAL),
BIND_GLOBAL_CONSTANT(HORIZONTAL),
BIND_GLOBAL_CONSTANT(HALIGN_LEFT),
BIND_GLOBAL_CONSTANT(HALIGN_CENTER),
BIND_GLOBAL_CONSTANT(HALIGN_RIGHT),
BIND_GLOBAL_CONSTANT(VALIGN_TOP),
BIND_GLOBAL_CONSTANT(VALIGN_CENTER),
BIND_GLOBAL_CONSTANT(VALIGN_BOTTOM),
// hueg list of keys
BIND_GLOBAL_CONSTANT( SPKEY ),
BIND_GLOBAL_CONSTANT(SPKEY),
BIND_GLOBAL_CONSTANT( KEY_ESCAPE ),
BIND_GLOBAL_CONSTANT( KEY_TAB ),
BIND_GLOBAL_CONSTANT( KEY_BACKTAB ),
BIND_GLOBAL_CONSTANT( KEY_BACKSPACE ),
BIND_GLOBAL_CONSTANT( KEY_RETURN ),
BIND_GLOBAL_CONSTANT( KEY_ENTER ),
BIND_GLOBAL_CONSTANT( KEY_INSERT ),
BIND_GLOBAL_CONSTANT( KEY_DELETE ),
BIND_GLOBAL_CONSTANT( KEY_PAUSE ),
BIND_GLOBAL_CONSTANT( KEY_PRINT ),
BIND_GLOBAL_CONSTANT( KEY_SYSREQ ),
BIND_GLOBAL_CONSTANT( KEY_CLEAR ),
BIND_GLOBAL_CONSTANT( KEY_HOME ),
BIND_GLOBAL_CONSTANT( KEY_END ),
BIND_GLOBAL_CONSTANT( KEY_LEFT ),
BIND_GLOBAL_CONSTANT( KEY_UP ),
BIND_GLOBAL_CONSTANT( KEY_RIGHT ),
BIND_GLOBAL_CONSTANT( KEY_DOWN ),
BIND_GLOBAL_CONSTANT( KEY_PAGEUP ),
BIND_GLOBAL_CONSTANT( KEY_PAGEDOWN ),
BIND_GLOBAL_CONSTANT( KEY_SHIFT ),
BIND_GLOBAL_CONSTANT( KEY_CONTROL ),
BIND_GLOBAL_CONSTANT( KEY_META ),
BIND_GLOBAL_CONSTANT( KEY_ALT ),
BIND_GLOBAL_CONSTANT( KEY_CAPSLOCK ),
BIND_GLOBAL_CONSTANT( KEY_NUMLOCK ),
BIND_GLOBAL_CONSTANT( KEY_SCROLLLOCK ),
BIND_GLOBAL_CONSTANT( KEY_F1 ),
BIND_GLOBAL_CONSTANT( KEY_F2 ),
BIND_GLOBAL_CONSTANT( KEY_F3 ),
BIND_GLOBAL_CONSTANT( KEY_F4 ),
BIND_GLOBAL_CONSTANT( KEY_F5 ),
BIND_GLOBAL_CONSTANT( KEY_F6 ),
BIND_GLOBAL_CONSTANT( KEY_F7 ),
BIND_GLOBAL_CONSTANT( KEY_F8 ),
BIND_GLOBAL_CONSTANT( KEY_F9 ),
BIND_GLOBAL_CONSTANT( KEY_F10 ),
BIND_GLOBAL_CONSTANT( KEY_F11 ),
BIND_GLOBAL_CONSTANT( KEY_F12 ),
BIND_GLOBAL_CONSTANT( KEY_F13 ),
BIND_GLOBAL_CONSTANT( KEY_F14 ),
BIND_GLOBAL_CONSTANT( KEY_F15 ),
BIND_GLOBAL_CONSTANT( KEY_F16 ),
BIND_GLOBAL_CONSTANT( KEY_KP_ENTER ),
BIND_GLOBAL_CONSTANT( KEY_KP_MULTIPLY ),
BIND_GLOBAL_CONSTANT( KEY_KP_DIVIDE ),
BIND_GLOBAL_CONSTANT( KEY_KP_SUBTRACT ),
BIND_GLOBAL_CONSTANT( KEY_KP_PERIOD ),
BIND_GLOBAL_CONSTANT( KEY_KP_ADD ),
BIND_GLOBAL_CONSTANT( KEY_KP_0 ),
BIND_GLOBAL_CONSTANT( KEY_KP_1 ),
BIND_GLOBAL_CONSTANT( KEY_KP_2 ),
BIND_GLOBAL_CONSTANT( KEY_KP_3 ),
BIND_GLOBAL_CONSTANT( KEY_KP_4 ),
BIND_GLOBAL_CONSTANT( KEY_KP_5 ),
BIND_GLOBAL_CONSTANT( KEY_KP_6 ),
BIND_GLOBAL_CONSTANT( KEY_KP_7 ),
BIND_GLOBAL_CONSTANT( KEY_KP_8 ),
BIND_GLOBAL_CONSTANT( KEY_KP_9 ),
BIND_GLOBAL_CONSTANT( KEY_SUPER_L ),
BIND_GLOBAL_CONSTANT( KEY_SUPER_R ),
BIND_GLOBAL_CONSTANT( KEY_MENU ),
BIND_GLOBAL_CONSTANT( KEY_HYPER_L ),
BIND_GLOBAL_CONSTANT( KEY_HYPER_R ),
BIND_GLOBAL_CONSTANT( KEY_HELP ),
BIND_GLOBAL_CONSTANT( KEY_DIRECTION_L ),
BIND_GLOBAL_CONSTANT( KEY_DIRECTION_R ),
BIND_GLOBAL_CONSTANT( KEY_BACK ),
BIND_GLOBAL_CONSTANT( KEY_FORWARD ),
BIND_GLOBAL_CONSTANT( KEY_STOP ),
BIND_GLOBAL_CONSTANT( KEY_REFRESH ),
BIND_GLOBAL_CONSTANT( KEY_VOLUMEDOWN ),
BIND_GLOBAL_CONSTANT( KEY_VOLUMEMUTE ),
BIND_GLOBAL_CONSTANT( KEY_VOLUMEUP ),
BIND_GLOBAL_CONSTANT( KEY_BASSBOOST ),
BIND_GLOBAL_CONSTANT( KEY_BASSUP ),
BIND_GLOBAL_CONSTANT( KEY_BASSDOWN ),
BIND_GLOBAL_CONSTANT( KEY_TREBLEUP ),
BIND_GLOBAL_CONSTANT( KEY_TREBLEDOWN ),
BIND_GLOBAL_CONSTANT( KEY_MEDIAPLAY ),
BIND_GLOBAL_CONSTANT( KEY_MEDIASTOP ),
BIND_GLOBAL_CONSTANT( KEY_MEDIAPREVIOUS ),
BIND_GLOBAL_CONSTANT( KEY_MEDIANEXT ),
BIND_GLOBAL_CONSTANT( KEY_MEDIARECORD ),
BIND_GLOBAL_CONSTANT( KEY_HOMEPAGE ),
BIND_GLOBAL_CONSTANT( KEY_FAVORITES ),
BIND_GLOBAL_CONSTANT( KEY_SEARCH ),
BIND_GLOBAL_CONSTANT( KEY_STANDBY ),
BIND_GLOBAL_CONSTANT( KEY_OPENURL ),
BIND_GLOBAL_CONSTANT( KEY_LAUNCHMAIL ),
BIND_GLOBAL_CONSTANT( KEY_LAUNCHMEDIA ),
BIND_GLOBAL_CONSTANT( KEY_LAUNCH0 ),
BIND_GLOBAL_CONSTANT( KEY_LAUNCH1 ),
BIND_GLOBAL_CONSTANT( KEY_LAUNCH2 ),
BIND_GLOBAL_CONSTANT( KEY_LAUNCH3 ),
BIND_GLOBAL_CONSTANT( KEY_LAUNCH4 ),
BIND_GLOBAL_CONSTANT( KEY_LAUNCH5 ),
BIND_GLOBAL_CONSTANT( KEY_LAUNCH6 ),
BIND_GLOBAL_CONSTANT( KEY_LAUNCH7 ),
BIND_GLOBAL_CONSTANT( KEY_LAUNCH8 ),
BIND_GLOBAL_CONSTANT( KEY_LAUNCH9 ),
BIND_GLOBAL_CONSTANT( KEY_LAUNCHA ),
BIND_GLOBAL_CONSTANT( KEY_LAUNCHB ),
BIND_GLOBAL_CONSTANT( KEY_LAUNCHC ),
BIND_GLOBAL_CONSTANT( KEY_LAUNCHD ),
BIND_GLOBAL_CONSTANT( KEY_LAUNCHE ),
BIND_GLOBAL_CONSTANT( KEY_LAUNCHF ),
BIND_GLOBAL_CONSTANT(KEY_ESCAPE),
BIND_GLOBAL_CONSTANT(KEY_TAB),
BIND_GLOBAL_CONSTANT(KEY_BACKTAB),
BIND_GLOBAL_CONSTANT(KEY_BACKSPACE),
BIND_GLOBAL_CONSTANT(KEY_RETURN),
BIND_GLOBAL_CONSTANT(KEY_ENTER),
BIND_GLOBAL_CONSTANT(KEY_INSERT),
BIND_GLOBAL_CONSTANT(KEY_DELETE),
BIND_GLOBAL_CONSTANT(KEY_PAUSE),
BIND_GLOBAL_CONSTANT(KEY_PRINT),
BIND_GLOBAL_CONSTANT(KEY_SYSREQ),
BIND_GLOBAL_CONSTANT(KEY_CLEAR),
BIND_GLOBAL_CONSTANT(KEY_HOME),
BIND_GLOBAL_CONSTANT(KEY_END),
BIND_GLOBAL_CONSTANT(KEY_LEFT),
BIND_GLOBAL_CONSTANT(KEY_UP),
BIND_GLOBAL_CONSTANT(KEY_RIGHT),
BIND_GLOBAL_CONSTANT(KEY_DOWN),
BIND_GLOBAL_CONSTANT(KEY_PAGEUP),
BIND_GLOBAL_CONSTANT(KEY_PAGEDOWN),
BIND_GLOBAL_CONSTANT(KEY_SHIFT),
BIND_GLOBAL_CONSTANT(KEY_CONTROL),
BIND_GLOBAL_CONSTANT(KEY_META),
BIND_GLOBAL_CONSTANT(KEY_ALT),
BIND_GLOBAL_CONSTANT(KEY_CAPSLOCK),
BIND_GLOBAL_CONSTANT(KEY_NUMLOCK),
BIND_GLOBAL_CONSTANT(KEY_SCROLLLOCK),
BIND_GLOBAL_CONSTANT(KEY_F1),
BIND_GLOBAL_CONSTANT(KEY_F2),
BIND_GLOBAL_CONSTANT(KEY_F3),
BIND_GLOBAL_CONSTANT(KEY_F4),
BIND_GLOBAL_CONSTANT(KEY_F5),
BIND_GLOBAL_CONSTANT(KEY_F6),
BIND_GLOBAL_CONSTANT(KEY_F7),
BIND_GLOBAL_CONSTANT(KEY_F8),
BIND_GLOBAL_CONSTANT(KEY_F9),
BIND_GLOBAL_CONSTANT(KEY_F10),
BIND_GLOBAL_CONSTANT(KEY_F11),
BIND_GLOBAL_CONSTANT(KEY_F12),
BIND_GLOBAL_CONSTANT(KEY_F13),
BIND_GLOBAL_CONSTANT(KEY_F14),
BIND_GLOBAL_CONSTANT(KEY_F15),
BIND_GLOBAL_CONSTANT(KEY_F16),
BIND_GLOBAL_CONSTANT(KEY_KP_ENTER),
BIND_GLOBAL_CONSTANT(KEY_KP_MULTIPLY),
BIND_GLOBAL_CONSTANT(KEY_KP_DIVIDE),
BIND_GLOBAL_CONSTANT(KEY_KP_SUBTRACT),
BIND_GLOBAL_CONSTANT(KEY_KP_PERIOD),
BIND_GLOBAL_CONSTANT(KEY_KP_ADD),
BIND_GLOBAL_CONSTANT(KEY_KP_0),
BIND_GLOBAL_CONSTANT(KEY_KP_1),
BIND_GLOBAL_CONSTANT(KEY_KP_2),
BIND_GLOBAL_CONSTANT(KEY_KP_3),
BIND_GLOBAL_CONSTANT(KEY_KP_4),
BIND_GLOBAL_CONSTANT(KEY_KP_5),
BIND_GLOBAL_CONSTANT(KEY_KP_6),
BIND_GLOBAL_CONSTANT(KEY_KP_7),
BIND_GLOBAL_CONSTANT(KEY_KP_8),
BIND_GLOBAL_CONSTANT(KEY_KP_9),
BIND_GLOBAL_CONSTANT(KEY_SUPER_L),
BIND_GLOBAL_CONSTANT(KEY_SUPER_R),
BIND_GLOBAL_CONSTANT(KEY_MENU),
BIND_GLOBAL_CONSTANT(KEY_HYPER_L),
BIND_GLOBAL_CONSTANT(KEY_HYPER_R),
BIND_GLOBAL_CONSTANT(KEY_HELP),
BIND_GLOBAL_CONSTANT(KEY_DIRECTION_L),
BIND_GLOBAL_CONSTANT(KEY_DIRECTION_R),
BIND_GLOBAL_CONSTANT(KEY_BACK),
BIND_GLOBAL_CONSTANT(KEY_FORWARD),
BIND_GLOBAL_CONSTANT(KEY_STOP),
BIND_GLOBAL_CONSTANT(KEY_REFRESH),
BIND_GLOBAL_CONSTANT(KEY_VOLUMEDOWN),
BIND_GLOBAL_CONSTANT(KEY_VOLUMEMUTE),
BIND_GLOBAL_CONSTANT(KEY_VOLUMEUP),
BIND_GLOBAL_CONSTANT(KEY_BASSBOOST),
BIND_GLOBAL_CONSTANT(KEY_BASSUP),
BIND_GLOBAL_CONSTANT(KEY_BASSDOWN),
BIND_GLOBAL_CONSTANT(KEY_TREBLEUP),
BIND_GLOBAL_CONSTANT(KEY_TREBLEDOWN),
BIND_GLOBAL_CONSTANT(KEY_MEDIAPLAY),
BIND_GLOBAL_CONSTANT(KEY_MEDIASTOP),
BIND_GLOBAL_CONSTANT(KEY_MEDIAPREVIOUS),
BIND_GLOBAL_CONSTANT(KEY_MEDIANEXT),
BIND_GLOBAL_CONSTANT(KEY_MEDIARECORD),
BIND_GLOBAL_CONSTANT(KEY_HOMEPAGE),
BIND_GLOBAL_CONSTANT(KEY_FAVORITES),
BIND_GLOBAL_CONSTANT(KEY_SEARCH),
BIND_GLOBAL_CONSTANT(KEY_STANDBY),
BIND_GLOBAL_CONSTANT(KEY_OPENURL),
BIND_GLOBAL_CONSTANT(KEY_LAUNCHMAIL),
BIND_GLOBAL_CONSTANT(KEY_LAUNCHMEDIA),
BIND_GLOBAL_CONSTANT(KEY_LAUNCH0),
BIND_GLOBAL_CONSTANT(KEY_LAUNCH1),
BIND_GLOBAL_CONSTANT(KEY_LAUNCH2),
BIND_GLOBAL_CONSTANT(KEY_LAUNCH3),
BIND_GLOBAL_CONSTANT(KEY_LAUNCH4),
BIND_GLOBAL_CONSTANT(KEY_LAUNCH5),
BIND_GLOBAL_CONSTANT(KEY_LAUNCH6),
BIND_GLOBAL_CONSTANT(KEY_LAUNCH7),
BIND_GLOBAL_CONSTANT(KEY_LAUNCH8),
BIND_GLOBAL_CONSTANT(KEY_LAUNCH9),
BIND_GLOBAL_CONSTANT(KEY_LAUNCHA),
BIND_GLOBAL_CONSTANT(KEY_LAUNCHB),
BIND_GLOBAL_CONSTANT(KEY_LAUNCHC),
BIND_GLOBAL_CONSTANT(KEY_LAUNCHD),
BIND_GLOBAL_CONSTANT(KEY_LAUNCHE),
BIND_GLOBAL_CONSTANT(KEY_LAUNCHF),
BIND_GLOBAL_CONSTANT( KEY_UNKNOWN ),
BIND_GLOBAL_CONSTANT( KEY_SPACE ),
BIND_GLOBAL_CONSTANT( KEY_EXCLAM ),
BIND_GLOBAL_CONSTANT( KEY_QUOTEDBL ),
BIND_GLOBAL_CONSTANT( KEY_NUMBERSIGN ),
BIND_GLOBAL_CONSTANT( KEY_DOLLAR ),
BIND_GLOBAL_CONSTANT( KEY_PERCENT ),
BIND_GLOBAL_CONSTANT( KEY_AMPERSAND ),
BIND_GLOBAL_CONSTANT( KEY_APOSTROPHE ),
BIND_GLOBAL_CONSTANT( KEY_PARENLEFT ),
BIND_GLOBAL_CONSTANT( KEY_PARENRIGHT ),
BIND_GLOBAL_CONSTANT( KEY_ASTERISK ),
BIND_GLOBAL_CONSTANT( KEY_PLUS ),
BIND_GLOBAL_CONSTANT( KEY_COMMA ),
BIND_GLOBAL_CONSTANT( KEY_MINUS ),
BIND_GLOBAL_CONSTANT( KEY_PERIOD ),
BIND_GLOBAL_CONSTANT( KEY_SLASH ),
BIND_GLOBAL_CONSTANT( KEY_0 ),
BIND_GLOBAL_CONSTANT( KEY_1 ),
BIND_GLOBAL_CONSTANT( KEY_2 ),
BIND_GLOBAL_CONSTANT( KEY_3 ),
BIND_GLOBAL_CONSTANT( KEY_4 ),
BIND_GLOBAL_CONSTANT( KEY_5 ),
BIND_GLOBAL_CONSTANT( KEY_6 ),
BIND_GLOBAL_CONSTANT( KEY_7 ),
BIND_GLOBAL_CONSTANT( KEY_8 ),
BIND_GLOBAL_CONSTANT( KEY_9 ),
BIND_GLOBAL_CONSTANT( KEY_COLON ),
BIND_GLOBAL_CONSTANT( KEY_SEMICOLON ),
BIND_GLOBAL_CONSTANT( KEY_LESS ),
BIND_GLOBAL_CONSTANT( KEY_EQUAL ),
BIND_GLOBAL_CONSTANT( KEY_GREATER ),
BIND_GLOBAL_CONSTANT( KEY_QUESTION ),
BIND_GLOBAL_CONSTANT( KEY_AT ),
BIND_GLOBAL_CONSTANT( KEY_A ),
BIND_GLOBAL_CONSTANT( KEY_B ),
BIND_GLOBAL_CONSTANT( KEY_C ),
BIND_GLOBAL_CONSTANT( KEY_D ),
BIND_GLOBAL_CONSTANT( KEY_E ),
BIND_GLOBAL_CONSTANT( KEY_F ),
BIND_GLOBAL_CONSTANT( KEY_G ),
BIND_GLOBAL_CONSTANT( KEY_H ),
BIND_GLOBAL_CONSTANT( KEY_I ),
BIND_GLOBAL_CONSTANT( KEY_J ),
BIND_GLOBAL_CONSTANT( KEY_K ),
BIND_GLOBAL_CONSTANT( KEY_L ),
BIND_GLOBAL_CONSTANT( KEY_M ),
BIND_GLOBAL_CONSTANT( KEY_N ),
BIND_GLOBAL_CONSTANT( KEY_O ),
BIND_GLOBAL_CONSTANT( KEY_P ),
BIND_GLOBAL_CONSTANT( KEY_Q ),
BIND_GLOBAL_CONSTANT( KEY_R ),
BIND_GLOBAL_CONSTANT( KEY_S ),
BIND_GLOBAL_CONSTANT( KEY_T ),
BIND_GLOBAL_CONSTANT( KEY_U ),
BIND_GLOBAL_CONSTANT( KEY_V ),
BIND_GLOBAL_CONSTANT( KEY_W ),
BIND_GLOBAL_CONSTANT( KEY_X ),
BIND_GLOBAL_CONSTANT( KEY_Y ),
BIND_GLOBAL_CONSTANT( KEY_Z ),
BIND_GLOBAL_CONSTANT( KEY_BRACKETLEFT ),
BIND_GLOBAL_CONSTANT( KEY_BACKSLASH ),
BIND_GLOBAL_CONSTANT( KEY_BRACKETRIGHT ),
BIND_GLOBAL_CONSTANT( KEY_ASCIICIRCUM ),
BIND_GLOBAL_CONSTANT( KEY_UNDERSCORE ),
BIND_GLOBAL_CONSTANT( KEY_QUOTELEFT ),
BIND_GLOBAL_CONSTANT( KEY_BRACELEFT ),
BIND_GLOBAL_CONSTANT( KEY_BAR ),
BIND_GLOBAL_CONSTANT( KEY_BRACERIGHT ),
BIND_GLOBAL_CONSTANT( KEY_ASCIITILDE ),
BIND_GLOBAL_CONSTANT( KEY_NOBREAKSPACE ),
BIND_GLOBAL_CONSTANT( KEY_EXCLAMDOWN ),
BIND_GLOBAL_CONSTANT( KEY_CENT ),
BIND_GLOBAL_CONSTANT( KEY_STERLING ),
BIND_GLOBAL_CONSTANT( KEY_CURRENCY ),
BIND_GLOBAL_CONSTANT( KEY_YEN ),
BIND_GLOBAL_CONSTANT( KEY_BROKENBAR ),
BIND_GLOBAL_CONSTANT( KEY_SECTION ),
BIND_GLOBAL_CONSTANT( KEY_DIAERESIS ),
BIND_GLOBAL_CONSTANT( KEY_COPYRIGHT ),
BIND_GLOBAL_CONSTANT( KEY_ORDFEMININE ),
BIND_GLOBAL_CONSTANT( KEY_GUILLEMOTLEFT ),
BIND_GLOBAL_CONSTANT( KEY_NOTSIGN ),
BIND_GLOBAL_CONSTANT( KEY_HYPHEN ),
BIND_GLOBAL_CONSTANT( KEY_REGISTERED ),
BIND_GLOBAL_CONSTANT( KEY_MACRON ),
BIND_GLOBAL_CONSTANT( KEY_DEGREE ),
BIND_GLOBAL_CONSTANT( KEY_PLUSMINUS ),
BIND_GLOBAL_CONSTANT( KEY_TWOSUPERIOR ),
BIND_GLOBAL_CONSTANT( KEY_THREESUPERIOR ),
BIND_GLOBAL_CONSTANT( KEY_ACUTE ),
BIND_GLOBAL_CONSTANT( KEY_MU ),
BIND_GLOBAL_CONSTANT( KEY_PARAGRAPH ),
BIND_GLOBAL_CONSTANT( KEY_PERIODCENTERED ),
BIND_GLOBAL_CONSTANT( KEY_CEDILLA ),
BIND_GLOBAL_CONSTANT( KEY_ONESUPERIOR ),
BIND_GLOBAL_CONSTANT( KEY_MASCULINE ),
BIND_GLOBAL_CONSTANT( KEY_GUILLEMOTRIGHT ),
BIND_GLOBAL_CONSTANT( KEY_ONEQUARTER ),
BIND_GLOBAL_CONSTANT( KEY_ONEHALF ),
BIND_GLOBAL_CONSTANT( KEY_THREEQUARTERS ),
BIND_GLOBAL_CONSTANT( KEY_QUESTIONDOWN ),
BIND_GLOBAL_CONSTANT( KEY_AGRAVE ),
BIND_GLOBAL_CONSTANT( KEY_AACUTE ),
BIND_GLOBAL_CONSTANT( KEY_ACIRCUMFLEX ),
BIND_GLOBAL_CONSTANT( KEY_ATILDE ),
BIND_GLOBAL_CONSTANT( KEY_ADIAERESIS ),
BIND_GLOBAL_CONSTANT( KEY_ARING ),
BIND_GLOBAL_CONSTANT( KEY_AE ),
BIND_GLOBAL_CONSTANT( KEY_CCEDILLA ),
BIND_GLOBAL_CONSTANT( KEY_EGRAVE ),
BIND_GLOBAL_CONSTANT( KEY_EACUTE ),
BIND_GLOBAL_CONSTANT( KEY_ECIRCUMFLEX ),
BIND_GLOBAL_CONSTANT( KEY_EDIAERESIS ),
BIND_GLOBAL_CONSTANT( KEY_IGRAVE ),
BIND_GLOBAL_CONSTANT( KEY_IACUTE ),
BIND_GLOBAL_CONSTANT( KEY_ICIRCUMFLEX ),
BIND_GLOBAL_CONSTANT( KEY_IDIAERESIS ),
BIND_GLOBAL_CONSTANT( KEY_ETH ),
BIND_GLOBAL_CONSTANT( KEY_NTILDE ),
BIND_GLOBAL_CONSTANT( KEY_OGRAVE ),
BIND_GLOBAL_CONSTANT( KEY_OACUTE ),
BIND_GLOBAL_CONSTANT( KEY_OCIRCUMFLEX ),
BIND_GLOBAL_CONSTANT( KEY_OTILDE ),
BIND_GLOBAL_CONSTANT( KEY_ODIAERESIS ),
BIND_GLOBAL_CONSTANT( KEY_MULTIPLY ),
BIND_GLOBAL_CONSTANT( KEY_OOBLIQUE ),
BIND_GLOBAL_CONSTANT( KEY_UGRAVE ),
BIND_GLOBAL_CONSTANT( KEY_UACUTE ),
BIND_GLOBAL_CONSTANT( KEY_UCIRCUMFLEX ),
BIND_GLOBAL_CONSTANT( KEY_UDIAERESIS ),
BIND_GLOBAL_CONSTANT( KEY_YACUTE ),
BIND_GLOBAL_CONSTANT( KEY_THORN ),
BIND_GLOBAL_CONSTANT( KEY_SSHARP ),
BIND_GLOBAL_CONSTANT(KEY_UNKNOWN),
BIND_GLOBAL_CONSTANT(KEY_SPACE),
BIND_GLOBAL_CONSTANT(KEY_EXCLAM),
BIND_GLOBAL_CONSTANT(KEY_QUOTEDBL),
BIND_GLOBAL_CONSTANT(KEY_NUMBERSIGN),
BIND_GLOBAL_CONSTANT(KEY_DOLLAR),
BIND_GLOBAL_CONSTANT(KEY_PERCENT),
BIND_GLOBAL_CONSTANT(KEY_AMPERSAND),
BIND_GLOBAL_CONSTANT(KEY_APOSTROPHE),
BIND_GLOBAL_CONSTANT(KEY_PARENLEFT),
BIND_GLOBAL_CONSTANT(KEY_PARENRIGHT),
BIND_GLOBAL_CONSTANT(KEY_ASTERISK),
BIND_GLOBAL_CONSTANT(KEY_PLUS),
BIND_GLOBAL_CONSTANT(KEY_COMMA),
BIND_GLOBAL_CONSTANT(KEY_MINUS),
BIND_GLOBAL_CONSTANT(KEY_PERIOD),
BIND_GLOBAL_CONSTANT(KEY_SLASH),
BIND_GLOBAL_CONSTANT(KEY_0),
BIND_GLOBAL_CONSTANT(KEY_1),
BIND_GLOBAL_CONSTANT(KEY_2),
BIND_GLOBAL_CONSTANT(KEY_3),
BIND_GLOBAL_CONSTANT(KEY_4),
BIND_GLOBAL_CONSTANT(KEY_5),
BIND_GLOBAL_CONSTANT(KEY_6),
BIND_GLOBAL_CONSTANT(KEY_7),
BIND_GLOBAL_CONSTANT(KEY_8),
BIND_GLOBAL_CONSTANT(KEY_9),
BIND_GLOBAL_CONSTANT(KEY_COLON),
BIND_GLOBAL_CONSTANT(KEY_SEMICOLON),
BIND_GLOBAL_CONSTANT(KEY_LESS),
BIND_GLOBAL_CONSTANT(KEY_EQUAL),
BIND_GLOBAL_CONSTANT(KEY_GREATER),
BIND_GLOBAL_CONSTANT(KEY_QUESTION),
BIND_GLOBAL_CONSTANT(KEY_AT),
BIND_GLOBAL_CONSTANT(KEY_A),
BIND_GLOBAL_CONSTANT(KEY_B),
BIND_GLOBAL_CONSTANT(KEY_C),
BIND_GLOBAL_CONSTANT(KEY_D),
BIND_GLOBAL_CONSTANT(KEY_E),
BIND_GLOBAL_CONSTANT(KEY_F),
BIND_GLOBAL_CONSTANT(KEY_G),
BIND_GLOBAL_CONSTANT(KEY_H),
BIND_GLOBAL_CONSTANT(KEY_I),
BIND_GLOBAL_CONSTANT(KEY_J),
BIND_GLOBAL_CONSTANT(KEY_K),
BIND_GLOBAL_CONSTANT(KEY_L),
BIND_GLOBAL_CONSTANT(KEY_M),
BIND_GLOBAL_CONSTANT(KEY_N),
BIND_GLOBAL_CONSTANT(KEY_O),
BIND_GLOBAL_CONSTANT(KEY_P),
BIND_GLOBAL_CONSTANT(KEY_Q),
BIND_GLOBAL_CONSTANT(KEY_R),
BIND_GLOBAL_CONSTANT(KEY_S),
BIND_GLOBAL_CONSTANT(KEY_T),
BIND_GLOBAL_CONSTANT(KEY_U),
BIND_GLOBAL_CONSTANT(KEY_V),
BIND_GLOBAL_CONSTANT(KEY_W),
BIND_GLOBAL_CONSTANT(KEY_X),
BIND_GLOBAL_CONSTANT(KEY_Y),
BIND_GLOBAL_CONSTANT(KEY_Z),
BIND_GLOBAL_CONSTANT(KEY_BRACKETLEFT),
BIND_GLOBAL_CONSTANT(KEY_BACKSLASH),
BIND_GLOBAL_CONSTANT(KEY_BRACKETRIGHT),
BIND_GLOBAL_CONSTANT(KEY_ASCIICIRCUM),
BIND_GLOBAL_CONSTANT(KEY_UNDERSCORE),
BIND_GLOBAL_CONSTANT(KEY_QUOTELEFT),
BIND_GLOBAL_CONSTANT(KEY_BRACELEFT),
BIND_GLOBAL_CONSTANT(KEY_BAR),
BIND_GLOBAL_CONSTANT(KEY_BRACERIGHT),
BIND_GLOBAL_CONSTANT(KEY_ASCIITILDE),
BIND_GLOBAL_CONSTANT(KEY_NOBREAKSPACE),
BIND_GLOBAL_CONSTANT(KEY_EXCLAMDOWN),
BIND_GLOBAL_CONSTANT(KEY_CENT),
BIND_GLOBAL_CONSTANT(KEY_STERLING),
BIND_GLOBAL_CONSTANT(KEY_CURRENCY),
BIND_GLOBAL_CONSTANT(KEY_YEN),
BIND_GLOBAL_CONSTANT(KEY_BROKENBAR),
BIND_GLOBAL_CONSTANT(KEY_SECTION),
BIND_GLOBAL_CONSTANT(KEY_DIAERESIS),
BIND_GLOBAL_CONSTANT(KEY_COPYRIGHT),
BIND_GLOBAL_CONSTANT(KEY_ORDFEMININE),
BIND_GLOBAL_CONSTANT(KEY_GUILLEMOTLEFT),
BIND_GLOBAL_CONSTANT(KEY_NOTSIGN),
BIND_GLOBAL_CONSTANT(KEY_HYPHEN),
BIND_GLOBAL_CONSTANT(KEY_REGISTERED),
BIND_GLOBAL_CONSTANT(KEY_MACRON),
BIND_GLOBAL_CONSTANT(KEY_DEGREE),
BIND_GLOBAL_CONSTANT(KEY_PLUSMINUS),
BIND_GLOBAL_CONSTANT(KEY_TWOSUPERIOR),
BIND_GLOBAL_CONSTANT(KEY_THREESUPERIOR),
BIND_GLOBAL_CONSTANT(KEY_ACUTE),
BIND_GLOBAL_CONSTANT(KEY_MU),
BIND_GLOBAL_CONSTANT(KEY_PARAGRAPH),
BIND_GLOBAL_CONSTANT(KEY_PERIODCENTERED),
BIND_GLOBAL_CONSTANT(KEY_CEDILLA),
BIND_GLOBAL_CONSTANT(KEY_ONESUPERIOR),
BIND_GLOBAL_CONSTANT(KEY_MASCULINE),
BIND_GLOBAL_CONSTANT(KEY_GUILLEMOTRIGHT),
BIND_GLOBAL_CONSTANT(KEY_ONEQUARTER),
BIND_GLOBAL_CONSTANT(KEY_ONEHALF),
BIND_GLOBAL_CONSTANT(KEY_THREEQUARTERS),
BIND_GLOBAL_CONSTANT(KEY_QUESTIONDOWN),
BIND_GLOBAL_CONSTANT(KEY_AGRAVE),
BIND_GLOBAL_CONSTANT(KEY_AACUTE),
BIND_GLOBAL_CONSTANT(KEY_ACIRCUMFLEX),
BIND_GLOBAL_CONSTANT(KEY_ATILDE),
BIND_GLOBAL_CONSTANT(KEY_ADIAERESIS),
BIND_GLOBAL_CONSTANT(KEY_ARING),
BIND_GLOBAL_CONSTANT(KEY_AE),
BIND_GLOBAL_CONSTANT(KEY_CCEDILLA),
BIND_GLOBAL_CONSTANT(KEY_EGRAVE),
BIND_GLOBAL_CONSTANT(KEY_EACUTE),
BIND_GLOBAL_CONSTANT(KEY_ECIRCUMFLEX),
BIND_GLOBAL_CONSTANT(KEY_EDIAERESIS),
BIND_GLOBAL_CONSTANT(KEY_IGRAVE),
BIND_GLOBAL_CONSTANT(KEY_IACUTE),
BIND_GLOBAL_CONSTANT(KEY_ICIRCUMFLEX),
BIND_GLOBAL_CONSTANT(KEY_IDIAERESIS),
BIND_GLOBAL_CONSTANT(KEY_ETH),
BIND_GLOBAL_CONSTANT(KEY_NTILDE),
BIND_GLOBAL_CONSTANT(KEY_OGRAVE),
BIND_GLOBAL_CONSTANT(KEY_OACUTE),
BIND_GLOBAL_CONSTANT(KEY_OCIRCUMFLEX),
BIND_GLOBAL_CONSTANT(KEY_OTILDE),
BIND_GLOBAL_CONSTANT(KEY_ODIAERESIS),
BIND_GLOBAL_CONSTANT(KEY_MULTIPLY),
BIND_GLOBAL_CONSTANT(KEY_OOBLIQUE),
BIND_GLOBAL_CONSTANT(KEY_UGRAVE),
BIND_GLOBAL_CONSTANT(KEY_UACUTE),
BIND_GLOBAL_CONSTANT(KEY_UCIRCUMFLEX),
BIND_GLOBAL_CONSTANT(KEY_UDIAERESIS),
BIND_GLOBAL_CONSTANT(KEY_YACUTE),
BIND_GLOBAL_CONSTANT(KEY_THORN),
BIND_GLOBAL_CONSTANT(KEY_SSHARP),
BIND_GLOBAL_CONSTANT( KEY_DIVISION ),
BIND_GLOBAL_CONSTANT( KEY_YDIAERESIS ),
BIND_GLOBAL_CONSTANT(KEY_DIVISION),
BIND_GLOBAL_CONSTANT(KEY_YDIAERESIS),
BIND_GLOBAL_CONSTANT( KEY_CODE_MASK ),
BIND_GLOBAL_CONSTANT( KEY_MODIFIER_MASK ),
BIND_GLOBAL_CONSTANT(KEY_CODE_MASK),
BIND_GLOBAL_CONSTANT(KEY_MODIFIER_MASK),
BIND_GLOBAL_CONSTANT( KEY_MASK_SHIFT ),
BIND_GLOBAL_CONSTANT( KEY_MASK_ALT ),
BIND_GLOBAL_CONSTANT( KEY_MASK_META ),
BIND_GLOBAL_CONSTANT( KEY_MASK_CTRL ),
BIND_GLOBAL_CONSTANT( KEY_MASK_CMD ),
BIND_GLOBAL_CONSTANT( KEY_MASK_KPAD ),
BIND_GLOBAL_CONSTANT( KEY_MASK_GROUP_SWITCH ),
BIND_GLOBAL_CONSTANT(KEY_MASK_SHIFT),
BIND_GLOBAL_CONSTANT(KEY_MASK_ALT),
BIND_GLOBAL_CONSTANT(KEY_MASK_META),
BIND_GLOBAL_CONSTANT(KEY_MASK_CTRL),
BIND_GLOBAL_CONSTANT(KEY_MASK_CMD),
BIND_GLOBAL_CONSTANT(KEY_MASK_KPAD),
BIND_GLOBAL_CONSTANT(KEY_MASK_GROUP_SWITCH),
// mouse
BIND_GLOBAL_CONSTANT( BUTTON_LEFT ),
BIND_GLOBAL_CONSTANT( BUTTON_RIGHT ),
BIND_GLOBAL_CONSTANT( BUTTON_MIDDLE ),
BIND_GLOBAL_CONSTANT( BUTTON_WHEEL_UP ),
BIND_GLOBAL_CONSTANT( BUTTON_WHEEL_DOWN ),
BIND_GLOBAL_CONSTANT( BUTTON_WHEEL_LEFT ),
BIND_GLOBAL_CONSTANT( BUTTON_WHEEL_RIGHT ),
BIND_GLOBAL_CONSTANT( BUTTON_MASK_LEFT ),
BIND_GLOBAL_CONSTANT( BUTTON_MASK_RIGHT ),
BIND_GLOBAL_CONSTANT( BUTTON_MASK_MIDDLE ),
BIND_GLOBAL_CONSTANT(BUTTON_LEFT),
BIND_GLOBAL_CONSTANT(BUTTON_RIGHT),
BIND_GLOBAL_CONSTANT(BUTTON_MIDDLE),
BIND_GLOBAL_CONSTANT(BUTTON_WHEEL_UP),
BIND_GLOBAL_CONSTANT(BUTTON_WHEEL_DOWN),
BIND_GLOBAL_CONSTANT(BUTTON_WHEEL_LEFT),
BIND_GLOBAL_CONSTANT(BUTTON_WHEEL_RIGHT),
BIND_GLOBAL_CONSTANT(BUTTON_MASK_LEFT),
BIND_GLOBAL_CONSTANT(BUTTON_MASK_RIGHT),
BIND_GLOBAL_CONSTANT(BUTTON_MASK_MIDDLE),
//joysticks
BIND_GLOBAL_CONSTANT( JOY_BUTTON_0 ),
BIND_GLOBAL_CONSTANT( JOY_BUTTON_1 ),
BIND_GLOBAL_CONSTANT( JOY_BUTTON_2 ),
BIND_GLOBAL_CONSTANT( JOY_BUTTON_3 ),
BIND_GLOBAL_CONSTANT( JOY_BUTTON_4 ),
BIND_GLOBAL_CONSTANT( JOY_BUTTON_5 ),
BIND_GLOBAL_CONSTANT( JOY_BUTTON_6 ),
BIND_GLOBAL_CONSTANT( JOY_BUTTON_7 ),
BIND_GLOBAL_CONSTANT( JOY_BUTTON_8 ),
BIND_GLOBAL_CONSTANT( JOY_BUTTON_9 ),
BIND_GLOBAL_CONSTANT( JOY_BUTTON_10 ),
BIND_GLOBAL_CONSTANT( JOY_BUTTON_11 ),
BIND_GLOBAL_CONSTANT( JOY_BUTTON_12 ),
BIND_GLOBAL_CONSTANT( JOY_BUTTON_13 ),
BIND_GLOBAL_CONSTANT( JOY_BUTTON_14 ),
BIND_GLOBAL_CONSTANT( JOY_BUTTON_15 ),
BIND_GLOBAL_CONSTANT( JOY_BUTTON_MAX ),
BIND_GLOBAL_CONSTANT(JOY_BUTTON_0),
BIND_GLOBAL_CONSTANT(JOY_BUTTON_1),
BIND_GLOBAL_CONSTANT(JOY_BUTTON_2),
BIND_GLOBAL_CONSTANT(JOY_BUTTON_3),
BIND_GLOBAL_CONSTANT(JOY_BUTTON_4),
BIND_GLOBAL_CONSTANT(JOY_BUTTON_5),
BIND_GLOBAL_CONSTANT(JOY_BUTTON_6),
BIND_GLOBAL_CONSTANT(JOY_BUTTON_7),
BIND_GLOBAL_CONSTANT(JOY_BUTTON_8),
BIND_GLOBAL_CONSTANT(JOY_BUTTON_9),
BIND_GLOBAL_CONSTANT(JOY_BUTTON_10),
BIND_GLOBAL_CONSTANT(JOY_BUTTON_11),
BIND_GLOBAL_CONSTANT(JOY_BUTTON_12),
BIND_GLOBAL_CONSTANT(JOY_BUTTON_13),
BIND_GLOBAL_CONSTANT(JOY_BUTTON_14),
BIND_GLOBAL_CONSTANT(JOY_BUTTON_15),
BIND_GLOBAL_CONSTANT(JOY_BUTTON_MAX),
BIND_GLOBAL_CONSTANT( JOY_SNES_A ),
BIND_GLOBAL_CONSTANT( JOY_SNES_B ),
BIND_GLOBAL_CONSTANT( JOY_SNES_X ),
BIND_GLOBAL_CONSTANT( JOY_SNES_Y ),
BIND_GLOBAL_CONSTANT(JOY_SNES_A),
BIND_GLOBAL_CONSTANT(JOY_SNES_B),
BIND_GLOBAL_CONSTANT(JOY_SNES_X),
BIND_GLOBAL_CONSTANT(JOY_SNES_Y),
BIND_GLOBAL_CONSTANT( JOY_SONY_CIRCLE ),
BIND_GLOBAL_CONSTANT( JOY_SONY_X ),
BIND_GLOBAL_CONSTANT( JOY_SONY_SQUARE ),
BIND_GLOBAL_CONSTANT( JOY_SONY_TRIANGLE ),
BIND_GLOBAL_CONSTANT(JOY_SONY_CIRCLE),
BIND_GLOBAL_CONSTANT(JOY_SONY_X),
BIND_GLOBAL_CONSTANT(JOY_SONY_SQUARE),
BIND_GLOBAL_CONSTANT(JOY_SONY_TRIANGLE),
BIND_GLOBAL_CONSTANT( JOY_SEGA_B ),
BIND_GLOBAL_CONSTANT( JOY_SEGA_A ),
BIND_GLOBAL_CONSTANT( JOY_SEGA_X ),
BIND_GLOBAL_CONSTANT( JOY_SEGA_Y ),
BIND_GLOBAL_CONSTANT(JOY_SEGA_B),
BIND_GLOBAL_CONSTANT(JOY_SEGA_A),
BIND_GLOBAL_CONSTANT(JOY_SEGA_X),
BIND_GLOBAL_CONSTANT(JOY_SEGA_Y),
BIND_GLOBAL_CONSTANT( JOY_XBOX_B ),
BIND_GLOBAL_CONSTANT( JOY_XBOX_A ),
BIND_GLOBAL_CONSTANT( JOY_XBOX_X ),
BIND_GLOBAL_CONSTANT( JOY_XBOX_Y ),
BIND_GLOBAL_CONSTANT(JOY_XBOX_B),
BIND_GLOBAL_CONSTANT(JOY_XBOX_A),
BIND_GLOBAL_CONSTANT(JOY_XBOX_X),
BIND_GLOBAL_CONSTANT(JOY_XBOX_Y),
BIND_GLOBAL_CONSTANT( JOY_DS_A ),
BIND_GLOBAL_CONSTANT( JOY_DS_B ),
BIND_GLOBAL_CONSTANT( JOY_DS_X ),
BIND_GLOBAL_CONSTANT( JOY_DS_Y ),
BIND_GLOBAL_CONSTANT(JOY_DS_A),
BIND_GLOBAL_CONSTANT(JOY_DS_B),
BIND_GLOBAL_CONSTANT(JOY_DS_X),
BIND_GLOBAL_CONSTANT(JOY_DS_Y),
BIND_GLOBAL_CONSTANT( JOY_SELECT ),
BIND_GLOBAL_CONSTANT( JOY_START ),
BIND_GLOBAL_CONSTANT( JOY_DPAD_UP ),
BIND_GLOBAL_CONSTANT( JOY_DPAD_DOWN ),
BIND_GLOBAL_CONSTANT( JOY_DPAD_LEFT ),
BIND_GLOBAL_CONSTANT( JOY_DPAD_RIGHT ),
BIND_GLOBAL_CONSTANT( JOY_L ),
BIND_GLOBAL_CONSTANT( JOY_L2 ),
BIND_GLOBAL_CONSTANT( JOY_L3 ),
BIND_GLOBAL_CONSTANT( JOY_R ),
BIND_GLOBAL_CONSTANT( JOY_R2 ),
BIND_GLOBAL_CONSTANT( JOY_R3 ),
BIND_GLOBAL_CONSTANT(JOY_SELECT),
BIND_GLOBAL_CONSTANT(JOY_START),
BIND_GLOBAL_CONSTANT(JOY_DPAD_UP),
BIND_GLOBAL_CONSTANT(JOY_DPAD_DOWN),
BIND_GLOBAL_CONSTANT(JOY_DPAD_LEFT),
BIND_GLOBAL_CONSTANT(JOY_DPAD_RIGHT),
BIND_GLOBAL_CONSTANT(JOY_L),
BIND_GLOBAL_CONSTANT(JOY_L2),
BIND_GLOBAL_CONSTANT(JOY_L3),
BIND_GLOBAL_CONSTANT(JOY_R),
BIND_GLOBAL_CONSTANT(JOY_R2),
BIND_GLOBAL_CONSTANT(JOY_R3),
BIND_GLOBAL_CONSTANT( JOY_AXIS_0 ),
BIND_GLOBAL_CONSTANT( JOY_AXIS_1 ),
BIND_GLOBAL_CONSTANT( JOY_AXIS_2 ),
BIND_GLOBAL_CONSTANT( JOY_AXIS_3 ),
BIND_GLOBAL_CONSTANT( JOY_AXIS_4 ),
BIND_GLOBAL_CONSTANT( JOY_AXIS_5 ),
BIND_GLOBAL_CONSTANT( JOY_AXIS_6 ),
BIND_GLOBAL_CONSTANT( JOY_AXIS_7 ),
BIND_GLOBAL_CONSTANT( JOY_AXIS_MAX ),
BIND_GLOBAL_CONSTANT(JOY_AXIS_0),
BIND_GLOBAL_CONSTANT(JOY_AXIS_1),
BIND_GLOBAL_CONSTANT(JOY_AXIS_2),
BIND_GLOBAL_CONSTANT(JOY_AXIS_3),
BIND_GLOBAL_CONSTANT(JOY_AXIS_4),
BIND_GLOBAL_CONSTANT(JOY_AXIS_5),
BIND_GLOBAL_CONSTANT(JOY_AXIS_6),
BIND_GLOBAL_CONSTANT(JOY_AXIS_7),
BIND_GLOBAL_CONSTANT(JOY_AXIS_MAX),
BIND_GLOBAL_CONSTANT( JOY_ANALOG_0_X ),
BIND_GLOBAL_CONSTANT( JOY_ANALOG_0_Y ),
BIND_GLOBAL_CONSTANT(JOY_ANALOG_0_X),
BIND_GLOBAL_CONSTANT(JOY_ANALOG_0_Y),
BIND_GLOBAL_CONSTANT( JOY_ANALOG_1_X ),
BIND_GLOBAL_CONSTANT( JOY_ANALOG_1_Y ),
BIND_GLOBAL_CONSTANT(JOY_ANALOG_1_X),
BIND_GLOBAL_CONSTANT(JOY_ANALOG_1_Y),
BIND_GLOBAL_CONSTANT( JOY_ANALOG_2_X ),
BIND_GLOBAL_CONSTANT( JOY_ANALOG_2_Y ),
BIND_GLOBAL_CONSTANT( JOY_ANALOG_L2 ),
BIND_GLOBAL_CONSTANT( JOY_ANALOG_R2 ),
BIND_GLOBAL_CONSTANT(JOY_ANALOG_2_X),
BIND_GLOBAL_CONSTANT(JOY_ANALOG_2_Y),
BIND_GLOBAL_CONSTANT(JOY_ANALOG_L2),
BIND_GLOBAL_CONSTANT(JOY_ANALOG_R2),
// error list
BIND_GLOBAL_CONSTANT( OK ),
BIND_GLOBAL_CONSTANT( FAILED ), ///< Generic fail error
BIND_GLOBAL_CONSTANT( ERR_UNAVAILABLE ), ///< What is requested is unsupported/unavailable
BIND_GLOBAL_CONSTANT( ERR_UNCONFIGURED ), ///< The object being used hasnt been properly set up yet
BIND_GLOBAL_CONSTANT( ERR_UNAUTHORIZED ), ///< Missing credentials for requested resource
BIND_GLOBAL_CONSTANT( ERR_PARAMETER_RANGE_ERROR ), ///< Parameter given out of range
BIND_GLOBAL_CONSTANT( ERR_OUT_OF_MEMORY ), ///< Out of memory
BIND_GLOBAL_CONSTANT( ERR_FILE_NOT_FOUND ),
BIND_GLOBAL_CONSTANT( ERR_FILE_BAD_DRIVE ),
BIND_GLOBAL_CONSTANT( ERR_FILE_BAD_PATH ),
BIND_GLOBAL_CONSTANT( ERR_FILE_NO_PERMISSION ),
BIND_GLOBAL_CONSTANT( ERR_FILE_ALREADY_IN_USE ),
BIND_GLOBAL_CONSTANT( ERR_FILE_CANT_OPEN ),
BIND_GLOBAL_CONSTANT( ERR_FILE_CANT_WRITE ),
BIND_GLOBAL_CONSTANT( ERR_FILE_CANT_READ ),
BIND_GLOBAL_CONSTANT( ERR_FILE_UNRECOGNIZED ),
BIND_GLOBAL_CONSTANT( ERR_FILE_CORRUPT ),
BIND_GLOBAL_CONSTANT( ERR_FILE_MISSING_DEPENDENCIES),
BIND_GLOBAL_CONSTANT( ERR_FILE_EOF ),
BIND_GLOBAL_CONSTANT( ERR_CANT_OPEN ), ///< Can't open a resource/socket/file
BIND_GLOBAL_CONSTANT( ERR_CANT_CREATE ),
BIND_GLOBAL_CONSTANT( ERR_PARSE_ERROR ),
BIND_GLOBAL_CONSTANT( ERROR_QUERY_FAILED ),
BIND_GLOBAL_CONSTANT( ERR_ALREADY_IN_USE ),
BIND_GLOBAL_CONSTANT( ERR_LOCKED ), ///< resource is locked
BIND_GLOBAL_CONSTANT( ERR_TIMEOUT ),
BIND_GLOBAL_CONSTANT( ERR_CANT_AQUIRE_RESOURCE ),
BIND_GLOBAL_CONSTANT( ERR_INVALID_DATA ), ///< Data passed is invalid
BIND_GLOBAL_CONSTANT( ERR_INVALID_PARAMETER ), ///< Parameter passed is invalid
BIND_GLOBAL_CONSTANT( ERR_ALREADY_EXISTS ), ///< When adding ), item already exists
BIND_GLOBAL_CONSTANT( ERR_DOES_NOT_EXIST ), ///< When retrieving/erasing ), it item does not exist
BIND_GLOBAL_CONSTANT( ERR_DATABASE_CANT_READ ), ///< database is full
BIND_GLOBAL_CONSTANT( ERR_DATABASE_CANT_WRITE ), ///< database is full
BIND_GLOBAL_CONSTANT( ERR_COMPILATION_FAILED ),
BIND_GLOBAL_CONSTANT( ERR_METHOD_NOT_FOUND ),
BIND_GLOBAL_CONSTANT( ERR_LINK_FAILED ),
BIND_GLOBAL_CONSTANT( ERR_SCRIPT_FAILED ),
BIND_GLOBAL_CONSTANT( ERR_CYCLIC_LINK ),
BIND_GLOBAL_CONSTANT( ERR_BUSY ),
BIND_GLOBAL_CONSTANT( ERR_HELP ), ///< user requested help!!
BIND_GLOBAL_CONSTANT( ERR_BUG ), ///< a bug in the software certainly happened ), due to a double check failing or unexpected behavior.
BIND_GLOBAL_CONSTANT( ERR_WTF ),
BIND_GLOBAL_CONSTANT(OK),
BIND_GLOBAL_CONSTANT(FAILED), ///< Generic fail error
BIND_GLOBAL_CONSTANT(ERR_UNAVAILABLE), ///< What is requested is unsupported/unavailable
BIND_GLOBAL_CONSTANT(ERR_UNCONFIGURED), ///< The object being used hasnt been properly set up yet
BIND_GLOBAL_CONSTANT(ERR_UNAUTHORIZED), ///< Missing credentials for requested resource
BIND_GLOBAL_CONSTANT(ERR_PARAMETER_RANGE_ERROR), ///< Parameter given out of range
BIND_GLOBAL_CONSTANT(ERR_OUT_OF_MEMORY), ///< Out of memory
BIND_GLOBAL_CONSTANT(ERR_FILE_NOT_FOUND),
BIND_GLOBAL_CONSTANT(ERR_FILE_BAD_DRIVE),
BIND_GLOBAL_CONSTANT(ERR_FILE_BAD_PATH),
BIND_GLOBAL_CONSTANT(ERR_FILE_NO_PERMISSION),
BIND_GLOBAL_CONSTANT(ERR_FILE_ALREADY_IN_USE),
BIND_GLOBAL_CONSTANT(ERR_FILE_CANT_OPEN),
BIND_GLOBAL_CONSTANT(ERR_FILE_CANT_WRITE),
BIND_GLOBAL_CONSTANT(ERR_FILE_CANT_READ),
BIND_GLOBAL_CONSTANT(ERR_FILE_UNRECOGNIZED),
BIND_GLOBAL_CONSTANT(ERR_FILE_CORRUPT),
BIND_GLOBAL_CONSTANT(ERR_FILE_MISSING_DEPENDENCIES),
BIND_GLOBAL_CONSTANT(ERR_FILE_EOF),
BIND_GLOBAL_CONSTANT(ERR_CANT_OPEN), ///< Can't open a resource/socket/file
BIND_GLOBAL_CONSTANT(ERR_CANT_CREATE),
BIND_GLOBAL_CONSTANT(ERR_PARSE_ERROR),
BIND_GLOBAL_CONSTANT(ERROR_QUERY_FAILED),
BIND_GLOBAL_CONSTANT(ERR_ALREADY_IN_USE),
BIND_GLOBAL_CONSTANT(ERR_LOCKED), ///< resource is locked
BIND_GLOBAL_CONSTANT(ERR_TIMEOUT),
BIND_GLOBAL_CONSTANT(ERR_CANT_AQUIRE_RESOURCE),
BIND_GLOBAL_CONSTANT(ERR_INVALID_DATA), ///< Data passed is invalid
BIND_GLOBAL_CONSTANT(ERR_INVALID_PARAMETER), ///< Parameter passed is invalid
BIND_GLOBAL_CONSTANT(ERR_ALREADY_EXISTS), ///< When adding ), item already exists
BIND_GLOBAL_CONSTANT(ERR_DOES_NOT_EXIST), ///< When retrieving/erasing ), it item does not exist
BIND_GLOBAL_CONSTANT(ERR_DATABASE_CANT_READ), ///< database is full
BIND_GLOBAL_CONSTANT(ERR_DATABASE_CANT_WRITE), ///< database is full
BIND_GLOBAL_CONSTANT(ERR_COMPILATION_FAILED),
BIND_GLOBAL_CONSTANT(ERR_METHOD_NOT_FOUND),
BIND_GLOBAL_CONSTANT(ERR_LINK_FAILED),
BIND_GLOBAL_CONSTANT(ERR_SCRIPT_FAILED),
BIND_GLOBAL_CONSTANT(ERR_CYCLIC_LINK),
BIND_GLOBAL_CONSTANT(ERR_BUSY),
BIND_GLOBAL_CONSTANT(ERR_HELP), ///< user requested help!!
BIND_GLOBAL_CONSTANT(ERR_BUG), ///< a bug in the software certainly happened ), due to a double check failing or unexpected behavior.
BIND_GLOBAL_CONSTANT(ERR_WTF),
BIND_GLOBAL_CONSTANT(PROPERTY_HINT_NONE),
BIND_GLOBAL_CONSTANT(PROPERTY_HINT_RANGE),
BIND_GLOBAL_CONSTANT(PROPERTY_HINT_EXP_RANGE),
BIND_GLOBAL_CONSTANT(PROPERTY_HINT_ENUM),
BIND_GLOBAL_CONSTANT(PROPERTY_HINT_EXP_EASING),
BIND_GLOBAL_CONSTANT(PROPERTY_HINT_LENGTH),
BIND_GLOBAL_CONSTANT(PROPERTY_HINT_KEY_ACCEL),
BIND_GLOBAL_CONSTANT(PROPERTY_HINT_FLAGS),
BIND_GLOBAL_CONSTANT(PROPERTY_HINT_ALL_FLAGS),
BIND_GLOBAL_CONSTANT(PROPERTY_HINT_FILE),
BIND_GLOBAL_CONSTANT(PROPERTY_HINT_DIR),
BIND_GLOBAL_CONSTANT(PROPERTY_HINT_GLOBAL_FILE),
BIND_GLOBAL_CONSTANT(PROPERTY_HINT_GLOBAL_DIR),
BIND_GLOBAL_CONSTANT(PROPERTY_HINT_RESOURCE_TYPE),
BIND_GLOBAL_CONSTANT(PROPERTY_HINT_MULTILINE_TEXT),
BIND_GLOBAL_CONSTANT(PROPERTY_HINT_COLOR_NO_ALPHA),
BIND_GLOBAL_CONSTANT(PROPERTY_HINT_IMAGE_COMPRESS_LOSSY),
BIND_GLOBAL_CONSTANT(PROPERTY_HINT_IMAGE_COMPRESS_LOSSLESS),
BIND_GLOBAL_CONSTANT( PROPERTY_HINT_NONE ),
BIND_GLOBAL_CONSTANT( PROPERTY_HINT_RANGE ),
BIND_GLOBAL_CONSTANT( PROPERTY_HINT_EXP_RANGE ),
BIND_GLOBAL_CONSTANT( PROPERTY_HINT_ENUM ),
BIND_GLOBAL_CONSTANT( PROPERTY_HINT_EXP_EASING ),
BIND_GLOBAL_CONSTANT( PROPERTY_HINT_LENGTH ),
BIND_GLOBAL_CONSTANT( PROPERTY_HINT_KEY_ACCEL ),
BIND_GLOBAL_CONSTANT( PROPERTY_HINT_FLAGS ),
BIND_GLOBAL_CONSTANT( PROPERTY_HINT_ALL_FLAGS ),
BIND_GLOBAL_CONSTANT( PROPERTY_HINT_FILE ),
BIND_GLOBAL_CONSTANT( PROPERTY_HINT_DIR ),
BIND_GLOBAL_CONSTANT( PROPERTY_HINT_GLOBAL_FILE ),
BIND_GLOBAL_CONSTANT( PROPERTY_HINT_GLOBAL_DIR ),
BIND_GLOBAL_CONSTANT( PROPERTY_HINT_RESOURCE_TYPE ),
BIND_GLOBAL_CONSTANT( PROPERTY_HINT_MULTILINE_TEXT ),
BIND_GLOBAL_CONSTANT( PROPERTY_HINT_COLOR_NO_ALPHA ),
BIND_GLOBAL_CONSTANT( PROPERTY_HINT_IMAGE_COMPRESS_LOSSY ),
BIND_GLOBAL_CONSTANT( PROPERTY_HINT_IMAGE_COMPRESS_LOSSLESS ),
BIND_GLOBAL_CONSTANT(PROPERTY_USAGE_STORAGE),
BIND_GLOBAL_CONSTANT(PROPERTY_USAGE_EDITOR),
BIND_GLOBAL_CONSTANT(PROPERTY_USAGE_NETWORK),
BIND_GLOBAL_CONSTANT(PROPERTY_USAGE_EDITOR_HELPER),
BIND_GLOBAL_CONSTANT(PROPERTY_USAGE_CHECKABLE),
BIND_GLOBAL_CONSTANT(PROPERTY_USAGE_CHECKED),
BIND_GLOBAL_CONSTANT(PROPERTY_USAGE_INTERNATIONALIZED),
BIND_GLOBAL_CONSTANT(PROPERTY_USAGE_BUNDLE),
BIND_GLOBAL_CONSTANT(PROPERTY_USAGE_CATEGORY),
BIND_GLOBAL_CONSTANT(PROPERTY_USAGE_STORE_IF_NONZERO),
BIND_GLOBAL_CONSTANT(PROPERTY_USAGE_STORE_IF_NONONE),
BIND_GLOBAL_CONSTANT(PROPERTY_USAGE_NO_INSTANCE_STATE),
BIND_GLOBAL_CONSTANT(PROPERTY_USAGE_RESTART_IF_CHANGED),
BIND_GLOBAL_CONSTANT(PROPERTY_USAGE_SCRIPT_VARIABLE),
BIND_GLOBAL_CONSTANT( PROPERTY_USAGE_STORAGE ),
BIND_GLOBAL_CONSTANT( PROPERTY_USAGE_EDITOR ),
BIND_GLOBAL_CONSTANT( PROPERTY_USAGE_NETWORK ),
BIND_GLOBAL_CONSTANT(PROPERTY_USAGE_DEFAULT),
BIND_GLOBAL_CONSTANT(PROPERTY_USAGE_DEFAULT_INTL),
BIND_GLOBAL_CONSTANT(PROPERTY_USAGE_NOEDITOR),
BIND_GLOBAL_CONSTANT( PROPERTY_USAGE_EDITOR_HELPER ),
BIND_GLOBAL_CONSTANT( PROPERTY_USAGE_CHECKABLE ),
BIND_GLOBAL_CONSTANT( PROPERTY_USAGE_CHECKED ),
BIND_GLOBAL_CONSTANT( PROPERTY_USAGE_INTERNATIONALIZED ),
BIND_GLOBAL_CONSTANT( PROPERTY_USAGE_BUNDLE ),
BIND_GLOBAL_CONSTANT( PROPERTY_USAGE_CATEGORY ),
BIND_GLOBAL_CONSTANT( PROPERTY_USAGE_STORE_IF_NONZERO ),
BIND_GLOBAL_CONSTANT( PROPERTY_USAGE_STORE_IF_NONONE ),
BIND_GLOBAL_CONSTANT( PROPERTY_USAGE_NO_INSTANCE_STATE ),
BIND_GLOBAL_CONSTANT( PROPERTY_USAGE_RESTART_IF_CHANGED ),
BIND_GLOBAL_CONSTANT( PROPERTY_USAGE_SCRIPT_VARIABLE ),
BIND_GLOBAL_CONSTANT(METHOD_FLAG_NORMAL),
BIND_GLOBAL_CONSTANT(METHOD_FLAG_EDITOR),
BIND_GLOBAL_CONSTANT(METHOD_FLAG_NOSCRIPT),
BIND_GLOBAL_CONSTANT(METHOD_FLAG_CONST),
BIND_GLOBAL_CONSTANT(METHOD_FLAG_REVERSE),
BIND_GLOBAL_CONSTANT(METHOD_FLAG_VIRTUAL),
BIND_GLOBAL_CONSTANT(METHOD_FLAG_FROM_SCRIPT),
BIND_GLOBAL_CONSTANT(METHOD_FLAGS_DEFAULT),
BIND_GLOBAL_CONSTANT( PROPERTY_USAGE_DEFAULT ),
BIND_GLOBAL_CONSTANT( PROPERTY_USAGE_DEFAULT_INTL ),
BIND_GLOBAL_CONSTANT( PROPERTY_USAGE_NOEDITOR ),
BIND_GLOBAL_CONSTANT( METHOD_FLAG_NORMAL ),
BIND_GLOBAL_CONSTANT( METHOD_FLAG_EDITOR ),
BIND_GLOBAL_CONSTANT( METHOD_FLAG_NOSCRIPT ),
BIND_GLOBAL_CONSTANT( METHOD_FLAG_CONST ),
BIND_GLOBAL_CONSTANT( METHOD_FLAG_REVERSE ),
BIND_GLOBAL_CONSTANT( METHOD_FLAG_VIRTUAL ),
BIND_GLOBAL_CONSTANT( METHOD_FLAG_FROM_SCRIPT ),
BIND_GLOBAL_CONSTANT( METHOD_FLAGS_DEFAULT ),
{"TYPE_NIL",Variant::NIL},
{"TYPE_BOOL",Variant::BOOL},
{"TYPE_INT",Variant::INT},
{"TYPE_REAL",Variant::REAL},
{"TYPE_STRING",Variant::STRING},
{"TYPE_VECTOR2",Variant::VECTOR2}, // 5
{"TYPE_RECT2",Variant::RECT2},
{"TYPE_VECTOR3",Variant::VECTOR3},
{"TYPE_MATRIX32",Variant::MATRIX32},
{"TYPE_PLANE",Variant::PLANE},
{"TYPE_QUAT",Variant::QUAT}, // 10
{"TYPE_AABB",Variant::_AABB}, //sorry naming convention fail :( not like it's used often
{"TYPE_MATRIX3",Variant::MATRIX3},
{"TYPE_TRANSFORM",Variant::TRANSFORM},
{"TYPE_COLOR",Variant::COLOR},
{"TYPE_IMAGE",Variant::IMAGE}, // 15
{"TYPE_NODE_PATH",Variant::NODE_PATH},
{"TYPE_RID",Variant::_RID},
{"TYPE_OBJECT",Variant::OBJECT},
{"TYPE_INPUT_EVENT",Variant::INPUT_EVENT},
{"TYPE_DICTIONARY",Variant::DICTIONARY}, // 20
{"TYPE_ARRAY",Variant::ARRAY},
{"TYPE_RAW_ARRAY",Variant::RAW_ARRAY},
{"TYPE_INT_ARRAY",Variant::INT_ARRAY},
{"TYPE_REAL_ARRAY",Variant::REAL_ARRAY},
{"TYPE_STRING_ARRAY",Variant::STRING_ARRAY}, // 25
{"TYPE_VECTOR2_ARRAY",Variant::VECTOR2_ARRAY},
{"TYPE_VECTOR3_ARRAY",Variant::VECTOR3_ARRAY},
{"TYPE_COLOR_ARRAY",Variant::COLOR_ARRAY},
{"TYPE_MAX",Variant::VARIANT_MAX},
{NULL,0}
{ "TYPE_NIL", Variant::NIL },
{ "TYPE_BOOL", Variant::BOOL },
{ "TYPE_INT", Variant::INT },
{ "TYPE_REAL", Variant::REAL },
{ "TYPE_STRING", Variant::STRING },
{ "TYPE_VECTOR2", Variant::VECTOR2 }, // 5
{ "TYPE_RECT2", Variant::RECT2 },
{ "TYPE_VECTOR3", Variant::VECTOR3 },
{ "TYPE_MATRIX32", Variant::MATRIX32 },
{ "TYPE_PLANE", Variant::PLANE },
{ "TYPE_QUAT", Variant::QUAT }, // 10
{ "TYPE_AABB", Variant::_AABB }, //sorry naming convention fail :( not like it's used often
{ "TYPE_MATRIX3", Variant::MATRIX3 },
{ "TYPE_TRANSFORM", Variant::TRANSFORM },
{ "TYPE_COLOR", Variant::COLOR },
{ "TYPE_IMAGE", Variant::IMAGE }, // 15
{ "TYPE_NODE_PATH", Variant::NODE_PATH },
{ "TYPE_RID", Variant::_RID },
{ "TYPE_OBJECT", Variant::OBJECT },
{ "TYPE_INPUT_EVENT", Variant::INPUT_EVENT },
{ "TYPE_DICTIONARY", Variant::DICTIONARY }, // 20
{ "TYPE_ARRAY", Variant::ARRAY },
{ "TYPE_RAW_ARRAY", Variant::RAW_ARRAY },
{ "TYPE_INT_ARRAY", Variant::INT_ARRAY },
{ "TYPE_REAL_ARRAY", Variant::REAL_ARRAY },
{ "TYPE_STRING_ARRAY", Variant::STRING_ARRAY }, // 25
{ "TYPE_VECTOR2_ARRAY", Variant::VECTOR2_ARRAY },
{ "TYPE_VECTOR3_ARRAY", Variant::VECTOR3_ARRAY },
{ "TYPE_COLOR_ARRAY", Variant::COLOR_ARRAY },
{ "TYPE_MAX", Variant::VARIANT_MAX },
{ NULL, 0 }
};
int GlobalConstants::get_global_constant_count() {
int i=0;
while(_global_constants[i].name)
int i = 0;
while (_global_constants[i].name)
i++;
return i;
}
const char *GlobalConstants::get_global_constant_name(int p_idx) {
@ -556,5 +552,3 @@ int GlobalConstants::get_global_constant_value(int p_idx) {
return _global_constants[p_idx].value;
}

View File

@ -29,10 +29,8 @@
#ifndef GLOBAL_CONSTANTS_H
#define GLOBAL_CONSTANTS_H
class GlobalConstants {
public:
static int get_global_constant_count();
static const char *get_global_constant_name(int p_idx);
static int get_global_constant_value(int p_idx);

File diff suppressed because it is too large Load Diff

View File

@ -30,32 +30,32 @@
#define GLOBALS_H
#include "object.h"
#include "set.h"
#include "os/thread_safe.h"
#include "set.h"
/**
@author Juan Linietsky <reduzio@gmail.com>
*/
class Globals : public Object {
OBJ_TYPE( Globals, Object );
OBJ_TYPE(Globals, Object);
_THREAD_SAFE_CLASS_
public:
typedef Map<String,Variant> CustomMap;
typedef Map<String, Variant> CustomMap;
struct Singleton {
StringName name;
Object *ptr;
Singleton(const StringName& p_name=StringName(), Object *p_ptr=NULL) { name=p_name; ptr=p_ptr; }
Singleton(const StringName &p_name = StringName(), Object *p_ptr = NULL) {
name = p_name;
ptr = p_ptr;
}
};
protected:
enum {
NO_ORDER_BASE=1<<18
NO_ORDER_BASE = 1 << 18
};
struct VariantContainer {
@ -64,22 +64,32 @@ protected:
Variant variant;
bool hide_from_editor;
bool overrided;
VariantContainer(){ order=0; hide_from_editor=false; persist=false; overrided=false; }
VariantContainer(const Variant& p_variant, int p_order, bool p_persist=false) { variant=p_variant; order=p_order; hide_from_editor=false; persist=p_persist; overrided=false; }
VariantContainer() {
order = 0;
hide_from_editor = false;
persist = false;
overrided = false;
}
VariantContainer(const Variant &p_variant, int p_order, bool p_persist = false) {
variant = p_variant;
order = p_order;
hide_from_editor = false;
persist = p_persist;
overrided = false;
}
};
bool registering_order;
int last_order;
Map<StringName,VariantContainer> props;
Map<StringName, VariantContainer> props;
String resource_path;
Map<StringName,PropertyInfo> custom_prop_info;
Map<StringName, PropertyInfo> custom_prop_info;
bool disable_platform_override;
bool using_datapack;
List<String> input_presets;
bool _set(const StringName& p_name, const Variant& p_value);
bool _get(const StringName& p_name,Variant &r_ret) const;
bool _set(const StringName &p_name, const Variant &p_value);
bool _get(const StringName &p_name, Variant &r_ret) const;
void _get_property_list(List<PropertyInfo> *p_list) const;
static Globals *singleton;
@ -87,55 +97,53 @@ protected:
Error _load_settings(const String p_path);
Error _load_settings_binary(const String p_path);
Error _save_settings_text(const String& p_file,const Map<String,List<String> > &props,const CustomMap& p_custom=CustomMap());
Error _save_settings_binary(const String& p_file,const Map<String,List<String> > &props,const CustomMap& p_custom=CustomMap());
Error _save_settings_text(const String &p_file, const Map<String, List<String> > &props, const CustomMap &p_custom = CustomMap());
Error _save_settings_binary(const String &p_file, const Map<String, List<String> > &props, const CustomMap &p_custom = CustomMap());
List<Singleton> singletons;
Error _save_custom_bnd(const String& p_file);
Error _save_custom_bnd(const String &p_file);
bool _load_resource_pack(const String& p_pack);
bool _load_resource_pack(const String &p_pack);
void _add_property_info_bind(const Dictionary& p_info);
void _add_property_info_bind(const Dictionary &p_info);
protected:
static void _bind_methods();
public:
bool has(String p_var) const;
String localize_path(const String& p_path) const;
String globalize_path(const String& p_path) const;
String localize_path(const String &p_path) const;
String globalize_path(const String &p_path) const;
void set_persisting(const String& p_name, bool p_persist);
bool is_persisting(const String& p_name) const;
void set_persisting(const String &p_name, bool p_persist);
bool is_persisting(const String &p_name) const;
String get_resource_path() const;
static Globals *get_singleton();
void clear(const String& p_name);
int get_order(const String& p_name) const;
void set_order(const String& p_name, int p_order);
void clear(const String &p_name);
int get_order(const String &p_name) const;
void set_order(const String &p_name, int p_order);
Error setup(const String& p_path, const String &p_main_pack);
Error setup(const String &p_path, const String &p_main_pack);
Error save_custom(const String& p_path="",const CustomMap& p_custom=CustomMap(),const Set<String>& p_ignore_masks=Set<String>());
Error save_custom(const String &p_path = "", const CustomMap &p_custom = CustomMap(), const Set<String> &p_ignore_masks = Set<String>());
Error save();
void set_custom_property_info(const String& p_prop,const PropertyInfo& p_info);
void set_custom_property_info(const String &p_prop, const PropertyInfo &p_info);
void add_singleton(const Singleton &p_singleton);
void get_singletons(List<Singleton> *p_singletons);
bool has_singleton(const String& p_name) const;
bool has_singleton(const String &p_name) const;
Vector<String> get_optimizer_presets() const;
List<String> get_input_presets() const { return input_presets; }
void set_disable_platform_override(bool p_disable);
Object* get_singleton_object(const String& p_name) const;
Object *get_singleton_object(const String &p_name) const;
void register_global_defaults();
@ -145,10 +153,9 @@ public:
Globals();
~Globals();
};
//not a macro any longer
Variant _GLOBAL_DEF( const String& p_var, const Variant& p_default);
#define GLOBAL_DEF(m_var,m_value) _GLOBAL_DEF(m_var,m_value)
Variant _GLOBAL_DEF(const String &p_var, const Variant &p_default);
#define GLOBAL_DEF(m_var, m_value) _GLOBAL_DEF(m_var, m_value)
#endif

View File

@ -29,39 +29,36 @@
#ifndef HASH_MAP_H
#define HASH_MAP_H
#include "hashfuncs.h"
#include "error_macros.h"
#include "ustring.h"
#include "os/memory.h"
#include "hashfuncs.h"
#include "list.h"
#include "os/memory.h"
#include "ustring.h"
class HashMapHahserDefault {
public:
static _FORCE_INLINE_ uint32_t hash(const String &p_string) { return p_string.hash(); }
static _FORCE_INLINE_ uint32_t hash(const char *p_cstr) { return hash_djb2(p_cstr); }
static _FORCE_INLINE_ uint32_t hash(const uint64_t p_int) {
uint64_t v=p_int;
static _FORCE_INLINE_ uint32_t hash(const String &p_string) { return p_string.hash(); }
static _FORCE_INLINE_ uint32_t hash(const char *p_cstr) { return hash_djb2(p_cstr); }
static _FORCE_INLINE_ uint32_t hash(const uint64_t p_int) {
uint64_t v = p_int;
v = (~v) + (v << 18); // v = (v << 18) - v - 1;
v = v ^ (v >> 31);
v = v * 21; // v = (v + (v << 2)) + (v << 4);
v = v ^ (v >> 11);
v = v + (v << 6);
v = v ^ (v >> 22);
return (int) v;
return (int)v;
}
static _FORCE_INLINE_ uint32_t hash(const int64_t p_int) { return hash(uint64_t(p_int)); }
static _FORCE_INLINE_ uint32_t hash(const int64_t p_int) { return hash(uint64_t(p_int)); }
static _FORCE_INLINE_ uint32_t hash(const uint32_t p_int) { return p_int; }
static _FORCE_INLINE_ uint32_t hash(const int32_t p_int) { return (uint32_t)p_int; }
static _FORCE_INLINE_ uint32_t hash(const uint16_t p_int) { return p_int; }
static _FORCE_INLINE_ uint32_t hash(const int16_t p_int) { return (uint32_t)p_int; }
static _FORCE_INLINE_ uint32_t hash(const uint8_t p_int) { return p_int; }
static _FORCE_INLINE_ uint32_t hash(const int8_t p_int) { return (uint32_t)p_int; }
static _FORCE_INLINE_ uint32_t hash(const wchar_t p_wchar) { return (uint32_t)p_wchar; }
// static _FORCE_INLINE_ uint32_t hash(const void* p_ptr) { return uint32_t(uint64_t(p_ptr))*(0x9e3779b1L); }
static _FORCE_INLINE_ uint32_t hash(const uint32_t p_int) { return p_int; }
static _FORCE_INLINE_ uint32_t hash(const int32_t p_int) { return (uint32_t)p_int; }
static _FORCE_INLINE_ uint32_t hash(const uint16_t p_int) { return p_int; }
static _FORCE_INLINE_ uint32_t hash(const int16_t p_int) { return (uint32_t)p_int; }
static _FORCE_INLINE_ uint32_t hash(const uint8_t p_int) { return p_int; }
static _FORCE_INLINE_ uint32_t hash(const int8_t p_int) { return (uint32_t)p_int; }
static _FORCE_INLINE_ uint32_t hash(const wchar_t p_wchar) { return (uint32_t)p_wchar; }
// static _FORCE_INLINE_ uint32_t hash(const void* p_ptr) { return uint32_t(uint64_t(p_ptr))*(0x9e3779b1L); }
};
/**
@ -80,20 +77,21 @@ public:
*
*/
template<class TKey, class TData, class Hasher=HashMapHahserDefault,uint8_t MIN_HASH_TABLE_POWER=3,uint8_t RELATIONSHIP=8>
template <class TKey, class TData, class Hasher = HashMapHahserDefault, uint8_t MIN_HASH_TABLE_POWER = 3, uint8_t RELATIONSHIP = 8>
class HashMap {
public:
struct Pair {
TKey key;
TData data;
Pair() {}
Pair(const TKey& p_key, const TData& p_data) { key=p_key; data=p_data; }
Pair(const TKey &p_key, const TData &p_data) {
key = p_key;
data = p_data;
}
};
private:
struct Entry {
@ -101,7 +99,7 @@ private:
Entry *next;
Pair pair;
Entry() { next=0; }
Entry() { next = 0; }
};
Entry **hash_table;
@ -110,206 +108,192 @@ private:
void make_hash_table() {
ERR_FAIL_COND( hash_table );
ERR_FAIL_COND(hash_table);
hash_table = memnew_arr( Entry*, (1<<MIN_HASH_TABLE_POWER) );
hash_table = memnew_arr(Entry *, (1 << MIN_HASH_TABLE_POWER));
hash_table_power = MIN_HASH_TABLE_POWER;
elements=0;
for (int i=0;i<(1<<MIN_HASH_TABLE_POWER);i++)
hash_table[i]=0;
elements = 0;
for (int i = 0; i < (1 << MIN_HASH_TABLE_POWER); i++)
hash_table[i] = 0;
}
void erase_hash_table() {
ERR_FAIL_COND(elements);
memdelete_arr( hash_table );
hash_table=0;
hash_table_power=0;
elements=0;
memdelete_arr(hash_table);
hash_table = 0;
hash_table_power = 0;
elements = 0;
}
void check_hash_table() {
int new_hash_table_power=-1;
int new_hash_table_power = -1;
if ((int)elements > ( (1<<hash_table_power) * RELATIONSHIP ) ) {
if ((int)elements > ((1 << hash_table_power) * RELATIONSHIP)) {
/* rehash up */
new_hash_table_power=hash_table_power+1;
new_hash_table_power = hash_table_power + 1;
while( (int)elements > ( (1<<new_hash_table_power) * RELATIONSHIP ) ) {
while ((int)elements > ((1 << new_hash_table_power) * RELATIONSHIP)) {
new_hash_table_power++;
}
} else if ( (hash_table_power>(int)MIN_HASH_TABLE_POWER) && ((int)elements < ( (1<<(hash_table_power-1)) * RELATIONSHIP ) ) ) {
} else if ((hash_table_power > (int)MIN_HASH_TABLE_POWER) && ((int)elements < ((1 << (hash_table_power - 1)) * RELATIONSHIP))) {
/* rehash down */
new_hash_table_power=hash_table_power-1;
new_hash_table_power = hash_table_power - 1;
while( (int)elements < ( (1<<(new_hash_table_power-1)) * RELATIONSHIP ) ) {
while ((int)elements < ((1 << (new_hash_table_power - 1)) * RELATIONSHIP)) {
new_hash_table_power--;
}
if (new_hash_table_power<(int)MIN_HASH_TABLE_POWER)
new_hash_table_power=MIN_HASH_TABLE_POWER;
if (new_hash_table_power < (int)MIN_HASH_TABLE_POWER)
new_hash_table_power = MIN_HASH_TABLE_POWER;
}
if (new_hash_table_power==-1)
if (new_hash_table_power == -1)
return;
Entry ** new_hash_table = memnew_arr( Entry*, (1<<new_hash_table_power) );
Entry **new_hash_table = memnew_arr(Entry *, (1 << new_hash_table_power));
if (!new_hash_table) {
ERR_PRINT("Out of Memory");
return;
}
for (int i=0;i<(1<<new_hash_table_power);i++) {
for (int i = 0; i < (1 << new_hash_table_power); i++) {
new_hash_table[i]=0;
new_hash_table[i] = 0;
}
for (int i=0;i<(1<<hash_table_power);i++) {
for (int i = 0; i < (1 << hash_table_power); i++) {
while( hash_table[i] ) {
while (hash_table[i]) {
Entry *se=hash_table[i];
hash_table[i]=se->next;
int new_pos = se->hash & ((1<<new_hash_table_power)-1);
se->next=new_hash_table[new_pos];
new_hash_table[new_pos]=se;
Entry *se = hash_table[i];
hash_table[i] = se->next;
int new_pos = se->hash & ((1 << new_hash_table_power) - 1);
se->next = new_hash_table[new_pos];
new_hash_table[new_pos] = se;
}
}
if (hash_table)
memdelete_arr( hash_table );
hash_table=new_hash_table;
hash_table_power=new_hash_table_power;
memdelete_arr(hash_table);
hash_table = new_hash_table;
hash_table_power = new_hash_table_power;
}
/* I want to have only one function.. */
_FORCE_INLINE_ const Entry * get_entry( const TKey& p_key ) const {
_FORCE_INLINE_ const Entry *get_entry(const TKey &p_key) const {
uint32_t hash = Hasher::hash( p_key );
uint32_t index = hash&((1<<hash_table_power)-1);
uint32_t hash = Hasher::hash(p_key);
uint32_t index = hash & ((1 << hash_table_power) - 1);
Entry *e = hash_table[index];
while (e) {
/* checking hash first avoids comparing key, which may take longer */
if (e->hash == hash && e->pair.key == p_key ) {
if (e->hash == hash && e->pair.key == p_key) {
/* the pair exists in this hashtable, so just update data */
return e;
}
e=e->next;
e = e->next;
}
return NULL;
}
Entry * create_entry(const TKey& p_key) {
Entry *create_entry(const TKey &p_key) {
/* if entry doesn't exist, create it */
Entry *e = memnew( Entry );
ERR_FAIL_COND_V(!e,NULL); /* out of memory */
uint32_t hash = Hasher::hash( p_key );
uint32_t index = hash&((1<<hash_table_power)-1);
Entry *e = memnew(Entry);
ERR_FAIL_COND_V(!e, NULL); /* out of memory */
uint32_t hash = Hasher::hash(p_key);
uint32_t index = hash & ((1 << hash_table_power) - 1);
e->next = hash_table[index];
e->hash = hash;
e->pair.key=p_key;
e->pair.key = p_key;
hash_table[index]=e;
hash_table[index] = e;
elements++;
return e;
}
void copy_from(const HashMap &p_t) {
void copy_from(const HashMap& p_t) {
if (&p_t==this)
if (&p_t == this)
return; /* much less bother with that */
clear();
if (!p_t.hash_table || p_t.hash_table_power==0)
if (!p_t.hash_table || p_t.hash_table_power == 0)
return; /* not copying from empty table */
hash_table = memnew_arr(Entry*,1<<p_t.hash_table_power);
hash_table_power=p_t.hash_table_power;
elements=p_t.elements;
hash_table = memnew_arr(Entry *, 1 << p_t.hash_table_power);
hash_table_power = p_t.hash_table_power;
elements = p_t.elements;
for (int i=0;i<( 1<<p_t.hash_table_power );i++) {
for (int i = 0; i < (1 << p_t.hash_table_power); i++) {
hash_table[i]=NULL;
hash_table[i] = NULL;
/* elements will be in the reverse order, but it doesn't matter */
const Entry *e = p_t.hash_table[i];
while(e) {
while (e) {
Entry *le = memnew( Entry ); /* local entry */
Entry *le = memnew(Entry); /* local entry */
*le=*e; /* copy data */
*le = *e; /* copy data */
/* add to list and reassign pointers */
le->next=hash_table[i];
hash_table[i]=le;
le->next = hash_table[i];
hash_table[i] = le;
e=e->next;
e = e->next;
}
}
}
public:
void set(const TKey &p_key, const TData &p_data) {
void set( const TKey& p_key, const TData& p_data ) {
set( Pair( p_key, p_data ) );
set(Pair(p_key, p_data));
}
void set( const Pair& p_pair ) {
void set(const Pair &p_pair) {
Entry *e=NULL;
Entry *e = NULL;
if (!hash_table)
make_hash_table(); // if no table, make one
else
e = const_cast<Entry*>( get_entry(p_pair.key) );
e = const_cast<Entry *>(get_entry(p_pair.key));
/* if we made it up to here, the pair doesn't exist, create and assign */
if (!e) {
e=create_entry(p_pair.key);
e = create_entry(p_pair.key);
if (!e)
return;
check_hash_table(); // perform mantenience routine
}
e->pair.data = p_pair.data;
}
bool has(const TKey &p_key) const {
bool has( const TKey& p_key ) const {
return getptr(p_key)!=NULL;
return getptr(p_key) != NULL;
}
/**
@ -318,17 +302,17 @@ public:
* first with has(key)
*/
const TData& get( const TKey& p_key ) const {
const TData &get(const TKey &p_key) const {
const TData* res = getptr(p_key);
ERR_FAIL_COND_V(!res,*res);
const TData *res = getptr(p_key);
ERR_FAIL_COND_V(!res, *res);
return *res;
}
TData& get( const TKey& p_key ) {
TData &get(const TKey &p_key) {
TData* res = getptr(p_key);
ERR_FAIL_COND_V(!res,*res);
TData *res = getptr(p_key);
ERR_FAIL_COND_V(!res, *res);
return *res;
}
@ -337,33 +321,30 @@ public:
* This is mainly used for speed purposes.
*/
_FORCE_INLINE_ TData* getptr( const TKey& p_key ) {
_FORCE_INLINE_ TData *getptr(const TKey &p_key) {
if (!hash_table)
return NULL;
Entry *e=const_cast<Entry*>(get_entry(p_key ));
Entry *e = const_cast<Entry *>(get_entry(p_key));
if (e)
return &e->pair.data;
return NULL;
}
_FORCE_INLINE_ const TData* getptr( const TKey& p_key ) const {
_FORCE_INLINE_ const TData *getptr(const TKey &p_key) const {
if (!hash_table)
return NULL;
const Entry *e=const_cast<Entry*>(get_entry(p_key ));
const Entry *e = const_cast<Entry *>(get_entry(p_key));
if (e)
return &e->pair.data;
return NULL;
}
/**
@ -371,129 +352,124 @@ public:
* This version is custom, will take a hash and a custom key (that should support operator==()
*/
template<class C>
_FORCE_INLINE_ TData* custom_getptr( C p_custom_key,uint32_t p_custom_hash ) {
template <class C>
_FORCE_INLINE_ TData *custom_getptr(C p_custom_key, uint32_t p_custom_hash) {
if (!hash_table)
return NULL;
uint32_t hash = p_custom_hash;
uint32_t index = hash&((1<<hash_table_power)-1);
uint32_t index = hash & ((1 << hash_table_power) - 1);
Entry *e = hash_table[index];
while (e) {
/* checking hash first avoids comparing key, which may take longer */
if (e->hash == hash && e->pair.key == p_custom_key ) {
if (e->hash == hash && e->pair.key == p_custom_key) {
/* the pair exists in this hashtable, so just update data */
return &e->pair.data;
}
e=e->next;
e = e->next;
}
return NULL;
}
template<class C>
_FORCE_INLINE_ const TData* custom_getptr( C p_custom_key,uint32_t p_custom_hash ) const {
template <class C>
_FORCE_INLINE_ const TData *custom_getptr(C p_custom_key, uint32_t p_custom_hash) const {
if (!hash_table)
return NULL;
uint32_t hash = p_custom_hash;
uint32_t index = hash&((1<<hash_table_power)-1);
uint32_t index = hash & ((1 << hash_table_power) - 1);
const Entry *e = hash_table[index];
while (e) {
/* checking hash first avoids comparing key, which may take longer */
if (e->hash == hash && e->pair.key == p_custom_key ) {
if (e->hash == hash && e->pair.key == p_custom_key) {
/* the pair exists in this hashtable, so just update data */
return &e->pair.data;
}
e=e->next;
e = e->next;
}
return NULL;
}
/**
* Erase an item, return true if erasing was succesful
*/
bool erase( const TKey& p_key ) {
bool erase(const TKey &p_key) {
if (!hash_table)
return false;
uint32_t hash = Hasher::hash( p_key );
uint32_t index = hash&((1<<hash_table_power)-1);
uint32_t hash = Hasher::hash(p_key);
uint32_t index = hash & ((1 << hash_table_power) - 1);
Entry *e = hash_table[index];
Entry *p=NULL;
Entry *p = NULL;
while (e) {
/* checking hash first avoids comparing key, which may take longer */
if (e->hash == hash && e->pair.key == p_key ) {
if (e->hash == hash && e->pair.key == p_key) {
if (p) {
p->next=e->next;
p->next = e->next;
} else {
//begin of list
hash_table[index]=e->next;
hash_table[index] = e->next;
}
memdelete(e);
elements--;
if (elements==0)
if (elements == 0)
erase_hash_table();
else
check_hash_table();
return true;
}
p=e;
e=e->next;
p = e;
e = e->next;
}
return false;
}
inline const TData& operator[](const TKey& p_key) const { //constref
inline const TData &operator[](const TKey &p_key) const { //constref
return get(p_key);
}
inline TData& operator[](const TKey& p_key ) { //assignment
inline TData &operator[](const TKey &p_key) { //assignment
Entry *e=NULL;
Entry *e = NULL;
if (!hash_table)
make_hash_table(); // if no table, make one
else
e = const_cast<Entry*>( get_entry(p_key) );
e = const_cast<Entry *>(get_entry(p_key));
/* if we made it up to here, the pair doesn't exist, create */
if (!e) {
e=create_entry(p_key);
e = create_entry(p_key);
if (!e)
return *(TData*)NULL; /* panic! */
return *(TData *)NULL; /* panic! */
check_hash_table(); // perform mantenience routine
}
return e->pair.data;
}
/**
@ -511,13 +487,13 @@ public:
* }
*
*/
const TKey* next(const TKey* p_key) const {
const TKey *next(const TKey *p_key) const {
if (!hash_table) return NULL;
if (!p_key) { /* get the first key */
for (int i=0;i<(1<<hash_table_power);i++) {
for (int i = 0; i < (1 << hash_table_power); i++) {
if (hash_table[i]) {
return &hash_table[i]->pair.key;
@ -526,17 +502,17 @@ public:
} else { /* get the next key */
const Entry *e = get_entry( *p_key );
ERR_FAIL_COND_V( !e, NULL ); /* invalid key supplied */
const Entry *e = get_entry(*p_key);
ERR_FAIL_COND_V(!e, NULL); /* invalid key supplied */
if (e->next) {
/* if there is a "next" in the list, return that */
return &e->next->pair.key;
} else {
/* go to next entries */
uint32_t index = e->hash&((1<<hash_table_power)-1);
uint32_t index = e->hash & ((1 << hash_table_power) - 1);
index++;
for (int i=index;i<(1<<hash_table_power);i++) {
for (int i = index; i < (1 << hash_table_power); i++) {
if (hash_table[i]) {
return &hash_table[i]->pair.key;
@ -545,10 +521,8 @@ public:
}
/* nothing found, was at end */
}
return NULL; /* nothing found */
}
@ -559,71 +533,68 @@ public:
inline bool empty() const {
return elements==0;
return elements == 0;
}
void clear() {
/* clean up */
if (hash_table) {
for (int i=0;i<(1<<hash_table_power);i++) {
for (int i = 0; i < (1 << hash_table_power); i++) {
while (hash_table[i]) {
Entry *e=hash_table[i];
hash_table[i]=e->next;
memdelete( e );
Entry *e = hash_table[i];
hash_table[i] = e->next;
memdelete(e);
}
}
memdelete_arr( hash_table );
memdelete_arr(hash_table);
}
hash_table=0;
hash_table_power=0;
elements=0;
hash_table = 0;
hash_table_power = 0;
elements = 0;
}
void operator=(const HashMap& p_table) {
void operator=(const HashMap &p_table) {
copy_from(p_table);
}
HashMap() {
hash_table=NULL;
elements=0;
hash_table_power=0;
hash_table = NULL;
elements = 0;
hash_table_power = 0;
}
void get_key_list(List<TKey> *p_keys) const {
if (!hash_table)
return;
for(int i=0;i<(1<<hash_table_power);i++) {
for (int i = 0; i < (1 << hash_table_power); i++) {
Entry *e=hash_table[i];
while(e) {
Entry *e = hash_table[i];
while (e) {
p_keys->push_back(e->pair.key);
e=e->next;
e = e->next;
}
}
}
HashMap(const HashMap& p_table) {
HashMap(const HashMap &p_table) {
hash_table=NULL;
elements=0;
hash_table_power=0;
hash_table = NULL;
elements = 0;
hash_table_power = 0;
copy_from(p_table);
}
~HashMap() {
clear();
}
};
#endif

View File

@ -29,14 +29,12 @@
#ifndef HASHFUNCS_H
#define HASHFUNCS_H
#include "typedefs.h"
/**
* Hashing functions
*/
/**
* DJB2 Hash function
* @param C String
@ -44,7 +42,7 @@
*/
static inline uint32_t hash_djb2(const char *p_cstr) {
const unsigned char* chr=(const unsigned char*)p_cstr;
const unsigned char *chr = (const unsigned char *)p_cstr;
uint32_t hash = 5381;
uint32_t c;
@ -54,66 +52,64 @@ static inline uint32_t hash_djb2(const char *p_cstr) {
return hash;
}
static inline uint32_t hash_djb2_buffer(const uint8_t *p_buff, int p_len,uint32_t p_prev=5381) {
static inline uint32_t hash_djb2_buffer(const uint8_t *p_buff, int p_len, uint32_t p_prev = 5381) {
uint32_t hash = p_prev;
for(int i=0;i<p_len;i++)
for (int i = 0; i < p_len; i++)
hash = ((hash << 5) + hash) + p_buff[i]; /* hash * 33 + c */
return hash;
}
static inline uint32_t hash_djb2_one_32(uint32_t p_in,uint32_t p_prev=5381) {
static inline uint32_t hash_djb2_one_32(uint32_t p_in, uint32_t p_prev = 5381) {
return ((p_prev<<5)+p_prev)+p_in;
return ((p_prev << 5) + p_prev) + p_in;
}
static inline uint32_t hash_djb2_one_float(float p_in,uint32_t p_prev=5381) {
static inline uint32_t hash_djb2_one_float(float p_in, uint32_t p_prev = 5381) {
union {
float f;
uint32_t i;
} u;
// handle -0 case
if (p_in==0.0f) u.f=0.0f;
else u.f=p_in;
if (p_in == 0.0f)
u.f = 0.0f;
else
u.f = p_in;
return ((p_prev<<5)+p_prev)+u.i;
return ((p_prev << 5) + p_prev) + u.i;
}
template<class T>
template <class T>
static inline uint32_t make_uint32_t(T p_in) {
union {
T t;
uint32_t _u32;
} _u;
_u._u32=0;
_u.t=p_in;
_u._u32 = 0;
_u.t = p_in;
return _u._u32;
}
static inline uint64_t hash_djb2_one_64(uint64_t p_in, uint64_t p_prev = 5381) {
static inline uint64_t hash_djb2_one_64(uint64_t p_in,uint64_t p_prev=5381) {
return ((p_prev<<5)+p_prev)+p_in;
return ((p_prev << 5) + p_prev) + p_in;
}
template<class T>
template <class T>
static inline uint64_t make_uint64_t(T p_in) {
union {
T t;
uint64_t _u64;
} _u;
_u._u64=0; // in case p_in is smaller
_u._u64 = 0; // in case p_in is smaller
_u.t=p_in;
_u.t = p_in;
return _u._u64;
}
#endif

View File

@ -31,12 +31,17 @@
#include "core/helper/math_fieldwise.h"
#define SETUP_TYPE(m_type) m_type source=p_source; m_type target=p_target;
#define TRY_TRANSFER_FIELD(m_name,m_member) if (p_field==m_name) { target.m_member=source.m_member; }
#define SETUP_TYPE(m_type) \
m_type source = p_source; \
m_type target = p_target;
#define TRY_TRANSFER_FIELD(m_name, m_member) \
if (p_field == m_name) { \
target.m_member = source.m_member; \
}
Variant fieldwise_assign(const Variant& p_target, const Variant& p_source, const String& p_field) {
Variant fieldwise_assign(const Variant &p_target, const Variant &p_source, const String &p_field) {
ERR_FAIL_COND_V(p_target.get_type()!=p_source.get_type(),p_target);
ERR_FAIL_COND_V(p_target.get_type() != p_source.get_type(), p_target);
switch (p_source.get_type()) {
@ -44,122 +49,81 @@ Variant fieldwise_assign(const Variant& p_target, const Variant& p_source, const
SETUP_TYPE(Vector2)
/**/ TRY_TRANSFER_FIELD("x",x)
else TRY_TRANSFER_FIELD("y",y)
/**/ TRY_TRANSFER_FIELD("x", x) else TRY_TRANSFER_FIELD("y", y)
return target;
return target;
}
case Variant::RECT2: {
SETUP_TYPE(Rect2)
/**/ TRY_TRANSFER_FIELD("x",pos.x)
else TRY_TRANSFER_FIELD("y",pos.y)
else TRY_TRANSFER_FIELD("w",size.x)
else TRY_TRANSFER_FIELD("h",size.y)
/**/ TRY_TRANSFER_FIELD("x", pos.x) else TRY_TRANSFER_FIELD("y", pos.y) else TRY_TRANSFER_FIELD("w", size.x) else TRY_TRANSFER_FIELD("h", size.y)
return target;
return target;
}
case Variant::VECTOR3: {
SETUP_TYPE(Vector3)
/**/ TRY_TRANSFER_FIELD("x",x)
else TRY_TRANSFER_FIELD("y",y)
else TRY_TRANSFER_FIELD("z",z)
/**/ TRY_TRANSFER_FIELD("x", x) else TRY_TRANSFER_FIELD("y", y) else TRY_TRANSFER_FIELD("z", z)
return target;
return target;
}
case Variant::PLANE: {
SETUP_TYPE(Plane)
/**/ TRY_TRANSFER_FIELD("x",normal.x)
else TRY_TRANSFER_FIELD("y",normal.y)
else TRY_TRANSFER_FIELD("z",normal.z)
else TRY_TRANSFER_FIELD("d",d)
/**/ TRY_TRANSFER_FIELD("x", normal.x) else TRY_TRANSFER_FIELD("y", normal.y) else TRY_TRANSFER_FIELD("z", normal.z) else TRY_TRANSFER_FIELD("d", d)
return target;
return target;
}
case Variant::QUAT: {
SETUP_TYPE(Quat)
/**/ TRY_TRANSFER_FIELD("x",x)
else TRY_TRANSFER_FIELD("y",y)
else TRY_TRANSFER_FIELD("z",z)
else TRY_TRANSFER_FIELD("w",w)
/**/ TRY_TRANSFER_FIELD("x", x) else TRY_TRANSFER_FIELD("y", y) else TRY_TRANSFER_FIELD("z", z) else TRY_TRANSFER_FIELD("w", w)
return target;
return target;
}
case Variant::_AABB: {
SETUP_TYPE(AABB)
/**/ TRY_TRANSFER_FIELD("px",pos.x)
else TRY_TRANSFER_FIELD("py",pos.y)
else TRY_TRANSFER_FIELD("pz",pos.z)
else TRY_TRANSFER_FIELD("sx",size.x)
else TRY_TRANSFER_FIELD("sy",size.y)
else TRY_TRANSFER_FIELD("sz",size.z)
/**/ TRY_TRANSFER_FIELD("px", pos.x) else TRY_TRANSFER_FIELD("py", pos.y) else TRY_TRANSFER_FIELD("pz", pos.z) else TRY_TRANSFER_FIELD("sx", size.x) else TRY_TRANSFER_FIELD("sy", size.y) else TRY_TRANSFER_FIELD("sz", size.z)
return target;
return target;
}
case Variant::MATRIX32: {
SETUP_TYPE(Matrix32)
/**/ TRY_TRANSFER_FIELD("xx",elements[0][0])
else TRY_TRANSFER_FIELD("xy",elements[0][1])
else TRY_TRANSFER_FIELD("yx",elements[1][0])
else TRY_TRANSFER_FIELD("yy",elements[1][1])
else TRY_TRANSFER_FIELD("ox",elements[2][0])
else TRY_TRANSFER_FIELD("oy",elements[2][1])
/**/ TRY_TRANSFER_FIELD("xx", elements[0][0]) else TRY_TRANSFER_FIELD("xy", elements[0][1]) else TRY_TRANSFER_FIELD("yx", elements[1][0]) else TRY_TRANSFER_FIELD("yy", elements[1][1]) else TRY_TRANSFER_FIELD("ox", elements[2][0]) else TRY_TRANSFER_FIELD("oy", elements[2][1])
return target;
return target;
}
case Variant::MATRIX3: {
SETUP_TYPE(Matrix3)
/**/ TRY_TRANSFER_FIELD("xx",elements[0][0])
else TRY_TRANSFER_FIELD("xy",elements[0][1])
else TRY_TRANSFER_FIELD("xz",elements[0][2])
else TRY_TRANSFER_FIELD("yx",elements[1][0])
else TRY_TRANSFER_FIELD("yy",elements[1][1])
else TRY_TRANSFER_FIELD("yz",elements[1][2])
else TRY_TRANSFER_FIELD("zx",elements[2][0])
else TRY_TRANSFER_FIELD("zy",elements[2][1])
else TRY_TRANSFER_FIELD("zz",elements[2][2])
/**/ TRY_TRANSFER_FIELD("xx", elements[0][0]) else TRY_TRANSFER_FIELD("xy", elements[0][1]) else TRY_TRANSFER_FIELD("xz", elements[0][2]) else TRY_TRANSFER_FIELD("yx", elements[1][0]) else TRY_TRANSFER_FIELD("yy", elements[1][1]) else TRY_TRANSFER_FIELD("yz", elements[1][2]) else TRY_TRANSFER_FIELD("zx", elements[2][0]) else TRY_TRANSFER_FIELD("zy", elements[2][1]) else TRY_TRANSFER_FIELD("zz", elements[2][2])
return target;
return target;
}
case Variant::TRANSFORM: {
SETUP_TYPE(Transform)
/**/ TRY_TRANSFER_FIELD("xx",basis.elements[0][0])
else TRY_TRANSFER_FIELD("xy",basis.elements[0][1])
else TRY_TRANSFER_FIELD("xz",basis.elements[0][2])
else TRY_TRANSFER_FIELD("yx",basis.elements[1][0])
else TRY_TRANSFER_FIELD("yy",basis.elements[1][1])
else TRY_TRANSFER_FIELD("yz",basis.elements[1][2])
else TRY_TRANSFER_FIELD("zx",basis.elements[2][0])
else TRY_TRANSFER_FIELD("zy",basis.elements[2][1])
else TRY_TRANSFER_FIELD("zz",basis.elements[2][2])
else TRY_TRANSFER_FIELD("xo",origin.x)
else TRY_TRANSFER_FIELD("yo",origin.y)
else TRY_TRANSFER_FIELD("zo",origin.z)
/**/ TRY_TRANSFER_FIELD("xx", basis.elements[0][0]) else TRY_TRANSFER_FIELD("xy", basis.elements[0][1]) else TRY_TRANSFER_FIELD("xz", basis.elements[0][2]) else TRY_TRANSFER_FIELD("yx", basis.elements[1][0]) else TRY_TRANSFER_FIELD("yy", basis.elements[1][1]) else TRY_TRANSFER_FIELD("yz", basis.elements[1][2]) else TRY_TRANSFER_FIELD("zx", basis.elements[2][0]) else TRY_TRANSFER_FIELD("zy", basis.elements[2][1]) else TRY_TRANSFER_FIELD("zz", basis.elements[2][2]) else TRY_TRANSFER_FIELD("xo", origin.x) else TRY_TRANSFER_FIELD("yo", origin.y) else TRY_TRANSFER_FIELD("zo", origin.z)
return target;
return target;
}
default: {

View File

@ -33,7 +33,7 @@
#include "core/variant.h"
Variant fieldwise_assign(const Variant& p_target, const Variant& p_source, const String& p_field);
Variant fieldwise_assign(const Variant &p_target, const Variant &p_source, const String &p_field);
#endif // TOOLS_ENABLED

View File

@ -34,8 +34,9 @@
class ValueEvaluator : public Object {
OBJ_TYPE(ValueEvaluator, Object);
public:
virtual double eval(const String& p_text) {
virtual double eval(const String &p_text) {
return p_text.to_double();
}
};

File diff suppressed because it is too large Load Diff

View File

@ -29,8 +29,8 @@
#ifndef IMAGE_H
#define IMAGE_H
#include "dvector.h"
#include "color.h"
#include "dvector.h"
#include "math_2d.h"
/**
* @author Juan Linietsky <reduzio@gmail.com>
@ -42,16 +42,16 @@
class Image;
typedef Error (*SavePNGFunc)(const String &p_path, Image& p_img);
typedef Error (*SavePNGFunc)(const String &p_path, Image &p_img);
class Image {
enum {
MAX_WIDTH=16384, // force a limit somehow
MAX_HEIGHT=16384// force a limit somehow
MAX_WIDTH = 16384, // force a limit somehow
MAX_HEIGHT = 16384 // force a limit somehow
};
public:
public:
static SavePNGFunc save_png_func;
enum Format {
@ -87,7 +87,7 @@ public:
FORMAT_MAX
};
static const char* format_names[FORMAT_MAX];
static const char *format_names[FORMAT_MAX];
enum Interpolation {
INTERPOLATE_NEAREST,
@ -96,8 +96,8 @@ public:
/* INTERPOLATE GAUSS */
};
static Image (*_png_mem_loader_func)(const uint8_t* p_png,int p_size);
static Image (*_jpg_mem_loader_func)(const uint8_t* p_png,int p_size);
static Image (*_png_mem_loader_func)(const uint8_t *p_png, int p_size);
static Image (*_jpg_mem_loader_func)(const uint8_t *p_png, int p_size);
static void (*_image_compress_bc_func)(Image *);
static void (*_image_compress_pvrtc2_func)(Image *);
static void (*_image_compress_pvrtc4_func)(Image *);
@ -108,25 +108,35 @@ public:
Error _decompress_bc();
static DVector<uint8_t> (*lossy_packer)(const Image& p_image,float p_quality);
static Image (*lossy_unpacker)(const DVector<uint8_t>& p_buffer);
static DVector<uint8_t> (*lossless_packer)(const Image& p_image);
static Image (*lossless_unpacker)(const DVector<uint8_t>& p_buffer);
private:
static DVector<uint8_t> (*lossy_packer)(const Image &p_image, float p_quality);
static Image (*lossy_unpacker)(const DVector<uint8_t> &p_buffer);
static DVector<uint8_t> (*lossless_packer)(const Image &p_image);
static Image (*lossless_unpacker)(const DVector<uint8_t> &p_buffer);
private:
//internal byte based color
struct BColor {
union {
uint8_t col[4];
struct {
uint8_t r,g,b,a;
uint8_t r, g, b, a;
};
};
bool operator==(const BColor& p_color) const { for(int i=0;i<4;i++) {if (col[i]!=p_color.col[i]) return false; } return true; }
_FORCE_INLINE_ uint8_t gray() const { return (uint16_t(col[0])+uint16_t(col[1])+uint16_t(col[2]))/3; }
bool operator==(const BColor &p_color) const {
for (int i = 0; i < 4; i++) {
if (col[i] != p_color.col[i]) return false;
}
return true;
}
_FORCE_INLINE_ uint8_t gray() const { return (uint16_t(col[0]) + uint16_t(col[1]) + uint16_t(col[2])) / 3; }
_FORCE_INLINE_ BColor() {}
BColor(uint8_t p_r,uint8_t p_g,uint8_t p_b,uint8_t p_a=255) { col[0]=p_r; col[1]=p_g; col[2]=p_b; col[3]=p_a; }
BColor(uint8_t p_r, uint8_t p_g, uint8_t p_b, uint8_t p_a = 255) {
col[0] = p_r;
col[1] = p_g;
col[2] = p_b;
col[3] = p_a;
}
};
//median cut classes
@ -137,22 +147,22 @@ private:
BColor color;
struct SortR {
bool operator()(const BColorPos& ca, const BColorPos& cb) const { return ca.color.r < cb.color.r; }
bool operator()(const BColorPos &ca, const BColorPos &cb) const { return ca.color.r < cb.color.r; }
};
struct SortG {
bool operator()(const BColorPos& ca, const BColorPos& cb) const { return ca.color.g < cb.color.g; }
bool operator()(const BColorPos &ca, const BColorPos &cb) const { return ca.color.g < cb.color.g; }
};
struct SortB {
bool operator()(const BColorPos& ca, const BColorPos& cb) const { return ca.color.b < cb.color.b; }
bool operator()(const BColorPos &ca, const BColorPos &cb) const { return ca.color.b < cb.color.b; }
};
struct SortA {
bool operator()(const BColorPos& ca, const BColorPos& cb) const { return ca.color.a < cb.color.a; }
bool operator()(const BColorPos &ca, const BColorPos &cb) const { return ca.color.a < cb.color.a; }
};
};
@ -166,45 +176,42 @@ private:
int color;
};
int right;
SPTree() { leaf=true; left=-1; right=-1;}
SPTree() {
leaf = true;
left = -1;
right = -1;
}
};
struct MCBlock {
BColorPos min_color,max_color;
BColorPos min_color, max_color;
BColorPos *colors;
int sp_idx;
int color_count;
int get_longest_axis_index() const;
int get_longest_axis_length() const;
bool operator<(const MCBlock& p_block) const;
bool operator<(const MCBlock &p_block) const;
void shrink();
MCBlock();
MCBlock(BColorPos *p_colors,int p_color_count);
MCBlock(BColorPos *p_colors, int p_color_count);
};
Format format;
DVector<uint8_t> data;
int width,height,mipmaps;
int width, height, mipmaps;
_FORCE_INLINE_ BColor _get_pixel(int p_x, int p_y, const unsigned char *p_data, int p_data_size) const;
_FORCE_INLINE_ BColor _get_pixelw(int p_x, int p_y, int p_width, const unsigned char *p_data, int p_data_size) const;
_FORCE_INLINE_ void _put_pixelw(int p_x, int p_y, int p_width, const BColor &p_color, unsigned char *p_data);
_FORCE_INLINE_ void _put_pixel(int p_x, int p_y, const BColor &p_color, unsigned char *p_data);
_FORCE_INLINE_ void _get_mipmap_offset_and_size(int p_mipmap, int &r_offset, int &r_width, int &r_height) const; //get where the mipmap begins in data
_FORCE_INLINE_ static void _get_format_min_data_size(Format p_format, int &r_w, int &r_h);
_FORCE_INLINE_ BColor _get_pixel(int p_x,int p_y,const unsigned char *p_data,int p_data_size) const;
_FORCE_INLINE_ BColor _get_pixelw(int p_x,int p_y,int p_width,const unsigned char *p_data,int p_data_size) const;
_FORCE_INLINE_ void _put_pixelw(int p_x,int p_y, int p_width, const BColor& p_color, unsigned char *p_data);
_FORCE_INLINE_ void _put_pixel(int p_x,int p_y, const BColor& p_color, unsigned char *p_data);
_FORCE_INLINE_ void _get_mipmap_offset_and_size(int p_mipmap,int &r_offset, int &r_width, int &r_height) const; //get where the mipmap begins in data
_FORCE_INLINE_ static void _get_format_min_data_size(Format p_format,int &r_w, int &r_h);
static int _get_dst_image_size(int p_width, int p_height, Format p_format,int &r_mipmaps,int p_mipmaps=-1);
static int _get_dst_image_size(int p_width, int p_height, Format p_format, int &r_mipmaps, int p_mipmaps = -1);
bool _can_modify(Format p_format) const;
public:
int get_width() const; ///< Get image width
int get_height() const; ///< Get image height
int get_mipmaps() const;
@ -213,16 +220,16 @@ public:
* Get a pixel from the image. for grayscale or indexed formats, use Color::gray to obtain the actual
* value.
*/
Color get_pixel(int p_x,int p_y,int p_mipmap=0) const;
Color get_pixel(int p_x, int p_y, int p_mipmap = 0) const;
/**
* Set a pixel into the image. for grayscale or indexed formats, a suitable Color constructor.
*/
void put_pixel(int p_x,int p_y, const Color& p_color,int p_mipmap=0); /* alpha and index are averaged */
void put_pixel(int p_x, int p_y, const Color &p_color, int p_mipmap = 0); /* alpha and index are averaged */
/**
* Convert the image to another format, as close as it can be done.
*/
void convert( Format p_new_format );
void convert(Format p_new_format);
Image converted(int p_new_format) {
ERR_FAIL_INDEX_V(p_new_format, FORMAT_MAX, Image());
@ -238,48 +245,46 @@ public:
Format get_format() const;
int get_mipmap_offset(int p_mipmap) const; //get where the mipmap begins in data
void get_mipmap_offset_and_size(int p_mipmap,int &r_ofs, int &r_size) const; //get where the mipmap begins in data
void get_mipmap_offset_size_and_dimensions(int p_mipmap,int &r_ofs, int &r_size,int &w, int& h) const; //get where the mipmap begins in data
void get_mipmap_offset_and_size(int p_mipmap, int &r_ofs, int &r_size) const; //get where the mipmap begins in data
void get_mipmap_offset_size_and_dimensions(int p_mipmap, int &r_ofs, int &r_size, int &w, int &h) const; //get where the mipmap begins in data
/**
* Resize the image, using the prefered interpolation method.
* Indexed-Color images always use INTERPOLATE_NEAREST.
*/
void resize_to_po2(bool p_square=false);
void resize( int p_width, int p_height, Interpolation p_interpolation=INTERPOLATE_BILINEAR );
Image resized( int p_width, int p_height, int p_interpolation=INTERPOLATE_BILINEAR );
void resize_to_po2(bool p_square = false);
void resize(int p_width, int p_height, Interpolation p_interpolation = INTERPOLATE_BILINEAR);
Image resized(int p_width, int p_height, int p_interpolation = INTERPOLATE_BILINEAR);
void shrink_x2();
void expand_x2_hq2x();
/**
* Crop the image to a specific size, if larger, then the image is filled by black
*/
void crop( int p_width, int p_height );
void crop(int p_width, int p_height);
void flip_x();
void flip_y();
/**
* Generate a mipmap to an image (creates an image 1/4 the size, with averaging of 4->1)
*/
Error generate_mipmaps(int p_amount=-1,bool p_keep_existing=false);
Error generate_mipmaps(int p_amount = -1, bool p_keep_existing = false);
void clear_mipmaps();
/**
* Generate a normal map from a grayscale image
*/
void make_normalmap(float p_height_scale=1.0);
void make_normalmap(float p_height_scale = 1.0);
/**
* Create a new image of a given size and format. Current image will be lost
*/
void create(int p_width, int p_height, bool p_use_mipmaps, Format p_format);
void create(int p_width, int p_height, int p_mipmaps, Format p_format, const DVector<uint8_t>& p_data);
void create(int p_width, int p_height, int p_mipmaps, Format p_format, const DVector<uint8_t> &p_data);
void create( const char ** p_xpm );
void create(const char **p_xpm);
/**
* returns true when the image is empty (0,0) in size
*/
@ -287,8 +292,8 @@ public:
DVector<uint8_t> get_data() const;
Error load(const String& p_path);
Error save_png(const String& p_path);
Error load(const String &p_path);
Error save_png(const String &p_path);
/**
* create an empty image
@ -301,7 +306,7 @@ public:
/**
* import an image of a specific size and format from a pointer
*/
Image(int p_width, int p_height, int p_mipmaps, Format p_format, const DVector<uint8_t>& p_data);
Image(int p_width, int p_height, int p_mipmaps, Format p_format, const DVector<uint8_t> &p_data);
enum AlphaMode {
ALPHA_NONE,
@ -312,21 +317,17 @@ public:
AlphaMode detect_alpha() const;
bool is_invisible() const;
void put_indexed_pixel(int p_x, int p_y, uint8_t p_idx,int p_mipmap=0);
uint8_t get_indexed_pixel(int p_x, int p_y,int p_mipmap=0) const;
void set_pallete(const DVector<uint8_t>& p_data);
void put_indexed_pixel(int p_x, int p_y, uint8_t p_idx, int p_mipmap = 0);
uint8_t get_indexed_pixel(int p_x, int p_y, int p_mipmap = 0) const;
void set_pallete(const DVector<uint8_t> &p_data);
static int get_format_pixel_size(Format p_format);
static int get_format_pixel_rshift(Format p_format);
static int get_format_pallete_size(Format p_format);
static int get_image_data_size(int p_width, int p_height, Format p_format,int p_mipmaps=0);
static int get_image_data_size(int p_width, int p_height, Format p_format, int p_mipmaps = 0);
static int get_image_required_mipmaps(int p_width, int p_height, Format p_format);
bool operator==(const Image& p_image) const;
bool operator==(const Image &p_image) const;
void quantize();
@ -337,7 +338,7 @@ public:
COMPRESS_ETC
};
Error compress(CompressMode p_mode=COMPRESS_BC);
Error compress(CompressMode p_mode = COMPRESS_BC);
Image compressed(int p_mode); /* from the Image::CompressMode enum */
Error decompress();
Image decompressed() const;
@ -348,21 +349,19 @@ public:
void srgb_to_linear();
void normalmap_to_xy();
void blit_rect(const Image& p_src, const Rect2& p_src_rect,const Point2& p_dest);
void brush_transfer(const Image& p_src, const Image& p_brush, const Point2& p_dest);
Image brushed(const Image& p_src, const Image& p_brush, const Point2& p_dest) const;
void blit_rect(const Image &p_src, const Rect2 &p_src_rect, const Point2 &p_dest);
void brush_transfer(const Image &p_src, const Image &p_brush, const Point2 &p_dest);
Image brushed(const Image &p_src, const Image &p_brush, const Point2 &p_dest) const;
Rect2 get_used_rect() const;
Image get_rect(const Rect2& p_area) const;
Image get_rect(const Rect2 &p_area) const;
static void set_compress_bc_func(void (*p_compress_func)(Image *));
static String get_format_name(Format p_format);
Image(const uint8_t* p_mem_png_jpg, int p_len=-1);
Image(const uint8_t *p_mem_png_jpg, int p_len = -1);
Image(const char **p_xpm);
~Image();
};
#endif

View File

@ -27,41 +27,38 @@
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
/*************************************************************************/
#include "image.h"
#include <stdio.h>
#include "print_string.h"
#include <stdio.h>
#ifdef TOOLS_ENABLED
#include "os/os.h"
#include "set.h"
#include "sort.h"
#include "os/os.h"
//#define QUANTIZE_SPEED_OVER_QUALITY
Image::MCBlock::MCBlock() {
}
Image::MCBlock::MCBlock(BColorPos *p_colors,int p_color_count) {
Image::MCBlock::MCBlock(BColorPos *p_colors, int p_color_count) {
colors=p_colors;
color_count=p_color_count;
min_color.color=BColor(255,255,255,255);
max_color.color=BColor(0,0,0,0);
colors = p_colors;
color_count = p_color_count;
min_color.color = BColor(255, 255, 255, 255);
max_color.color = BColor(0, 0, 0, 0);
shrink();
}
int Image::MCBlock::get_longest_axis_index() const {
int max_dist=-1;
int max_index=0;
int max_dist = -1;
int max_index = 0;
for(int i=0;i<4;i++) {
for (int i = 0; i < 4; i++) {
int d = max_color.color.col[i]-min_color.color.col[i];
if (d>max_dist) {
max_index=i;
max_dist=d;
int d = max_color.color.col[i] - min_color.color.col[i];
if (d > max_dist) {
max_index = i;
max_dist = d;
}
}
@ -69,88 +66,80 @@ int Image::MCBlock::get_longest_axis_index() const {
}
int Image::MCBlock::get_longest_axis_length() const {
int max_dist=-1;
int max_dist = -1;
for(int i=0;i<4;i++) {
for (int i = 0; i < 4; i++) {
int d = max_color.color.col[i]-min_color.color.col[i];
if (d>max_dist) {
max_dist=d;
int d = max_color.color.col[i] - min_color.color.col[i];
if (d > max_dist) {
max_dist = d;
}
}
return max_dist;
}
bool Image::MCBlock::operator<(const MCBlock& p_block) const {
bool Image::MCBlock::operator<(const MCBlock &p_block) const {
int alen = get_longest_axis_length();
int blen = p_block.get_longest_axis_length();
if (alen==blen) {
if (alen == blen) {
return colors < p_block.colors;
} else
return alen < blen;
}
void Image::MCBlock::shrink() {
min_color=colors[0];
max_color=colors[0];
min_color = colors[0];
max_color = colors[0];
for(int i=1;i<color_count;i++) {
for (int i = 1; i < color_count; i++) {
for(int j=0;j<4;j++) {
for (int j = 0; j < 4; j++) {
min_color.color.col[j]=MIN(min_color.color.col[j],colors[i].color.col[j]);
max_color.color.col[j]=MAX(max_color.color.col[j],colors[i].color.col[j]);
min_color.color.col[j] = MIN(min_color.color.col[j], colors[i].color.col[j]);
max_color.color.col[j] = MAX(max_color.color.col[j], colors[i].color.col[j]);
}
}
}
void Image::quantize() {
bool has_alpha = detect_alpha()!=ALPHA_NONE;
bool has_alpha = detect_alpha() != ALPHA_NONE;
bool quantize_fast=OS::get_singleton()->has_environment("QUANTIZE_FAST");
bool quantize_fast = OS::get_singleton()->has_environment("QUANTIZE_FAST");
convert(FORMAT_RGBA);
ERR_FAIL_COND( format!=FORMAT_RGBA );
ERR_FAIL_COND(format != FORMAT_RGBA);
DVector<uint8_t> indexed_data;
{
int color_count = data.size()/4;
int color_count = data.size() / 4;
ERR_FAIL_COND(color_count==0);
ERR_FAIL_COND(color_count == 0);
Set<MCBlock> block_queue;
DVector<BColorPos> data_colors;
data_colors.resize(color_count);
DVector<BColorPos>::Write dcw=data_colors.write();
DVector<BColorPos>::Write dcw = data_colors.write();
DVector<uint8_t>::Read dr = data.read();
const BColor * drptr=(const BColor*)&dr[0];
BColorPos *bcptr=&dcw[0];
const BColor *drptr = (const BColor *)&dr[0];
BColorPos *bcptr = &dcw[0];
{
for(int i=0;i<color_count;i++) {
for (int i = 0; i < color_count; i++) {
//uint32_t data_ofs=i<<2;
bcptr[i].color=drptr[i];//BColor(drptr[data_ofs+0],drptr[data_ofs+1],drptr[data_ofs+2],drptr[data_ofs+3]);
bcptr[i].index=i;
bcptr[i].color = drptr[i]; //BColor(drptr[data_ofs+0],drptr[data_ofs+1],drptr[data_ofs+2],drptr[data_ofs+3]);
bcptr[i].index = i;
}
}
//printf("color count: %i\n",color_count);
@ -161,11 +150,11 @@ void Image::quantize() {
printf("%i - %i,%i,%i,%i\n",i,bc.r,bc.g,bc.b,bc.a);
}*/
MCBlock initial_block((BColorPos*)&dcw[0],color_count);
MCBlock initial_block((BColorPos *)&dcw[0], color_count);
block_queue.insert(initial_block);
while( block_queue.size() < 256 && block_queue.back()->get().color_count > 1 ) {
while (block_queue.size() < 256 && block_queue.back()->get().color_count > 1) {
MCBlock longest = block_queue.back()->get();
//printf("longest: %i (%i)\n",longest.get_longest_axis_index(),longest.get_longest_axis_length());
@ -173,7 +162,7 @@ void Image::quantize() {
block_queue.erase(block_queue.back());
BColorPos *first = longest.colors;
BColorPos *median = longest.colors + (longest.color_count+1)/2;
BColorPos *median = longest.colors + (longest.color_count + 1) / 2;
BColorPos *end = longest.colors + longest.color_count;
#if 0
@ -234,111 +223,122 @@ void Image::quantize() {
block_queue.insert(right);
#else
switch(longest.get_longest_axis_index()) {
case 0: { SortArray<BColorPos,BColorPos::SortR> sort; sort.nth_element(0,end-first,median-first,first); } break;
case 1: { SortArray<BColorPos,BColorPos::SortG> sort; sort.nth_element(0,end-first,median-first,first); } break;
case 2: { SortArray<BColorPos,BColorPos::SortB> sort; sort.nth_element(0,end-first,median-first,first); } break;
case 3: { SortArray<BColorPos,BColorPos::SortA> sort; sort.nth_element(0,end-first,median-first,first); } break;
switch (longest.get_longest_axis_index()) {
case 0: {
SortArray<BColorPos, BColorPos::SortR> sort;
sort.nth_element(0, end - first, median - first, first);
} break;
case 1: {
SortArray<BColorPos, BColorPos::SortG> sort;
sort.nth_element(0, end - first, median - first, first);
} break;
case 2: {
SortArray<BColorPos, BColorPos::SortB> sort;
sort.nth_element(0, end - first, median - first, first);
} break;
case 3: {
SortArray<BColorPos, BColorPos::SortA> sort;
sort.nth_element(0, end - first, median - first, first);
} break;
}
MCBlock left(first,median-first);
MCBlock right(median,end-median);
MCBlock left(first, median - first);
MCBlock right(median, end - median);
block_queue.insert(left);
block_queue.insert(right);
#endif
}
while(block_queue.size() > 256) {
while (block_queue.size() > 256) {
block_queue.erase(block_queue.front());// erase least significant
block_queue.erase(block_queue.front()); // erase least significant
}
int res_colors=0;
int res_colors = 0;
int comp_size = (has_alpha?4:3);
indexed_data.resize(color_count + 256*comp_size);
int comp_size = (has_alpha ? 4 : 3);
indexed_data.resize(color_count + 256 * comp_size);
DVector<uint8_t>::Write iw = indexed_data.write();
uint8_t *iwptr=&iw[0];
uint8_t *iwptr = &iw[0];
BColor pallete[256];
// print_line("applying quantization - res colors "+itos(block_queue.size()));
// print_line("applying quantization - res colors "+itos(block_queue.size()));
while(block_queue.size()) {
while (block_queue.size()) {
const MCBlock &b = block_queue.back()->get();
uint64_t sum[4]={0,0,0,0};
uint64_t sum[4] = { 0, 0, 0, 0 };
for(int i=0;i<b.color_count;i++) {
for (int i = 0; i < b.color_count; i++) {
sum[0]+=b.colors[i].color.col[0];
sum[1]+=b.colors[i].color.col[1];
sum[2]+=b.colors[i].color.col[2];
sum[3]+=b.colors[i].color.col[3];
sum[0] += b.colors[i].color.col[0];
sum[1] += b.colors[i].color.col[1];
sum[2] += b.colors[i].color.col[2];
sum[3] += b.colors[i].color.col[3];
}
BColor c( sum[0]/b.color_count, sum[1]/b.color_count, sum[2]/b.color_count, sum[3]/b.color_count );
BColor c(sum[0] / b.color_count, sum[1] / b.color_count, sum[2] / b.color_count, sum[3] / b.color_count);
//printf(" %i: %i,%i,%i,%i out of %i\n",res_colors,c.r,c.g,c.b,c.a,b.color_count);
for(int i=0;i<comp_size;i++) {
iwptr[ color_count + res_colors * comp_size + i ] = c.col[i];
for (int i = 0; i < comp_size; i++) {
iwptr[color_count + res_colors * comp_size + i] = c.col[i];
}
if (quantize_fast) {
for(int i=0;i<b.color_count;i++) {
iwptr[b.colors[i].index]=res_colors;
for (int i = 0; i < b.color_count; i++) {
iwptr[b.colors[i].index] = res_colors;
}
} else {
pallete[res_colors]=c;
pallete[res_colors] = c;
}
res_colors++;
block_queue.erase(block_queue.back());
}
if (!quantize_fast) {
for(int i=0;i<color_count;i++) {
for (int i = 0; i < color_count; i++) {
const BColor &c=drptr[i];
uint8_t best_dist_idx=0;
uint32_t dist=0xFFFFFFFF;
const BColor &c = drptr[i];
uint8_t best_dist_idx = 0;
uint32_t dist = 0xFFFFFFFF;
for(int j=0;j<res_colors;j++) {
for (int j = 0; j < res_colors; j++) {
const BColor &pc=pallete[j];
const BColor &pc = pallete[j];
uint32_t d = 0;
{ int16_t v = (int16_t)c.r-(int16_t)pc.r; d+=v*v; }
{ int16_t v = (int16_t)c.g-(int16_t)pc.g; d+=v*v; }
{ int16_t v = (int16_t)c.b-(int16_t)pc.b; d+=v*v; }
{ int16_t v = (int16_t)c.a-(int16_t)pc.a; d+=v*v; }
{
int16_t v = (int16_t)c.r - (int16_t)pc.r;
d += v * v;
}
{
int16_t v = (int16_t)c.g - (int16_t)pc.g;
d += v * v;
}
{
int16_t v = (int16_t)c.b - (int16_t)pc.b;
d += v * v;
}
{
int16_t v = (int16_t)c.a - (int16_t)pc.a;
d += v * v;
}
if (d<=dist) {
best_dist_idx=j;
dist=d;
if (d <= dist) {
best_dist_idx = j;
dist = d;
}
}
iwptr[ i ] = best_dist_idx;
iwptr[i] = best_dist_idx;
}
}
@ -348,18 +348,13 @@ void Image::quantize() {
}
print_line(itos(indexed_data.size()));
data=indexed_data;
format=has_alpha?FORMAT_INDEXED_ALPHA:FORMAT_INDEXED;
data = indexed_data;
format = has_alpha ? FORMAT_INDEXED_ALPHA : FORMAT_INDEXED;
} //do none
#else
void Image::quantize() {} //do none
#endif

View File

@ -30,50 +30,45 @@
#include "globals.h"
#include "os/keyboard.h"
InputMap *InputMap::singleton=NULL;
InputMap *InputMap::singleton = NULL;
void InputMap::_bind_methods() {
ObjectTypeDB::bind_method(_MD("has_action","action"),&InputMap::has_action);
ObjectTypeDB::bind_method(_MD("get_action_id","action"),&InputMap::get_action_id);
ObjectTypeDB::bind_method(_MD("get_action_from_id","id"),&InputMap::get_action_from_id);
ObjectTypeDB::bind_method(_MD("get_actions"),&InputMap::_get_actions);
ObjectTypeDB::bind_method(_MD("add_action","action"),&InputMap::add_action);
ObjectTypeDB::bind_method(_MD("erase_action","action"),&InputMap::erase_action);
ObjectTypeDB::bind_method(_MD("action_add_event","action","event"),&InputMap::action_add_event);
ObjectTypeDB::bind_method(_MD("action_has_event","action","event"),&InputMap::action_has_event);
ObjectTypeDB::bind_method(_MD("action_erase_event","action","event"),&InputMap::action_erase_event);
ObjectTypeDB::bind_method(_MD("get_action_list","action"),&InputMap::_get_action_list);
ObjectTypeDB::bind_method(_MD("event_is_action","event","action"),&InputMap::event_is_action);
ObjectTypeDB::bind_method(_MD("load_from_globals"),&InputMap::load_from_globals);
ObjectTypeDB::bind_method(_MD("has_action", "action"), &InputMap::has_action);
ObjectTypeDB::bind_method(_MD("get_action_id", "action"), &InputMap::get_action_id);
ObjectTypeDB::bind_method(_MD("get_action_from_id", "id"), &InputMap::get_action_from_id);
ObjectTypeDB::bind_method(_MD("get_actions"), &InputMap::_get_actions);
ObjectTypeDB::bind_method(_MD("add_action", "action"), &InputMap::add_action);
ObjectTypeDB::bind_method(_MD("erase_action", "action"), &InputMap::erase_action);
ObjectTypeDB::bind_method(_MD("action_add_event", "action", "event"), &InputMap::action_add_event);
ObjectTypeDB::bind_method(_MD("action_has_event", "action", "event"), &InputMap::action_has_event);
ObjectTypeDB::bind_method(_MD("action_erase_event", "action", "event"), &InputMap::action_erase_event);
ObjectTypeDB::bind_method(_MD("get_action_list", "action"), &InputMap::_get_action_list);
ObjectTypeDB::bind_method(_MD("event_is_action", "event", "action"), &InputMap::event_is_action);
ObjectTypeDB::bind_method(_MD("load_from_globals"), &InputMap::load_from_globals);
}
void InputMap::add_action(const StringName &p_action) {
void InputMap::add_action(const StringName& p_action) {
ERR_FAIL_COND( input_map.has(p_action) );
input_map[p_action]=Action();
static int last_id=1;
input_map[p_action].id=last_id;
input_id_map[last_id]=p_action;
ERR_FAIL_COND(input_map.has(p_action));
input_map[p_action] = Action();
static int last_id = 1;
input_map[p_action].id = last_id;
input_id_map[last_id] = p_action;
last_id++;
}
void InputMap::erase_action(const StringName& p_action) {
void InputMap::erase_action(const StringName &p_action) {
ERR_FAIL_COND( !input_map.has(p_action) );
ERR_FAIL_COND(!input_map.has(p_action));
input_id_map.erase(input_map[p_action].id);
input_map.erase(p_action);
}
StringName InputMap::get_action_from_id(int p_id) const {
ERR_FAIL_COND_V(!input_id_map.has(p_id),StringName());
ERR_FAIL_COND_V(!input_id_map.has(p_id), StringName());
return input_id_map[p_id];
}
@ -81,10 +76,10 @@ Array InputMap::_get_actions() {
Array ret;
List<StringName> actions = get_actions();
if(actions.empty())
if (actions.empty())
return ret;
for(const List<StringName>::Element *E=actions.front();E;E=E->next()) {
for (const List<StringName>::Element *E = actions.front(); E; E = E->next()) {
ret.push_back(E->get());
}
@ -95,49 +90,49 @@ Array InputMap::_get_actions() {
List<StringName> InputMap::get_actions() const {
List<StringName> actions = List<StringName>();
if(input_map.empty()){
if (input_map.empty()) {
return actions;
}
for (Map<StringName, Action>::Element *E=input_map.front();E;E=E->next()) {
for (Map<StringName, Action>::Element *E = input_map.front(); E; E = E->next()) {
actions.push_back(E->key());
}
return actions;
}
List<InputEvent>::Element *InputMap::_find_event(List<InputEvent> &p_list,const InputEvent& p_event) const {
List<InputEvent>::Element *InputMap::_find_event(List<InputEvent> &p_list, const InputEvent &p_event) const {
for (List<InputEvent>::Element *E=p_list.front();E;E=E->next()) {
for (List<InputEvent>::Element *E = p_list.front(); E; E = E->next()) {
const InputEvent& e=E->get();
if(e.type!=p_event.type)
const InputEvent &e = E->get();
if (e.type != p_event.type)
continue;
if (e.type!=InputEvent::KEY && e.device!=p_event.device)
if (e.type != InputEvent::KEY && e.device != p_event.device)
continue;
bool same=false;
bool same = false;
switch(p_event.type) {
switch (p_event.type) {
case InputEvent::KEY: {
same=(e.key.scancode==p_event.key.scancode && e.key.mod == p_event.key.mod);
same = (e.key.scancode == p_event.key.scancode && e.key.mod == p_event.key.mod);
} break;
case InputEvent::JOYSTICK_BUTTON: {
same=(e.joy_button.button_index==p_event.joy_button.button_index);
same = (e.joy_button.button_index == p_event.joy_button.button_index);
} break;
case InputEvent::MOUSE_BUTTON: {
same=(e.mouse_button.button_index==p_event.mouse_button.button_index);
same = (e.mouse_button.button_index == p_event.mouse_button.button_index);
} break;
case InputEvent::JOYSTICK_MOTION: {
same=(e.joy_motion.axis==p_event.joy_motion.axis && (e.joy_motion.axis_value < 0) == (p_event.joy_motion.axis_value < 0));
same = (e.joy_motion.axis == p_event.joy_motion.axis && (e.joy_motion.axis_value < 0) == (p_event.joy_motion.axis_value < 0));
} break;
}
@ -146,90 +141,82 @@ List<InputEvent>::Element *InputMap::_find_event(List<InputEvent> &p_list,const
return E;
}
return NULL;
}
bool InputMap::has_action(const StringName& p_action) const {
bool InputMap::has_action(const StringName &p_action) const {
return input_map.has(p_action);
}
void InputMap::action_add_event(const StringName& p_action,const InputEvent& p_event) {
void InputMap::action_add_event(const StringName &p_action, const InputEvent &p_event) {
ERR_FAIL_COND(p_event.type==InputEvent::ACTION);
ERR_FAIL_COND( !input_map.has(p_action) );
if (_find_event(input_map[p_action].inputs,p_event))
ERR_FAIL_COND(p_event.type == InputEvent::ACTION);
ERR_FAIL_COND(!input_map.has(p_action));
if (_find_event(input_map[p_action].inputs, p_event))
return; //already gots
input_map[p_action].inputs.push_back(p_event);
}
int InputMap::get_action_id(const StringName &p_action) const {
int InputMap::get_action_id(const StringName& p_action) const {
ERR_FAIL_COND_V(!input_map.has(p_action),-1);
ERR_FAIL_COND_V(!input_map.has(p_action), -1);
return input_map[p_action].id;
}
bool InputMap::action_has_event(const StringName& p_action,const InputEvent& p_event) {
ERR_FAIL_COND_V( !input_map.has(p_action), false );
return (_find_event(input_map[p_action].inputs,p_event)!=NULL);
bool InputMap::action_has_event(const StringName &p_action, const InputEvent &p_event) {
ERR_FAIL_COND_V(!input_map.has(p_action), false);
return (_find_event(input_map[p_action].inputs, p_event) != NULL);
}
void InputMap::action_erase_event(const StringName& p_action,const InputEvent& p_event) {
void InputMap::action_erase_event(const StringName &p_action, const InputEvent &p_event) {
ERR_FAIL_COND( !input_map.has(p_action) );
ERR_FAIL_COND(!input_map.has(p_action));
List<InputEvent>::Element *E=_find_event(input_map[p_action].inputs,p_event);
List<InputEvent>::Element *E = _find_event(input_map[p_action].inputs, p_event);
if (E)
input_map[p_action].inputs.erase(E);
}
Array InputMap::_get_action_list(const StringName& p_action) {
Array InputMap::_get_action_list(const StringName &p_action) {
Array ret;
const List<InputEvent> *al = get_action_list(p_action);
if (al) {
for(const List<InputEvent>::Element *E=al->front();E;E=E->next()) {
for (const List<InputEvent>::Element *E = al->front(); E; E = E->next()) {
ret.push_back(E->get());
}
}
return ret;
}
const List<InputEvent> *InputMap::get_action_list(const StringName& p_action) {
const List<InputEvent> *InputMap::get_action_list(const StringName &p_action) {
const Map<StringName, Action>::Element *E=input_map.find(p_action);
const Map<StringName, Action>::Element *E = input_map.find(p_action);
if (!E)
return NULL;
return &E->get().inputs;
}
bool InputMap::event_is_action(const InputEvent& p_event, const StringName& p_action) const {
bool InputMap::event_is_action(const InputEvent &p_event, const StringName &p_action) const {
Map<StringName,Action >::Element *E=input_map.find(p_action);
if(!E) {
ERR_EXPLAIN("Request for nonexistent InputMap action: "+String(p_action));
ERR_FAIL_COND_V(!E,false);
Map<StringName, Action>::Element *E = input_map.find(p_action);
if (!E) {
ERR_EXPLAIN("Request for nonexistent InputMap action: " + String(p_action));
ERR_FAIL_COND_V(!E, false);
}
if (p_event.type==InputEvent::ACTION) {
if (p_event.type == InputEvent::ACTION) {
return p_event.action.action==E->get().id;
return p_event.action.action == E->get().id;
}
return _find_event(E->get().inputs,p_event)!=NULL;
return _find_event(E->get().inputs, p_event) != NULL;
}
void InputMap::load_from_globals() {
@ -239,94 +226,88 @@ void InputMap::load_from_globals() {
List<PropertyInfo> pinfo;
Globals::get_singleton()->get_property_list(&pinfo);
for(List<PropertyInfo>::Element *E=pinfo.front();E;E=E->next()) {
const PropertyInfo &pi=E->get();
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());
String name = pi.name.substr(pi.name.find("/") + 1, pi.name.length());
add_action(name);
Array va = Globals::get_singleton()->get(pi.name);
for(int i=0;i<va.size();i++) {
for (int i = 0; i < va.size(); i++) {
InputEvent ie=va[i];
if (ie.type==InputEvent::NONE)
InputEvent ie = va[i];
if (ie.type == InputEvent::NONE)
continue;
action_add_event(name,ie);
action_add_event(name, ie);
}
}
}
void InputMap::load_default() {
InputEvent key;
key.type=InputEvent::KEY;
key.type = InputEvent::KEY;
add_action("ui_accept");
key.key.scancode=KEY_RETURN;
action_add_event("ui_accept",key);
key.key.scancode=KEY_ENTER;
action_add_event("ui_accept",key);
key.key.scancode=KEY_SPACE;
action_add_event("ui_accept",key);
key.key.scancode = KEY_RETURN;
action_add_event("ui_accept", key);
key.key.scancode = KEY_ENTER;
action_add_event("ui_accept", key);
key.key.scancode = KEY_SPACE;
action_add_event("ui_accept", key);
add_action("ui_select");
key.key.scancode=KEY_SPACE;
action_add_event("ui_select",key);
key.key.scancode = KEY_SPACE;
action_add_event("ui_select", key);
add_action("ui_cancel");
key.key.scancode=KEY_ESCAPE;
action_add_event("ui_cancel",key);
key.key.scancode = KEY_ESCAPE;
action_add_event("ui_cancel", key);
add_action("ui_focus_next");
key.key.scancode=KEY_TAB;
action_add_event("ui_focus_next",key);
key.key.scancode = KEY_TAB;
action_add_event("ui_focus_next", key);
add_action("ui_focus_prev");
key.key.scancode=KEY_TAB;
key.key.mod.shift=true;
action_add_event("ui_focus_prev",key);
key.key.mod.shift=false;
key.key.scancode = KEY_TAB;
key.key.mod.shift = true;
action_add_event("ui_focus_prev", key);
key.key.mod.shift = false;
add_action("ui_left");
key.key.scancode=KEY_LEFT;
action_add_event("ui_left",key);
key.key.scancode = KEY_LEFT;
action_add_event("ui_left", key);
add_action("ui_right");
key.key.scancode=KEY_RIGHT;
action_add_event("ui_right",key);
key.key.scancode = KEY_RIGHT;
action_add_event("ui_right", key);
add_action("ui_up");
key.key.scancode=KEY_UP;
action_add_event("ui_up",key);
key.key.scancode = KEY_UP;
action_add_event("ui_up", key);
add_action("ui_down");
key.key.scancode=KEY_DOWN;
action_add_event("ui_down",key);
key.key.scancode = KEY_DOWN;
action_add_event("ui_down", key);
add_action("ui_page_up");
key.key.scancode=KEY_PAGEUP;
action_add_event("ui_page_up",key);
key.key.scancode = KEY_PAGEUP;
action_add_event("ui_page_up", key);
add_action("ui_page_down");
key.key.scancode=KEY_PAGEDOWN;
action_add_event("ui_page_down",key);
// set("display/orientation", "landscape");
key.key.scancode = KEY_PAGEDOWN;
action_add_event("ui_page_down", key);
// set("display/orientation", "landscape");
}
InputMap::InputMap() {
ERR_FAIL_COND(singleton);
singleton=this;
singleton = this;
}

View File

@ -29,12 +29,11 @@
#ifndef INPUT_MAP_H
#define INPUT_MAP_H
#include "object.h"
class InputMap : public Object {
OBJ_TYPE( InputMap, Object );
OBJ_TYPE(InputMap, Object);
static InputMap *singleton;
struct Action {
@ -42,35 +41,32 @@ class InputMap : public Object {
List<InputEvent> inputs;
};
mutable Map<StringName, Action> input_map;
mutable Map<int,StringName> input_id_map;
mutable Map<int, StringName> input_id_map;
List<InputEvent>::Element *_find_event(List<InputEvent> &p_list,const InputEvent& p_event) const;
List<InputEvent>::Element *_find_event(List<InputEvent> &p_list, const InputEvent &p_event) const;
Array _get_action_list(const StringName& p_action);
Array _get_action_list(const StringName &p_action);
Array _get_actions();
protected:
static void _bind_methods();
public:
public:
static _FORCE_INLINE_ InputMap *get_singleton() { return singleton; }
bool has_action(const StringName& p_action) const;
int get_action_id(const StringName& p_action) const;
bool has_action(const StringName &p_action) const;
int get_action_id(const StringName &p_action) const;
StringName get_action_from_id(int p_id) const;
List<StringName> get_actions() const;
void add_action(const StringName& p_action);
void erase_action(const StringName& p_action);
void add_action(const StringName &p_action);
void erase_action(const StringName &p_action);
void action_add_event(const StringName& p_action,const InputEvent& p_event);
bool action_has_event(const StringName& p_action,const InputEvent& p_event);
void action_erase_event(const StringName& p_action,const InputEvent& p_event);
const List<InputEvent> *get_action_list(const StringName& p_action);
bool event_is_action(const InputEvent& p_event, const StringName& p_action) const;
void action_add_event(const StringName &p_action, const InputEvent &p_event);
bool action_has_event(const StringName &p_action, const InputEvent &p_event);
void action_erase_event(const StringName &p_action, const InputEvent &p_event);
const List<InputEvent> *get_action_list(const StringName &p_action);
bool event_is_action(const InputEvent &p_event, const StringName &p_action) const;
void load_from_globals();
void load_default();

View File

@ -29,25 +29,25 @@
#ifdef _MSC_VER
typedef signed __int8 int8_t;
typedef unsigned __int8 uint8_t;
typedef signed __int16 int16_t;
typedef unsigned __int16 uint16_t;
typedef signed __int32 int32_t;
typedef unsigned __int32 uint32_t;
typedef signed __int64 int64_t;
typedef unsigned __int64 uint64_t;
typedef signed __int8 int8_t;
typedef unsigned __int8 uint8_t;
typedef signed __int16 int16_t;
typedef unsigned __int16 uint16_t;
typedef signed __int32 int32_t;
typedef unsigned __int32 uint32_t;
typedef signed __int64 int64_t;
typedef unsigned __int64 uint64_t;
#else
#ifdef NO_STDINT_H
typedef unsigned char uint8_t;
typedef signed char int8_t;
typedef unsigned short uint16_t;
typedef signed short int16_t;
typedef unsigned int uint32_t;
typedef signed int int32_t;
typedef long long int64_t;
typedef unsigned char uint8_t;
typedef signed char int8_t;
typedef unsigned short uint16_t;
typedef signed short int16_t;
typedef unsigned int uint32_t;
typedef signed int int32_t;
typedef long long int64_t;
typedef unsigned long long uint64_t;
#else
#include <stdint.h>

View File

@ -26,25 +26,25 @@
/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
/*************************************************************************/
#include "zlib.h"
#include "os/copymem.h"
#include "compression.h"
#include "os/copymem.h"
#include "zlib.h"
#include "fastlz.h"
#include "zip_io.h"
int Compression::compress(uint8_t *p_dst, const uint8_t *p_src, int p_src_size,Mode p_mode) {
int Compression::compress(uint8_t *p_dst, const uint8_t *p_src, int p_src_size, Mode p_mode) {
switch(p_mode) {
switch (p_mode) {
case MODE_FASTLZ: {
if (p_src_size<16) {
if (p_src_size < 16) {
uint8_t src[16];
zeromem(&src[p_src_size],16-p_src_size);
copymem(src,p_src,p_src_size);
return fastlz_compress(src,16,p_dst);
zeromem(&src[p_src_size], 16 - p_src_size);
copymem(src, p_src, p_src_size);
return fastlz_compress(src, 16, p_dst);
} else {
return fastlz_compress(p_src,p_src_size,p_dst);
return fastlz_compress(p_src, p_src_size, p_dst);
}
} break;
@ -54,16 +54,16 @@ int Compression::compress(uint8_t *p_dst, const uint8_t *p_src, int p_src_size,M
strm.zalloc = zipio_alloc;
strm.zfree = zipio_free;
strm.opaque = Z_NULL;
int err = deflateInit(&strm,Z_DEFAULT_COMPRESSION);
if (err!=Z_OK)
return -1;
int err = deflateInit(&strm, Z_DEFAULT_COMPRESSION);
if (err != Z_OK)
return -1;
strm.avail_in=p_src_size;
int aout = deflateBound(&strm,p_src_size);
strm.avail_out=aout;
strm.next_in=(Bytef*)p_src;
strm.next_out=p_dst;
deflate(&strm,Z_FINISH);
strm.avail_in = p_src_size;
int aout = deflateBound(&strm, p_src_size);
strm.avail_out = aout;
strm.next_in = (Bytef *)p_src;
strm.next_out = p_dst;
deflate(&strm, Z_FINISH);
aout = aout - strm.avail_out;
deflateEnd(&strm);
return aout;
@ -74,15 +74,14 @@ int Compression::compress(uint8_t *p_dst, const uint8_t *p_src, int p_src_size,M
ERR_FAIL_V(-1);
}
int Compression::get_max_compressed_buffer_size(int p_src_size,Mode p_mode){
int Compression::get_max_compressed_buffer_size(int p_src_size, Mode p_mode) {
switch(p_mode) {
switch (p_mode) {
case MODE_FASTLZ: {
int ss = p_src_size+p_src_size*6/100;
if (ss<66)
ss=66;
int ss = p_src_size + p_src_size * 6 / 100;
if (ss < 66)
ss = 66;
return ss;
} break;
@ -92,32 +91,29 @@ int Compression::get_max_compressed_buffer_size(int p_src_size,Mode p_mode){
strm.zalloc = zipio_alloc;
strm.zfree = zipio_free;
strm.opaque = Z_NULL;
int err = deflateInit(&strm,Z_DEFAULT_COMPRESSION);
if (err!=Z_OK)
return -1;
int aout = deflateBound(&strm,p_src_size);
int err = deflateInit(&strm, Z_DEFAULT_COMPRESSION);
if (err != Z_OK)
return -1;
int aout = deflateBound(&strm, p_src_size);
deflateEnd(&strm);
return aout;
} break;
}
ERR_FAIL_V(-1);
}
void Compression::decompress(uint8_t *p_dst, int p_dst_max_size, const uint8_t *p_src, int p_src_size, Mode p_mode) {
void Compression::decompress(uint8_t *p_dst, int p_dst_max_size, const uint8_t *p_src, int p_src_size,Mode p_mode){
switch(p_mode) {
switch (p_mode) {
case MODE_FASTLZ: {
if (p_dst_max_size<16) {
if (p_dst_max_size < 16) {
uint8_t dst[16];
fastlz_decompress(p_src,p_src_size,dst,16);
copymem(p_dst,dst,p_dst_max_size);
fastlz_decompress(p_src, p_src_size, dst, 16);
copymem(p_dst, dst, p_dst_max_size);
} else {
fastlz_decompress(p_src,p_src_size,p_dst,p_dst_max_size);
fastlz_decompress(p_src, p_src_size, p_dst, p_dst_max_size);
}
return;
} break;
@ -127,19 +123,19 @@ void Compression::decompress(uint8_t *p_dst, int p_dst_max_size, const uint8_t *
strm.zalloc = zipio_alloc;
strm.zfree = zipio_free;
strm.opaque = Z_NULL;
strm.avail_in= 0;
strm.next_in=Z_NULL;
strm.avail_in = 0;
strm.next_in = Z_NULL;
int err = inflateInit(&strm);
ERR_FAIL_COND(err!=Z_OK);
ERR_FAIL_COND(err != Z_OK);
strm.avail_in=p_src_size;
strm.avail_out=p_dst_max_size;
strm.next_in=(Bytef*)p_src;
strm.next_out=p_dst;
strm.avail_in = p_src_size;
strm.avail_out = p_dst_max_size;
strm.next_in = (Bytef *)p_src;
strm.next_out = p_dst;
err = inflate(&strm,Z_FINISH);
err = inflate(&strm, Z_FINISH);
inflateEnd(&strm);
ERR_FAIL_COND(err!=Z_STREAM_END);
ERR_FAIL_COND(err != Z_STREAM_END);
return;
} break;
}

View File

@ -31,23 +31,18 @@
#include "typedefs.h"
class Compression
{
class Compression {
public:
enum Mode {
MODE_FASTLZ,
MODE_DEFLATE
};
static int compress(uint8_t *p_dst, const uint8_t *p_src, int p_src_size,Mode p_mode=MODE_FASTLZ);
static int get_max_compressed_buffer_size(int p_src_size,Mode p_mode=MODE_FASTLZ);
static void decompress(uint8_t *p_dst, int p_dst_max_size, const uint8_t *p_src, int p_src_size,Mode p_mode=MODE_FASTLZ);
static int compress(uint8_t *p_dst, const uint8_t *p_src, int p_src_size, Mode p_mode = MODE_FASTLZ);
static int get_max_compressed_buffer_size(int p_src_size, Mode p_mode = MODE_FASTLZ);
static void decompress(uint8_t *p_dst, int p_dst_max_size, const uint8_t *p_src, int p_src_size, Mode p_mode = MODE_FASTLZ);
Compression();
};
#endif // COMPRESSION_H

View File

@ -27,8 +27,8 @@
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
/*************************************************************************/
#include "config_file.h"
#include "os/keyboard.h"
#include "os/file_access.h"
#include "os/keyboard.h"
#include "variant_parser.h"
StringArray ConfigFile::_get_sections() const {
@ -37,35 +37,33 @@ StringArray ConfigFile::_get_sections() const {
get_sections(&s);
StringArray arr;
arr.resize(s.size());
int idx=0;
for(const List<String>::Element *E=s.front();E;E=E->next()) {
int idx = 0;
for (const List<String>::Element *E = s.front(); E; E = E->next()) {
arr.set(idx++,E->get());
arr.set(idx++, E->get());
}
return arr;
}
StringArray ConfigFile::_get_section_keys(const String& p_section) const{
StringArray ConfigFile::_get_section_keys(const String &p_section) const {
List<String> s;
get_section_keys(p_section,&s);
get_section_keys(p_section, &s);
StringArray arr;
arr.resize(s.size());
int idx=0;
for(const List<String>::Element *E=s.front();E;E=E->next()) {
int idx = 0;
for (const List<String>::Element *E = s.front(); E; E = E->next()) {
arr.set(idx++,E->get());
arr.set(idx++, E->get());
}
return arr;
}
void ConfigFile::set_value(const String &p_section, const String &p_key, const Variant &p_value) {
void ConfigFile::set_value(const String& p_section, const String& p_key, const Variant& p_value){
if (p_value.get_type()==Variant::NIL) {
if (p_value.get_type() == Variant::NIL) {
//erase
if (!values.has(p_section))
return; // ?
@ -76,55 +74,49 @@ void ConfigFile::set_value(const String& p_section, const String& p_key, const V
} else {
if (!values.has(p_section)) {
values[p_section]=Map<String, Variant>();
values[p_section] = Map<String, Variant>();
}
values[p_section][p_key]=p_value;
values[p_section][p_key] = p_value;
}
}
Variant ConfigFile::get_value(const String& p_section, const String& p_key, Variant p_default) const {
Variant ConfigFile::get_value(const String &p_section, const String &p_key, Variant p_default) const {
ERR_FAIL_COND_V(!values.has(p_section),p_default);
ERR_FAIL_COND_V(!values[p_section].has(p_key),p_default);
ERR_FAIL_COND_V(!values.has(p_section), p_default);
ERR_FAIL_COND_V(!values[p_section].has(p_key), p_default);
return values[p_section][p_key];
}
bool ConfigFile::has_section(const String& p_section) const {
bool ConfigFile::has_section(const String &p_section) const {
return values.has(p_section);
}
bool ConfigFile::has_section_key(const String& p_section,const String& p_key) const {
bool ConfigFile::has_section_key(const String &p_section, const String &p_key) const {
if (!values.has(p_section))
return false;
return values[p_section].has(p_key);
}
void ConfigFile::get_sections(List<String> *r_sections) const{
void ConfigFile::get_sections(List<String> *r_sections) const {
for(const Map< String, Map<String, Variant> >::Element *E=values.front();E;E=E->next()) {
for (const Map<String, Map<String, Variant> >::Element *E = values.front(); E; E = E->next()) {
r_sections->push_back(E->key());
}
}
void ConfigFile::get_section_keys(const String& p_section,List<String> *r_keys) const{
void ConfigFile::get_section_keys(const String &p_section, List<String> *r_keys) const {
ERR_FAIL_COND(!values.has(p_section));
for(const Map<String, Variant> ::Element *E=values[p_section].front();E;E=E->next()) {
for (const Map<String, Variant>::Element *E = values[p_section].front(); E; E = E->next()) {
r_keys->push_back(E->key());
}
}
Error ConfigFile::save(const String& p_path){
Error ConfigFile::save(const String &p_path) {
Error err;
FileAccess *file = FileAccess::open(p_path,FileAccess::WRITE,&err);
FileAccess *file = FileAccess::open(p_path, FileAccess::WRITE, &err);
if (err) {
if (file)
@ -132,18 +124,17 @@ Error ConfigFile::save(const String& p_path){
return err;
}
for (Map<String, Map<String, Variant> >::Element *E = values.front(); E; E = E->next()) {
for(Map< String, Map<String, Variant> >::Element *E=values.front();E;E=E->next()) {
if (E!=values.front())
if (E != values.front())
file->store_string("\n");
file->store_string("["+E->key()+"]\n\n");
file->store_string("[" + E->key() + "]\n\n");
for(Map<String, Variant>::Element *F=E->get().front();F;F=F->next()) {
for (Map<String, Variant>::Element *F = E->get().front(); F; F = F->next()) {
String vstr;
VariantWriter::write_to_string(F->get(),vstr);
file->store_string(F->key()+"="+vstr+"\n");
VariantWriter::write_to_string(F->get(), vstr);
file->store_string(F->key() + "=" + vstr + "\n");
}
}
@ -152,48 +143,46 @@ Error ConfigFile::save(const String& p_path){
return OK;
}
Error ConfigFile::load(const String& p_path) {
Error ConfigFile::load(const String &p_path) {
Error err;
FileAccess *f= FileAccess::open(p_path,FileAccess::READ,&err);
FileAccess *f = FileAccess::open(p_path, FileAccess::READ, &err);
if (!f)
return ERR_CANT_OPEN;
VariantParser::StreamFile stream;
stream.f=f;
stream.f = f;
String assign;
Variant value;
VariantParser::Tag next_tag;
int lines=0;
int lines = 0;
String error_text;
String section;
while(true) {
while (true) {
assign=Variant();
assign = Variant();
next_tag.fields.clear();
next_tag.name=String();
next_tag.name = String();
err = VariantParser::parse_tag_assign_eof(&stream,lines,error_text,next_tag,assign,value,NULL,true);
if (err==ERR_FILE_EOF) {
err = VariantParser::parse_tag_assign_eof(&stream, lines, error_text, next_tag, assign, value, NULL, true);
if (err == ERR_FILE_EOF) {
memdelete(f);
return OK;
}
else if (err!=OK) {
ERR_PRINTS("ConfgFile::load - "+p_path+":"+itos(lines)+" error: "+error_text);
} else if (err != OK) {
ERR_PRINTS("ConfgFile::load - " + p_path + ":" + itos(lines) + " error: " + error_text);
memdelete(f);
return err;
}
if (assign!=String()) {
set_value(section,assign,value);
} else if (next_tag.name!=String()) {
section=next_tag.name;
if (assign != String()) {
set_value(section, assign, value);
} else if (next_tag.name != String()) {
section = next_tag.name;
}
}
@ -202,25 +191,20 @@ Error ConfigFile::load(const String& p_path) {
return OK;
}
void ConfigFile::_bind_methods() {
ObjectTypeDB::bind_method(_MD("set_value", "section", "key", "value"), &ConfigFile::set_value);
ObjectTypeDB::bind_method(_MD("get_value:Variant", "section", "key", "default"), &ConfigFile::get_value, DEFVAL(Variant()));
void ConfigFile::_bind_methods(){
ObjectTypeDB::bind_method(_MD("has_section", "section"), &ConfigFile::has_section);
ObjectTypeDB::bind_method(_MD("has_section_key", "section", "key"), &ConfigFile::has_section_key);
ObjectTypeDB::bind_method(_MD("set_value","section","key","value"),&ConfigFile::set_value);
ObjectTypeDB::bind_method(_MD("get_value:Variant","section","key","default"),&ConfigFile::get_value,DEFVAL(Variant()));
ObjectTypeDB::bind_method(_MD("has_section","section"),&ConfigFile::has_section);
ObjectTypeDB::bind_method(_MD("has_section_key","section","key"),&ConfigFile::has_section_key);
ObjectTypeDB::bind_method(_MD("get_sections"),&ConfigFile::_get_sections);
ObjectTypeDB::bind_method(_MD("get_section_keys","section"),&ConfigFile::_get_section_keys);
ObjectTypeDB::bind_method(_MD("load:Error","path"),&ConfigFile::load);
ObjectTypeDB::bind_method(_MD("save:Error","path"),&ConfigFile::save);
ObjectTypeDB::bind_method(_MD("get_sections"), &ConfigFile::_get_sections);
ObjectTypeDB::bind_method(_MD("get_section_keys", "section"), &ConfigFile::_get_section_keys);
ObjectTypeDB::bind_method(_MD("load:Error", "path"), &ConfigFile::load);
ObjectTypeDB::bind_method(_MD("save:Error", "path"), &ConfigFile::save);
}
ConfigFile::ConfigFile()
{
ConfigFile::ConfigFile() {
}

View File

@ -31,31 +31,30 @@
#include "reference.h"
class ConfigFile : public Reference {
OBJ_TYPE(ConfigFile,Reference);
OBJ_TYPE(ConfigFile, Reference);
Map< String, Map<String, Variant> > values;
Map<String, Map<String, Variant> > values;
StringArray _get_sections() const;
StringArray _get_section_keys(const String& p_section) const;
StringArray _get_section_keys(const String &p_section) const;
protected:
static void _bind_methods();
public:
void set_value(const String &p_section, const String &p_key, const Variant &p_value);
Variant get_value(const String &p_section, const String &p_key, Variant p_default = Variant()) const;
void set_value(const String& p_section, const String& p_key, const Variant& p_value);
Variant get_value(const String& p_section, const String& p_key, Variant p_default=Variant()) const;
bool has_section(const String& p_section) const;
bool has_section_key(const String& p_section,const String& p_key) const;
bool has_section(const String &p_section) const;
bool has_section_key(const String &p_section, const String &p_key) const;
void get_sections(List<String> *r_sections) const;
void get_section_keys(const String& p_section,List<String> *r_keys) const;
void get_section_keys(const String &p_section, List<String> *r_keys) const;
Error save(const String& p_path);
Error load(const String& p_path);
Error save(const String &p_path);
Error load(const String &p_path);
ConfigFile();
};

View File

@ -1,2 +1 @@
#include "export_data.h"

View File

@ -1,9 +1,9 @@
#ifndef EXPORT_DATA_H
#define EXPORT_DATA_H
#include "map.h"
#include "variant.h"
#include "vector.h"
#include "map.h"
struct ExportData {
struct Dependency {
@ -11,7 +11,7 @@ struct ExportData {
String type;
};
Map<int,Dependency> dependencies;
Map<int, Dependency> dependencies;
struct PropertyData {
String name;
@ -23,12 +23,10 @@ struct ExportData {
String type;
int index;
List<PropertyData> properties;
};
Vector<ResourceData> resources;
struct NodeData {
bool text_data;
@ -41,19 +39,20 @@ struct ExportData {
int parent_int;
bool instance_is_placeholder;
//text info
NodePath parent;
NodePath owner;
String instance_placeholder;
Vector<String> groups;
List<PropertyData> properties;
NodeData() { parent_int=0; owner_int=0; text_data=true; instanced=false;}
NodeData() {
parent_int = 0;
owner_int = 0;
text_data = true;
instanced = false;
}
};
Vector<NodeData> nodes;
@ -72,7 +71,7 @@ struct ExportData {
Array binds;
int flags;
Connection() { text_data=true; }
Connection() { text_data = true; }
};
Vector<Connection> connections;
@ -80,8 +79,6 @@ struct ExportData {
Array node_paths; //for integer packed data
Variant base_scene;
};
#endif // EXPORT_DATA_H

View File

@ -92,7 +92,7 @@ bool FileAccessBuffered::eof_reached() const {
uint8_t FileAccessBuffered::get_8() const {
ERR_FAIL_COND_V(!file.open,0);
ERR_FAIL_COND_V(!file.open, 0);
uint8_t byte = 0;
if (cache_data_left() >= 1) {
@ -105,7 +105,7 @@ uint8_t FileAccessBuffered::get_8() const {
return byte;
};
int FileAccessBuffered::get_buffer(uint8_t *p_dest,int p_elements) const {
int FileAccessBuffered::get_buffer(uint8_t *p_dest, int p_elements) const {
ERR_FAIL_COND_V(!file.open, -1);
@ -135,7 +135,6 @@ int FileAccessBuffered::get_buffer(uint8_t *p_dest,int p_elements) const {
return total_read;
};
int to_read = p_elements;
int total_read = 0;
while (to_read > 0) {
@ -154,7 +153,7 @@ int FileAccessBuffered::get_buffer(uint8_t *p_dest,int p_elements) const {
int r = MIN(left, to_read);
//DVector<uint8_t>::Read read = cache.buffer.read();
//memcpy(p_dest+total_read, &read.ptr()[file.offset - cache.offset], r);
memcpy(p_dest+total_read, cache.buffer.ptr() + (file.offset - cache.offset), r);
memcpy(p_dest + total_read, cache.buffer.ptr() + (file.offset - cache.offset), r);
file.offset += r;
total_read += r;
@ -179,6 +178,5 @@ FileAccessBuffered::FileAccessBuffered() {
cache_size = DEFAULT_CACHE_SIZE;
};
FileAccessBuffered::~FileAccessBuffered(){
FileAccessBuffered::~FileAccessBuffered() {
}

View File

@ -42,14 +42,12 @@ public:
};
private:
int cache_size;
int cache_data_left() const;
mutable Error last_error;
protected:
Error set_error(Error p_error) const;
mutable struct File {
@ -67,23 +65,22 @@ protected:
int offset;
} cache;
virtual int read_data_block(int p_offset, int p_size, uint8_t *p_dest = 0) const =0;
virtual int read_data_block(int p_offset, int p_size, uint8_t *p_dest = 0) const = 0;
void set_cache_size(int p_size);
int get_cache_size();
public:
virtual size_t get_pos() const; ///< get position in the file
virtual size_t get_len() const; ///< get size of the file
virtual void seek(size_t p_position); ///< seek to a given position
virtual void seek_end(int64_t p_position=0); ///< seek from the end of file
virtual void seek_end(int64_t p_position = 0); ///< seek from the end of file
virtual bool eof_reached() const;
virtual uint8_t get_8() const;
virtual int get_buffer(uint8_t *p_dst,int p_length) const; ///< get an array of bytes
virtual int get_buffer(uint8_t *p_dst, int p_length) const; ///< get an array of bytes
virtual bool is_open() const;
@ -94,4 +91,3 @@ public:
};
#endif

View File

@ -31,16 +31,16 @@
#include "core/io/file_access_buffered.h"
template<class T>
template <class T>
class FileAccessBufferedFA : public FileAccessBuffered {
T f;
int read_data_block(int p_offset, int p_size, uint8_t *p_dest = 0) const {
ERR_FAIL_COND_V( !f.is_open(), -1 );
ERR_FAIL_COND_V(!f.is_open(), -1);
((T*)&f)->seek(p_offset);
((T *)&f)->seek(p_offset);
if (p_dest) {
@ -63,9 +63,9 @@ class FileAccessBufferedFA : public FileAccessBuffered {
};
};
static FileAccess* create() {
static FileAccess *create() {
return memnew( FileAccessBufferedFA<T>() );
return memnew(FileAccessBufferedFA<T>());
};
protected:
@ -75,29 +75,27 @@ protected:
};
public:
void store_8(uint8_t p_dest) {
f.store_8(p_dest);
};
void store_buffer(const uint8_t *p_src,int p_length) {
void store_buffer(const uint8_t *p_src, int p_length) {
f.store_buffer(p_src, p_length);
};
bool file_exists(const String& p_name) {
bool file_exists(const String &p_name) {
return f.file_exists(p_name);
};
Error _open(const String& p_path, int p_mode_flags) {
Error _open(const String &p_path, int p_mode_flags) {
close();
Error ret = f._open(p_path, p_mode_flags);
if (ret !=OK)
if (ret != OK)
return ret;
//ERR_FAIL_COND_V( ret != OK, ret );
@ -127,21 +125,19 @@ public:
set_error(OK);
};
// static void make_default() {
// static void make_default() {
//FileAccess::create_func = FileAccessBufferedFA<T>::create;
// };
//FileAccess::create_func = FileAccessBufferedFA<T>::create;
// };
virtual uint64_t _get_modified_time(const String& p_file) {
virtual uint64_t _get_modified_time(const String &p_file) {
return f._get_modified_time(p_file);
}
FileAccessBufferedFA() {
FileAccessBufferedFA(){
};
};
#endif // FILE_ACCESS_BUFFERED_FA_H

View File

@ -28,244 +28,223 @@
/*************************************************************************/
#include "file_access_compressed.h"
#include "print_string.h"
void FileAccessCompressed::configure(const String& p_magic, Compression::Mode p_mode, int p_block_size) {
void FileAccessCompressed::configure(const String &p_magic, Compression::Mode p_mode, int p_block_size) {
magic=p_magic.ascii().get_data();
if (magic.length()>4)
magic=magic.substr(0,4);
magic = p_magic.ascii().get_data();
if (magic.length() > 4)
magic = magic.substr(0, 4);
else {
while(magic.length()<4)
magic+=" ";
while (magic.length() < 4)
magic += " ";
}
cmode=p_mode;
block_size=p_block_size;
}
#define WRITE_FIT(m_bytes) \
{\
if (write_pos+(m_bytes) > write_max) {\
write_max=write_pos+(m_bytes);\
}\
if (write_max > write_buffer_size) {\
write_buffer_size = nearest_power_of_2( write_max );\
buffer.resize(write_buffer_size);\
write_ptr=buffer.ptr();\
}\
cmode = p_mode;
block_size = p_block_size;
}
#define WRITE_FIT(m_bytes) \
{ \
if (write_pos + (m_bytes) > write_max) { \
write_max = write_pos + (m_bytes); \
} \
if (write_max > write_buffer_size) { \
write_buffer_size = nearest_power_of_2(write_max); \
buffer.resize(write_buffer_size); \
write_ptr = buffer.ptr(); \
} \
}
Error FileAccessCompressed::open_after_magic(FileAccess *p_base) {
f=p_base;
cmode=(Compression::Mode)f->get_32();
block_size=f->get_32();
read_total=f->get_32();
int bc = (read_total/block_size)+1;
int acc_ofs=f->get_pos()+bc*4;
int max_bs=0;
for(int i=0;i<bc;i++) {
f = p_base;
cmode = (Compression::Mode)f->get_32();
block_size = f->get_32();
read_total = f->get_32();
int bc = (read_total / block_size) + 1;
int acc_ofs = f->get_pos() + bc * 4;
int max_bs = 0;
for (int i = 0; i < bc; i++) {
ReadBlock rb;
rb.offset=acc_ofs;
rb.csize=f->get_32();
acc_ofs+=rb.csize;
max_bs=MAX(max_bs,rb.csize);
rb.offset = acc_ofs;
rb.csize = f->get_32();
acc_ofs += rb.csize;
max_bs = MAX(max_bs, rb.csize);
read_blocks.push_back(rb);
}
comp_buffer.resize(max_bs);
buffer.resize(block_size);
read_ptr=buffer.ptr();
f->get_buffer(comp_buffer.ptr(),read_blocks[0].csize);
at_end=false;
read_eof=false;
read_block_count=bc;
read_block_size=read_blocks.size()==1?read_total:block_size;
read_ptr = buffer.ptr();
f->get_buffer(comp_buffer.ptr(), read_blocks[0].csize);
at_end = false;
read_eof = false;
read_block_count = bc;
read_block_size = read_blocks.size() == 1 ? read_total : block_size;
Compression::decompress(buffer.ptr(),read_block_size,comp_buffer.ptr(),read_blocks[0].csize,cmode);
read_block=0;
read_pos=0;
Compression::decompress(buffer.ptr(), read_block_size, comp_buffer.ptr(), read_blocks[0].csize, cmode);
read_block = 0;
read_pos = 0;
return OK;
}
Error FileAccessCompressed::_open(const String& p_path, int p_mode_flags){
Error FileAccessCompressed::_open(const String &p_path, int p_mode_flags) {
ERR_FAIL_COND_V(p_mode_flags==READ_WRITE,ERR_UNAVAILABLE);
ERR_FAIL_COND_V(p_mode_flags == READ_WRITE, ERR_UNAVAILABLE);
if (f)
close();
Error err;
f = FileAccess::open(p_path,p_mode_flags,&err);
if (err!=OK) {
f = FileAccess::open(p_path, p_mode_flags, &err);
if (err != OK) {
//not openable
f=NULL;
f = NULL;
return err;
}
if (p_mode_flags&WRITE) {
if (p_mode_flags & WRITE) {
buffer.clear();
writing=true;
write_pos=0;
write_buffer_size=256;
writing = true;
write_pos = 0;
write_buffer_size = 256;
buffer.resize(256);
write_max=0;
write_ptr=buffer.ptr();
write_max = 0;
write_ptr = buffer.ptr();
//don't store anything else unless it's done saving!
} else {
char rmagic[5];
f->get_buffer((uint8_t*)rmagic,4);
rmagic[4]=0;
if (magic!=rmagic) {
f->get_buffer((uint8_t *)rmagic, 4);
rmagic[4] = 0;
if (magic != rmagic) {
memdelete(f);
f=NULL;
f = NULL;
return ERR_FILE_UNRECOGNIZED;
}
open_after_magic(f);
}
return OK;
}
void FileAccessCompressed::close(){
void FileAccessCompressed::close() {
if (!f)
return;
if (writing) {
//save block table and all compressed blocks
CharString mgc = magic.utf8();
f->store_buffer((const uint8_t*)mgc.get_data(),mgc.length()); //write header 4
f->store_buffer((const uint8_t *)mgc.get_data(), mgc.length()); //write header 4
f->store_32(cmode); //write compression mode 4
f->store_32(block_size); //write block size 4
f->store_32(write_max); //max amount of data written 4
int bc=(write_max/block_size)+1;
int bc = (write_max / block_size) + 1;
for(int i=0;i<bc;i++) {
for (int i = 0; i < bc; i++) {
f->store_32(0); //compressed sizes, will update later
}
Vector<int> block_sizes;
for(int i=0;i<bc;i++) {
for (int i = 0; i < bc; i++) {
int bl = i==(bc-1) ? write_max % block_size : block_size;
uint8_t *bp = &write_ptr[i*block_size];
int bl = i == (bc - 1) ? write_max % block_size : block_size;
uint8_t *bp = &write_ptr[i * block_size];
Vector<uint8_t> cblock;
cblock.resize(Compression::get_max_compressed_buffer_size(bl,cmode));
int s = Compression::compress(cblock.ptr(),bp,bl,cmode);
cblock.resize(Compression::get_max_compressed_buffer_size(bl, cmode));
int s = Compression::compress(cblock.ptr(), bp, bl, cmode);
f->store_buffer(cblock.ptr(),s);
f->store_buffer(cblock.ptr(), s);
block_sizes.push_back(s);
}
f->seek(16); //ok write block sizes
for(int i=0;i<bc;i++)
for (int i = 0; i < bc; i++)
f->store_32(block_sizes[i]);
f->seek_end();
f->store_buffer((const uint8_t*)mgc.get_data(),mgc.length()); //magic at the end too
f->store_buffer((const uint8_t *)mgc.get_data(), mgc.length()); //magic at the end too
buffer.clear();
} else {
comp_buffer.clear();
buffer.clear();
read_blocks.clear();
}
memdelete(f);
f=NULL;
f = NULL;
}
bool FileAccessCompressed::is_open() const{
bool FileAccessCompressed::is_open() const {
return f!=NULL;
return f != NULL;
}
void FileAccessCompressed::seek(size_t p_position){
void FileAccessCompressed::seek(size_t p_position) {
ERR_FAIL_COND(!f);
if (writing) {
ERR_FAIL_COND(p_position>write_max);
ERR_FAIL_COND(p_position > write_max);
write_pos=p_position;
write_pos = p_position;
} else {
ERR_FAIL_COND(p_position>read_total);
if (p_position==read_total) {
at_end=true;
ERR_FAIL_COND(p_position > read_total);
if (p_position == read_total) {
at_end = true;
} else {
int block_idx = p_position/block_size;
if (block_idx!=read_block) {
int block_idx = p_position / block_size;
if (block_idx != read_block) {
read_block=block_idx;
read_block = block_idx;
f->seek(read_blocks[read_block].offset);
f->get_buffer(comp_buffer.ptr(),read_blocks[read_block].csize);
Compression::decompress(buffer.ptr(),read_blocks.size()==1?read_total:block_size,comp_buffer.ptr(),read_blocks[read_block].csize,cmode);
read_block_size=read_block==read_block_count-1?read_total%block_size:block_size;
f->get_buffer(comp_buffer.ptr(), read_blocks[read_block].csize);
Compression::decompress(buffer.ptr(), read_blocks.size() == 1 ? read_total : block_size, comp_buffer.ptr(), read_blocks[read_block].csize, cmode);
read_block_size = read_block == read_block_count - 1 ? read_total % block_size : block_size;
}
read_pos=p_position%block_size;
read_pos = p_position % block_size;
}
}
}
void FileAccessCompressed::seek_end(int64_t p_position){
void FileAccessCompressed::seek_end(int64_t p_position) {
ERR_FAIL_COND(!f);
if (writing) {
seek(write_max+p_position);
seek(write_max + p_position);
} else {
seek(read_total+p_position);
seek(read_total + p_position);
}
}
size_t FileAccessCompressed::get_pos() const{
size_t FileAccessCompressed::get_pos() const {
ERR_FAIL_COND_V(!f,0);
ERR_FAIL_COND_V(!f, 0);
if (writing) {
return write_pos;
} else {
return read_block*block_size+read_pos;
return read_block * block_size + read_pos;
}
}
size_t FileAccessCompressed::get_len() const{
size_t FileAccessCompressed::get_len() const {
ERR_FAIL_COND_V(!f,0);
ERR_FAIL_COND_V(!f, 0);
if (writing) {
return write_max;
@ -274,9 +253,9 @@ size_t FileAccessCompressed::get_len() const{
}
}
bool FileAccessCompressed::eof_reached() const{
bool FileAccessCompressed::eof_reached() const {
ERR_FAIL_COND_V(!f,false);
ERR_FAIL_COND_V(!f, false);
if (writing) {
return false;
} else {
@ -284,106 +263,99 @@ bool FileAccessCompressed::eof_reached() const{
}
}
uint8_t FileAccessCompressed::get_8() const{
uint8_t FileAccessCompressed::get_8() const {
ERR_FAIL_COND_V(writing,0);
ERR_FAIL_COND_V(!f,0);
ERR_FAIL_COND_V(writing, 0);
ERR_FAIL_COND_V(!f, 0);
if (at_end) {
read_eof=true;
read_eof = true;
return 0;
}
uint8_t ret = read_ptr[read_pos];
read_pos++;
if (read_pos>=read_block_size) {
if (read_pos >= read_block_size) {
read_block++;
if (read_block<read_block_count) {
if (read_block < read_block_count) {
//read another block of compressed data
f->get_buffer(comp_buffer.ptr(),read_blocks[read_block].csize);
Compression::decompress(buffer.ptr(),read_blocks.size()==1?read_total:block_size,comp_buffer.ptr(),read_blocks[read_block].csize,cmode);
read_block_size=read_block==read_block_count-1?read_total%block_size:block_size;
read_pos=0;
f->get_buffer(comp_buffer.ptr(), read_blocks[read_block].csize);
Compression::decompress(buffer.ptr(), read_blocks.size() == 1 ? read_total : block_size, comp_buffer.ptr(), read_blocks[read_block].csize, cmode);
read_block_size = read_block == read_block_count - 1 ? read_total % block_size : block_size;
read_pos = 0;
} else {
read_block--;
at_end=true;
ret =0;
at_end = true;
ret = 0;
}
}
return ret;
}
int FileAccessCompressed::get_buffer(uint8_t *p_dst, int p_length) const{
int FileAccessCompressed::get_buffer(uint8_t *p_dst, int p_length) const {
ERR_FAIL_COND_V(writing,0);
ERR_FAIL_COND_V(!f,0);
ERR_FAIL_COND_V(writing, 0);
ERR_FAIL_COND_V(!f, 0);
if (at_end) {
read_eof=true;
read_eof = true;
return 0;
}
for (int i = 0; i < p_length; i++) {
for(int i=0;i<p_length;i++) {
p_dst[i]=read_ptr[read_pos];
p_dst[i] = read_ptr[read_pos];
read_pos++;
if (read_pos>=read_block_size) {
if (read_pos >= read_block_size) {
read_block++;
if (read_block<read_block_count) {
if (read_block < read_block_count) {
//read another block of compressed data
f->get_buffer(comp_buffer.ptr(),read_blocks[read_block].csize);
Compression::decompress(buffer.ptr(),read_blocks.size()==1?read_total:block_size,comp_buffer.ptr(),read_blocks[read_block].csize,cmode);
read_block_size=read_block==read_block_count-1?read_total%block_size:block_size;
read_pos=0;
f->get_buffer(comp_buffer.ptr(), read_blocks[read_block].csize);
Compression::decompress(buffer.ptr(), read_blocks.size() == 1 ? read_total : block_size, comp_buffer.ptr(), read_blocks[read_block].csize, cmode);
read_block_size = read_block == read_block_count - 1 ? read_total % block_size : block_size;
read_pos = 0;
} else {
read_block--;
at_end=true;
if (i<p_length-1)
read_eof=true;
at_end = true;
if (i < p_length - 1)
read_eof = true;
return i;
}
}
}
return p_length;
}
Error FileAccessCompressed::get_error() const{
Error FileAccessCompressed::get_error() const {
return read_eof?ERR_FILE_EOF:OK;
return read_eof ? ERR_FILE_EOF : OK;
}
void FileAccessCompressed::store_8(uint8_t p_dest){
void FileAccessCompressed::store_8(uint8_t p_dest) {
ERR_FAIL_COND(!f);
ERR_FAIL_COND(!writing);
WRITE_FIT(1);
write_ptr[write_pos++]=p_dest;
write_ptr[write_pos++] = p_dest;
}
bool FileAccessCompressed::file_exists(const String& p_name){
bool FileAccessCompressed::file_exists(const String &p_name) {
FileAccess *fa = FileAccess::open(p_name,FileAccess::READ);
FileAccess *fa = FileAccess::open(p_name, FileAccess::READ);
if (!fa)
return false;
memdelete(fa);
return true;
}
uint64_t FileAccessCompressed::_get_modified_time(const String& p_file) {
uint64_t FileAccessCompressed::_get_modified_time(const String &p_file) {
if (f)
return f->get_modified_time(p_file);
@ -393,29 +365,27 @@ uint64_t FileAccessCompressed::_get_modified_time(const String& p_file) {
FileAccessCompressed::FileAccessCompressed() {
f=NULL;
magic="GCMP";
block_size=16384;
cmode=Compression::MODE_DEFLATE;
writing=false;
write_ptr=0;
write_buffer_size=0;
write_max=0;
block_size=0;
read_eof=false;
at_end=false;
read_total=0;
read_ptr=NULL;
read_block=0;
read_block_count=0;
read_block_size=0;
read_pos=0;
f = NULL;
magic = "GCMP";
block_size = 16384;
cmode = Compression::MODE_DEFLATE;
writing = false;
write_ptr = 0;
write_buffer_size = 0;
write_max = 0;
block_size = 0;
read_eof = false;
at_end = false;
read_total = 0;
read_ptr = NULL;
read_block = 0;
read_block_count = 0;
read_block_size = 0;
read_pos = 0;
}
FileAccessCompressed::~FileAccessCompressed(){
FileAccessCompressed::~FileAccessCompressed() {
if (f)
close();
}

View File

@ -37,7 +37,7 @@ class FileAccessCompressed : public FileAccess {
Compression::Mode cmode;
bool writing;
int write_pos;
uint8_t*write_ptr;
uint8_t *write_ptr;
int write_buffer_size;
int write_max;
int block_size;
@ -58,24 +58,21 @@ class FileAccessCompressed : public FileAccess {
Vector<ReadBlock> read_blocks;
int read_total;
String magic;
mutable Vector<uint8_t> buffer;
FileAccess *f;
public:
void configure(const String& p_magic, Compression::Mode p_mode=Compression::MODE_FASTLZ, int p_block_size=4096);
public:
void configure(const String &p_magic, Compression::Mode p_mode = Compression::MODE_FASTLZ, int p_block_size = 4096);
Error open_after_magic(FileAccess *p_base);
virtual Error _open(const String& p_path, int p_mode_flags); ///< open a file
virtual Error _open(const String &p_path, int p_mode_flags); ///< open a file
virtual void close(); ///< close a file
virtual bool is_open() const; ///< true when file is open
virtual void seek(size_t p_position); ///< seek to a given position
virtual void seek_end(int64_t p_position=0); ///< seek from the end of file
virtual void seek_end(int64_t p_position = 0); ///< seek from the end of file
virtual size_t get_pos() const; ///< get position in the file
virtual size_t get_len() const; ///< get size of the file
@ -88,14 +85,12 @@ public:
virtual void store_8(uint8_t p_dest); ///< store a byte
virtual bool file_exists(const String& p_name); ///< return true if a file exists
virtual uint64_t _get_modified_time(const String& p_file);
virtual bool file_exists(const String &p_name); ///< return true if a file exists
virtual uint64_t _get_modified_time(const String &p_file);
FileAccessCompressed();
virtual ~FileAccessCompressed();
};
#endif // FILE_ACCESS_COMPRESSED_H

View File

@ -36,55 +36,55 @@
#include "core/variant.h"
#include <stdio.h>
Error FileAccessEncrypted::open_and_parse(FileAccess *p_base,const Vector<uint8_t>& p_key,Mode p_mode) {
Error FileAccessEncrypted::open_and_parse(FileAccess *p_base, const Vector<uint8_t> &p_key, Mode p_mode) {
//print_line("open and parse!");
ERR_FAIL_COND_V(file!=NULL,ERR_ALREADY_IN_USE);
ERR_FAIL_COND_V(p_key.size()!=32,ERR_INVALID_PARAMETER);
ERR_FAIL_COND_V(file != NULL, ERR_ALREADY_IN_USE);
ERR_FAIL_COND_V(p_key.size() != 32, ERR_INVALID_PARAMETER);
pos=0;
eofed=false;
pos = 0;
eofed = false;
if (p_mode==MODE_WRITE_AES256) {
if (p_mode == MODE_WRITE_AES256) {
data.clear();
writing=true;
file=p_base;
mode=p_mode;
key=p_key;
writing = true;
file = p_base;
mode = p_mode;
key = p_key;
} else if (p_mode==MODE_READ) {
} else if (p_mode == MODE_READ) {
writing=false;
key=p_key;
writing = false;
key = p_key;
uint32_t magic = p_base->get_32();
print_line("MAGIC: "+itos(magic));
ERR_FAIL_COND_V(magic!=COMP_MAGIC,ERR_FILE_UNRECOGNIZED);
mode=Mode(p_base->get_32());
ERR_FAIL_INDEX_V(mode,MODE_MAX,ERR_FILE_CORRUPT);
ERR_FAIL_COND_V(mode==0,ERR_FILE_CORRUPT);
print_line("MODE: "+itos(mode));
print_line("MAGIC: " + itos(magic));
ERR_FAIL_COND_V(magic != COMP_MAGIC, ERR_FILE_UNRECOGNIZED);
mode = Mode(p_base->get_32());
ERR_FAIL_INDEX_V(mode, MODE_MAX, ERR_FILE_CORRUPT);
ERR_FAIL_COND_V(mode == 0, ERR_FILE_CORRUPT);
print_line("MODE: " + itos(mode));
unsigned char md5d[16];
p_base->get_buffer(md5d,16);
length=p_base->get_64();
base=p_base->get_pos();
ERR_FAIL_COND_V(p_base->get_len() < base+length, ERR_FILE_CORRUPT );
p_base->get_buffer(md5d, 16);
length = p_base->get_64();
base = p_base->get_pos();
ERR_FAIL_COND_V(p_base->get_len() < base + length, ERR_FILE_CORRUPT);
int ds = length;
if (ds % 16) {
ds+=16-(ds % 16);
ds += 16 - (ds % 16);
}
data.resize(ds);
int blen = p_base->get_buffer(data.ptr(),ds);
ERR_FAIL_COND_V(blen!=ds,ERR_FILE_CORRUPT);
int blen = p_base->get_buffer(data.ptr(), ds);
ERR_FAIL_COND_V(blen != ds, ERR_FILE_CORRUPT);
aes256_context ctx;
aes256_init(&ctx,key.ptr());
aes256_init(&ctx, key.ptr());
for(size_t i=0;i<ds;i+=16) {
for (size_t i = 0; i < ds; i += 16) {
aes256_decrypt_ecb(&ctx,&data[i]);
aes256_decrypt_ecb(&ctx, &data[i]);
}
aes256_done(&ctx);
@ -93,37 +93,32 @@ Error FileAccessEncrypted::open_and_parse(FileAccess *p_base,const Vector<uint8_
MD5_CTX md5;
MD5Init(&md5);
MD5Update(&md5,data.ptr(),data.size());
MD5Update(&md5, data.ptr(), data.size());
MD5Final(&md5);
ERR_FAIL_COND_V(String::md5(md5.digest) != String::md5(md5d), ERR_FILE_CORRUPT);
ERR_FAIL_COND_V(String::md5(md5.digest)!=String::md5(md5d),ERR_FILE_CORRUPT) ;
file=p_base;
file = p_base;
}
return OK;
}
Error FileAccessEncrypted::open_and_parse_password(FileAccess *p_base,const String& p_key,Mode p_mode){
Error FileAccessEncrypted::open_and_parse_password(FileAccess *p_base, const String &p_key, Mode p_mode) {
String cs = p_key.md5_text();
ERR_FAIL_COND_V(cs.length()!=32,ERR_INVALID_PARAMETER);
ERR_FAIL_COND_V(cs.length() != 32, ERR_INVALID_PARAMETER);
Vector<uint8_t> key;
key.resize(32);
for(int i=0;i<32;i++) {
for (int i = 0; i < 32; i++) {
key[i]=cs[i];
key[i] = cs[i];
}
return open_and_parse(p_base,key,p_mode);
return open_and_parse(p_base, key, p_mode);
}
Error FileAccessEncrypted::_open(const String& p_path, int p_mode_flags) {
Error FileAccessEncrypted::_open(const String &p_path, int p_mode_flags) {
return OK;
}
@ -137,26 +132,26 @@ void FileAccessEncrypted::close() {
Vector<uint8_t> compressed;
size_t len = data.size();
if (len % 16) {
len+=16-(len % 16);
len += 16 - (len % 16);
}
MD5_CTX md5;
MD5Init(&md5);
MD5Update(&md5,data.ptr(),data.size());
MD5Update(&md5, data.ptr(), data.size());
MD5Final(&md5);
compressed.resize(len);
zeromem( compressed.ptr(), len );
for(int i=0;i<data.size();i++) {
compressed[i]=data[i];
zeromem(compressed.ptr(), len);
for (int i = 0; i < data.size(); i++) {
compressed[i] = data[i];
}
aes256_context ctx;
aes256_init(&ctx,key.ptr());
aes256_init(&ctx, key.ptr());
for(size_t i=0;i<len;i+=16) {
for (size_t i = 0; i < len; i += 16) {
aes256_encrypt_ecb(&ctx,&compressed[i]);
aes256_encrypt_ecb(&ctx, &compressed[i]);
}
aes256_done(&ctx);
@ -164,14 +159,13 @@ void FileAccessEncrypted::close() {
file->store_32(COMP_MAGIC);
file->store_32(mode);
file->store_buffer(md5.digest,16);
file->store_buffer(md5.digest, 16);
file->store_64(data.size());
file->store_buffer(compressed.ptr(),compressed.size());
file->store_buffer(compressed.ptr(), compressed.size());
file->close();
memdelete(file);
file=NULL;
file = NULL;
data.clear();
} else {
@ -179,143 +173,133 @@ void FileAccessEncrypted::close() {
file->close();
memdelete(file);
data.clear();
file=NULL;
file = NULL;
}
}
bool FileAccessEncrypted::is_open() const{
bool FileAccessEncrypted::is_open() const {
return file!=NULL;
return file != NULL;
}
void FileAccessEncrypted::seek(size_t p_position){
void FileAccessEncrypted::seek(size_t p_position) {
if (p_position > (size_t)data.size())
p_position=data.size();
pos=p_position;
eofed=false;
p_position = data.size();
pos = p_position;
eofed = false;
}
void FileAccessEncrypted::seek_end(int64_t p_position) {
void FileAccessEncrypted::seek_end(int64_t p_position){
seek( data.size() + p_position );
seek(data.size() + p_position);
}
size_t FileAccessEncrypted::get_pos() const{
size_t FileAccessEncrypted::get_pos() const {
return pos;
}
size_t FileAccessEncrypted::get_len() const{
size_t FileAccessEncrypted::get_len() const {
return data.size();
}
bool FileAccessEncrypted::eof_reached() const{
bool FileAccessEncrypted::eof_reached() const {
return eofed;
}
uint8_t FileAccessEncrypted::get_8() const{
uint8_t FileAccessEncrypted::get_8() const {
ERR_FAIL_COND_V(writing,0);
if (pos>=data.size()) {
eofed=true;
ERR_FAIL_COND_V(writing, 0);
if (pos >= data.size()) {
eofed = true;
return 0;
}
uint8_t b = data[pos];
pos++;
return b;
}
int FileAccessEncrypted::get_buffer(uint8_t *p_dst, int p_length) const{
int FileAccessEncrypted::get_buffer(uint8_t *p_dst, int p_length) const {
ERR_FAIL_COND_V(writing,0);
ERR_FAIL_COND_V(writing, 0);
int to_copy=MIN(p_length,data.size()-pos);
for(int i=0;i<to_copy;i++) {
int to_copy = MIN(p_length, data.size() - pos);
for (int i = 0; i < to_copy; i++) {
p_dst[i]=data[pos++];
p_dst[i] = data[pos++];
}
if (to_copy<p_length) {
eofed=true;
if (to_copy < p_length) {
eofed = true;
}
return to_copy;
}
Error FileAccessEncrypted::get_error() const{
Error FileAccessEncrypted::get_error() const {
return eofed?ERR_FILE_EOF:OK;
return eofed ? ERR_FILE_EOF : OK;
}
void FileAccessEncrypted::store_buffer(const uint8_t *p_src,int p_length) {
void FileAccessEncrypted::store_buffer(const uint8_t *p_src, int p_length) {
ERR_FAIL_COND(!writing);
if (pos<data.size()) {
if (pos < data.size()) {
for(int i=0;i<p_length;i++) {
for (int i = 0; i < p_length; i++) {
store_8(p_src[i]);
}
} else if (pos==data.size()) {
} else if (pos == data.size()) {
data.resize(pos+p_length);
for(int i=0;i<p_length;i++) {
data.resize(pos + p_length);
for (int i = 0; i < p_length; i++) {
data[pos+i]=p_src[i];
data[pos + i] = p_src[i];
}
pos+=p_length;
pos += p_length;
}
}
void FileAccessEncrypted::store_8(uint8_t p_dest){
void FileAccessEncrypted::store_8(uint8_t p_dest) {
ERR_FAIL_COND(!writing);
if (pos<data.size()) {
data[pos]=p_dest;
if (pos < data.size()) {
data[pos] = p_dest;
pos++;
} else if (pos==data.size()){
} else if (pos == data.size()) {
data.push_back(p_dest);
pos++;
}
}
bool FileAccessEncrypted::file_exists(const String& p_name){
bool FileAccessEncrypted::file_exists(const String &p_name) {
FileAccess *fa = FileAccess::open(p_name,FileAccess::READ);
FileAccess *fa = FileAccess::open(p_name, FileAccess::READ);
if (!fa)
return false;
memdelete(fa);
return true;
}
uint64_t FileAccessEncrypted::_get_modified_time(const String& p_file){
uint64_t FileAccessEncrypted::_get_modified_time(const String &p_file) {
return 0;
}
FileAccessEncrypted::FileAccessEncrypted() {
file=NULL;
pos=0;
eofed=false;
mode=MODE_MAX;
writing=false;
file = NULL;
pos = 0;
eofed = false;
mode = MODE_MAX;
writing = false;
}
FileAccessEncrypted::~FileAccessEncrypted() {
if (file)

View File

@ -29,12 +29,10 @@
#ifndef FILE_ACCESS_ENCRYPTED_H
#define FILE_ACCESS_ENCRYPTED_H
#include "os/file_access.h"
class FileAccessEncrypted : public FileAccess {
public:
enum Mode {
MODE_READ,
MODE_WRITE_AES256,
@ -42,8 +40,6 @@ public:
};
private:
Mode mode;
Vector<uint8_t> key;
bool writing;
@ -54,21 +50,16 @@ private:
mutable size_t pos;
mutable bool eofed;
public:
Error open_and_parse(FileAccess *p_base, const Vector<uint8_t> &p_key, Mode p_mode);
Error open_and_parse_password(FileAccess *p_base, const String &p_key, Mode p_mode);
Error open_and_parse(FileAccess *p_base,const Vector<uint8_t>& p_key,Mode p_mode);
Error open_and_parse_password(FileAccess *p_base,const String& p_key,Mode p_mode);
virtual Error _open(const String& p_path, int p_mode_flags); ///< open a file
virtual Error _open(const String &p_path, int p_mode_flags); ///< open a file
virtual void close(); ///< close a file
virtual bool is_open() const; ///< true when file is open
virtual void seek(size_t p_position); ///< seek to a given position
virtual void seek_end(int64_t p_position=0); ///< seek from the end of file
virtual void seek_end(int64_t p_position = 0); ///< seek from the end of file
virtual size_t get_pos() const; ///< get position in the file
virtual size_t get_len() const; ///< get size of the file
@ -80,11 +71,11 @@ public:
virtual Error get_error() const; ///< get last error
virtual void store_8(uint8_t p_dest); ///< store a byte
virtual void store_buffer(const uint8_t *p_src,int p_length); ///< store an array of bytes
virtual void store_buffer(const uint8_t *p_src, int p_length); ///< store an array of bytes
virtual bool file_exists(const String& p_name); ///< return true if a file exists
virtual bool file_exists(const String &p_name); ///< return true if a file exists
virtual uint64_t _get_modified_time(const String& p_file);
virtual uint64_t _get_modified_time(const String &p_file);
FileAccessEncrypted();
~FileAccessEncrypted();

View File

@ -28,12 +28,12 @@
/*************************************************************************/
#include "file_access_memory.h"
#include "os/dir_access.h"
#include "os/copymem.h"
#include "globals.h"
#include "map.h"
#include "os/copymem.h"
#include "os/dir_access.h"
static Map<String, Vector<uint8_t> >* files = NULL;
static Map<String, Vector<uint8_t> > *files = NULL;
void FileAccessMemory::register_file(String p_name, Vector<uint8_t> p_data) {
@ -59,37 +59,35 @@ void FileAccessMemory::cleanup() {
memdelete(files);
}
FileAccess* FileAccessMemory::create() {
FileAccess *FileAccessMemory::create() {
return memnew(FileAccessMemory);
}
bool FileAccessMemory::file_exists(const String& p_name) {
bool FileAccessMemory::file_exists(const String &p_name) {
String name = fix_path(p_name);
// name = DirAccess::normalize_path(name);
// name = DirAccess::normalize_path(name);
return files && (files->find(name) != NULL);
}
Error FileAccessMemory::open_custom(const uint8_t *p_data, int p_len) {
Error FileAccessMemory::open_custom(const uint8_t* p_data, int p_len) {
data=(uint8_t*)p_data;
length=p_len;
pos=0;
data = (uint8_t *)p_data;
length = p_len;
pos = 0;
return OK;
}
Error FileAccessMemory::_open(const String& p_path, int p_mode_flags) {
Error FileAccessMemory::_open(const String &p_path, int p_mode_flags) {
ERR_FAIL_COND_V(!files, ERR_FILE_NOT_FOUND);
String name = fix_path(p_path);
// name = DirAccess::normalize_path(name);
// name = DirAccess::normalize_path(name);
Map<String, Vector<uint8_t> >::Element* E = files->find(name);
Map<String, Vector<uint8_t> >::Element *E = files->find(name);
ERR_FAIL_COND_V(!E, ERR_FILE_NOT_FOUND);
data = &(E->get()[0]);
@ -149,7 +147,7 @@ uint8_t FileAccessMemory::get_8() const {
return ret;
}
int FileAccessMemory::get_buffer(uint8_t *p_dst,int p_length) const {
int FileAccessMemory::get_buffer(uint8_t *p_dst, int p_length) const {
ERR_FAIL_COND_V(!data, -1);
@ -178,7 +176,7 @@ void FileAccessMemory::store_8(uint8_t p_byte) {
data[pos++] = p_byte;
}
void FileAccessMemory::store_buffer(const uint8_t *p_src,int p_length) {
void FileAccessMemory::store_buffer(const uint8_t *p_src, int p_length) {
int left = length - pos;
int write = MIN(p_length, left);

View File

@ -33,19 +33,18 @@
class FileAccessMemory : public FileAccess {
uint8_t* data;
uint8_t *data;
int length;
mutable int pos;
static FileAccess* create();
static FileAccess *create();
public:
static void register_file(String p_name, Vector<uint8_t> p_data);
static void cleanup();
virtual Error open_custom(const uint8_t* p_data, int p_len); ///< open a file
virtual Error _open(const String& p_path, int p_mode_flags); ///< open a file
virtual Error open_custom(const uint8_t *p_data, int p_len); ///< open a file
virtual Error _open(const String &p_path, int p_mode_flags); ///< open a file
virtual void close(); ///< close a file
virtual bool is_open() const; ///< true when file is open
@ -58,18 +57,16 @@ public:
virtual uint8_t get_8() const; ///< get a byte
virtual int get_buffer(uint8_t *p_dst,int p_length) const; ///< get an array of bytes
virtual int get_buffer(uint8_t *p_dst, int p_length) const; ///< get an array of bytes
virtual Error get_error() const; ///< get last error
virtual void store_8(uint8_t p_dest); ///< store a byte
virtual void store_buffer(const uint8_t *p_src,int p_length); ///< store an array of bytes
virtual bool file_exists(const String& p_name); ///< return true if a file exists
virtual uint64_t _get_modified_time(const String& p_file) { return 0; }
virtual void store_buffer(const uint8_t *p_src, int p_length); ///< store an array of bytes
virtual bool file_exists(const String &p_name); ///< return true if a file exists
virtual uint64_t _get_modified_time(const String &p_file) { return 0; }
FileAccessMemory();
};

View File

@ -27,19 +27,16 @@
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
/*************************************************************************/
#include "file_access_network.h"
#include "marshalls.h"
#include "globals.h"
#include "os/os.h"
#include "io/ip.h"
#include "marshalls.h"
#include "os/os.h"
//#define DEBUG_PRINT(m_p) print_line(m_p)
//#define DEBUG_TIME(m_what) printf("MS: %s - %lli\n",m_what,OS::get_singleton()->get_ticks_usec());
#define DEBUG_PRINT(m_p)
#define DEBUG_TIME(m_what)
void FileAccessNetworkClient::lock_mutex() {
mutex->lock();
@ -50,59 +47,55 @@ void FileAccessNetworkClient::unlock_mutex() {
lockcount--;
mutex->unlock();
}
void FileAccessNetworkClient::put_32(int p_32) {
uint8_t buf[4];
encode_uint32(p_32,buf);
client->put_data(buf,4);
DEBUG_PRINT("put32: "+itos(p_32));
encode_uint32(p_32, buf);
client->put_data(buf, 4);
DEBUG_PRINT("put32: " + itos(p_32));
}
void FileAccessNetworkClient::put_64(int64_t p_64) {
uint8_t buf[8];
encode_uint64(p_64,buf);
client->put_data(buf,8);
DEBUG_PRINT("put64: "+itos(p_64));
encode_uint64(p_64, buf);
client->put_data(buf, 8);
DEBUG_PRINT("put64: " + itos(p_64));
}
int FileAccessNetworkClient::get_32() {
uint8_t buf[4];
client->get_data(buf,4);
client->get_data(buf, 4);
return decode_uint32(buf);
}
int64_t FileAccessNetworkClient::get_64() {
uint8_t buf[8];
client->get_data(buf,8);
client->get_data(buf, 8);
return decode_uint64(buf);
}
void FileAccessNetworkClient::_thread_func() {
client->set_nodelay(true);
while(!quit) {
while (!quit) {
DEBUG_PRINT("SEM WAIT - "+itos(sem->get()));
DEBUG_PRINT("SEM WAIT - " + itos(sem->get()));
Error err = sem->wait();
DEBUG_TIME("sem_unlock");
//DEBUG_PRINT("semwait returned "+itos(werr));
DEBUG_PRINT("MUTEX LOCK "+itos(lockcount));
DEBUG_PRINT("MUTEX LOCK " + itos(lockcount));
DEBUG_PRINT("POPO");
DEBUG_PRINT("PEPE");
lock_mutex();
DEBUG_PRINT("MUTEX PASS");
blockrequest_mutex->lock();
while(block_requests.size()) {
while (block_requests.size()) {
put_32(block_requests.front()->get().id);
put_32(FileAccessNetwork::COMMAND_READ_BLOCK);
put_64(block_requests.front()->get().offset);
@ -117,35 +110,32 @@ void FileAccessNetworkClient::_thread_func() {
int id = get_32();
int response = get_32();
DEBUG_PRINT("GET RESPONSE: "+itos(response));
DEBUG_PRINT("GET RESPONSE: " + itos(response));
FileAccessNetwork *fa=NULL;
FileAccessNetwork *fa = NULL;
if (response!=FileAccessNetwork::RESPONSE_DATA) {
if (response != FileAccessNetwork::RESPONSE_DATA) {
ERR_FAIL_COND(!accesses.has(id));
}
if (accesses.has(id))
fa=accesses[id];
fa = accesses[id];
switch(response) {
switch (response) {
case FileAccessNetwork::RESPONSE_OPEN: {
DEBUG_TIME("sem_open");
int status = get_32();
if (status!=OK) {
fa->_respond(0,Error(status));
if (status != OK) {
fa->_respond(0, Error(status));
} else {
uint64_t len = get_64();
fa->_respond(len,Error(status));
fa->_respond(len, Error(status));
}
fa->sem->post();
} break;
case FileAccessNetwork::RESPONSE_DATA: {
@ -154,104 +144,95 @@ void FileAccessNetworkClient::_thread_func() {
Vector<uint8_t> block;
block.resize(len);
client->get_data(block.ptr(),len);
client->get_data(block.ptr(), len);
if (fa) //may have been queued
fa->_set_block(offset,block);
fa->_set_block(offset, block);
} break;
case FileAccessNetwork::RESPONSE_FILE_EXISTS: {
int status = get_32();
fa->exists_modtime=status!=0;
fa->exists_modtime = status != 0;
fa->sem->post();
} break;
case FileAccessNetwork::RESPONSE_GET_MODTIME: {
uint64_t status = get_64();
fa->exists_modtime=status;
fa->exists_modtime = status;
fa->sem->post();
} break;
}
unlock_mutex();
}
}
void FileAccessNetworkClient::_thread_func(void *s) {
FileAccessNetworkClient *self =(FileAccessNetworkClient*)s;
FileAccessNetworkClient *self = (FileAccessNetworkClient *)s;
self->_thread_func();
}
Error FileAccessNetworkClient::connect(const String& p_host,int p_port,const String& p_password) {
Error FileAccessNetworkClient::connect(const String &p_host, int p_port, const String &p_password) {
IP_Address ip;
if (p_host.is_valid_ip_address()) {
ip=p_host;
ip = p_host;
} else {
ip=IP::get_singleton()->resolve_hostname(p_host);
ip = IP::get_singleton()->resolve_hostname(p_host);
}
DEBUG_PRINT("IP: "+String(ip)+" port "+itos(p_port));
Error err = client->connect(ip,p_port);
ERR_FAIL_COND_V(err,err);
while(client->get_status()==StreamPeerTCP::STATUS_CONNECTING) {
//DEBUG_PRINT("trying to connect....");
DEBUG_PRINT("IP: " + String(ip) + " port " + itos(p_port));
Error err = client->connect(ip, p_port);
ERR_FAIL_COND_V(err, err);
while (client->get_status() == StreamPeerTCP::STATUS_CONNECTING) {
//DEBUG_PRINT("trying to connect....");
OS::get_singleton()->delay_usec(1000);
}
if (client->get_status()!=StreamPeerTCP::STATUS_CONNECTED) {
if (client->get_status() != StreamPeerTCP::STATUS_CONNECTED) {
return ERR_CANT_CONNECT;
}
CharString cs = p_password.utf8();
put_32(cs.length());
client->put_data((const uint8_t*)cs.ptr(),cs.length());
client->put_data((const uint8_t *)cs.ptr(), cs.length());
int e = get_32();
if (e!=OK) {
if (e != OK) {
return ERR_INVALID_PARAMETER;
}
thread = Thread::create(_thread_func,this);
thread = Thread::create(_thread_func, this);
return OK;
}
FileAccessNetworkClient *FileAccessNetworkClient::singleton=NULL;
FileAccessNetworkClient *FileAccessNetworkClient::singleton = NULL;
FileAccessNetworkClient::FileAccessNetworkClient() {
thread=NULL;
thread = NULL;
mutex = Mutex::create();
blockrequest_mutex = Mutex::create();
quit=false;
singleton=this;
last_id=0;
client = Ref<StreamPeerTCP>( StreamPeerTCP::create_ref() );
sem=Semaphore::create();
lockcount=0;
quit = false;
singleton = this;
last_id = 0;
client = Ref<StreamPeerTCP>(StreamPeerTCP::create_ref());
sem = Semaphore::create();
lockcount = 0;
}
FileAccessNetworkClient::~FileAccessNetworkClient() {
if (thread) {
quit=true;
quit = true;
sem->post();
Thread::wait_to_finish(thread);
memdelete(thread);
@ -260,72 +241,64 @@ FileAccessNetworkClient::~FileAccessNetworkClient() {
memdelete(blockrequest_mutex);
memdelete(mutex);
memdelete(sem);
}
void FileAccessNetwork::_set_block(size_t p_offset,const Vector<uint8_t>& p_block) {
void FileAccessNetwork::_set_block(size_t p_offset, const Vector<uint8_t> &p_block) {
int page = p_offset/page_size;
ERR_FAIL_INDEX(page,pages.size());
if (page<pages.size()-1) {
ERR_FAIL_COND(p_block.size()!=page_size);
int page = p_offset / page_size;
ERR_FAIL_INDEX(page, pages.size());
if (page < pages.size() - 1) {
ERR_FAIL_COND(p_block.size() != page_size);
} else {
ERR_FAIL_COND( (p_block.size() != (total_size%page_size)));
ERR_FAIL_COND((p_block.size() != (total_size % page_size)));
}
buffer_mutex->lock();
pages[page].buffer=p_block;
pages[page].queued=false;
pages[page].buffer = p_block;
pages[page].queued = false;
buffer_mutex->unlock();
if (waiting_on_page==page) {
waiting_on_page=-1;
if (waiting_on_page == page) {
waiting_on_page = -1;
page_sem->post();
}
}
void FileAccessNetwork::_respond(size_t p_len, Error p_status) {
void FileAccessNetwork::_respond(size_t p_len,Error p_status) {
DEBUG_PRINT("GOT RESPONSE - len: "+itos(p_len)+" status: "+itos(p_status));
response=p_status;
if (response!=OK)
DEBUG_PRINT("GOT RESPONSE - len: " + itos(p_len) + " status: " + itos(p_status));
response = p_status;
if (response != OK)
return;
opened=true;
total_size=p_len;
int pc = ((total_size-1)/page_size)+1;
opened = true;
total_size = p_len;
int pc = ((total_size - 1) / page_size) + 1;
pages.resize(pc);
}
Error FileAccessNetwork::_open(const String& p_path, int p_mode_flags) {
Error FileAccessNetwork::_open(const String &p_path, int p_mode_flags) {
ERR_FAIL_COND_V(p_mode_flags!=READ,ERR_UNAVAILABLE);
ERR_FAIL_COND_V(p_mode_flags != READ, ERR_UNAVAILABLE);
if (opened)
close();
FileAccessNetworkClient *nc = FileAccessNetworkClient::singleton;
DEBUG_PRINT("open: "+p_path);
DEBUG_PRINT("open: " + p_path);
DEBUG_TIME("open_begin");
nc->lock_mutex();
nc->put_32(id);
nc->accesses[id]=this;
nc->accesses[id] = this;
nc->put_32(COMMAND_OPEN_FILE);
CharString cs =p_path.utf8();
CharString cs = p_path.utf8();
nc->put_32(cs.length());
nc->client->put_data((const uint8_t*)cs.ptr(),cs.length());
pos=0;
eof_flag=false;
last_page=-1;
last_page_buff=NULL;
nc->client->put_data((const uint8_t *)cs.ptr(), cs.length());
pos = 0;
eof_flag = false;
last_page = -1;
last_page_buff = NULL;
// buffers.clear();
// buffers.clear();
nc->unlock_mutex();
DEBUG_PRINT("OPEN POST");
DEBUG_TIME("open_post");
@ -338,7 +311,7 @@ Error FileAccessNetwork::_open(const String& p_path, int p_mode_flags) {
return response;
}
void FileAccessNetwork::close(){
void FileAccessNetwork::close() {
if (!opened)
return;
@ -350,110 +323,103 @@ void FileAccessNetwork::close(){
nc->put_32(id);
nc->put_32(COMMAND_CLOSE);
pages.clear();
opened=false;
opened = false;
nc->unlock_mutex();
}
bool FileAccessNetwork::is_open() const{
bool FileAccessNetwork::is_open() const {
return opened;
}
void FileAccessNetwork::seek(size_t p_position){
void FileAccessNetwork::seek(size_t p_position) {
ERR_FAIL_COND(!opened);
eof_flag=p_position>total_size;
eof_flag = p_position > total_size;
if (p_position>=total_size) {
p_position=total_size;
if (p_position >= total_size) {
p_position = total_size;
}
pos=p_position;
pos = p_position;
}
void FileAccessNetwork::seek_end(int64_t p_position){
seek(total_size+p_position);
void FileAccessNetwork::seek_end(int64_t p_position) {
seek(total_size + p_position);
}
size_t FileAccessNetwork::get_pos() const{
size_t FileAccessNetwork::get_pos() const {
ERR_FAIL_COND_V(!opened,0);
ERR_FAIL_COND_V(!opened, 0);
return pos;
}
size_t FileAccessNetwork::get_len() const{
size_t FileAccessNetwork::get_len() const {
ERR_FAIL_COND_V(!opened,0);
ERR_FAIL_COND_V(!opened, 0);
return total_size;
}
bool FileAccessNetwork::eof_reached() const{
bool FileAccessNetwork::eof_reached() const {
ERR_FAIL_COND_V(!opened,false);
ERR_FAIL_COND_V(!opened, false);
return eof_flag;
}
uint8_t FileAccessNetwork::get_8() const{
uint8_t FileAccessNetwork::get_8() const {
uint8_t v;
get_buffer(&v,1);
get_buffer(&v, 1);
return v;
}
void FileAccessNetwork::_queue_page(int p_page) const {
if (p_page>=pages.size())
if (p_page >= pages.size())
return;
if (pages[p_page].buffer.empty() && !pages[p_page].queued) {
FileAccessNetworkClient *nc = FileAccessNetworkClient::singleton;
nc->blockrequest_mutex->lock();
FileAccessNetworkClient::BlockRequest br;
br.id=id;
br.offset=size_t(p_page)*page_size;
br.size=page_size;
br.id = id;
br.offset = size_t(p_page) * page_size;
br.size = page_size;
nc->block_requests.push_back(br);
pages[p_page].queued=true;
pages[p_page].queued = true;
nc->blockrequest_mutex->unlock();
DEBUG_PRINT("QUEUE PAGE POST");
nc->sem->post();
DEBUG_PRINT("queued "+itos(p_page));
DEBUG_PRINT("queued " + itos(p_page));
}
}
int FileAccessNetwork::get_buffer(uint8_t *p_dst, int p_length) const{
int FileAccessNetwork::get_buffer(uint8_t *p_dst, int p_length) const {
//bool eof=false;
if (pos+p_length>total_size) {
eof_flag=true;
if (pos + p_length > total_size) {
eof_flag = true;
}
if (pos+p_length>=total_size) {
p_length=total_size-pos;
if (pos + p_length >= total_size) {
p_length = total_size - pos;
}
// FileAccessNetworkClient *nc = FileAccessNetworkClient::singleton;
// FileAccessNetworkClient *nc = FileAccessNetworkClient::singleton;
uint8_t *buff=last_page_buff;
uint8_t *buff = last_page_buff;
for(int i=0;i<p_length;i++) {
for (int i = 0; i < p_length; i++) {
int page=pos/page_size;
int page = pos / page_size;
if (page!=last_page) {
if (page != last_page) {
buffer_mutex->lock();
if (pages[page].buffer.empty()) {
//fuck
waiting_on_page=page;
for(int j=0;j<read_ahead;j++) {
waiting_on_page = page;
for (int j = 0; j < read_ahead; j++) {
_queue_page(page+j);
_queue_page(page + j);
}
buffer_mutex->unlock();
DEBUG_PRINT("wait");
@ -461,30 +427,30 @@ int FileAccessNetwork::get_buffer(uint8_t *p_dst, int p_length) const{
DEBUG_PRINT("done");
} else {
for(int j=0;j<read_ahead;j++) {
for (int j = 0; j < read_ahead; j++) {
_queue_page(page+j);
_queue_page(page + j);
}
buff=pages[page].buffer.ptr();
buff = pages[page].buffer.ptr();
//queue pages
buffer_mutex->unlock();
}
buff=pages[page].buffer.ptr();
last_page_buff=buff;
last_page=page;
buff = pages[page].buffer.ptr();
last_page_buff = buff;
last_page = page;
}
p_dst[i]=buff[pos-uint64_t(page)*page_size];
p_dst[i] = buff[pos - uint64_t(page) * page_size];
pos++;
}
return p_length;
}
Error FileAccessNetwork::get_error() const{
Error FileAccessNetwork::get_error() const {
return pos==total_size?ERR_FILE_EOF:OK;
return pos == total_size ? ERR_FILE_EOF : OK;
}
void FileAccessNetwork::store_8(uint8_t p_dest) {
@ -492,63 +458,59 @@ void FileAccessNetwork::store_8(uint8_t p_dest) {
ERR_FAIL();
}
bool FileAccessNetwork::file_exists(const String& p_path){
bool FileAccessNetwork::file_exists(const String &p_path) {
FileAccessNetworkClient *nc = FileAccessNetworkClient::singleton;
nc->lock_mutex();
nc->put_32(id);
nc->put_32(COMMAND_FILE_EXISTS);
CharString cs=p_path.utf8();
CharString cs = p_path.utf8();
nc->put_32(cs.length());
nc->client->put_data((const uint8_t*)cs.ptr(),cs.length());
nc->client->put_data((const uint8_t *)cs.ptr(), cs.length());
nc->unlock_mutex();
DEBUG_PRINT("FILE EXISTS POST");
nc->sem->post();
sem->wait();
return exists_modtime!=0;
return exists_modtime != 0;
}
uint64_t FileAccessNetwork::_get_modified_time(const String& p_file){
uint64_t FileAccessNetwork::_get_modified_time(const String &p_file) {
FileAccessNetworkClient *nc = FileAccessNetworkClient::singleton;
nc->lock_mutex();
nc->put_32(id);
nc->put_32(COMMAND_GET_MODTIME);
CharString cs=p_file.utf8();
CharString cs = p_file.utf8();
nc->put_32(cs.length());
nc->client->put_data((const uint8_t*)cs.ptr(),cs.length());
nc->client->put_data((const uint8_t *)cs.ptr(), cs.length());
nc->unlock_mutex();
DEBUG_PRINT("MODTIME POST");
nc->sem->post();
sem->wait();
return exists_modtime;
}
FileAccessNetwork::FileAccessNetwork() {
eof_flag=false;
opened=false;
pos=0;
sem=Semaphore::create();
page_sem=Semaphore::create();
buffer_mutex=Mutex::create();
eof_flag = false;
opened = false;
pos = 0;
sem = Semaphore::create();
page_sem = Semaphore::create();
buffer_mutex = Mutex::create();
FileAccessNetworkClient *nc = FileAccessNetworkClient::singleton;
nc->lock_mutex();
id=nc->last_id++;
nc->accesses[id]=this;
id = nc->last_id++;
nc->accesses[id] = this;
nc->unlock_mutex();
page_size = GLOBAL_DEF("remote_fs/page_size",65536);
read_ahead = GLOBAL_DEF("remote_fs/page_read_ahead",4);
max_pages = GLOBAL_DEF("remote_fs/max_pages",20);
last_activity_val=0;
waiting_on_page=-1;
last_page=-1;
page_size = GLOBAL_DEF("remote_fs/page_size", 65536);
read_ahead = GLOBAL_DEF("remote_fs/page_read_ahead", 4);
max_pages = GLOBAL_DEF("remote_fs/max_pages", 20);
last_activity_val = 0;
waiting_on_page = -1;
last_page = -1;
}
FileAccessNetwork::~FileAccessNetwork() {
@ -560,8 +522,7 @@ FileAccessNetwork::~FileAccessNetwork() {
FileAccessNetworkClient *nc = FileAccessNetworkClient::singleton;
nc->lock_mutex();
id=nc->last_id++;
id = nc->last_id++;
nc->accesses.erase(id);
nc->unlock_mutex();
}

View File

@ -29,16 +29,15 @@
#ifndef FILE_ACCESS_NETWORK_H
#define FILE_ACCESS_NETWORK_H
#include "io/stream_peer_tcp.h"
#include "os/file_access.h"
#include "os/semaphore.h"
#include "os/thread.h"
#include "io/stream_peer_tcp.h"
class FileAccessNetwork;
class FileAccessNetworkClient {
struct BlockRequest {
int id;
@ -55,7 +54,7 @@ class FileAccessNetworkClient {
bool quit;
Mutex *mutex;
Mutex *blockrequest_mutex;
Map<int,FileAccessNetwork*> accesses;
Map<int, FileAccessNetwork *> accesses;
Ref<StreamPeerTCP> client;
int last_id;
@ -72,18 +71,16 @@ class FileAccessNetworkClient {
void lock_mutex();
void unlock_mutex();
friend class FileAccessNetwork;
friend class FileAccessNetwork;
static FileAccessNetworkClient *singleton;
public:
static FileAccessNetworkClient *get_singleton() { return singleton; }
Error connect(const String& p_host,int p_port,const String& p_password="");
Error connect(const String &p_host, int p_port, const String &p_password = "");
FileAccessNetworkClient();
~FileAccessNetworkClient();
};
class FileAccessNetwork : public FileAccess {
@ -109,21 +106,23 @@ class FileAccessNetwork : public FileAccess {
int activity;
bool queued;
Vector<uint8_t> buffer;
Page() { activity=0; queued=false; }
Page() {
activity = 0;
queued = false;
}
};
mutable Vector< Page > pages;
mutable Vector<Page> pages;
mutable Error response;
uint64_t exists_modtime;
friend class FileAccessNetworkClient;
friend class FileAccessNetworkClient;
void _queue_page(int p_page) const;
void _respond(size_t p_len,Error p_status);
void _set_block(size_t p_offset,const Vector<uint8_t>& p_block);
void _respond(size_t p_len, Error p_status);
void _set_block(size_t p_offset, const Vector<uint8_t> &p_block);
public:
enum Command {
COMMAND_OPEN_FILE,
COMMAND_READ_BLOCK,
@ -139,13 +138,12 @@ public:
RESPONSE_GET_MODTIME,
};
virtual Error _open(const String& p_path, int p_mode_flags); ///< open a file
virtual Error _open(const String &p_path, int p_mode_flags); ///< open a file
virtual void close(); ///< close a file
virtual bool is_open() const; ///< true when file is open
virtual void seek(size_t p_position); ///< seek to a given position
virtual void seek_end(int64_t p_position=0); ///< seek from the end of file
virtual void seek_end(int64_t p_position = 0); ///< seek from the end of file
virtual size_t get_pos() const; ///< get position in the file
virtual size_t get_len() const; ///< get size of the file
@ -158,9 +156,9 @@ public:
virtual void store_8(uint8_t p_dest); ///< store a byte
virtual bool file_exists(const String& p_path); ///< return true if a file exists
virtual bool file_exists(const String &p_path); ///< return true if a file exists
virtual uint64_t _get_modified_time(const String& p_file);
virtual uint64_t _get_modified_time(const String &p_file);
FileAccessNetwork();
~FileAccessNetwork();

View File

@ -33,9 +33,9 @@
#define PACK_VERSION 0
Error PackedData::add_pack(const String& p_path) {
Error PackedData::add_pack(const String &p_path) {
for (int i=0; i<sources.size(); i++) {
for (int i = 0; i < sources.size(); i++) {
if (sources[i]->try_open_pack(p_path)) {
@ -46,7 +46,7 @@ Error PackedData::add_pack(const String& p_path) {
return ERR_FILE_UNRECOGNIZED;
};
void PackedData::add_path(const String& pkg_path, const String& path, uint64_t ofs, uint64_t size,const uint8_t* p_md5, PackSource* p_src) {
void PackedData::add_path(const String &pkg_path, const String &path, uint64_t ofs, uint64_t size, const uint8_t *p_md5, PackSource *p_src) {
PathMD5 pmd5(path.md5_buffer());
//printf("adding path %ls, %lli, %lli\n", path.c_str(), pmd5.a, pmd5.b);
@ -54,35 +54,35 @@ void PackedData::add_path(const String& pkg_path, const String& path, uint64_t o
bool exists = files.has(pmd5);
PackedFile pf;
pf.pack=pkg_path;
pf.offset=ofs;
pf.size=size;
for(int i=0;i<16;i++)
pf.md5[i]=p_md5[i];
pf.pack = pkg_path;
pf.offset = ofs;
pf.size = size;
for (int i = 0; i < 16; i++)
pf.md5[i] = p_md5[i];
pf.src = p_src;
files[pmd5]=pf;
files[pmd5] = pf;
if (!exists) {
//search for dir
String p = path.replace_first("res://","");
PackedDir *cd=root;
String p = path.replace_first("res://", "");
PackedDir *cd = root;
if (p.find("/")!=-1) { //in a subdir
if (p.find("/") != -1) { //in a subdir
Vector<String> ds=p.get_base_dir().split("/");
Vector<String> ds = p.get_base_dir().split("/");
for(int j=0;j<ds.size();j++) {
for (int j = 0; j < ds.size(); j++) {
if (!cd->subdirs.has(ds[j])) {
PackedDir *pd = memnew( PackedDir );
pd->name=ds[j];
pd->parent=cd;
cd->subdirs[pd->name]=pd;
cd=pd;
PackedDir *pd = memnew(PackedDir);
pd->name = ds[j];
pd->parent = cd;
cd->subdirs[pd->name] = pd;
cd = pd;
} else {
cd=cd->subdirs[ds[j]];
cd = cd->subdirs[ds[j]];
}
}
}
@ -97,61 +97,59 @@ void PackedData::add_pack_source(PackSource *p_source) {
}
};
PackedData *PackedData::singleton=NULL;
PackedData *PackedData::singleton = NULL;
PackedData::PackedData() {
singleton=this;
root=memnew(PackedDir);
root->parent=NULL;
disabled=false;
singleton = this;
root = memnew(PackedDir);
root->parent = NULL;
disabled = false;
add_pack_source(memnew(PackedSourcePCK));
}
void PackedData::_free_packed_dirs(PackedDir *p_dir) {
for (Map<String,PackedDir*>::Element *E=p_dir->subdirs.front();E;E=E->next())
for (Map<String, PackedDir *>::Element *E = p_dir->subdirs.front(); E; E = E->next())
_free_packed_dirs(E->get());
memdelete(p_dir);
}
PackedData::~PackedData() {
for(int i=0;i<sources.size();i++) {
for (int i = 0; i < sources.size(); i++) {
memdelete(sources[i]);
}
_free_packed_dirs(root);
}
//////////////////////////////////////////////////////////////////
bool PackedSourcePCK::try_open_pack(const String& p_path) {
bool PackedSourcePCK::try_open_pack(const String &p_path) {
FileAccess *f = FileAccess::open(p_path,FileAccess::READ);
FileAccess *f = FileAccess::open(p_path, FileAccess::READ);
if (!f)
return false;
//printf("try open %ls!\n", p_path.c_str());
uint32_t magic= f->get_32();
uint32_t magic = f->get_32();
if (magic != 0x43504447) {
//maybe at he end.... self contained exe
f->seek_end();
f->seek( f->get_pos() -4 );
f->seek(f->get_pos() - 4);
magic = f->get_32();
if (magic != 0x43504447) {
memdelete(f);
return false;
}
f->seek( f->get_pos() -12 );
f->seek(f->get_pos() - 12);
uint64_t ds = f->get_64();
f->seek( f->get_pos() -ds-8 );
f->seek(f->get_pos() - ds - 8);
magic = f->get_32();
if (magic != 0x43504447) {
@ -159,7 +157,6 @@ bool PackedSourcePCK::try_open_pack(const String& p_path) {
memdelete(f);
return false;
}
}
uint32_t version = f->get_32();
@ -167,25 +164,25 @@ bool PackedSourcePCK::try_open_pack(const String& p_path) {
uint32_t ver_minor = f->get_32();
uint32_t ver_rev = f->get_32();
ERR_EXPLAIN("Pack version newer than supported by engine: "+itos(version));
ERR_FAIL_COND_V( version > PACK_VERSION, ERR_INVALID_DATA);
ERR_EXPLAIN("Pack created with a newer version of the engine: "+itos(ver_major)+"."+itos(ver_minor)+"."+itos(ver_rev));
ERR_FAIL_COND_V( ver_major > VERSION_MAJOR || (ver_major == VERSION_MAJOR && ver_minor > VERSION_MINOR), ERR_INVALID_DATA);
ERR_EXPLAIN("Pack version newer than supported by engine: " + itos(version));
ERR_FAIL_COND_V(version > PACK_VERSION, ERR_INVALID_DATA);
ERR_EXPLAIN("Pack created with a newer version of the engine: " + itos(ver_major) + "." + itos(ver_minor) + "." + itos(ver_rev));
ERR_FAIL_COND_V(ver_major > VERSION_MAJOR || (ver_major == VERSION_MAJOR && ver_minor > VERSION_MINOR), ERR_INVALID_DATA);
for(int i=0;i<16;i++) {
for (int i = 0; i < 16; i++) {
//reserved
f->get_32();
}
int file_count = f->get_32();
for(int i=0;i<file_count;i++) {
for (int i = 0; i < file_count; i++) {
uint32_t sl = f->get_32();
CharString cs;
cs.resize(sl+1);
f->get_buffer((uint8_t*)cs.ptr(),sl);
cs[sl]=0;
cs.resize(sl + 1);
f->get_buffer((uint8_t *)cs.ptr(), sl);
cs[sl] = 0;
String path;
path.parse_utf8(cs.ptr());
@ -193,22 +190,21 @@ bool PackedSourcePCK::try_open_pack(const String& p_path) {
uint64_t ofs = f->get_64();
uint64_t size = f->get_64();
uint8_t md5[16];
f->get_buffer(md5,16);
PackedData::get_singleton()->add_path(p_path, path, ofs, size, md5,this);
f->get_buffer(md5, 16);
PackedData::get_singleton()->add_path(p_path, path, ofs, size, md5, this);
};
return true;
};
FileAccess* PackedSourcePCK::get_file(const String &p_path, PackedData::PackedFile* p_file) {
FileAccess *PackedSourcePCK::get_file(const String &p_path, PackedData::PackedFile *p_file) {
return memnew( FileAccessPack(p_path, *p_file));
return memnew(FileAccessPack(p_path, *p_file));
};
//////////////////////////////////////////////////////////////////
Error FileAccessPack::_open(const String& p_path, int p_mode_flags) {
Error FileAccessPack::_open(const String &p_path, int p_mode_flags) {
ERR_FAIL_V(ERR_UNAVAILABLE);
return ERR_UNAVAILABLE;
@ -219,45 +215,44 @@ void FileAccessPack::close() {
f->close();
}
bool FileAccessPack::is_open() const{
bool FileAccessPack::is_open() const {
return f->is_open();
}
void FileAccessPack::seek(size_t p_position){
void FileAccessPack::seek(size_t p_position) {
if (p_position>pf.size) {
eof=true;
if (p_position > pf.size) {
eof = true;
} else {
eof=false;
eof = false;
}
f->seek(pf.offset+p_position);
pos=p_position;
f->seek(pf.offset + p_position);
pos = p_position;
}
void FileAccessPack::seek_end(int64_t p_position){
seek(pf.size+p_position);
void FileAccessPack::seek_end(int64_t p_position) {
seek(pf.size + p_position);
}
size_t FileAccessPack::get_pos() const {
return pos;
}
size_t FileAccessPack::get_len() const{
size_t FileAccessPack::get_len() const {
return pf.size;
}
bool FileAccessPack::eof_reached() const{
bool FileAccessPack::eof_reached() const {
return eof;
}
uint8_t FileAccessPack::get_8() const {
if (pos>=pf.size) {
eof=true;
if (pos >= pf.size) {
eof = true;
return 0;
}
@ -265,23 +260,22 @@ uint8_t FileAccessPack::get_8() const {
return f->get_8();
}
int FileAccessPack::get_buffer(uint8_t *p_dst,int p_length) const {
int FileAccessPack::get_buffer(uint8_t *p_dst, int p_length) const {
if (eof)
return 0;
int64_t to_read=p_length;
if (to_read+pos > pf.size) {
eof=true;
to_read=int64_t(pf.size)-int64_t(pos);
int64_t to_read = p_length;
if (to_read + pos > pf.size) {
eof = true;
to_read = int64_t(pf.size) - int64_t(pos);
}
pos+=p_length;
pos += p_length;
if (to_read<=0)
if (to_read <= 0)
return 0;
f->get_buffer(p_dst,to_read);
f->get_buffer(p_dst, to_read);
return to_read;
}
@ -301,32 +295,29 @@ Error FileAccessPack::get_error() const {
void FileAccessPack::store_8(uint8_t p_dest) {
ERR_FAIL();
}
void FileAccessPack::store_buffer(const uint8_t *p_src,int p_length) {
void FileAccessPack::store_buffer(const uint8_t *p_src, int p_length) {
ERR_FAIL();
}
bool FileAccessPack::file_exists(const String& p_name) {
bool FileAccessPack::file_exists(const String &p_name) {
return false;
}
FileAccessPack::FileAccessPack(const String &p_path, const PackedData::PackedFile &p_file) {
FileAccessPack::FileAccessPack(const String& p_path, const PackedData::PackedFile& p_file) {
pf=p_file;
f=FileAccess::open(pf.pack,FileAccess::READ);
pf = p_file;
f = FileAccess::open(pf.pack, FileAccess::READ);
if (!f) {
ERR_EXPLAIN("Can't open pack-referenced file: "+String(pf.pack));
ERR_EXPLAIN("Can't open pack-referenced file: " + String(pf.pack));
ERR_FAIL_COND(!f);
}
f->seek(pf.offset);
pos=0;
eof=false;
pos = 0;
eof = false;
}
FileAccessPack::~FileAccessPack() {
@ -334,24 +325,21 @@ FileAccessPack::~FileAccessPack() {
memdelete(f);
}
//////////////////////////////////////////////////////////////////////////////////
// DIR ACCESS
//////////////////////////////////////////////////////////////////////////////////
bool DirAccessPack::list_dir_begin() {
list_dirs.clear();
list_files.clear();
for (Map<String,PackedData::PackedDir*>::Element *E=current->subdirs.front();E;E=E->next()) {
for (Map<String, PackedData::PackedDir *>::Element *E = current->subdirs.front(); E; E = E->next()) {
list_dirs.push_back(E->key());
}
for (Set<String>::Element *E=current->files.front();E;E=E->next()) {
for (Set<String>::Element *E = current->files.front(); E; E = E->next()) {
list_files.push_back(E->get());
}
@ -359,15 +347,15 @@ bool DirAccessPack::list_dir_begin() {
return true;
}
String DirAccessPack::get_next(){
String DirAccessPack::get_next() {
if (list_dirs.size()) {
cdir=true;
cdir = true;
String d = list_dirs.front()->get();
list_dirs.pop_front();
return d;
} else if (list_files.size()) {
cdir=false;
cdir = false;
String f = list_files.front()->get();
list_files.pop_front();
return f;
@ -375,11 +363,11 @@ String DirAccessPack::get_next(){
return String();
}
}
bool DirAccessPack::current_is_dir() const{
bool DirAccessPack::current_is_dir() const {
return cdir;
}
bool DirAccessPack::current_is_hidden() const{
bool DirAccessPack::current_is_hidden() const {
return false;
}
@ -400,18 +388,18 @@ String DirAccessPack::get_drive(int p_drive) {
Error DirAccessPack::change_dir(String p_dir) {
String nd = p_dir.replace("\\","/");
bool absolute=false;
String nd = p_dir.replace("\\", "/");
bool absolute = false;
if (nd.begins_with("res://")) {
nd=nd.replace_first("res://","");
absolute=true;
nd = nd.replace_first("res://", "");
absolute = true;
}
nd=nd.simplify_path();
nd = nd.simplify_path();
if (nd.begins_with("/")) {
nd=nd.replace_first("/","") ;
absolute=true;
nd = nd.replace_first("/", "");
absolute = true;
}
Vector<String> paths = nd.split("/");
@ -423,18 +411,18 @@ Error DirAccessPack::change_dir(String p_dir) {
else
pd = current;
for(int i=0;i<paths.size();i++) {
for (int i = 0; i < paths.size(); i++) {
String p = paths[i];
if (p==".") {
if (p == ".") {
continue;
} else if (p=="..") {
} else if (p == "..") {
if (pd->parent) {
pd=pd->parent;
pd = pd->parent;
}
} else if (pd->subdirs.has(p)) {
pd=pd->subdirs[p];
pd = pd->subdirs[p];
} else {
@ -442,29 +430,26 @@ Error DirAccessPack::change_dir(String p_dir) {
}
}
current=pd;
current = pd;
return OK;
}
String DirAccessPack::get_current_dir() {
String p;
PackedData::PackedDir *pd = current;
while(pd->parent) {
while (pd->parent) {
if (pd!=current)
p="/"+p;
p=p+pd->name;
if (pd != current)
p = "/" + p;
p = p + pd->name;
}
return "res://"+p;
return "res://" + p;
}
bool DirAccessPack::file_exists(String p_file){
bool DirAccessPack::file_exists(String p_file) {
return current->files.has(p_file);
}
@ -474,36 +459,30 @@ bool DirAccessPack::dir_exists(String p_dir) {
return current->subdirs.has(p_dir);
}
Error DirAccessPack::make_dir(String p_dir){
Error DirAccessPack::make_dir(String p_dir) {
return ERR_UNAVAILABLE;
}
Error DirAccessPack::rename(String p_from, String p_to){
Error DirAccessPack::rename(String p_from, String p_to) {
return ERR_UNAVAILABLE;
}
Error DirAccessPack::remove(String p_name){
Error DirAccessPack::remove(String p_name) {
return ERR_UNAVAILABLE;
}
size_t DirAccessPack::get_space_left(){
size_t DirAccessPack::get_space_left() {
return 0;
}
DirAccessPack::DirAccessPack() {
current=PackedData::get_singleton()->root;
cdir=false;
current = PackedData::get_singleton()->root;
cdir = false;
}
DirAccessPack::~DirAccessPack() {
}

View File

@ -29,18 +29,18 @@
#ifndef FILE_ACCESS_PACK_H
#define FILE_ACCESS_PACK_H
#include "os/file_access.h"
#include "os/dir_access.h"
#include "map.h"
#include "list.h"
#include "map.h"
#include "os/dir_access.h"
#include "os/file_access.h"
#include "print_string.h"
class PackSource;
class PackedData {
friend class FileAccessPack;
friend class DirAccessPack;
friend class PackSource;
friend class FileAccessPack;
friend class DirAccessPack;
friend class PackSource;
public:
struct PackedFile {
@ -49,21 +49,21 @@ public:
uint64_t offset; //if offset is ZERO, the file was ERASED
uint64_t size;
uint8_t md5[16];
PackSource* src;
PackSource *src;
};
private:
struct PackedDir {
PackedDir *parent;
String name;
Map<String,PackedDir*> subdirs;
Map<String, PackedDir *> subdirs;
Set<String> files;
};
struct PathMD5 {
uint64_t a;
uint64_t b;
bool operator < (const PathMD5& p_md5) const {
bool operator<(const PathMD5 &p_md5) const {
if (p_md5.a == a) {
return b < p_md5.b;
@ -72,7 +72,7 @@ private:
}
}
bool operator == (const PathMD5& p_md5) const {
bool operator==(const PathMD5 &p_md5) const {
return a == p_md5.a && b == p_md5.b;
};
@ -81,14 +81,14 @@ private:
};
PathMD5(const Vector<uint8_t> p_buf) {
a = *((uint64_t*)&p_buf[0]);
b = *((uint64_t*)&p_buf[8]);
a = *((uint64_t *)&p_buf[0]);
b = *((uint64_t *)&p_buf[8]);
};
};
Map<PathMD5,PackedFile> files;
Map<PathMD5, PackedFile> files;
Vector<PackSource*> sources;
Vector<PackSource *> sources;
PackedDir *root;
//Map<String,PackedDir*> dirs;
@ -99,18 +99,17 @@ private:
void _free_packed_dirs(PackedDir *p_dir);
public:
void add_pack_source(PackSource *p_source);
void add_path(const String &pkg_path, const String &path, uint64_t ofs, uint64_t size, const uint8_t *p_md5, PackSource *p_src); // for PackSource
void add_pack_source(PackSource* p_source);
void add_path(const String& pkg_path, const String& path, uint64_t ofs, uint64_t size,const uint8_t* p_md5, PackSource* p_src); // for PackSource
void set_disabled(bool p_disabled) { disabled=p_disabled; }
void set_disabled(bool p_disabled) { disabled = p_disabled; }
_FORCE_INLINE_ bool is_disabled() const { return disabled; }
static PackedData *get_singleton() { return singleton; }
Error add_pack(const String& p_path);
Error add_pack(const String &p_path);
_FORCE_INLINE_ FileAccess *try_open_path(const String& p_path);
_FORCE_INLINE_ bool has_path(const String& p_path);
_FORCE_INLINE_ FileAccess *try_open_path(const String &p_path);
_FORCE_INLINE_ bool has_path(const String &p_path);
PackedData();
~PackedData();
@ -119,21 +118,18 @@ public:
class PackSource {
public:
virtual bool try_open_pack(const String& p_path)=0;
virtual FileAccess* get_file(const String& p_path, PackedData::PackedFile* p_file)=0;
virtual bool try_open_pack(const String &p_path) = 0;
virtual FileAccess *get_file(const String &p_path, PackedData::PackedFile *p_file) = 0;
virtual ~PackSource() {}
};
class PackedSourcePCK : public PackSource {
public:
virtual bool try_open_pack(const String &p_path);
virtual FileAccess* get_file(const String& p_path, PackedData::PackedFile* p_file);
virtual FileAccess *get_file(const String &p_path, PackedData::PackedFile *p_file);
};
class FileAccessPack : public FileAccess {
PackedData::PackedFile pf;
@ -142,17 +138,15 @@ class FileAccessPack : public FileAccess {
mutable bool eof;
FileAccess *f;
virtual Error _open(const String& p_path, int p_mode_flags);
virtual uint64_t _get_modified_time(const String& p_file) { return 0; }
virtual Error _open(const String &p_path, int p_mode_flags);
virtual uint64_t _get_modified_time(const String &p_file) { return 0; }
public:
virtual void close();
virtual bool is_open() const;
virtual void seek(size_t p_position);
virtual void seek_end(int64_t p_position=0);
virtual void seek_end(int64_t p_position = 0);
virtual size_t get_pos() const;
virtual size_t get_len() const;
@ -160,8 +154,7 @@ public:
virtual uint8_t get_8() const;
virtual int get_buffer(uint8_t *p_dst,int p_length) const;
virtual int get_buffer(uint8_t *p_dst, int p_length) const;
virtual void set_endian_swap(bool p_swap);
@ -169,38 +162,34 @@ public:
virtual void store_8(uint8_t p_dest);
virtual void store_buffer(const uint8_t *p_src,int p_length);
virtual void store_buffer(const uint8_t *p_src, int p_length);
virtual bool file_exists(const String& p_name);
virtual bool file_exists(const String &p_name);
FileAccessPack(const String& p_path, const PackedData::PackedFile& p_file);
FileAccessPack(const String &p_path, const PackedData::PackedFile &p_file);
~FileAccessPack();
};
FileAccess *PackedData::try_open_path(const String& p_path) {
FileAccess *PackedData::try_open_path(const String &p_path) {
//print_line("try open path " + p_path);
PathMD5 pmd5(p_path.md5_buffer());
Map<PathMD5,PackedFile>::Element *E=files.find(pmd5);
Map<PathMD5, PackedFile>::Element *E = files.find(pmd5);
if (!E)
return NULL; //not found
if (E->get().offset==0)
if (E->get().offset == 0)
return NULL; //was erased
return E->get().src->get_file(p_path, &E->get());
}
bool PackedData::has_path(const String& p_path) {
bool PackedData::has_path(const String &p_path) {
return files.has(PathMD5(p_path.md5_buffer()));
}
class DirAccessPack : public DirAccess {
PackedData::PackedDir *current;
List<String> list_dirs;
@ -208,7 +197,6 @@ class DirAccessPack : public DirAccess {
bool cdir;
public:
virtual bool list_dir_begin();
virtual String get_next();
virtual bool current_is_dir() const;
@ -221,7 +209,6 @@ public:
virtual Error change_dir(String p_dir);
virtual String get_current_dir();
virtual bool file_exists(String p_file);
virtual bool dir_exists(String p_dir);
@ -234,8 +221,6 @@ public:
DirAccessPack();
~DirAccessPack();
};
#endif // FILE_ACCESS_PACK_H

View File

@ -30,78 +30,75 @@
#include "file_access_zip.h"
#include "core/os/file_access.h"
#include "core/os/copymem.h"
#include "core/os/file_access.h"
ZipArchive* ZipArchive::instance = NULL;
ZipArchive *ZipArchive::instance = NULL;
extern "C" {
static void* godot_open(void* data, const char* p_fname, int mode) {
static void *godot_open(void *data, const char *p_fname, int mode) {
if (mode & ZLIB_FILEFUNC_MODE_WRITE) {
return NULL;
};
FileAccess* f = (FileAccess*)data;
FileAccess *f = (FileAccess *)data;
f->open(p_fname, FileAccess::READ);
return f->is_open()?data:NULL;
return f->is_open() ? data : NULL;
};
static uLong godot_read(void* data, void* fdata, void* buf, uLong size) {
static uLong godot_read(void *data, void *fdata, void *buf, uLong size) {
FileAccess* f = (FileAccess*)data;
f->get_buffer((uint8_t*)buf, size);
FileAccess *f = (FileAccess *)data;
f->get_buffer((uint8_t *)buf, size);
return size;
};
static uLong godot_write(voidpf opaque, voidpf stream, const void* buf, uLong size) {
static uLong godot_write(voidpf opaque, voidpf stream, const void *buf, uLong size) {
return 0;
};
static long godot_tell(voidpf opaque, voidpf stream) {
static long godot_tell (voidpf opaque, voidpf stream) {
FileAccess* f = (FileAccess*)opaque;
FileAccess *f = (FileAccess *)opaque;
return f->get_pos();
};
static long godot_seek(voidpf opaque, voidpf stream, uLong offset, int origin) {
FileAccess* f = (FileAccess*)opaque;
FileAccess *f = (FileAccess *)opaque;
int pos = offset;
switch (origin) {
case ZLIB_FILEFUNC_SEEK_CUR:
pos = f->get_pos() + offset;
break;
case ZLIB_FILEFUNC_SEEK_END:
pos = f->get_len() + offset;
break;
default:
break;
case ZLIB_FILEFUNC_SEEK_CUR:
pos = f->get_pos() + offset;
break;
case ZLIB_FILEFUNC_SEEK_END:
pos = f->get_len() + offset;
break;
default:
break;
};
f->seek(pos);
return 0;
};
static int godot_close(voidpf opaque, voidpf stream) {
FileAccess* f = (FileAccess*)opaque;
FileAccess *f = (FileAccess *)opaque;
f->close();
return 0;
};
static int godot_testerror(voidpf opaque, voidpf stream) {
FileAccess* f = (FileAccess*)opaque;
return f->get_error()!=OK?1:0;
FileAccess *f = (FileAccess *)opaque;
return f->get_error() != OK ? 1 : 0;
};
static voidpf godot_alloc(voidpf opaque, uInt items, uInt size) {
@ -119,7 +116,7 @@ static void godot_free(voidpf opaque, voidpf address) {
void ZipArchive::close_handle(unzFile p_file) const {
ERR_FAIL_COND(!p_file);
FileAccess* f = (FileAccess*)unzGetOpaque(p_file);
FileAccess *f = (FileAccess *)unzGetOpaque(p_file);
unzCloseCurrentFile(p_file);
unzClose(p_file);
memdelete(f);
@ -130,7 +127,7 @@ unzFile ZipArchive::get_file_handle(String p_file) const {
ERR_FAIL_COND_V(!file_exists(p_file), NULL);
File file = files[p_file];
FileAccess* f = FileAccess::open(packages[file.package].filename, FileAccess::READ);
FileAccess *f = FileAccess::open(packages[file.package].filename, FileAccess::READ);
ERR_FAIL_COND_V(!f, NULL);
zlib_filefunc_def io;
@ -162,7 +159,7 @@ unzFile ZipArchive::get_file_handle(String p_file) const {
return pkg;
};
bool ZipArchive::try_open_pack(const String& p_name) {
bool ZipArchive::try_open_pack(const String &p_name) {
//printf("opening zip pack %ls, %i, %i\n", p_name.c_str(), p_name.extension().nocasecmp_to("zip"), p_name.extension().nocasecmp_to("pcz"));
if (p_name.extension().nocasecmp_to("zip") != 0 && p_name.extension().nocasecmp_to("pcz") != 0)
@ -170,7 +167,7 @@ bool ZipArchive::try_open_pack(const String& p_name) {
zlib_filefunc_def io;
FileAccess* f = FileAccess::open(p_name, FileAccess::READ);
FileAccess *f = FileAccess::open(p_name, FileAccess::READ);
if (!f)
return false;
io.opaque = f;
@ -188,20 +185,20 @@ bool ZipArchive::try_open_pack(const String& p_name) {
unz_global_info64 gi;
int err = unzGetGlobalInfo64(zfile, &gi);
ERR_FAIL_COND_V(err!=UNZ_OK, false);
ERR_FAIL_COND_V(err != UNZ_OK, false);
Package pkg;
pkg.filename = p_name;
pkg.zfile = zfile;
packages.push_back(pkg);
int pkg_num = packages.size()-1;
int pkg_num = packages.size() - 1;
for (unsigned int i=0;i<gi.number_entry;i++) {
for (unsigned int i = 0; i < gi.number_entry; i++) {
char filename_inzip[256];
unz_file_info64 file_info;
err = unzGetCurrentFileInfo64(zfile,&file_info,filename_inzip,sizeof(filename_inzip),NULL,0,NULL,0);
err = unzGetCurrentFileInfo64(zfile, &file_info, filename_inzip, sizeof(filename_inzip), NULL, 0, NULL, 0);
ERR_CONTINUE(err != UNZ_OK);
File f;
@ -211,11 +208,11 @@ bool ZipArchive::try_open_pack(const String& p_name) {
String fname = String("res://") + filename_inzip;
files[fname] = f;
uint8_t md5[16]={0,0,0,0,0,0,0,0 , 0,0,0,0,0,0,0,0};
uint8_t md5[16] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
PackedData::get_singleton()->add_path(p_name, fname, 1, 0, md5, this);
//printf("packed data add path %ls, %ls\n", p_name.c_str(), fname.c_str());
if ((i+1)<gi.number_entry) {
if ((i + 1) < gi.number_entry) {
unzGoToNextFile(zfile);
};
};
@ -228,13 +225,12 @@ bool ZipArchive::file_exists(String p_name) const {
return files.has(p_name);
};
FileAccess* ZipArchive::get_file(const String& p_path, PackedData::PackedFile* p_file) {
FileAccess *ZipArchive::get_file(const String &p_path, PackedData::PackedFile *p_file) {
return memnew(FileAccessZip(p_path, *p_file));
};
ZipArchive* ZipArchive::get_singleton() {
ZipArchive *ZipArchive::get_singleton() {
if (instance == NULL) {
instance = memnew(ZipArchive);
@ -251,9 +247,9 @@ ZipArchive::ZipArchive() {
ZipArchive::~ZipArchive() {
for (int i=0; i<packages.size(); i++) {
for (int i = 0; i < packages.size(); i++) {
FileAccess* f = (FileAccess*)unzGetOpaque(packages[i].zfile);
FileAccess *f = (FileAccess *)unzGetOpaque(packages[i].zfile);
unzClose(packages[i].zfile);
memdelete(f);
};
@ -261,18 +257,17 @@ ZipArchive::~ZipArchive() {
packages.clear();
};
Error FileAccessZip::_open(const String& p_path, int p_mode_flags) {
Error FileAccessZip::_open(const String &p_path, int p_mode_flags) {
close();
ERR_FAIL_COND_V(p_mode_flags & FileAccess::WRITE, FAILED);
ZipArchive* arch = ZipArchive::get_singleton();
ZipArchive *arch = ZipArchive::get_singleton();
ERR_FAIL_COND_V(!arch, FAILED);
zfile = arch->get_file_handle(p_path);
ERR_FAIL_COND_V(!zfile, FAILED);
int err = unzGetCurrentFileInfo64(zfile,&file_info,NULL,0,NULL,0,NULL,0);
int err = unzGetCurrentFileInfo64(zfile, &file_info, NULL, 0, NULL, 0, NULL, 0);
ERR_FAIL_COND_V(err != UNZ_OK, FAILED);
return OK;
@ -283,7 +278,7 @@ void FileAccessZip::close() {
if (!zfile)
return;
ZipArchive* arch = ZipArchive::get_singleton();
ZipArchive *arch = ZipArchive::get_singleton();
ERR_FAIL_COND(!arch);
arch->close_handle(zfile);
zfile = NULL;
@ -332,7 +327,7 @@ uint8_t FileAccessZip::get_8() const {
return ret;
};
int FileAccessZip::get_buffer(uint8_t *p_dst,int p_length) const {
int FileAccessZip::get_buffer(uint8_t *p_dst, int p_length) const {
ERR_FAIL_COND_V(!zfile, -1);
at_eof = unzeof(zfile);
@ -363,13 +358,12 @@ void FileAccessZip::store_8(uint8_t p_dest) {
ERR_FAIL();
};
bool FileAccessZip::file_exists(const String& p_name) {
bool FileAccessZip::file_exists(const String &p_name) {
return false;
};
FileAccessZip::FileAccessZip(const String& p_path, const PackedData::PackedFile& p_file) {
FileAccessZip::FileAccessZip(const String &p_path, const PackedData::PackedFile &p_file) {
zfile = NULL;
_open(p_path, FileAccess::READ);

View File

@ -31,15 +31,14 @@
#ifndef FILE_ACCESS_Zip_H
#define FILE_ACCESS_Zip_H
#include <stdlib.h>
#include "core/io/file_access_pack.h"
#include "unzip.h"
#include "map.h"
#include "unzip.h"
#include <stdlib.h>
class ZipArchive : public PackSource {
public:
struct File {
int package;
@ -50,23 +49,20 @@ public:
};
};
private:
struct Package {
String filename;
unzFile zfile;
};
Vector<Package> packages;
Map<String,File> files;
Map<String, File> files;
static ZipArchive* instance;
static ZipArchive *instance;
FileAccess::CreateFunc fa_create_func;
public:
void close_handle(unzFile p_file) const;
unzFile get_file_handle(String p_file) const;
@ -74,49 +70,47 @@ public:
bool file_exists(String p_name) const;
virtual bool try_open_pack(const String& p_path);
FileAccess* get_file(const String& p_path, PackedData::PackedFile* p_file);
virtual bool try_open_pack(const String &p_path);
FileAccess *get_file(const String &p_path, PackedData::PackedFile *p_file);
static ZipArchive* get_singleton();
static ZipArchive *get_singleton();
ZipArchive();
~ZipArchive();
};
class FileAccessZip : public FileAccess {
unzFile zfile;
unz_file_info64 file_info;
unz_file_info64 file_info;
mutable bool at_eof;
ZipArchive* archive;
ZipArchive *archive;
public:
virtual Error _open(const String& p_path, int p_mode_flags); ///< open a file
virtual Error _open(const String &p_path, int p_mode_flags); ///< open a file
virtual void close(); ///< close a file
virtual bool is_open() const; ///< true when file is open
virtual void seek(size_t p_position); ///< seek to a given position
virtual void seek_end(int64_t p_position=0); ///< seek from the end of file
virtual void seek_end(int64_t p_position = 0); ///< seek from the end of file
virtual size_t get_pos() const; ///< get position in the file
virtual size_t get_len() const; ///< get size of the file
virtual bool eof_reached() const; ///< reading passed EOF
virtual uint8_t get_8() const; ///< get a byte
virtual int get_buffer(uint8_t *p_dst,int p_length) const;
virtual int get_buffer(uint8_t *p_dst, int p_length) const;
virtual Error get_error() const; ///< get last error
virtual void store_8(uint8_t p_dest); ///< store a byte
virtual bool file_exists(const String& p_name); ///< return true if a file exists
virtual bool file_exists(const String &p_name); ///< return true if a file exists
virtual uint64_t _get_modified_time(const String& p_file) { return 0; } // todo
virtual uint64_t _get_modified_time(const String &p_file) { return 0; } // todo
FileAccessZip(const String& p_path, const PackedData::PackedFile& p_file);
FileAccessZip(const String &p_path, const PackedData::PackedFile &p_file);
~FileAccessZip();
};

File diff suppressed because it is too large Load Diff

View File

@ -29,17 +29,16 @@
#ifndef HTTP_CLIENT_H
#define HTTP_CLIENT_H
#include "io/ip.h"
#include "io/stream_peer.h"
#include "io/stream_peer_tcp.h"
#include "io/ip.h"
#include "reference.h"
class HTTPClient : public Reference {
OBJ_TYPE(HTTPClient,Reference);
public:
OBJ_TYPE(HTTPClient, Reference);
public:
enum ResponseCode {
// 1xx informational
@ -131,7 +130,6 @@ public:
};
private:
IP::Type ip_type;
Status status;
IP::ResolverID resolving;
@ -160,22 +158,20 @@ private:
Dictionary _get_response_headers_as_dictionary();
int read_chunk_size;
Error _get_http_data(uint8_t* p_buffer, int p_bytes,int &r_received);
Error _get_http_data(uint8_t *p_buffer, int p_bytes, int &r_received);
public:
void set_ip_type(IP::Type p_type);
//Error connect_and_get(const String& p_url,bool p_verify_host=true); //connects to a full url and perform request
Error connect(const String &p_host,int p_port,bool p_ssl=false,bool p_verify_host=true);
Error connect(const String &p_host, int p_port, bool p_ssl = false, bool p_verify_host = true);
void set_connection(const Ref<StreamPeer>& p_connection);
void set_connection(const Ref<StreamPeer> &p_connection);
Ref<StreamPeer> get_connection() const;
Error request_raw( Method p_method, const String& p_url, const Vector<String>& p_headers,const DVector<uint8_t>& p_body);
Error request( Method p_method, const String& p_url, const Vector<String>& p_headers,const String& p_body=String());
Error send_body_text(const String& p_body);
Error send_body_data(const ByteArray& p_body);
Error request_raw(Method p_method, const String &p_url, const Vector<String> &p_headers, const DVector<uint8_t> &p_body);
Error request(Method p_method, const String &p_url, const Vector<String> &p_headers, const String &p_body = String());
Error send_body_text(const String &p_body);
Error send_body_data(const ByteArray &p_body);
void close();
@ -196,7 +192,7 @@ public:
Error poll();
String query_string_from_dict(const Dictionary& p_dict);
String query_string_from_dict(const Dictionary &p_dict);
HTTPClient();
~HTTPClient();

View File

@ -29,90 +29,78 @@
#include "image_loader.h"
#include "print_string.h"
bool ImageFormatLoader::recognize(const String& p_extension) const {
bool ImageFormatLoader::recognize(const String &p_extension) const {
List<String> extensions;
get_recognized_extensions(&extensions);
for (List<String>::Element *E=extensions.front();E;E=E->next()) {
for (List<String>::Element *E = extensions.front(); E; E = E->next()) {
if (E->get().nocasecmp_to(p_extension.extension())==0)
if (E->get().nocasecmp_to(p_extension.extension()) == 0)
return true;
}
return false;
}
Error ImageLoader::load_image(String p_file,Image *p_image, FileAccess *p_custom) {
Error ImageLoader::load_image(String p_file, Image *p_image, FileAccess *p_custom) {
FileAccess *f=p_custom;
FileAccess *f = p_custom;
if (!f) {
Error err;
f=FileAccess::open(p_file,FileAccess::READ,&err);
f = FileAccess::open(p_file, FileAccess::READ, &err);
if (!f) {
ERR_PRINTS("Error opening file: "+p_file);
ERR_PRINTS("Error opening file: " + p_file);
return err;
}
}
String extension = p_file.extension();
for (int i=0;i<loader_count;i++) {
for (int i = 0; i < loader_count; i++) {
if (!loader[i]->recognize(extension))
continue;
Error err = loader[i]->load_image(p_image,f);
if (err!=ERR_FILE_UNRECOGNIZED) {
Error err = loader[i]->load_image(p_image, f);
if (err != ERR_FILE_UNRECOGNIZED) {
if (!p_custom)
memdelete(f);
return err;
}
}
if (!p_custom)
memdelete(f);
return ERR_FILE_UNRECOGNIZED;
}
void ImageLoader::get_recognized_extensions(List<String> *p_extensions) {
for (int i=0;i<loader_count;i++) {
for (int i = 0; i < loader_count; i++) {
loader[i]->get_recognized_extensions(p_extensions);
}
}
bool ImageLoader::recognize(const String& p_extension) {
bool ImageLoader::recognize(const String &p_extension) {
for (int i=0;i<loader_count;i++) {
for (int i = 0; i < loader_count; i++) {
if (loader[i]->recognize(p_extension))
return true;
}
return false;
}
ImageFormatLoader *ImageLoader::loader[MAX_LOADERS];
int ImageLoader::loader_count=0;
int ImageLoader::loader_count = 0;
void ImageLoader::add_image_format_loader(ImageFormatLoader *p_loader) {
ERR_FAIL_COND(loader_count >=MAX_LOADERS );
loader[loader_count++]=p_loader;
ERR_FAIL_COND(loader_count >= MAX_LOADERS);
loader[loader_count++] = p_loader;
}

View File

@ -30,14 +30,13 @@
#define IMAGE_LOADER_H
#include "image.h"
#include "ustring.h"
#include "os/file_access.h"
#include "list.h"
#include "os/file_access.h"
#include "ustring.h"
/**
@author Juan Linietsky <reduzio@gmail.com>
*/
/**
* @class ImageScanLineLoader
* @author Juan Linietsky <reduzio@gmail.com>
@ -46,21 +45,19 @@
*/
class ImageLoader;
/**
* @class ImageLoader
* Base Class and singleton for loading images from disk
* Can load images in one go, or by scanline
*/
class ImageFormatLoader {
friend class ImageLoader;
protected:
virtual Error load_image(Image *p_image,FileAccess *p_fileaccess)=0;
virtual void get_recognized_extensions(List<String> *p_extensions) const=0;
bool recognize(const String& p_extension) const;
friend class ImageLoader;
protected:
virtual Error load_image(Image *p_image, FileAccess *p_fileaccess) = 0;
virtual void get_recognized_extensions(List<String> *p_extensions) const = 0;
bool recognize(const String &p_extension) const;
public:
virtual ~ImageFormatLoader() {}
@ -69,23 +66,19 @@ public:
class ImageLoader {
enum {
MAX_LOADERS=8
MAX_LOADERS = 8
};
static ImageFormatLoader *loader[MAX_LOADERS];
static int loader_count;
protected:
public:
static Error load_image(String p_file,Image *p_image, FileAccess *p_custom=NULL);
static void get_recognized_extensions(List<String> *p_extensions) ;
static bool recognize(const String& p_extension) ;
static Error load_image(String p_file, Image *p_image, FileAccess *p_custom = NULL);
static void get_recognized_extensions(List<String> *p_extensions);
static bool recognize(const String &p_extension);
static void add_image_format_loader(ImageFormatLoader *p_loader);
};
#endif

View File

@ -27,15 +27,14 @@
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
/*************************************************************************/
#include "ip.h"
#include "os/thread.h"
#include "os/semaphore.h"
#include "hash_map.h"
#include "os/semaphore.h"
#include "os/thread.h"
VARIANT_ENUM_CAST(IP::ResolverStatus);
/************* RESOLVER ******************/
struct _IP_ResolverPrivate {
struct QueueItem {
@ -49,7 +48,7 @@ struct _IP_ResolverPrivate {
status = IP::RESOLVER_STATUS_NONE;
response = IP_Address();
type = IP::TYPE_NONE;
hostname="";
hostname = "";
};
QueueItem() {
@ -61,8 +60,8 @@ struct _IP_ResolverPrivate {
IP::ResolverID find_empty_id() const {
for(int i=0;i<IP::RESOLVER_MAX_QUERIES;i++) {
if (queue[i].status==IP::RESOLVER_STATUS_NONE)
for (int i = 0; i < IP::RESOLVER_MAX_QUERIES; i++) {
if (queue[i].status == IP::RESOLVER_STATUS_NONE)
return i;
}
return IP::RESOLVER_INVALID_ID;
@ -70,39 +69,35 @@ struct _IP_ResolverPrivate {
Semaphore *sem;
Thread* thread;
Thread *thread;
//Semaphore* semaphore;
bool thread_abort;
void resolve_queues() {
for(int i=0;i<IP::RESOLVER_MAX_QUERIES;i++) {
for (int i = 0; i < IP::RESOLVER_MAX_QUERIES; i++) {
if (queue[i].status!=IP::RESOLVER_STATUS_WAITING)
if (queue[i].status != IP::RESOLVER_STATUS_WAITING)
continue;
queue[i].response=IP::get_singleton()->resolve_hostname(queue[i].hostname, queue[i].type);
queue[i].response = IP::get_singleton()->resolve_hostname(queue[i].hostname, queue[i].type);
if (queue[i].response==IP_Address())
queue[i].status=IP::RESOLVER_STATUS_ERROR;
if (queue[i].response == IP_Address())
queue[i].status = IP::RESOLVER_STATUS_ERROR;
else
queue[i].status=IP::RESOLVER_STATUS_DONE;
queue[i].status = IP::RESOLVER_STATUS_DONE;
}
}
static void _thread_function(void *self) {
_IP_ResolverPrivate *ipr=(_IP_ResolverPrivate*)self;
_IP_ResolverPrivate *ipr = (_IP_ResolverPrivate *)self;
while(!ipr->thread_abort) {
while (!ipr->thread_abort) {
ipr->sem->wait();
GLOBAL_LOCK_FUNCTION;
ipr->resolve_queues();
}
}
HashMap<String, IP_Address> cache;
@ -110,12 +105,9 @@ struct _IP_ResolverPrivate {
static String get_cache_key(String p_hostname, IP::Type p_type) {
return itos(p_type) + p_hostname;
}
};
IP_Address IP::resolve_hostname(const String& p_hostname, IP::Type p_type) {
IP_Address IP::resolve_hostname(const String &p_hostname, IP::Type p_type) {
GLOBAL_LOCK_FUNCTION;
@ -124,30 +116,29 @@ IP_Address IP::resolve_hostname(const String& p_hostname, IP::Type p_type) {
return resolver->cache[key];
IP_Address res = _resolve_hostname(p_hostname, p_type);
resolver->cache[key]=res;
resolver->cache[key] = res;
return res;
}
IP::ResolverID IP::resolve_hostname_queue_item(const String& p_hostname, IP::Type p_type) {
IP::ResolverID IP::resolve_hostname_queue_item(const String &p_hostname, IP::Type p_type) {
GLOBAL_LOCK_FUNCTION;
ResolverID id = resolver->find_empty_id();
if (id==RESOLVER_INVALID_ID) {
if (id == RESOLVER_INVALID_ID) {
WARN_PRINT("Out of resolver queries");
return id;
}
String key = _IP_ResolverPrivate::get_cache_key(p_hostname, p_type);
resolver->queue[id].hostname=p_hostname;
resolver->queue[id].hostname = p_hostname;
resolver->queue[id].type = p_type;
if (resolver->cache.has(key)) {
resolver->queue[id].response=resolver->cache[key];
resolver->queue[id].status=IP::RESOLVER_STATUS_DONE;
resolver->queue[id].response = resolver->cache[key];
resolver->queue[id].status = IP::RESOLVER_STATUS_DONE;
} else {
resolver->queue[id].response=IP_Address();
resolver->queue[id].status=IP::RESOLVER_STATUS_WAITING;
resolver->queue[id].response = IP_Address();
resolver->queue[id].status = IP::RESOLVER_STATUS_WAITING;
if (resolver->thread)
resolver->sem->post();
else
@ -159,37 +150,33 @@ IP::ResolverID IP::resolve_hostname_queue_item(const String& p_hostname, IP::Typ
IP::ResolverStatus IP::get_resolve_item_status(ResolverID p_id) const {
ERR_FAIL_INDEX_V(p_id,IP::RESOLVER_MAX_QUERIES,IP::RESOLVER_STATUS_NONE);
ERR_FAIL_INDEX_V(p_id, IP::RESOLVER_MAX_QUERIES, IP::RESOLVER_STATUS_NONE);
GLOBAL_LOCK_FUNCTION;
ERR_FAIL_COND_V(resolver->queue[p_id].status==IP::RESOLVER_STATUS_NONE,IP::RESOLVER_STATUS_NONE);
ERR_FAIL_COND_V(resolver->queue[p_id].status == IP::RESOLVER_STATUS_NONE, IP::RESOLVER_STATUS_NONE);
return resolver->queue[p_id].status;
}
IP_Address IP::get_resolve_item_address(ResolverID p_id) const {
ERR_FAIL_INDEX_V(p_id,IP::RESOLVER_MAX_QUERIES,IP_Address());
ERR_FAIL_INDEX_V(p_id, IP::RESOLVER_MAX_QUERIES, IP_Address());
GLOBAL_LOCK_FUNCTION;
if (resolver->queue[p_id].status!=IP::RESOLVER_STATUS_DONE) {
ERR_EXPLAIN("Resolve of '"+resolver->queue[p_id].hostname+"'' didn't complete yet.");
ERR_FAIL_COND_V(resolver->queue[p_id].status!=IP::RESOLVER_STATUS_DONE,IP_Address());
if (resolver->queue[p_id].status != IP::RESOLVER_STATUS_DONE) {
ERR_EXPLAIN("Resolve of '" + resolver->queue[p_id].hostname + "'' didn't complete yet.");
ERR_FAIL_COND_V(resolver->queue[p_id].status != IP::RESOLVER_STATUS_DONE, IP_Address());
}
return resolver->queue[p_id].response;
}
void IP::erase_resolve_item(ResolverID p_id) {
ERR_FAIL_INDEX(p_id,IP::RESOLVER_MAX_QUERIES);
ERR_FAIL_INDEX(p_id, IP::RESOLVER_MAX_QUERIES);
GLOBAL_LOCK_FUNCTION;
resolver->queue[p_id].status=IP::RESOLVER_STATUS_NONE;
resolver->queue[p_id].status = IP::RESOLVER_STATUS_NONE;
}
void IP::clear_cache(const String &p_hostname) {
@ -209,7 +196,7 @@ Array IP::_get_local_addresses() const {
Array addresses;
List<IP_Address> ip_addresses;
get_local_addresses(&ip_addresses);
for(List<IP_Address>::Element *E=ip_addresses.front();E;E=E->next()) {
for (List<IP_Address>::Element *E = ip_addresses.front(); E; E = E->next()) {
addresses.push_back(E->get());
}
@ -218,87 +205,82 @@ Array IP::_get_local_addresses() const {
void IP::_bind_methods() {
ObjectTypeDB::bind_method(_MD("resolve_hostname","host","ip_type"),&IP::resolve_hostname,DEFVAL(IP::TYPE_ANY));
ObjectTypeDB::bind_method(_MD("resolve_hostname_queue_item","host","ip_type"),&IP::resolve_hostname_queue_item,DEFVAL(IP::TYPE_ANY));
ObjectTypeDB::bind_method(_MD("get_resolve_item_status","id"),&IP::get_resolve_item_status);
ObjectTypeDB::bind_method(_MD("get_resolve_item_address","id"),&IP::get_resolve_item_address);
ObjectTypeDB::bind_method(_MD("erase_resolve_item","id"),&IP::erase_resolve_item);
ObjectTypeDB::bind_method(_MD("get_local_addresses"),&IP::_get_local_addresses);
ObjectTypeDB::bind_method(_MD("clear_cache"),&IP::clear_cache, DEFVAL(""));
ObjectTypeDB::bind_method(_MD("resolve_hostname", "host", "ip_type"), &IP::resolve_hostname, DEFVAL(IP::TYPE_ANY));
ObjectTypeDB::bind_method(_MD("resolve_hostname_queue_item", "host", "ip_type"), &IP::resolve_hostname_queue_item, DEFVAL(IP::TYPE_ANY));
ObjectTypeDB::bind_method(_MD("get_resolve_item_status", "id"), &IP::get_resolve_item_status);
ObjectTypeDB::bind_method(_MD("get_resolve_item_address", "id"), &IP::get_resolve_item_address);
ObjectTypeDB::bind_method(_MD("erase_resolve_item", "id"), &IP::erase_resolve_item);
ObjectTypeDB::bind_method(_MD("get_local_addresses"), &IP::_get_local_addresses);
ObjectTypeDB::bind_method(_MD("clear_cache"), &IP::clear_cache, DEFVAL(""));
BIND_CONSTANT( RESOLVER_STATUS_NONE );
BIND_CONSTANT( RESOLVER_STATUS_WAITING );
BIND_CONSTANT( RESOLVER_STATUS_DONE );
BIND_CONSTANT( RESOLVER_STATUS_ERROR );
BIND_CONSTANT(RESOLVER_STATUS_NONE);
BIND_CONSTANT(RESOLVER_STATUS_WAITING);
BIND_CONSTANT(RESOLVER_STATUS_DONE);
BIND_CONSTANT(RESOLVER_STATUS_ERROR);
BIND_CONSTANT( RESOLVER_MAX_QUERIES );
BIND_CONSTANT( RESOLVER_INVALID_ID );
BIND_CONSTANT(RESOLVER_MAX_QUERIES);
BIND_CONSTANT(RESOLVER_INVALID_ID);
BIND_CONSTANT( TYPE_NONE );
BIND_CONSTANT( TYPE_IPV4 );
BIND_CONSTANT( TYPE_IPV6 );
BIND_CONSTANT( TYPE_ANY );
BIND_CONSTANT(TYPE_NONE);
BIND_CONSTANT(TYPE_IPV4);
BIND_CONSTANT(TYPE_IPV6);
BIND_CONSTANT(TYPE_ANY);
}
IP *IP::singleton = NULL;
IP*IP::singleton=NULL;
IP* IP::get_singleton() {
IP *IP::get_singleton() {
return singleton;
}
IP *(*IP::_create)() = NULL;
IP* (*IP::_create)()=NULL;
IP *IP::create() {
IP* IP::create() {
ERR_FAIL_COND_V(singleton,NULL);
ERR_FAIL_COND_V(!_create,NULL);
ERR_FAIL_COND_V(singleton, NULL);
ERR_FAIL_COND_V(!_create, NULL);
return _create();
}
IP::IP() {
singleton=this;
resolver = memnew( _IP_ResolverPrivate );
resolver->sem=NULL;
singleton = this;
resolver = memnew(_IP_ResolverPrivate);
resolver->sem = NULL;
#ifndef NO_THREADS
//resolver->sem = Semaphore::create();
resolver->sem=NULL;
resolver->sem = NULL;
if (resolver->sem) {
resolver->thread_abort=false;
resolver->thread_abort = false;
resolver->thread = Thread::create( _IP_ResolverPrivate::_thread_function,resolver );
resolver->thread = Thread::create(_IP_ResolverPrivate::_thread_function, resolver);
if (!resolver->thread)
memdelete(resolver->sem); //wtf
} else {
resolver->thread=NULL;
resolver->thread = NULL;
}
#else
resolver->sem = NULL;
resolver->thread=NULL;
resolver->thread = NULL;
#endif
}
IP::~IP() {
#ifndef NO_THREADS
if (resolver->thread) {
resolver->thread_abort=true;
resolver->thread_abort = true;
resolver->sem->post();
Thread::wait_to_finish(resolver->thread);
memdelete( resolver->thread );
memdelete( resolver->sem);
memdelete(resolver->thread);
memdelete(resolver->sem);
}
memdelete(resolver);
#endif
}

View File

@ -29,17 +29,16 @@
#ifndef IP_H
#define IP_H
#include "os/os.h"
#include "io/ip_address.h"
#include "os/os.h"
struct _IP_ResolverPrivate;
class IP : public Object {
OBJ_TYPE( IP, Object );
OBJ_TYPE(IP, Object);
OBJ_CATEGORY("Networking");
public:
public:
enum ResolverStatus {
RESOLVER_STATUS_NONE,
@ -58,47 +57,40 @@ public:
enum {
RESOLVER_MAX_QUERIES = 32,
RESOLVER_INVALID_ID=-1
RESOLVER_INVALID_ID = -1
};
typedef int ResolverID;
private:
_IP_ResolverPrivate *resolver;
protected:
static IP*singleton;
protected:
static IP *singleton;
static void _bind_methods();
virtual IP_Address _resolve_hostname(const String& p_hostname, Type p_type = TYPE_ANY)=0;
virtual IP_Address _resolve_hostname(const String &p_hostname, Type p_type = TYPE_ANY) = 0;
Array _get_local_addresses() const;
static IP* (*_create)();
static IP *(*_create)();
public:
IP_Address resolve_hostname(const String& p_hostname, Type p_type = TYPE_ANY);
IP_Address resolve_hostname(const String &p_hostname, Type p_type = TYPE_ANY);
// async resolver hostname
ResolverID resolve_hostname_queue_item(const String& p_hostname, Type p_type = TYPE_ANY);
ResolverID resolve_hostname_queue_item(const String &p_hostname, Type p_type = TYPE_ANY);
ResolverStatus get_resolve_item_status(ResolverID p_id) const;
IP_Address get_resolve_item_address(ResolverID p_id) const;
virtual void get_local_addresses(List<IP_Address> *r_addresses) const=0;
virtual void get_local_addresses(List<IP_Address> *r_addresses) const = 0;
void erase_resolve_item(ResolverID p_id);
void clear_cache(const String& p_hostname = "");
void clear_cache(const String &p_hostname = "");
static IP* get_singleton();
static IP *get_singleton();
static IP* create();
static IP *create();
IP();
~IP();
};
VARIANT_ENUM_CAST(IP::Type);

View File

@ -33,29 +33,29 @@ IP_Address::operator Variant() const {
return operator String();
}*/
#include <string.h>
#include <stdio.h>
#include <string.h>
IP_Address::operator String() const {
if(is_ipv4())
if (is_ipv4())
// IPv4 address mapped to IPv6
return itos(field8[12])+"."+itos(field8[13])+"."+itos(field8[14])+"."+itos(field8[15]);
return itos(field8[12]) + "." + itos(field8[13]) + "." + itos(field8[14]) + "." + itos(field8[15]);
String ret;
for (int i=0; i<8; i++) {
for (int i = 0; i < 8; i++) {
if (i > 0)
ret = ret + ":";
uint16_t num = (field8[i*2] << 8) + field8[i*2+1];
uint16_t num = (field8[i * 2] << 8) + field8[i * 2 + 1];
ret = ret + String::num_int64(num, 16);
};
return ret;
}
static void _parse_hex(const String& p_string, int p_start, uint8_t* p_dst) {
static void _parse_hex(const String &p_string, int p_start, uint8_t *p_dst) {
uint16_t ret = 0;
for (int i=p_start; i<p_start + 4; i++) {
for (int i = p_start; i < p_start + 4; i++) {
if (i >= p_string.length()) {
break;
@ -84,17 +84,17 @@ static void _parse_hex(const String& p_string, int p_start, uint8_t* p_dst) {
p_dst[1] = ret & 0xff;
};
void IP_Address::_parse_ipv6(const String& p_string) {
void IP_Address::_parse_ipv6(const String &p_string) {
static const int parts_total = 8;
int parts[parts_total] = {0};
int parts[parts_total] = { 0 };
int parts_count = 0;
bool part_found = false;
bool part_skip = false;
bool part_ipv4 = false;
int parts_idx = 0;
for (int i=0; i<p_string.length(); i++) {
for (int i = 0; i < p_string.length(); i++) {
CharType c = p_string[i];
if (c == ':') {
@ -130,26 +130,25 @@ void IP_Address::_parse_ipv6(const String& p_string) {
};
int idx = 0;
for (int i=0; i<parts_idx; i++) {
for (int i = 0; i < parts_idx; i++) {
if (parts[i] == -1) {
for (int j=0; j<parts_extra; j++) {
for (int j = 0; j < parts_extra; j++) {
field16[idx++] = 0;
};
continue;
};
if (part_ipv4 && i == parts_idx - 1) {
_parse_ipv4(p_string, parts[i], (uint8_t*)&field16[idx]); // should be the last one
_parse_ipv4(p_string, parts[i], (uint8_t *)&field16[idx]); // should be the last one
} else {
_parse_hex(p_string, parts[i], (uint8_t*)&(field16[idx++]));
_parse_hex(p_string, parts[i], (uint8_t *)&(field16[idx++]));
};
};
};
void IP_Address::_parse_ipv4(const String& p_string, int p_start, uint8_t* p_ret) {
void IP_Address::_parse_ipv4(const String &p_string, int p_start, uint8_t *p_ret) {
String ip;
if (p_start != 0) {
@ -159,12 +158,12 @@ void IP_Address::_parse_ipv4(const String& p_string, int p_start, uint8_t* p_ret
};
int slices = ip.get_slice_count(".");
if (slices!=4) {
ERR_EXPLAIN("Invalid IP Address String: "+ip);
if (slices != 4) {
ERR_EXPLAIN("Invalid IP Address String: " + ip);
ERR_FAIL();
}
for(int i=0;i<4;i++) {
p_ret[i]=ip.get_slicec('.',i).to_int();
for (int i = 0; i < 4; i++) {
p_ret[i] = ip.get_slicec('.', i).to_int();
}
};
@ -173,32 +172,32 @@ void IP_Address::clear() {
memset(&field8[0], 0, sizeof(field8));
};
bool IP_Address::is_ipv4() const{
return (field32[0]==0 && field32[1]==0 && field16[4]==0 && field16[5]==0xffff);
bool IP_Address::is_ipv4() const {
return (field32[0] == 0 && field32[1] == 0 && field16[4] == 0 && field16[5] == 0xffff);
}
const uint8_t *IP_Address::get_ipv4() const{
ERR_FAIL_COND_V(!is_ipv4(),0);
const uint8_t *IP_Address::get_ipv4() const {
ERR_FAIL_COND_V(!is_ipv4(), 0);
return &(field8[12]);
}
void IP_Address::set_ipv4(const uint8_t *p_ip) {
clear();
field16[5]=0xffff;
field32[3]=*((const uint32_t *)p_ip);
field16[5] = 0xffff;
field32[3] = *((const uint32_t *)p_ip);
}
const uint8_t *IP_Address::get_ipv6() const{
const uint8_t *IP_Address::get_ipv6() const {
return field8;
}
void IP_Address::set_ipv6(const uint8_t *p_buf) {
clear();
for (int i=0; i<16; i++)
for (int i = 0; i < 16; i++)
field8[i] = p_buf[i];
}
IP_Address::IP_Address(const String& p_string) {
IP_Address::IP_Address(const String &p_string) {
clear();
if (p_string.find(":") >= 0) {
@ -211,7 +210,7 @@ IP_Address::IP_Address(const String& p_string) {
};
}
_FORCE_INLINE_ static void _32_to_buf(uint8_t* p_dst, uint32_t p_n) {
_FORCE_INLINE_ static void _32_to_buf(uint8_t *p_dst, uint32_t p_n) {
p_dst[0] = (p_n >> 24) & 0xff;
p_dst[1] = (p_n >> 16) & 0xff;
@ -219,16 +218,16 @@ _FORCE_INLINE_ static void _32_to_buf(uint8_t* p_dst, uint32_t p_n) {
p_dst[3] = (p_n >> 0) & 0xff;
};
IP_Address::IP_Address(uint32_t p_a,uint32_t p_b,uint32_t p_c,uint32_t p_d, bool is_v6) {
IP_Address::IP_Address(uint32_t p_a, uint32_t p_b, uint32_t p_c, uint32_t p_d, bool is_v6) {
clear();
if (!is_v6) {
// Mapped to IPv6
field16[5]=0xffff;
field8[12]=p_a;
field8[13]=p_b;
field8[14]=p_c;
field8[15]=p_d;
field16[5] = 0xffff;
field8[12] = p_a;
field8[13] = p_b;
field8[14] = p_c;
field8[15] = p_d;
} else {
_32_to_buf(&field8[0], p_a);
@ -236,5 +235,4 @@ IP_Address::IP_Address(uint32_t p_a,uint32_t p_b,uint32_t p_c,uint32_t p_d, bool
_32_to_buf(&field8[8], p_c);
_32_to_buf(&field8[12], p_d);
}
}

View File

@ -34,7 +34,6 @@
struct IP_Address {
private:
union {
uint8_t field8[16];
uint16_t field16[8];
@ -42,19 +41,19 @@ private:
};
protected:
void _parse_ipv6(const String& p_string);
void _parse_ipv4(const String& p_string, int p_start, uint8_t* p_ret);
void _parse_ipv6(const String &p_string);
void _parse_ipv4(const String &p_string, int p_start, uint8_t *p_ret);
public:
//operator Variant() const;
bool operator==(const IP_Address& p_ip) const {
for (int i=0; i<4; i++)
bool operator==(const IP_Address &p_ip) const {
for (int i = 0; i < 4; i++)
if (field32[i] != p_ip.field32[i])
return false;
return true;
}
bool operator!=(const IP_Address& p_ip) const {
for (int i=0; i<4; i++)
bool operator!=(const IP_Address &p_ip) const {
for (int i = 0; i < 4; i++)
if (field32[i] != p_ip.field32[i])
return true;
return false;
@ -69,11 +68,9 @@ public:
void set_ipv6(const uint8_t *buf);
operator String() const;
IP_Address(const String& p_string);
IP_Address(uint32_t p_a,uint32_t p_b,uint32_t p_c,uint32_t p_d, bool is_v6=false);
IP_Address(const String &p_string);
IP_Address(uint32_t p_a, uint32_t p_b, uint32_t p_c, uint32_t p_d, bool is_v6 = false);
IP_Address() { clear(); }
};
#endif // IP_ADDRESS_H

View File

@ -29,7 +29,7 @@
#include "json.h"
#include "print_string.h"
const char * JSON::tk_name[TK_MAX] = {
const char *JSON::tk_name[TK_MAX] = {
"'{'",
"'}'",
"'['",
@ -42,14 +42,12 @@ const char * JSON::tk_name[TK_MAX] = {
"EOF",
};
String JSON::_print_var(const Variant &p_var) {
String JSON::_print_var(const Variant& p_var) {
switch(p_var.get_type()) {
switch (p_var.get_type()) {
case Variant::NIL: return "null";
case Variant::BOOL: return p_var.operator bool() ? "true": "false";
case Variant::BOOL: return p_var.operator bool() ? "true" : "false";
case Variant::INT: return itos(p_var);
case Variant::REAL: return rtos(p_var);
case Variant::INT_ARRAY:
@ -59,12 +57,12 @@ String JSON::_print_var(const Variant& p_var) {
String s = "[";
Array a = p_var;
for(int i=0;i<a.size();i++) {
if (i>0)
s+=", ";
s+=_print_var(a[i]);
for (int i = 0; i < a.size(); i++) {
if (i > 0)
s += ", ";
s += _print_var(a[i]);
}
s+="]";
s += "]";
return s;
};
case Variant::DICTIONARY: {
@ -74,34 +72,31 @@ String JSON::_print_var(const Variant& p_var) {
List<Variant> keys;
d.get_key_list(&keys);
for (List<Variant>::Element *E=keys.front();E;E=E->next()) {
for (List<Variant>::Element *E = keys.front(); E; E = E->next()) {
if (E!=keys.front())
s+=", ";
s+=_print_var(String(E->get()));
s+=":";
s+=_print_var(d[E->get()]);
if (E != keys.front())
s += ", ";
s += _print_var(String(E->get()));
s += ":";
s += _print_var(d[E->get()]);
}
s+="}";
s += "}";
return s;
};
default: return "\""+String(p_var).json_escape()+"\"";
default: return "\"" + String(p_var).json_escape() + "\"";
}
}
String JSON::print(const Dictionary& p_dict) {
String JSON::print(const Dictionary &p_dict) {
return _print_var(p_dict);
}
Error JSON::_get_token(const CharType *p_str, int &idx, int p_len, Token& r_token,int &line,String &r_err_str) {
Error JSON::_get_token(const CharType *p_str, int &idx, int p_len, Token &r_token, int &line, String &r_err_str) {
while (true) {
switch(p_str[idx]) {
switch (p_str[idx]) {
case '\n': {
@ -110,42 +105,42 @@ Error JSON::_get_token(const CharType *p_str, int &idx, int p_len, Token& r_toke
break;
};
case 0: {
r_token.type=TK_EOF;
r_token.type = TK_EOF;
return OK;
} break;
case '{': {
r_token.type=TK_CURLY_BRACKET_OPEN;
r_token.type = TK_CURLY_BRACKET_OPEN;
idx++;
return OK;
};
case '}': {
r_token.type=TK_CURLY_BRACKET_CLOSE;
r_token.type = TK_CURLY_BRACKET_CLOSE;
idx++;
return OK;
};
case '[': {
r_token.type=TK_BRACKET_OPEN;
r_token.type = TK_BRACKET_OPEN;
idx++;
return OK;
};
case ']': {
r_token.type=TK_BRACKET_CLOSE;
r_token.type = TK_BRACKET_CLOSE;
idx++;
return OK;
};
case ':': {
r_token.type=TK_COLON;
r_token.type = TK_COLON;
idx++;
return OK;
};
case ',': {
r_token.type=TK_COMMA;
r_token.type = TK_COMMA;
idx++;
return OK;
};
@ -153,66 +148,62 @@ Error JSON::_get_token(const CharType *p_str, int &idx, int p_len, Token& r_toke
idx++;
String str;
while(true) {
if (p_str[idx]==0) {
r_err_str="Unterminated String";
while (true) {
if (p_str[idx] == 0) {
r_err_str = "Unterminated String";
return ERR_PARSE_ERROR;
} else if (p_str[idx]=='"') {
} else if (p_str[idx] == '"') {
idx++;
break;
} else if (p_str[idx]=='\\') {
} else if (p_str[idx] == '\\') {
//escaped characters...
idx++;
CharType next = p_str[idx];
if (next==0) {
r_err_str="Unterminated String";
return ERR_PARSE_ERROR;
if (next == 0) {
r_err_str = "Unterminated String";
return ERR_PARSE_ERROR;
}
CharType res=0;
CharType res = 0;
switch(next) {
switch (next) {
case 'b': res=8; break;
case 't': res=9; break;
case 'n': res=10; break;
case 'f': res=12; break;
case 'r': res=13; break;
case 'b': res = 8; break;
case 't': res = 9; break;
case 'n': res = 10; break;
case 'f': res = 12; break;
case 'r': res = 13; break;
case 'u': {
//hexnumbarh - oct is deprecated
for(int j=0;j<4;j++) {
CharType c = p_str[idx+j+1];
if (c==0) {
r_err_str="Unterminated String";
for (int j = 0; j < 4; j++) {
CharType c = p_str[idx + j + 1];
if (c == 0) {
r_err_str = "Unterminated String";
return ERR_PARSE_ERROR;
}
if (!((c>='0' && c<='9') || (c>='a' && c<='f') || (c>='A' && c<='F'))) {
if (!((c >= '0' && c <= '9') || (c >= 'a' && c <= 'f') || (c >= 'A' && c <= 'F'))) {
r_err_str="Malformed hex constant in string";
r_err_str = "Malformed hex constant in string";
return ERR_PARSE_ERROR;
}
CharType v;
if (c>='0' && c<='9') {
v=c-'0';
} else if (c>='a' && c<='f') {
v=c-'a';
v+=10;
} else if (c>='A' && c<='F') {
v=c-'A';
v+=10;
if (c >= '0' && c <= '9') {
v = c - '0';
} else if (c >= 'a' && c <= 'f') {
v = c - 'a';
v += 10;
} else if (c >= 'A' && c <= 'F') {
v = c - 'A';
v += 10;
} else {
ERR_PRINT("BUG");
v=0;
v = 0;
}
res<<=4;
res|=v;
res <<= 4;
res |= v;
}
idx+=4; //will add at the end anyway
idx += 4; //will add at the end anyway
} break;
//case '\"': res='\"'; break;
@ -225,253 +216,236 @@ Error JSON::_get_token(const CharType *p_str, int &idx, int p_len, Token& r_toke
} break;
}
str+=res;
str += res;
} else {
if (p_str[idx]=='\n')
if (p_str[idx] == '\n')
line++;
str+=p_str[idx];
str += p_str[idx];
}
idx++;
}
r_token.type=TK_STRING;
r_token.value=str;
r_token.type = TK_STRING;
r_token.value = str;
return OK;
} break;
default: {
if (p_str[idx]<=32) {
if (p_str[idx] <= 32) {
idx++;
break;
}
if (p_str[idx]=='-' || (p_str[idx]>='0' && p_str[idx]<='9')) {
if (p_str[idx] == '-' || (p_str[idx] >= '0' && p_str[idx] <= '9')) {
//a number
const CharType *rptr;
double number = String::to_double(&p_str[idx],&rptr);
idx+=(rptr - &p_str[idx]);
r_token.type=TK_NUMBER;
r_token.value=number;
double number = String::to_double(&p_str[idx], &rptr);
idx += (rptr - &p_str[idx]);
r_token.type = TK_NUMBER;
r_token.value = number;
return OK;
} else if ((p_str[idx]>='A' && p_str[idx]<='Z') || (p_str[idx]>='a' && p_str[idx]<='z')) {
} else if ((p_str[idx] >= 'A' && p_str[idx] <= 'Z') || (p_str[idx] >= 'a' && p_str[idx] <= 'z')) {
String id;
while((p_str[idx]>='A' && p_str[idx]<='Z') || (p_str[idx]>='a' && p_str[idx]<='z')) {
while ((p_str[idx] >= 'A' && p_str[idx] <= 'Z') || (p_str[idx] >= 'a' && p_str[idx] <= 'z')) {
id+=p_str[idx];
id += p_str[idx];
idx++;
}
r_token.type=TK_IDENTIFIER;
r_token.value=id;
r_token.type = TK_IDENTIFIER;
r_token.value = id;
return OK;
} else {
r_err_str="Unexpected character.";
r_err_str = "Unexpected character.";
return ERR_PARSE_ERROR;
}
}
}
}
return ERR_PARSE_ERROR;
}
Error JSON::_parse_value(Variant &value, Token &token, const CharType *p_str, int &index, int p_len, int &line, String &r_err_str) {
Error JSON::_parse_value(Variant &value,Token& token,const CharType *p_str,int &index, int p_len,int &line,String &r_err_str) {
if (token.type==TK_CURLY_BRACKET_OPEN) {
if (token.type == TK_CURLY_BRACKET_OPEN) {
Dictionary d(true);
Error err = _parse_object(d,p_str,index,p_len,line,r_err_str);
Error err = _parse_object(d, p_str, index, p_len, line, r_err_str);
if (err)
return err;
value=d;
value = d;
return OK;
} else if (token.type==TK_BRACKET_OPEN) {
} else if (token.type == TK_BRACKET_OPEN) {
Array a(true);
Error err = _parse_array(a,p_str,index,p_len,line,r_err_str);
Error err = _parse_array(a, p_str, index, p_len, line, r_err_str);
if (err)
return err;
value=a;
value = a;
return OK;
} else if (token.type==TK_IDENTIFIER) {
} else if (token.type == TK_IDENTIFIER) {
String id = token.value;
if (id=="true")
value=true;
else if (id=="false")
value=false;
else if (id=="null")
value=Variant();
if (id == "true")
value = true;
else if (id == "false")
value = false;
else if (id == "null")
value = Variant();
else {
r_err_str="Expected 'true','false' or 'null', got '"+id+"'.";
r_err_str = "Expected 'true','false' or 'null', got '" + id + "'.";
return ERR_PARSE_ERROR;
}
return OK;
} else if (token.type==TK_NUMBER) {
} else if (token.type == TK_NUMBER) {
value=token.value;
value = token.value;
return OK;
} else if (token.type==TK_STRING) {
} else if (token.type == TK_STRING) {
value=token.value;
value = token.value;
return OK;
} else {
r_err_str="Expected value, got "+String(tk_name[token.type])+".";
r_err_str = "Expected value, got " + String(tk_name[token.type]) + ".";
return ERR_PARSE_ERROR;
}
return ERR_PARSE_ERROR;
}
Error JSON::_parse_array(Array &array,const CharType *p_str,int &index, int p_len,int &line,String &r_err_str) {
Error JSON::_parse_array(Array &array, const CharType *p_str, int &index, int p_len, int &line, String &r_err_str) {
Token token;
bool need_comma=false;
bool need_comma = false;
while (index < p_len) {
while(index<p_len) {
Error err = _get_token(p_str,index,p_len,token,line,r_err_str);
if (err!=OK)
Error err = _get_token(p_str, index, p_len, token, line, r_err_str);
if (err != OK)
return err;
if (token.type==TK_BRACKET_CLOSE) {
if (token.type == TK_BRACKET_CLOSE) {
return OK;
}
if (need_comma) {
if (token.type!=TK_COMMA) {
if (token.type != TK_COMMA) {
r_err_str="Expected ','";
r_err_str = "Expected ','";
return ERR_PARSE_ERROR;
} else {
need_comma=false;
need_comma = false;
continue;
}
}
Variant v;
err = _parse_value(v,token,p_str,index,p_len,line,r_err_str);
err = _parse_value(v, token, p_str, index, p_len, line, r_err_str);
if (err)
return err;
array.push_back(v);
need_comma=true;
need_comma = true;
}
return ERR_PARSE_ERROR;
}
Error JSON::_parse_object(Dictionary &object,const CharType *p_str,int &index, int p_len,int &line,String &r_err_str) {
Error JSON::_parse_object(Dictionary &object, const CharType *p_str, int &index, int p_len, int &line, String &r_err_str) {
bool at_key=true;
bool at_key = true;
String key;
Token token;
bool need_comma=false;
while(index<p_len) {
bool need_comma = false;
while (index < p_len) {
if (at_key) {
Error err = _get_token(p_str,index,p_len,token,line,r_err_str);
if (err!=OK)
Error err = _get_token(p_str, index, p_len, token, line, r_err_str);
if (err != OK)
return err;
if (token.type==TK_CURLY_BRACKET_CLOSE) {
if (token.type == TK_CURLY_BRACKET_CLOSE) {
return OK;
}
if (need_comma) {
if (token.type!=TK_COMMA) {
if (token.type != TK_COMMA) {
r_err_str="Expected '}' or ','";
r_err_str = "Expected '}' or ','";
return ERR_PARSE_ERROR;
} else {
need_comma=false;
need_comma = false;
continue;
}
}
if (token.type!=TK_STRING) {
if (token.type != TK_STRING) {
r_err_str="Expected key";
r_err_str = "Expected key";
return ERR_PARSE_ERROR;
}
key=token.value;
err = _get_token(p_str,index,p_len,token,line,r_err_str);
if (err!=OK)
key = token.value;
err = _get_token(p_str, index, p_len, token, line, r_err_str);
if (err != OK)
return err;
if (token.type!=TK_COLON) {
if (token.type != TK_COLON) {
r_err_str="Expected ':'";
r_err_str = "Expected ':'";
return ERR_PARSE_ERROR;
}
at_key=false;
at_key = false;
} else {
Error err = _get_token(p_str,index,p_len,token,line,r_err_str);
if (err!=OK)
Error err = _get_token(p_str, index, p_len, token, line, r_err_str);
if (err != OK)
return err;
Variant v;
err = _parse_value(v,token,p_str,index,p_len,line,r_err_str);
err = _parse_value(v, token, p_str, index, p_len, line, r_err_str);
if (err)
return err;
object[key]=v;
need_comma=true;
at_key=true;
object[key] = v;
need_comma = true;
at_key = true;
}
}
return ERR_PARSE_ERROR;
}
Error JSON::parse(const String& p_json,Dictionary& r_ret,String &r_err_str,int &r_err_line) {
Error JSON::parse(const String &p_json, Dictionary &r_ret, String &r_err_str, int &r_err_line) {
const CharType *str = p_json.ptr();
int idx = 0;
int len = p_json.length();
Token token;
int line=0;
int line = 0;
String aux_key;
Error err = _get_token(str,idx,len,token,line,r_err_str);
Error err = _get_token(str, idx, len, token, line, r_err_str);
if (err)
return err;
if (token.type!=TK_CURLY_BRACKET_OPEN) {
if (token.type != TK_CURLY_BRACKET_OPEN) {
r_err_str="Expected '{'";
r_err_str = "Expected '{'";
return ERR_PARSE_ERROR;
}
return _parse_object(r_ret,str,idx,len,r_err_line,r_err_str);
return _parse_object(r_ret, str, idx, len, r_err_line, r_err_str);
}

View File

@ -29,11 +29,8 @@
#ifndef JSON_H
#define JSON_H
#include "variant.h"
class JSON {
enum TokenType {
@ -64,18 +61,18 @@ class JSON {
Variant value;
};
static const char * tk_name[TK_MAX];
static const char *tk_name[TK_MAX];
static String _print_var(const Variant& p_var);
static String _print_var(const Variant &p_var);
static Error _get_token(const CharType *p_str,int &index, int p_len,Token& r_token,int &line,String &r_err_str);
static Error _parse_value(Variant &value,Token& token,const CharType *p_str,int &index, int p_len,int &line,String &r_err_str);
static Error _parse_array(Array &array,const CharType *p_str,int &index, int p_len,int &line,String &r_err_str);
static Error _parse_object(Dictionary &object,const CharType *p_str,int &index, int p_len,int &line,String &r_err_str);
static Error _get_token(const CharType *p_str, int &index, int p_len, Token &r_token, int &line, String &r_err_str);
static Error _parse_value(Variant &value, Token &token, const CharType *p_str, int &index, int p_len, int &line, String &r_err_str);
static Error _parse_array(Array &array, const CharType *p_str, int &index, int p_len, int &line, String &r_err_str);
static Error _parse_object(Dictionary &object, const CharType *p_str, int &index, int p_len, int &line, String &r_err_str);
public:
static String print(const Dictionary& p_dict);
static Error parse(const String& p_json,Dictionary& r_ret,String &r_err_str,int &r_err_line);
static String print(const Dictionary &p_dict);
static Error parse(const String &p_json, Dictionary &r_ret, String &r_err_str, int &r_err_line);
};
#endif // JSON_H

File diff suppressed because it is too large Load Diff

View File

@ -38,7 +38,6 @@
* in an endian independent way
*/
union MarshallFloat {
uint32_t i; ///< int
@ -53,41 +52,44 @@ union MarshallDouble {
static inline unsigned int encode_uint16(uint16_t p_uint, uint8_t *p_arr) {
for (int i=0;i<2;i++) {
for (int i = 0; i < 2; i++) {
*p_arr=p_uint&0xFF;
p_arr++; p_uint>>=8;
*p_arr = p_uint & 0xFF;
p_arr++;
p_uint >>= 8;
}
return sizeof( uint16_t );
return sizeof(uint16_t);
}
static inline unsigned int encode_uint32(uint32_t p_uint, uint8_t *p_arr) {
for (int i=0;i<4;i++) {
for (int i = 0; i < 4; i++) {
*p_arr=p_uint&0xFF;
p_arr++; p_uint>>=8;
*p_arr = p_uint & 0xFF;
p_arr++;
p_uint >>= 8;
}
return sizeof( uint32_t );
return sizeof(uint32_t);
}
static inline unsigned int encode_float(float p_float, uint8_t *p_arr) {
MarshallFloat mf;
mf.f=p_float;
encode_uint32( mf.i, p_arr );
mf.f = p_float;
encode_uint32(mf.i, p_arr);
return sizeof( uint32_t );
return sizeof(uint32_t);
}
static inline unsigned int encode_uint64(uint64_t p_uint, uint8_t *p_arr) {
for (int i=0;i<8;i++) {
for (int i = 0; i < 8; i++) {
*p_arr=p_uint&0xFF;
p_arr++; p_uint>>=8;
*p_arr = p_uint & 0xFF;
p_arr++;
p_uint >>= 8;
}
return sizeof(uint64_t);
@ -96,23 +98,21 @@ static inline unsigned int encode_uint64(uint64_t p_uint, uint8_t *p_arr) {
static inline unsigned int encode_double(double p_double, uint8_t *p_arr) {
MarshallDouble md;
md.d=p_double;
encode_uint64( md.l, p_arr );
md.d = p_double;
encode_uint64(md.l, p_arr);
return sizeof(uint64_t);
}
static inline int encode_cstring(const char *p_string, uint8_t *p_data) {
static inline int encode_cstring(const char *p_string, uint8_t * p_data) {
int len=0;
int len = 0;
while (*p_string) {
if (p_data) {
*p_data=(uint8_t)*p_string;
*p_data = (uint8_t)*p_string;
p_data++;
}
p_string++;
@ -120,18 +120,18 @@ static inline int encode_cstring(const char *p_string, uint8_t * p_data) {
};
if (p_data) *p_data = 0;
return len+1;
return len + 1;
}
static inline uint16_t decode_uint16(const uint8_t *p_arr) {
uint16_t u=0;
uint16_t u = 0;
for (int i=0;i<2;i++) {
for (int i = 0; i < 2; i++) {
uint16_t b = *p_arr;
b<<=(i*8);
u|=b;
b <<= (i * 8);
u |= b;
p_arr++;
}
@ -140,13 +140,13 @@ static inline uint16_t decode_uint16(const uint8_t *p_arr) {
static inline uint32_t decode_uint32(const uint8_t *p_arr) {
uint32_t u=0;
uint32_t u = 0;
for (int i=0;i<4;i++) {
for (int i = 0; i < 4; i++) {
uint32_t b = *p_arr;
b<<=(i*8);
u|=b;
b <<= (i * 8);
u |= b;
p_arr++;
}
@ -162,13 +162,13 @@ static inline float decode_float(const uint8_t *p_arr) {
static inline uint64_t decode_uint64(const uint8_t *p_arr) {
uint64_t u=0;
uint64_t u = 0;
for (int i=0;i<8;i++) {
for (int i = 0; i < 8; i++) {
uint64_t b = (*p_arr)&0xFF;
b<<=(i*8);
u|=b;
uint64_t b = (*p_arr) & 0xFF;
b <<= (i * 8);
u |= b;
p_arr++;
}
@ -178,13 +178,11 @@ static inline uint64_t decode_uint64(const uint8_t *p_arr) {
static inline double decode_double(const uint8_t *p_arr) {
MarshallDouble md;
md.l = decode_uint64( p_arr );
md.l = decode_uint64(p_arr);
return md.d;
}
Error decode_variant(Variant& r_variant,const uint8_t *p_buffer, int p_len,int *r_len=NULL);
Error encode_variant(const Variant& p_variant, uint8_t *r_buffer, int &r_len);
Error decode_variant(Variant &r_variant, const uint8_t *p_buffer, int p_len, int *r_len = NULL);
Error encode_variant(const Variant &p_variant, uint8_t *r_buffer, int &r_len);
#endif

View File

@ -28,77 +28,71 @@
/*************************************************************************/
#include "packet_peer.h"
#include "io/marshalls.h"
#include "globals.h"
#include "io/marshalls.h"
/* helpers / binders */
PacketPeer::PacketPeer() {
last_get_error=OK;
last_get_error = OK;
}
Error PacketPeer::get_packet_buffer(DVector<uint8_t> &r_buffer) const {
const uint8_t *buffer;
int buffer_size;
Error err = get_packet(&buffer,buffer_size);
Error err = get_packet(&buffer, buffer_size);
if (err)
return err;
r_buffer.resize(buffer_size);
if (buffer_size==0)
if (buffer_size == 0)
return OK;
DVector<uint8_t>::Write w = r_buffer.write();
for(int i=0;i<buffer_size;i++)
w[i]=buffer[i];
for (int i = 0; i < buffer_size; i++)
w[i] = buffer[i];
return OK;
}
Error PacketPeer::put_packet_buffer(const DVector<uint8_t> &p_buffer) {
int len = p_buffer.size();
if (len==0)
if (len == 0)
return OK;
DVector<uint8_t>::Read r = p_buffer.read();
return put_packet(&r[0],len);
return put_packet(&r[0], len);
}
Error PacketPeer::get_var(Variant &r_variant) const {
const uint8_t *buffer;
int buffer_size;
Error err = get_packet(&buffer,buffer_size);
Error err = get_packet(&buffer, buffer_size);
if (err)
return err;
return decode_variant(r_variant,buffer,buffer_size);
return decode_variant(r_variant, buffer, buffer_size);
}
Error PacketPeer::put_var(const Variant& p_packet) {
Error PacketPeer::put_var(const Variant &p_packet) {
int len;
Error err = encode_variant(p_packet,NULL,len); // compute len first
Error err = encode_variant(p_packet, NULL, len); // compute len first
if (err)
return err;
if (len==0)
if (len == 0)
return OK;
uint8_t *buf = (uint8_t*)alloca(len);
ERR_FAIL_COND_V(!buf,ERR_OUT_OF_MEMORY);
err = encode_variant(p_packet,buf,len);
uint8_t *buf = (uint8_t *)alloca(len);
ERR_FAIL_COND_V(!buf, ERR_OUT_OF_MEMORY);
err = encode_variant(p_packet, buf, len);
ERR_FAIL_COND_V(err, err);
return put_packet(buf, len);
}
Variant PacketPeer::_bnd_get_var() const {
@ -108,13 +102,13 @@ Variant PacketPeer::_bnd_get_var() const {
return var;
};
Error PacketPeer::_put_packet(const DVector<uint8_t> &p_buffer) {
Error PacketPeer::_put_packet(const DVector<uint8_t> &p_buffer) {
return put_packet_buffer(p_buffer);
}
DVector<uint8_t> PacketPeer::_get_packet() const {
DVector<uint8_t> raw;
last_get_error=get_packet_buffer(raw);
last_get_error = get_packet_buffer(raw);
return raw;
}
@ -123,20 +117,18 @@ Error PacketPeer::_get_packet_error() const {
return last_get_error;
}
void PacketPeer::_bind_methods() {
ObjectTypeDB::bind_method(_MD("get_var:Variant"),&PacketPeer::_bnd_get_var);
ObjectTypeDB::bind_method(_MD("put_var", "var:Variant"),&PacketPeer::put_var);
ObjectTypeDB::bind_method(_MD("get_packet"),&PacketPeer::_get_packet);
ObjectTypeDB::bind_method(_MD("put_packet:Error", "buffer"),&PacketPeer::_put_packet);
ObjectTypeDB::bind_method(_MD("get_packet_error:Error"),&PacketPeer::_get_packet_error);
ObjectTypeDB::bind_method(_MD("get_available_packet_count"),&PacketPeer::get_available_packet_count);
ObjectTypeDB::bind_method(_MD("get_var:Variant"), &PacketPeer::_bnd_get_var);
ObjectTypeDB::bind_method(_MD("put_var", "var:Variant"), &PacketPeer::put_var);
ObjectTypeDB::bind_method(_MD("get_packet"), &PacketPeer::_get_packet);
ObjectTypeDB::bind_method(_MD("put_packet:Error", "buffer"), &PacketPeer::_put_packet);
ObjectTypeDB::bind_method(_MD("get_packet_error:Error"), &PacketPeer::_get_packet_error);
ObjectTypeDB::bind_method(_MD("get_available_packet_count"), &PacketPeer::get_available_packet_count);
};
/***************/
void PacketPeerStream::_set_stream_peer(REF p_peer) {
ERR_FAIL_COND(p_peer.is_null());
@ -145,22 +137,22 @@ void PacketPeerStream::_set_stream_peer(REF p_peer) {
void PacketPeerStream::_bind_methods() {
ObjectTypeDB::bind_method(_MD("set_stream_peer","peer:StreamPeer"),&PacketPeerStream::_set_stream_peer);
ObjectTypeDB::bind_method(_MD("set_stream_peer", "peer:StreamPeer"), &PacketPeerStream::_set_stream_peer);
}
Error PacketPeerStream::_poll_buffer() const {
ERR_FAIL_COND_V(peer.is_null(),ERR_UNCONFIGURED);
ERR_FAIL_COND_V(peer.is_null(), ERR_UNCONFIGURED);
int read = 0;
Error err = peer->get_partial_data(&temp_buffer[0], ring_buffer.space_left(), read);
if (err)
return err;
if (read==0)
if (read == 0)
return OK;
int w = ring_buffer.write(&temp_buffer[0],read);
ERR_FAIL_COND_V(w!=read,ERR_BUG);
int w = ring_buffer.write(&temp_buffer[0], read);
ERR_FAIL_COND_V(w != read, ERR_BUG);
return OK;
}
@ -171,73 +163,71 @@ int PacketPeerStream::get_available_packet_count() const {
uint32_t remaining = ring_buffer.data_left();
int ofs=0;
int count=0;
int ofs = 0;
int count = 0;
while(remaining>=4) {
while (remaining >= 4) {
uint8_t lbuf[4];
ring_buffer.copy(lbuf,ofs,4);
ring_buffer.copy(lbuf, ofs, 4);
uint32_t len = decode_uint32(lbuf);
remaining-=4;
ofs+=4;
if (len>remaining)
remaining -= 4;
ofs += 4;
if (len > remaining)
break;
remaining-=len;
ofs+=len;
remaining -= len;
ofs += len;
count++;
}
return count;
}
Error PacketPeerStream::get_packet(const uint8_t **r_buffer,int &r_buffer_size) const {
Error PacketPeerStream::get_packet(const uint8_t **r_buffer, int &r_buffer_size) const {
ERR_FAIL_COND_V(peer.is_null(),ERR_UNCONFIGURED);
ERR_FAIL_COND_V(peer.is_null(), ERR_UNCONFIGURED);
_poll_buffer();
int remaining = ring_buffer.data_left();
ERR_FAIL_COND_V(remaining<4,ERR_UNAVAILABLE);
ERR_FAIL_COND_V(remaining < 4, ERR_UNAVAILABLE);
uint8_t lbuf[4];
ring_buffer.copy(lbuf,0,4);
remaining-=4;
ring_buffer.copy(lbuf, 0, 4);
remaining -= 4;
uint32_t len = decode_uint32(lbuf);
ERR_FAIL_COND_V(remaining<(int)len,ERR_UNAVAILABLE);
ERR_FAIL_COND_V(remaining < (int)len, ERR_UNAVAILABLE);
ring_buffer.read(lbuf,4); //get rid of first 4 bytes
ring_buffer.read(&temp_buffer[0],len); // read packet
ring_buffer.read(lbuf, 4); //get rid of first 4 bytes
ring_buffer.read(&temp_buffer[0], len); // read packet
*r_buffer=&temp_buffer[0];
r_buffer_size=len;
*r_buffer = &temp_buffer[0];
r_buffer_size = len;
return OK;
}
Error PacketPeerStream::put_packet(const uint8_t *p_buffer,int p_buffer_size) {
Error PacketPeerStream::put_packet(const uint8_t *p_buffer, int p_buffer_size) {
ERR_FAIL_COND_V(peer.is_null(),ERR_UNCONFIGURED);
ERR_FAIL_COND_V(peer.is_null(), ERR_UNCONFIGURED);
Error err = _poll_buffer(); //won't hurt to poll here too
if (err)
return err;
if (p_buffer_size==0)
if (p_buffer_size == 0)
return OK;
ERR_FAIL_COND_V( p_buffer_size<0, ERR_INVALID_PARAMETER);
ERR_FAIL_COND_V( p_buffer_size+4 > temp_buffer.size(), ERR_INVALID_PARAMETER );
ERR_FAIL_COND_V(p_buffer_size < 0, ERR_INVALID_PARAMETER);
ERR_FAIL_COND_V(p_buffer_size + 4 > temp_buffer.size(), ERR_INVALID_PARAMETER);
encode_uint32(p_buffer_size,&temp_buffer[0]);
uint8_t *dst=&temp_buffer[4];
for(int i=0;i<p_buffer_size;i++)
dst[i]=p_buffer[i];
encode_uint32(p_buffer_size, &temp_buffer[0]);
uint8_t *dst = &temp_buffer[4];
for (int i = 0; i < p_buffer_size; i++)
dst[i] = p_buffer[i];
return peer->put_data(&temp_buffer[0],p_buffer_size+4);
return peer->put_data(&temp_buffer[0], p_buffer_size + 4);
}
int PacketPeerStream::get_max_packet_size() const {
return temp_buffer.size();
}
@ -249,7 +239,7 @@ void PacketPeerStream::set_stream_peer(const Ref<StreamPeer> &p_peer) {
ring_buffer.advance_read(ring_buffer.data_left()); // reset the ring buffer
};
peer=p_peer;
peer = p_peer;
}
void PacketPeerStream::set_input_buffer_max_size(int p_max_size) {
@ -257,18 +247,14 @@ void PacketPeerStream::set_input_buffer_max_size(int p_max_size) {
//warning may lose packets
ERR_EXPLAIN("Buffer in use, resizing would cause loss of data");
ERR_FAIL_COND(ring_buffer.data_left());
ring_buffer.resize(nearest_shift(p_max_size+4));
temp_buffer.resize(nearest_power_of_2(p_max_size+4));
ring_buffer.resize(nearest_shift(p_max_size + 4));
temp_buffer.resize(nearest_power_of_2(p_max_size + 4));
}
PacketPeerStream::PacketPeerStream() {
int rbsize=GLOBAL_DEF( "core/packet_stream_peer_max_buffer_po2",(16));
int rbsize = GLOBAL_DEF("core/packet_stream_peer_max_buffer_po2", (16));
ring_buffer.resize(rbsize);
temp_buffer.resize(1<<rbsize);
temp_buffer.resize(1 << rbsize);
}

View File

@ -29,33 +29,30 @@
#ifndef PACKET_PEER_H
#define PACKET_PEER_H
#include "object.h"
#include "io/stream_peer.h"
#include "object.h"
#include "ring_buffer.h"
class PacketPeer : public Reference {
OBJ_TYPE( PacketPeer, Reference );
OBJ_TYPE(PacketPeer, Reference);
Variant _bnd_get_var() const;
void _bnd_put_var(const Variant& p_var);
void _bnd_put_var(const Variant &p_var);
static void _bind_methods();
Error _put_packet(const DVector<uint8_t> &p_buffer);
DVector<uint8_t> _get_packet() const;
Error _get_packet_error() const;
mutable Error last_get_error;
public:
virtual int get_available_packet_count() const = 0;
virtual Error get_packet(const uint8_t **r_buffer, int &r_buffer_size) const = 0; ///< buffer is GONE after next get_packet
virtual Error put_packet(const uint8_t *p_buffer, int p_buffer_size) = 0;
virtual int get_available_packet_count() const=0;
virtual Error get_packet(const uint8_t **r_buffer,int &r_buffer_size) const=0; ///< buffer is GONE after next get_packet
virtual Error put_packet(const uint8_t *p_buffer,int p_buffer_size)=0;
virtual int get_max_packet_size() const=0;
virtual int get_max_packet_size() const = 0;
/* helpers / binders */
@ -63,15 +60,15 @@ public:
virtual Error put_packet_buffer(const DVector<uint8_t> &p_buffer);
virtual Error get_var(Variant &r_variant) const;
virtual Error put_var(const Variant& p_packet);
virtual Error put_var(const Variant &p_packet);
PacketPeer();
~PacketPeer(){}
~PacketPeer() {}
};
class PacketPeerStream : public PacketPeer {
OBJ_TYPE(PacketPeerStream,PacketPeer);
OBJ_TYPE(PacketPeerStream, PacketPeer);
//the way the buffers work sucks, will change later
@ -80,23 +77,21 @@ class PacketPeerStream : public PacketPeer {
mutable Vector<uint8_t> temp_buffer;
Error _poll_buffer() const;
protected:
protected:
void _set_stream_peer(REF p_peer);
static void _bind_methods();
public:
public:
virtual int get_available_packet_count() const;
virtual Error get_packet(const uint8_t **r_buffer,int &r_buffer_size) const;
virtual Error put_packet(const uint8_t *p_buffer,int p_buffer_size);
virtual Error get_packet(const uint8_t **r_buffer, int &r_buffer_size) const;
virtual Error put_packet(const uint8_t *p_buffer, int p_buffer_size);
virtual int get_max_packet_size() const;
void set_stream_peer(const Ref<StreamPeer>& p_peer);
void set_stream_peer(const Ref<StreamPeer> &p_peer);
void set_input_buffer_max_size(int p_max_size);
PacketPeerStream();
};
#endif // PACKET_STREAM_H

View File

@ -29,25 +29,25 @@
#include "packet_peer_udp.h"
#include "io/ip.h"
PacketPeerUDP* (*PacketPeerUDP::_create)()=NULL;
PacketPeerUDP *(*PacketPeerUDP::_create)() = NULL;
String PacketPeerUDP::_get_packet_ip() const {
return get_packet_address();
}
Error PacketPeerUDP::_set_send_address(const String& p_address, int p_port) {
Error PacketPeerUDP::_set_send_address(const String &p_address, int p_port) {
IP_Address ip;
if (p_address.is_valid_ip_address()) {
ip=p_address;
ip = p_address;
} else {
ip=IP::get_singleton()->resolve_hostname(p_address, ip_type);
if (ip==IP_Address())
ip = IP::get_singleton()->resolve_hostname(p_address, ip_type);
if (ip == IP_Address())
return ERR_CANT_RESOLVE;
}
set_send_address(ip,p_port);
set_send_address(ip, p_port);
return OK;
}
@ -58,17 +58,15 @@ void PacketPeerUDP::set_ip_type(IP::Type p_type) {
void PacketPeerUDP::_bind_methods() {
ObjectTypeDB::bind_method(_MD("set_ip_type","ip_type"),&PacketPeerUDP::set_ip_type);
ObjectTypeDB::bind_method(_MD("listen:Error","port", "recv_buf_size"),&PacketPeerUDP::listen,DEFVAL(65536));
ObjectTypeDB::bind_method(_MD("close"),&PacketPeerUDP::close);
ObjectTypeDB::bind_method(_MD("wait:Error"),&PacketPeerUDP::wait);
ObjectTypeDB::bind_method(_MD("is_listening"),&PacketPeerUDP::is_listening);
ObjectTypeDB::bind_method(_MD("get_packet_ip"),&PacketPeerUDP::_get_packet_ip);
ObjectTypeDB::bind_method(_MD("set_ip_type", "ip_type"), &PacketPeerUDP::set_ip_type);
ObjectTypeDB::bind_method(_MD("listen:Error", "port", "recv_buf_size"), &PacketPeerUDP::listen, DEFVAL(65536));
ObjectTypeDB::bind_method(_MD("close"), &PacketPeerUDP::close);
ObjectTypeDB::bind_method(_MD("wait:Error"), &PacketPeerUDP::wait);
ObjectTypeDB::bind_method(_MD("is_listening"), &PacketPeerUDP::is_listening);
ObjectTypeDB::bind_method(_MD("get_packet_ip"), &PacketPeerUDP::_get_packet_ip);
//ObjectTypeDB::bind_method(_MD("get_packet_address"),&PacketPeerUDP::_get_packet_address);
ObjectTypeDB::bind_method(_MD("get_packet_port"),&PacketPeerUDP::get_packet_port);
ObjectTypeDB::bind_method(_MD("set_send_address","host","port"),&PacketPeerUDP::_set_send_address);
ObjectTypeDB::bind_method(_MD("get_packet_port"), &PacketPeerUDP::get_packet_port);
ObjectTypeDB::bind_method(_MD("set_send_address", "host", "port"), &PacketPeerUDP::_set_send_address);
}
Ref<PacketPeerUDP> PacketPeerUDP::create_ref() {
@ -78,14 +76,13 @@ Ref<PacketPeerUDP> PacketPeerUDP::create_ref() {
return Ref<PacketPeerUDP>(_create());
}
PacketPeerUDP* PacketPeerUDP::create() {
PacketPeerUDP *PacketPeerUDP::create() {
if (!_create)
return NULL;
return _create();
}
PacketPeerUDP::PacketPeerUDP()
{
PacketPeerUDP::PacketPeerUDP() {
ip_type = IP::TYPE_ANY;
}

View File

@ -29,38 +29,34 @@
#ifndef PACKET_PEER_UDP_H
#define PACKET_PEER_UDP_H
#include "io/ip.h"
#include "io/packet_peer.h"
class PacketPeerUDP : public PacketPeer {
OBJ_TYPE(PacketPeerUDP,PacketPeer);
OBJ_TYPE(PacketPeerUDP, PacketPeer);
protected:
IP::Type ip_type;
static PacketPeerUDP* (*_create)();
static PacketPeerUDP *(*_create)();
static void _bind_methods();
String _get_packet_ip() const;
virtual Error _set_send_address(const String& p_address,int p_port);
virtual Error _set_send_address(const String &p_address, int p_port);
public:
virtual void set_ip_type(IP::Type p_type);
virtual Error listen(int p_port, int p_recv_buffer_size=65536)=0;
virtual void close()=0;
virtual Error wait()=0;
virtual bool is_listening() const=0;
virtual IP_Address get_packet_address() const=0;
virtual int get_packet_port() const=0;
virtual void set_send_address(const IP_Address& p_address,int p_port)=0;
virtual Error listen(int p_port, int p_recv_buffer_size = 65536) = 0;
virtual void close() = 0;
virtual Error wait() = 0;
virtual bool is_listening() const = 0;
virtual IP_Address get_packet_address() const = 0;
virtual int get_packet_port() const = 0;
virtual void set_send_address(const IP_Address &p_address, int p_port) = 0;
static Ref<PacketPeerUDP> create_ref();
static PacketPeerUDP* create();
static PacketPeerUDP *create();
PacketPeerUDP();
};

View File

@ -42,9 +42,9 @@ static uint64_t _align(uint64_t p_n, int p_alignment) {
return p_n + (p_alignment - rest);
};
static void _pad(FileAccess* p_file, int p_bytes) {
static void _pad(FileAccess *p_file, int p_bytes) {
for (int i=0; i<p_bytes; i++) {
for (int i = 0; i < p_bytes; i++) {
p_file->store_8(0);
};
@ -52,13 +52,12 @@ static void _pad(FileAccess* p_file, int p_bytes) {
void PCKPacker::_bind_methods() {
ObjectTypeDB::bind_method(_MD("pck_start","pck_name","alignment"),&PCKPacker::pck_start);
ObjectTypeDB::bind_method(_MD("add_file","pck_path","source_path"),&PCKPacker::add_file);
ObjectTypeDB::bind_method(_MD("flush","verbose"),&PCKPacker::flush);
ObjectTypeDB::bind_method(_MD("pck_start", "pck_name", "alignment"), &PCKPacker::pck_start);
ObjectTypeDB::bind_method(_MD("add_file", "pck_path", "source_path"), &PCKPacker::add_file);
ObjectTypeDB::bind_method(_MD("flush", "verbose"), &PCKPacker::flush);
};
Error PCKPacker::pck_start(const String& p_file, int p_alignment) {
Error PCKPacker::pck_start(const String &p_file, int p_alignment) {
file = FileAccess::open(p_file, FileAccess::WRITE);
if (file == NULL) {
@ -74,7 +73,7 @@ Error PCKPacker::pck_start(const String& p_file, int p_alignment) {
file->store_32(0); // # minor
file->store_32(0); // # revision
for (int i=0; i<16; i++) {
for (int i = 0; i < 16; i++) {
file->store_32(0); // reserved
};
@ -84,9 +83,9 @@ Error PCKPacker::pck_start(const String& p_file, int p_alignment) {
return OK;
};
Error PCKPacker::add_file(const String& p_file, const String& p_src) {
Error PCKPacker::add_file(const String &p_file, const String &p_src) {
FileAccess* f = FileAccess::open(p_src, FileAccess::READ);
FileAccess *f = FileAccess::open(p_src, FileAccess::READ);
if (!f) {
return ERR_FILE_CANT_OPEN;
};
@ -116,7 +115,7 @@ Error PCKPacker::flush(bool p_verbose) {
file->store_32(files.size());
for (int i=0; i<files.size(); i++) {
for (int i = 0; i < files.size(); i++) {
file->store_pascal_string(files[i].path);
files[i].offset_offset = file->get_pos();
@ -130,7 +129,6 @@ Error PCKPacker::flush(bool p_verbose) {
file->store_32(0);
};
uint64_t ofs = file->get_pos();
ofs = _align(ofs, alignment);
@ -140,9 +138,9 @@ Error PCKPacker::flush(bool p_verbose) {
uint8_t *buf = memnew_arr(uint8_t, buf_max);
int count = 0;
for (int i=0; i<files.size(); i++) {
for (int i = 0; i < files.size(); i++) {
FileAccess* src = FileAccess::open(files[i].src_path, FileAccess::READ);
FileAccess *src = FileAccess::open(files[i].src_path, FileAccess::READ);
uint64_t to_write = files[i].size;
while (to_write > 0) {

View File

@ -34,7 +34,7 @@ class PCKPacker : public Reference {
OBJ_TYPE(PCKPacker, Reference);
FileAccess* file;
FileAccess *file;
int alignment;
static void _bind_methods();
@ -49,11 +49,10 @@ class PCKPacker : public Reference {
Vector<File> files;
public:
Error pck_start(const String& p_file, int p_alignment);
Error add_file(const String& p_file, const String& p_src);
Error pck_start(const String &p_file, int p_alignment);
Error add_file(const String &p_file, const String &p_src);
Error flush(bool p_verbose = false);
PCKPacker();
~PCKPacker();
};

File diff suppressed because it is too large Load Diff

View File

@ -33,7 +33,6 @@
#include "io/resource_saver.h"
#include "os/file_access.h"
class ResourceInteractiveLoaderBinary : public ResourceInteractiveLoader {
String local_path;
@ -43,7 +42,6 @@ class ResourceInteractiveLoaderBinary : public ResourceInteractiveLoader {
FileAccess *f;
bool endian_swap;
bool use_real64;
uint64_t importmd_ofs;
@ -71,62 +69,54 @@ class ResourceInteractiveLoaderBinary : public ResourceInteractiveLoader {
String get_unicode_string();
void _advance_padding(uint32_t p_len);
Map<String,String> remaps;
Map<String, String> remaps;
Error error;
int stage;
friend class ResourceFormatLoaderBinary;
friend class ResourceFormatLoaderBinary;
Error parse_variant(Variant& r_v, bool p_for_export_data=false);
Error parse_variant(Variant &r_v, bool p_for_export_data = false);
public:
virtual void set_local_path(const String& p_local_path);
virtual void set_local_path(const String &p_local_path);
virtual Ref<Resource> get_resource();
virtual Error poll();
virtual int get_stage() const;
virtual int get_stage_count() const;
void set_remaps(const Map<String,String>& p_remaps) { remaps=p_remaps; }
void set_remaps(const Map<String, String> &p_remaps) { remaps = p_remaps; }
void open(FileAccess *p_f);
String recognize(FileAccess *p_f);
void get_dependencies(FileAccess *p_f, List<String> *p_dependencies, bool p_add_types);
Error get_export_data(ExportData& r_export_data);
Error get_export_data(ExportData &r_export_data);
ResourceInteractiveLoaderBinary();
~ResourceInteractiveLoaderBinary();
};
class ResourceFormatLoaderBinary : public ResourceFormatLoader {
public:
virtual Ref<ResourceInteractiveLoader> load_interactive(const String &p_path,Error *r_error=NULL);
virtual void get_recognized_extensions_for_type(const String& p_type,List<String> *p_extensions) const;
virtual Ref<ResourceInteractiveLoader> load_interactive(const String &p_path, Error *r_error = NULL);
virtual void get_recognized_extensions_for_type(const String &p_type, List<String> *p_extensions) const;
virtual void get_recognized_extensions(List<String> *p_extensions) const;
virtual bool handles_type(const String& p_type) const;
virtual bool handles_type(const String &p_type) const;
virtual String get_resource_type(const String &p_path) const;
virtual void get_dependencies(const String& p_path, List<String> *p_dependencies, bool p_add_types=false);
virtual Error load_import_metadata(const String &p_path, Ref<ResourceImportMetadata>& r_var) const;
virtual Error rename_dependencies(const String &p_path,const Map<String,String>& p_map);
virtual Error get_export_data(const String& p_path,ExportData& r_export_data);
virtual void get_dependencies(const String &p_path, List<String> *p_dependencies, bool p_add_types = false);
virtual Error load_import_metadata(const String &p_path, Ref<ResourceImportMetadata> &r_var) const;
virtual Error rename_dependencies(const String &p_path, const Map<String, String> &p_map);
virtual Error get_export_data(const String &p_path, ExportData &r_export_data);
static ResourceFormatLoaderBinary *singleton;
ResourceFormatLoaderBinary() { singleton=this; }
ResourceFormatLoaderBinary() { singleton = this; }
};
class ResourceFormatSaverBinaryInstance {
class ResourceFormatSaverBinaryInstance {
String local_path;
bool relative_paths;
bool bundle_resources;
bool skip_editor;
@ -136,19 +126,16 @@ class ResourceFormatSaverBinaryInstance {
FileAccess *f;
String magic;
Set<RES> resource_set;
Map<StringName,int> string_map;
Map<StringName, int> string_map;
Vector<StringName> strings;
Map<RES,int> external_resources;
Map<RES, int> external_resources;
List<RES> saved_resources;
struct Property {
int name_idx;
Variant value;
PropertyInfo pi;
};
struct ResourceData {
@ -157,36 +144,25 @@ class ResourceFormatSaverBinaryInstance {
List<Property> properties;
};
void _pad_buffer(int p_bytes);
void write_variant(const Variant& p_property,const PropertyInfo& p_hint=PropertyInfo());
void _find_resources(const Variant& p_variant,bool p_main=false);
void save_unicode_string(const String& p_string);
int get_string_index(const String& p_string);
void write_variant(const Variant &p_property, const PropertyInfo &p_hint = PropertyInfo());
void _find_resources(const Variant &p_variant, bool p_main = false);
void save_unicode_string(const String &p_string);
int get_string_index(const String &p_string);
public:
Error save(const String &p_path,const RES& p_resource,uint32_t p_flags=0);
Error save(const String &p_path, const RES &p_resource, uint32_t p_flags = 0);
};
class ResourceFormatSaverBinary : public ResourceFormatSaver {
class ResourceFormatSaverBinary : public ResourceFormatSaver {
public:
static ResourceFormatSaverBinary* singleton;
virtual Error save(const String &p_path,const RES& p_resource,uint32_t p_flags=0);
virtual bool recognize(const RES& p_resource) const;
virtual void get_recognized_extensions(const RES& p_resource,List<String> *p_extensions) const;
static ResourceFormatSaverBinary *singleton;
virtual Error save(const String &p_path, const RES &p_resource, uint32_t p_flags = 0);
virtual bool recognize(const RES &p_resource) const;
virtual void get_recognized_extensions(const RES &p_resource, List<String> *p_extensions) const;
ResourceFormatSaverBinary();
};
#endif // RESOURCE_FORMAT_BINARY_H

File diff suppressed because it is too large Load Diff

View File

@ -33,8 +33,6 @@
#include "io/resource_saver.h"
#include "os/file_access.h"
class ResourceInteractiveLoaderXML : public ResourceInteractiveLoader {
String local_path;
@ -45,22 +43,19 @@ class ResourceInteractiveLoaderXML : public ResourceInteractiveLoader {
struct Tag {
String name;
HashMap<String,String> args;
HashMap<String, String> args;
};
_FORCE_INLINE_ Error _parse_array_element(Vector<char> &buff,bool p_number_only,FileAccess *f,bool *end);
_FORCE_INLINE_ Error _parse_array_element(Vector<char> &buff, bool p_number_only, FileAccess *f, bool *end);
struct ExtResource {
String path;
String type;
};
Map<String, String> remaps;
Map<String,String> remaps;
Map<int,ExtResource> ext_resources;
Map<int, ExtResource> ext_resources;
int resources_total;
int resource_current;
@ -70,24 +65,23 @@ class ResourceInteractiveLoaderXML : public ResourceInteractiveLoader {
uint8_t get_char() const;
int get_current_line() const;
friend class ResourceFormatLoaderXML;
friend class ResourceFormatLoaderXML;
List<Tag> tag_stack;
List<RES> resource_cache;
Tag* parse_tag(bool* r_exit=NULL,bool p_printerr=true,List<String> *r_order=NULL);
Error close_tag(const String& p_name);
_FORCE_INLINE_ void unquote(String& p_str);
Tag *parse_tag(bool *r_exit = NULL, bool p_printerr = true, List<String> *r_order = NULL);
Error close_tag(const String &p_name);
_FORCE_INLINE_ void unquote(String &p_str);
Error goto_end_of_tag();
Error parse_property_data(String &r_data);
Error parse_property(Variant& r_v, String &r_name,bool p_for_export_data=false);
Error parse_property(Variant &r_v, String &r_name, bool p_for_export_data = false);
Error error;
RES resource;
public:
virtual void set_local_path(const String& p_local_path);
virtual void set_local_path(const String &p_local_path);
virtual Ref<Resource> get_resource();
virtual Error poll();
virtual int get_stage() const;
@ -96,41 +90,34 @@ public:
void open(FileAccess *p_f);
String recognize(FileAccess *p_f);
void get_dependencies(FileAccess *p_f, List<String> *p_dependencies, bool p_add_types);
Error rename_dependencies(FileAccess *p_f, const String &p_path,const Map<String,String>& p_map);
Error rename_dependencies(FileAccess *p_f, const String &p_path, const Map<String, String> &p_map);
Error get_export_data(FileAccess *p_f,ExportData& r_export_data);
Error get_export_data(FileAccess *p_f, ExportData &r_export_data);
~ResourceInteractiveLoaderXML();
};
class ResourceFormatLoaderXML : public ResourceFormatLoader {
public:
static ResourceFormatLoaderXML *singleton;
virtual Ref<ResourceInteractiveLoader> load_interactive(const String &p_path,Error *r_error=NULL);
virtual void get_recognized_extensions_for_type(const String& p_type,List<String> *p_extensions) const;
virtual Ref<ResourceInteractiveLoader> load_interactive(const String &p_path, Error *r_error = NULL);
virtual void get_recognized_extensions_for_type(const String &p_type, List<String> *p_extensions) const;
virtual void get_recognized_extensions(List<String> *p_extensions) const;
virtual bool handles_type(const String& p_type) const;
virtual bool handles_type(const String &p_type) const;
virtual String get_resource_type(const String &p_path) const;
virtual void get_dependencies(const String& p_path, List<String> *p_dependencies, bool p_add_types=false);
virtual Error rename_dependencies(const String &p_path,const Map<String,String>& p_map);
virtual Error get_export_data(const String& p_path,ExportData& r_export_data);
ResourceFormatLoaderXML() { singleton=this; }
virtual void get_dependencies(const String &p_path, List<String> *p_dependencies, bool p_add_types = false);
virtual Error rename_dependencies(const String &p_path, const Map<String, String> &p_map);
virtual Error get_export_data(const String &p_path, ExportData &r_export_data);
ResourceFormatLoaderXML() { singleton = this; }
};
////////////////////////////////////////////////////////////////////////////////////////////
class ResourceFormatSaverXMLInstance {
class ResourceFormatSaverXMLInstance {
String local_path;
bool takeover_paths;
bool relative_paths;
bool bundle_resources;
@ -139,36 +126,30 @@ class ResourceFormatSaverXMLInstance {
int depth;
Set<RES> resource_set;
List<RES> saved_resources;
Map<RES,int> external_resources;
Map<RES, int> external_resources;
void enter_tag(const char* p_tag,const String& p_args=String());
void exit_tag(const char* p_tag);
void enter_tag(const char *p_tag, const String &p_args = String());
void exit_tag(const char *p_tag);
void _find_resources(const Variant& p_variant,bool p_main=false);
void write_property(const String& p_name,const Variant& p_property,bool *r_ok=NULL);
void escape(String& p_str);
void write_tabs(int p_diff=0);
void write_string(String p_str,bool p_escape=true);
void _find_resources(const Variant &p_variant, bool p_main = false);
void write_property(const String &p_name, const Variant &p_property, bool *r_ok = NULL);
void escape(String &p_str);
void write_tabs(int p_diff = 0);
void write_string(String p_str, bool p_escape = true);
public:
Error save(const String &p_path,const RES& p_resource,uint32_t p_flags=0);
Error save(const String &p_path, const RES &p_resource, uint32_t p_flags = 0);
};
class ResourceFormatSaverXML : public ResourceFormatSaver {
public:
static ResourceFormatSaverXML* singleton;
virtual Error save(const String &p_path,const RES& p_resource,uint32_t p_flags=0);
virtual bool recognize(const RES& p_resource) const;
virtual void get_recognized_extensions(const RES& p_resource,List<String> *p_extensions) const;
static ResourceFormatSaverXML *singleton;
virtual Error save(const String &p_path, const RES &p_resource, uint32_t p_flags = 0);
virtual bool recognize(const RES &p_resource) const;
virtual void get_recognized_extensions(const RES &p_resource, List<String> *p_extensions) const;
ResourceFormatSaverXML();
};
#endif // RESOURCE_FORMAT_XML_H

View File

@ -27,72 +27,69 @@
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
/*************************************************************************/
#include "resource_loader.h"
#include "print_string.h"
#include "globals.h"
#include "path_remap.h"
#include "os/file_access.h"
#include "os/os.h"
#include "path_remap.h"
#include "print_string.h"
ResourceFormatLoader *ResourceLoader::loader[MAX_LOADERS];
int ResourceLoader::loader_count=0;
int ResourceLoader::loader_count = 0;
Error ResourceInteractiveLoader::wait() {
Error err = poll();
while (err==OK) {
err=poll();
while (err == OK) {
err = poll();
}
return err;
}
bool ResourceFormatLoader::recognize(const String& p_extension) const {
bool ResourceFormatLoader::recognize(const String &p_extension) const {
List<String> extensions;
get_recognized_extensions(&extensions);
for (List<String>::Element *E=extensions.front();E;E=E->next()) {
for (List<String>::Element *E = extensions.front(); E; E = E->next()) {
if (E->get().nocasecmp_to(p_extension.extension())==0)
if (E->get().nocasecmp_to(p_extension.extension()) == 0)
return true;
}
return false;
}
void ResourceFormatLoader::get_recognized_extensions_for_type(const String& p_type,List<String> *p_extensions) const {
void ResourceFormatLoader::get_recognized_extensions_for_type(const String &p_type, List<String> *p_extensions) const {
if (p_type=="" || handles_type(p_type))
if (p_type == "" || handles_type(p_type))
get_recognized_extensions(p_extensions);
}
void ResourceLoader::get_recognized_extensions_for_type(const String& p_type,List<String> *p_extensions) {
void ResourceLoader::get_recognized_extensions_for_type(const String &p_type, List<String> *p_extensions) {
for (int i=0;i<loader_count;i++) {
loader[i]->get_recognized_extensions_for_type(p_type,p_extensions);
for (int i = 0; i < loader_count; i++) {
loader[i]->get_recognized_extensions_for_type(p_type, p_extensions);
}
}
void ResourceInteractiveLoader::_bind_methods() {
ObjectTypeDB::bind_method(_MD("get_resource"),&ResourceInteractiveLoader::get_resource);
ObjectTypeDB::bind_method(_MD("poll"),&ResourceInteractiveLoader::poll);
ObjectTypeDB::bind_method(_MD("wait"),&ResourceInteractiveLoader::wait);
ObjectTypeDB::bind_method(_MD("get_stage"),&ResourceInteractiveLoader::get_stage);
ObjectTypeDB::bind_method(_MD("get_stage_count"),&ResourceInteractiveLoader::get_stage_count);
ObjectTypeDB::bind_method(_MD("get_resource"), &ResourceInteractiveLoader::get_resource);
ObjectTypeDB::bind_method(_MD("poll"), &ResourceInteractiveLoader::poll);
ObjectTypeDB::bind_method(_MD("wait"), &ResourceInteractiveLoader::wait);
ObjectTypeDB::bind_method(_MD("get_stage"), &ResourceInteractiveLoader::get_stage);
ObjectTypeDB::bind_method(_MD("get_stage_count"), &ResourceInteractiveLoader::get_stage_count);
}
class ResourceInteractiveLoaderDefault : public ResourceInteractiveLoader {
OBJ_TYPE( ResourceInteractiveLoaderDefault, ResourceInteractiveLoader );
public:
OBJ_TYPE(ResourceInteractiveLoaderDefault, ResourceInteractiveLoader);
public:
Ref<Resource> resource;
virtual void set_local_path(const String& p_local_path) { /*scene->set_filename(p_local_path);*/ }
virtual void set_local_path(const String &p_local_path) { /*scene->set_filename(p_local_path);*/
}
virtual Ref<Resource> get_resource() { return resource; }
virtual Error poll() { return ERR_FILE_EOF; }
virtual int get_stage() const { return 1; }
@ -101,98 +98,92 @@ public:
ResourceInteractiveLoaderDefault() {}
};
Ref<ResourceInteractiveLoader> ResourceFormatLoader::load_interactive(const String &p_path, Error *r_error) {
//either this
Ref<Resource> res = load(p_path,p_path,r_error);
Ref<Resource> res = load(p_path, p_path, r_error);
if (res.is_null())
return Ref<ResourceInteractiveLoader>();
Ref<ResourceInteractiveLoaderDefault> ril = Ref<ResourceInteractiveLoaderDefault>( memnew( ResourceInteractiveLoaderDefault ));
ril->resource=res;
Ref<ResourceInteractiveLoaderDefault> ril = Ref<ResourceInteractiveLoaderDefault>(memnew(ResourceInteractiveLoaderDefault));
ril->resource = res;
return ril;
}
RES ResourceFormatLoader::load(const String &p_path, const String& p_original_path, Error *r_error) {
RES ResourceFormatLoader::load(const String &p_path, const String &p_original_path, Error *r_error) {
String path=p_path;
String path = p_path;
//or this must be implemented
Ref<ResourceInteractiveLoader> ril = load_interactive(p_path,r_error);
Ref<ResourceInteractiveLoader> ril = load_interactive(p_path, r_error);
if (!ril.is_valid())
return RES();
ril->set_local_path(p_original_path);
while(true) {
while (true) {
Error err = ril->poll();
if (err==ERR_FILE_EOF) {
if (err == ERR_FILE_EOF) {
if (r_error)
*r_error=OK;
*r_error = OK;
return ril->get_resource();
}
if (r_error)
*r_error=err;
*r_error = err;
ERR_FAIL_COND_V(err!=OK,RES());
ERR_FAIL_COND_V(err != OK, RES());
}
return RES();
}
void ResourceFormatLoader::get_dependencies(const String& p_path, List<String> *p_dependencies, bool p_add_types) {
void ResourceFormatLoader::get_dependencies(const String &p_path, List<String> *p_dependencies, bool p_add_types) {
//do nothing by default
}
///////////////////////////////////
RES ResourceLoader::load(const String &p_path, const String& p_type_hint, bool p_no_cache, Error *r_error) {
RES ResourceLoader::load(const String &p_path, const String &p_type_hint, bool p_no_cache, Error *r_error) {
if (r_error)
*r_error=ERR_CANT_OPEN;
*r_error = ERR_CANT_OPEN;
String local_path;
if (p_path.is_rel_path())
local_path="res://"+p_path;
local_path = "res://" + p_path;
else
local_path = Globals::get_singleton()->localize_path(p_path);
local_path=find_complete_path(local_path,p_type_hint);
ERR_FAIL_COND_V(local_path=="",RES());
local_path = find_complete_path(local_path, p_type_hint);
ERR_FAIL_COND_V(local_path == "", RES());
if (!p_no_cache && ResourceCache::has(local_path)) {
if (OS::get_singleton()->is_stdout_verbose())
print_line("load resource: "+local_path+" (cached)");
print_line("load resource: " + local_path + " (cached)");
return RES( ResourceCache::get(local_path ) );
return RES(ResourceCache::get(local_path));
}
String remapped_path = PathRemap::get_singleton()->get_remap(local_path);
if (OS::get_singleton()->is_stdout_verbose())
print_line("load resource: "+remapped_path);
print_line("load resource: " + remapped_path);
String extension=remapped_path.extension();
bool found=false;
String extension = remapped_path.extension();
bool found = false;
for (int i=0;i<loader_count;i++) {
for (int i = 0; i < loader_count; i++) {
if (!loader[i]->recognize(extension))
continue;
if (p_type_hint!="" && !loader[i]->handles_type(p_type_hint))
if (p_type_hint != "" && !loader[i]->handles_type(p_type_hint))
continue;
found=true;
RES res = loader[i]->load(remapped_path,local_path,r_error);
found = true;
RES res = loader[i]->load(remapped_path, local_path, r_error);
if (res.is_null())
continue;
if (!p_no_cache)
@ -211,46 +202,39 @@ RES ResourceLoader::load(const String &p_path, const String& p_type_hint, bool p
}
if (found) {
ERR_EXPLAIN("Failed loading resource: "+p_path);
ERR_EXPLAIN("Failed loading resource: " + p_path);
} else {
ERR_EXPLAIN("No loader found for resource: "+p_path);
ERR_EXPLAIN("No loader found for resource: " + p_path);
}
ERR_FAIL_V(RES());
return RES();
}
Ref<ResourceImportMetadata> ResourceLoader::load_import_metadata(const String &p_path) {
String local_path;
if (p_path.is_rel_path())
local_path="res://"+p_path;
local_path = "res://" + p_path;
else
local_path = Globals::get_singleton()->localize_path(p_path);
String extension=p_path.extension();
String extension = p_path.extension();
Ref<ResourceImportMetadata> ret;
for (int i=0;i<loader_count;i++) {
for (int i = 0; i < loader_count; i++) {
if (!loader[i]->recognize(extension))
continue;
Error err = loader[i]->load_import_metadata(local_path,ret);
if (err==OK)
Error err = loader[i]->load_import_metadata(local_path, ret);
if (err == OK)
break;
}
return ret;
}
String ResourceLoader::find_complete_path(const String& p_path,const String& p_type) {
String ResourceLoader::find_complete_path(const String &p_path, const String &p_type) {
//this is an old vestige when the engine saved files without extension.
//remains here for compatibility with old projects and only because it
//can be sometimes nice to open files using .* from a script and have it guess
@ -260,32 +244,30 @@ String ResourceLoader::find_complete_path(const String& p_path,const String& p_t
if (local_path.ends_with("*")) {
//find the extension for resource that ends with *
local_path = local_path.substr(0,local_path.length()-1);
local_path = local_path.substr(0, local_path.length() - 1);
List<String> extensions;
get_recognized_extensions_for_type(p_type,&extensions);
get_recognized_extensions_for_type(p_type, &extensions);
List<String> candidates;
for(List<String>::Element *E=extensions.front();E;E=E->next()) {
for (List<String>::Element *E = extensions.front(); E; E = E->next()) {
String path = local_path+E->get();
String path = local_path + E->get();
if (PathRemap::get_singleton()->has_remap(path) || FileAccess::exists(path)) {
candidates.push_back(path);
}
}
if (candidates.size()==0) {
if (candidates.size() == 0) {
return "";
} else if (candidates.size()==1 || p_type=="") {
} else if (candidates.size() == 1 || p_type == "") {
return candidates.front()->get();
} else {
for(List<String>::Element *E=candidates.front();E;E=E->next()) {
for (List<String>::Element *E = candidates.front(); E; E = E->next()) {
String rt = get_resource_type(E->get());
if (ObjectTypeDB::is_type(rt,p_type)) {
if (ObjectTypeDB::is_type(rt, p_type)) {
return E->get();
}
}
@ -297,27 +279,24 @@ String ResourceLoader::find_complete_path(const String& p_path,const String& p_t
return local_path;
}
Ref<ResourceInteractiveLoader> ResourceLoader::load_interactive(const String &p_path,const String& p_type_hint,bool p_no_cache,Error *r_error) {
Ref<ResourceInteractiveLoader> ResourceLoader::load_interactive(const String &p_path, const String &p_type_hint, bool p_no_cache, Error *r_error) {
if (r_error)
*r_error=ERR_CANT_OPEN;
*r_error = ERR_CANT_OPEN;
String local_path;
if (p_path.is_rel_path())
local_path="res://"+p_path;
local_path = "res://" + p_path;
else
local_path = Globals::get_singleton()->localize_path(p_path);
local_path=find_complete_path(local_path,p_type_hint);
ERR_FAIL_COND_V(local_path=="",Ref<ResourceInteractiveLoader>());
local_path = find_complete_path(local_path, p_type_hint);
ERR_FAIL_COND_V(local_path == "", Ref<ResourceInteractiveLoader>());
if (!p_no_cache && ResourceCache::has(local_path)) {
if (OS::get_singleton()->is_stdout_verbose())
print_line("load resource: "+local_path+" (cached)");
print_line("load resource: " + local_path + " (cached)");
Ref<Resource> res_cached = ResourceCache::get(local_path);
Ref<ResourceInteractiveLoaderDefault> ril = Ref<ResourceInteractiveLoaderDefault>(memnew(ResourceInteractiveLoaderDefault));
@ -331,17 +310,17 @@ Ref<ResourceInteractiveLoader> ResourceLoader::load_interactive(const String &p_
String remapped_path = PathRemap::get_singleton()->get_remap(local_path);
String extension=remapped_path.extension();
bool found=false;
String extension = remapped_path.extension();
bool found = false;
for (int i=0;i<loader_count;i++) {
for (int i = 0; i < loader_count; i++) {
if (!loader[i]->recognize(extension))
continue;
if (p_type_hint!="" && !loader[i]->handles_type(p_type_hint))
if (p_type_hint != "" && !loader[i]->handles_type(p_type_hint))
continue;
found=true;
Ref<ResourceInteractiveLoader> ril = loader[i]->load_interactive(remapped_path,r_error);
found = true;
Ref<ResourceInteractiveLoader> ril = loader[i]->load_interactive(remapped_path, r_error);
if (ril.is_null())
continue;
if (!p_no_cache)
@ -351,150 +330,137 @@ Ref<ResourceInteractiveLoader> ResourceLoader::load_interactive(const String &p_
}
if (found) {
ERR_EXPLAIN("Failed loading resource: "+p_path);
ERR_EXPLAIN("Failed loading resource: " + p_path);
} else {
ERR_EXPLAIN("No loader found for resource: "+p_path);
ERR_EXPLAIN("No loader found for resource: " + p_path);
}
ERR_FAIL_V(Ref<ResourceInteractiveLoader>());
return Ref<ResourceInteractiveLoader>();
}
void ResourceLoader::add_resource_format_loader(ResourceFormatLoader *p_format_loader, bool p_at_front) {
ERR_FAIL_COND( loader_count >= MAX_LOADERS );
ERR_FAIL_COND(loader_count >= MAX_LOADERS);
if (p_at_front) {
for(int i=loader_count;i>0;i--) {
loader[i]=loader[i-1];
for (int i = loader_count; i > 0; i--) {
loader[i] = loader[i - 1];
}
loader[0]=p_format_loader;
loader[0] = p_format_loader;
loader_count++;
} else {
loader[loader_count++]=p_format_loader;
loader[loader_count++] = p_format_loader;
}
}
void ResourceLoader::get_dependencies(const String& p_path, List<String> *p_dependencies, bool p_add_types) {
void ResourceLoader::get_dependencies(const String &p_path, List<String> *p_dependencies, bool p_add_types) {
String local_path;
if (p_path.is_rel_path())
local_path="res://"+p_path;
local_path = "res://" + p_path;
else
local_path = Globals::get_singleton()->localize_path(p_path);
String remapped_path = PathRemap::get_singleton()->get_remap(local_path);
String extension=remapped_path.extension();
String extension = remapped_path.extension();
for (int i=0;i<loader_count;i++) {
for (int i = 0; i < loader_count; i++) {
if (!loader[i]->recognize(extension))
continue;
//if (p_type_hint!="" && !loader[i]->handles_type(p_type_hint))
// continue;
loader[i]->get_dependencies(remapped_path,p_dependencies,p_add_types);
loader[i]->get_dependencies(remapped_path, p_dependencies, p_add_types);
}
}
Error ResourceLoader::get_export_data(const String& p_path,ExportData& r_export_data) {
Error ResourceLoader::get_export_data(const String &p_path, ExportData &r_export_data) {
String local_path;
if (p_path.is_rel_path())
local_path="res://"+p_path;
local_path = "res://" + p_path;
else
local_path = Globals::get_singleton()->localize_path(p_path);
String remapped_path = PathRemap::get_singleton()->get_remap(local_path);
String extension=remapped_path.extension();
String extension = remapped_path.extension();
for (int i=0;i<loader_count;i++) {
for (int i = 0; i < loader_count; i++) {
if (!loader[i]->recognize(extension))
continue;
//if (p_type_hint!="" && !loader[i]->handles_type(p_type_hint))
// continue;
return loader[i]->get_export_data(p_path,r_export_data);
return loader[i]->get_export_data(p_path, r_export_data);
}
return ERR_UNAVAILABLE;
}
Error ResourceLoader::rename_dependencies(const String &p_path,const Map<String,String>& p_map) {
Error ResourceLoader::rename_dependencies(const String &p_path, const Map<String, String> &p_map) {
String local_path;
if (p_path.is_rel_path())
local_path="res://"+p_path;
local_path = "res://" + p_path;
else
local_path = Globals::get_singleton()->localize_path(p_path);
String remapped_path = PathRemap::get_singleton()->get_remap(local_path);
String extension=remapped_path.extension();
String extension = remapped_path.extension();
for (int i=0;i<loader_count;i++) {
for (int i = 0; i < loader_count; i++) {
if (!loader[i]->recognize(extension))
continue;
//if (p_type_hint!="" && !loader[i]->handles_type(p_type_hint))
// continue;
return loader[i]->rename_dependencies(p_path,p_map);
return loader[i]->rename_dependencies(p_path, p_map);
}
return OK; // ??
}
String ResourceLoader::guess_full_filename(const String &p_path,const String& p_type) {
String ResourceLoader::guess_full_filename(const String &p_path, const String &p_type) {
String local_path;
if (p_path.is_rel_path())
local_path="res://"+p_path;
local_path = "res://" + p_path;
else
local_path = Globals::get_singleton()->localize_path(p_path);
return find_complete_path(local_path,p_type);
return find_complete_path(local_path, p_type);
}
String ResourceLoader::get_resource_type(const String &p_path) {
String local_path;
if (p_path.is_rel_path())
local_path="res://"+p_path;
local_path = "res://" + p_path;
else
local_path = Globals::get_singleton()->localize_path(p_path);
String remapped_path = PathRemap::get_singleton()->get_remap(local_path);
String extension=remapped_path.extension();
String extension = remapped_path.extension();
for (int i=0;i<loader_count;i++) {
for (int i = 0; i < loader_count; i++) {
String result = loader[i]->get_resource_type(local_path);
if (result!="")
if (result != "")
return result;
}
return "";
}
ResourceLoadErrorNotify ResourceLoader::err_notify=NULL;
void *ResourceLoader::err_notify_ud=NULL;
ResourceLoadErrorNotify ResourceLoader::err_notify = NULL;
void *ResourceLoader::err_notify_ud = NULL;
DependencyErrorNotify ResourceLoader::dep_err_notify=NULL;
void *ResourceLoader::dep_err_notify_ud=NULL;
bool ResourceLoader::abort_on_missing_resource=true;
bool ResourceLoader::timestamp_on_load=false;
DependencyErrorNotify ResourceLoader::dep_err_notify = NULL;
void *ResourceLoader::dep_err_notify_ud = NULL;
bool ResourceLoader::abort_on_missing_resource = true;
bool ResourceLoader::timestamp_on_load = false;

View File

@ -29,99 +29,102 @@
#ifndef RESOURCE_LOADER_H
#define RESOURCE_LOADER_H
#include "resource.h"
#include "export_data.h"
#include "resource.h"
/**
@author Juan Linietsky <reduzio@gmail.com>
*/
class ResourceInteractiveLoader : public Reference {
OBJ_TYPE(ResourceInteractiveLoader,Reference);
OBJ_TYPE(ResourceInteractiveLoader, Reference);
protected:
static void _bind_methods();
public:
virtual void set_local_path(const String& p_local_path)=0;
virtual Ref<Resource> get_resource()=0;
virtual Error poll()=0;
virtual int get_stage() const=0;
virtual int get_stage_count() const=0;
public:
virtual void set_local_path(const String &p_local_path) = 0;
virtual Ref<Resource> get_resource() = 0;
virtual Error poll() = 0;
virtual int get_stage() const = 0;
virtual int get_stage_count() const = 0;
virtual Error wait();
ResourceInteractiveLoader() {}
};
class ResourceFormatLoader {
public:
virtual Ref<ResourceInteractiveLoader> load_interactive(const String &p_path,Error *r_error=NULL);
virtual RES load(const String &p_path,const String& p_original_path="",Error *r_error=NULL);
virtual void get_recognized_extensions(List<String> *p_extensions) const=0;
virtual void get_recognized_extensions_for_type(const String& p_type,List<String> *p_extensions) const;
bool recognize(const String& p_extension) const;
virtual bool handles_type(const String& p_type) const=0;
virtual String get_resource_type(const String &p_path) const=0;
virtual void get_dependencies(const String& p_path,List<String> *p_dependencies,bool p_add_types=false);
virtual Error load_import_metadata(const String &p_path, Ref<ResourceImportMetadata>& r_var) const { return ERR_UNAVAILABLE; }
virtual Error rename_dependencies(const String &p_path,const Map<String,String>& p_map) { return OK; }
virtual Error get_export_data(const String& p_path,ExportData& r_export_data) { return ERR_UNAVAILABLE; }
virtual Ref<ResourceInteractiveLoader> load_interactive(const String &p_path, Error *r_error = NULL);
virtual RES load(const String &p_path, const String &p_original_path = "", Error *r_error = NULL);
virtual void get_recognized_extensions(List<String> *p_extensions) const = 0;
virtual void get_recognized_extensions_for_type(const String &p_type, List<String> *p_extensions) const;
bool recognize(const String &p_extension) const;
virtual bool handles_type(const String &p_type) const = 0;
virtual String get_resource_type(const String &p_path) const = 0;
virtual void get_dependencies(const String &p_path, List<String> *p_dependencies, bool p_add_types = false);
virtual Error load_import_metadata(const String &p_path, Ref<ResourceImportMetadata> &r_var) const { return ERR_UNAVAILABLE; }
virtual Error rename_dependencies(const String &p_path, const Map<String, String> &p_map) { return OK; }
virtual Error get_export_data(const String &p_path, ExportData &r_export_data) { return ERR_UNAVAILABLE; }
virtual ~ResourceFormatLoader() {}
};
typedef void (*ResourceLoadErrorNotify)(void *p_ud,const String& p_text);
typedef void (*DependencyErrorNotify)(void *p_ud,const String& p_loading,const String& p_which,const String& p_type);
typedef void (*ResourceLoadErrorNotify)(void *p_ud, const String &p_text);
typedef void (*DependencyErrorNotify)(void *p_ud, const String &p_loading, const String &p_which, const String &p_type);
class ResourceLoader {
enum {
MAX_LOADERS=64
MAX_LOADERS = 64
};
static ResourceFormatLoader *loader[MAX_LOADERS];
static int loader_count;
static bool timestamp_on_load;
static void* err_notify_ud;
static void *err_notify_ud;
static ResourceLoadErrorNotify err_notify;
static void* dep_err_notify_ud;
static void *dep_err_notify_ud;
static DependencyErrorNotify dep_err_notify;
static bool abort_on_missing_resource;
static String find_complete_path(const String& p_path,const String& p_type);
static String find_complete_path(const String &p_path, const String &p_type);
public:
static Ref<ResourceInteractiveLoader> load_interactive(const String &p_path,const String& p_type_hint="",bool p_no_cache=false,Error *r_error=NULL);
static RES load(const String &p_path,const String& p_type_hint="",bool p_no_cache=false,Error *r_error=NULL);
static Ref<ResourceInteractiveLoader> load_interactive(const String &p_path, const String &p_type_hint = "", bool p_no_cache = false, Error *r_error = NULL);
static RES load(const String &p_path, const String &p_type_hint = "", bool p_no_cache = false, Error *r_error = NULL);
static Ref<ResourceImportMetadata> load_import_metadata(const String &p_path);
static void get_recognized_extensions_for_type(const String& p_type,List<String> *p_extensions);
static void add_resource_format_loader(ResourceFormatLoader *p_format_loader,bool p_at_front=false);
static void get_recognized_extensions_for_type(const String &p_type, List<String> *p_extensions);
static void add_resource_format_loader(ResourceFormatLoader *p_format_loader, bool p_at_front = false);
static String get_resource_type(const String &p_path);
static void get_dependencies(const String& p_path,List<String> *p_dependencies,bool p_add_types=false);
static Error rename_dependencies(const String &p_path,const Map<String,String>& p_map);
static void get_dependencies(const String &p_path, List<String> *p_dependencies, bool p_add_types = false);
static Error rename_dependencies(const String &p_path, const Map<String, String> &p_map);
static Error get_export_data(const String& p_path,ExportData& r_export_data);
static Error get_export_data(const String &p_path, ExportData &r_export_data);
static String guess_full_filename(const String &p_path,const String& p_type);
static String guess_full_filename(const String &p_path, const String &p_type);
static void set_timestamp_on_load(bool p_timestamp) { timestamp_on_load=p_timestamp; }
static void set_timestamp_on_load(bool p_timestamp) { timestamp_on_load = p_timestamp; }
static void notify_load_error(const String& p_err) { if (err_notify) err_notify(err_notify_ud,p_err); }
static void set_error_notify_func(void* p_ud,ResourceLoadErrorNotify p_err_notify) { err_notify=p_err_notify; err_notify_ud=p_ud;}
static void notify_load_error(const String &p_err) {
if (err_notify) err_notify(err_notify_ud, p_err);
}
static void set_error_notify_func(void *p_ud, ResourceLoadErrorNotify p_err_notify) {
err_notify = p_err_notify;
err_notify_ud = p_ud;
}
static void notify_dependency_error(const String& p_path,const String& p_dependency,const String& p_type) { if (dep_err_notify) dep_err_notify(dep_err_notify_ud,p_path,p_dependency,p_type); }
static void set_dependency_error_notify_func(void* p_ud,DependencyErrorNotify p_err_notify) { dep_err_notify=p_err_notify; dep_err_notify_ud=p_ud;}
static void notify_dependency_error(const String &p_path, const String &p_dependency, const String &p_type) {
if (dep_err_notify) dep_err_notify(dep_err_notify_ud, p_path, p_dependency, p_type);
}
static void set_dependency_error_notify_func(void *p_ud, DependencyErrorNotify p_err_notify) {
dep_err_notify = p_err_notify;
dep_err_notify_ud = p_ud;
}
static void set_abort_on_missing_resources(bool p_abort) { abort_on_missing_resource=p_abort; }
static void set_abort_on_missing_resources(bool p_abort) { abort_on_missing_resource = p_abort; }
static bool get_abort_on_missing_resources() { return abort_on_missing_resource; }
};

View File

@ -29,62 +29,61 @@
#include "resource_saver.h"
#include "globals.h"
#include "os/file_access.h"
#include "script_language.h"
#include "resource_loader.h"
#include "script_language.h"
ResourceFormatSaver *ResourceSaver::saver[MAX_SAVERS];
int ResourceSaver::saver_count=0;
bool ResourceSaver::timestamp_on_save=false;
ResourceSavedCallback ResourceSaver::save_callback=0;
int ResourceSaver::saver_count = 0;
bool ResourceSaver::timestamp_on_save = false;
ResourceSavedCallback ResourceSaver::save_callback = 0;
Error ResourceSaver::save(const String &p_path,const RES& p_resource,uint32_t p_flags) {
Error ResourceSaver::save(const String &p_path, const RES &p_resource, uint32_t p_flags) {
String extension=p_path.extension();
Error err=ERR_FILE_UNRECOGNIZED;
String extension = p_path.extension();
Error err = ERR_FILE_UNRECOGNIZED;
for (int i=0;i<saver_count;i++) {
for (int i = 0; i < saver_count; i++) {
if (!saver[i]->recognize(p_resource))
continue;
List<String> extensions;
bool recognized=false;
saver[i]->get_recognized_extensions(p_resource,&extensions);
bool recognized = false;
saver[i]->get_recognized_extensions(p_resource, &extensions);
for (List<String>::Element *E=extensions.front();E;E=E->next()) {
for (List<String>::Element *E = extensions.front(); E; E = E->next()) {
if (E->get().nocasecmp_to(extension.extension())==0)
recognized=true;
if (E->get().nocasecmp_to(extension.extension()) == 0)
recognized = true;
}
if (!recognized)
continue;
String old_path=p_resource->get_path();
String old_path = p_resource->get_path();
String local_path=Globals::get_singleton()->localize_path(p_path);
String local_path = Globals::get_singleton()->localize_path(p_path);
RES rwcopy = p_resource;
if (p_flags&FLAG_CHANGE_PATH)
if (p_flags & FLAG_CHANGE_PATH)
rwcopy->set_path(local_path);
err = saver[i]->save(p_path,p_resource,p_flags);
err = saver[i]->save(p_path, p_resource, p_flags);
if (err == OK ) {
if (err == OK) {
#ifdef TOOLS_ENABLED
((Resource*)p_resource.ptr())->set_edited(false);
((Resource *)p_resource.ptr())->set_edited(false);
if (timestamp_on_save) {
uint64_t mt = FileAccess::get_modified_time(p_path);
((Resource*)p_resource.ptr())->set_last_modified_time(mt);
((Resource *)p_resource.ptr())->set_last_modified_time(mt);
}
#endif
if (p_flags&FLAG_CHANGE_PATH)
if (p_flags & FLAG_CHANGE_PATH)
rwcopy->set_path(old_path);
if (save_callback && p_path.begins_with("res://"))
@ -92,46 +91,36 @@ Error ResourceSaver::save(const String &p_path,const RES& p_resource,uint32_t p_
return OK;
} else {
}
}
return err;
}
void ResourceSaver::set_save_callback(ResourceSavedCallback p_callback) {
save_callback=p_callback;
save_callback = p_callback;
}
void ResourceSaver::get_recognized_extensions(const RES &p_resource, List<String> *p_extensions) {
void ResourceSaver::get_recognized_extensions(const RES& p_resource,List<String> *p_extensions) {
for (int i = 0; i < saver_count; i++) {
for (int i=0;i<saver_count;i++) {
saver[i]->get_recognized_extensions(p_resource,p_extensions);
saver[i]->get_recognized_extensions(p_resource, p_extensions);
}
}
void ResourceSaver::add_resource_format_saver(ResourceFormatSaver *p_format_saver, bool p_at_front) {
ERR_FAIL_COND( saver_count >= MAX_SAVERS );
ERR_FAIL_COND(saver_count >= MAX_SAVERS);
if (p_at_front) {
for(int i=saver_count;i>0;i--) {
saver[i]=saver[i-1];
for (int i = saver_count; i > 0; i--) {
saver[i] = saver[i - 1];
}
saver[0]=p_format_saver;
saver[0] = p_format_saver;
saver_count++;
} else {
saver[saver_count++]=p_format_saver;
saver[saver_count++] = p_format_saver;
}
}

View File

@ -35,27 +35,21 @@
@author Juan Linietsky <reduzio@gmail.com>
*/
class ResourceFormatSaver {
public:
virtual Error save(const String &p_path,const RES& p_resource,uint32_t p_flags=0)=0;
virtual bool recognize(const RES& p_resource) const=0;
virtual void get_recognized_extensions(const RES& p_resource,List<String> *p_extensions) const=0;
virtual Error save(const String &p_path, const RES &p_resource, uint32_t p_flags = 0) = 0;
virtual bool recognize(const RES &p_resource) const = 0;
virtual void get_recognized_extensions(const RES &p_resource, List<String> *p_extensions) const = 0;
virtual ~ResourceFormatSaver() {}
};
typedef void (*ResourceSavedCallback)(const String& p_path);
typedef void (*ResourceSavedCallback)(const String &p_path);
class ResourceSaver {
enum {
MAX_SAVERS=64
MAX_SAVERS = 64
};
static ResourceFormatSaver *saver[MAX_SAVERS];
@ -63,31 +57,24 @@ class ResourceSaver {
static bool timestamp_on_save;
static ResourceSavedCallback save_callback;
public:
enum SaverFlags {
FLAG_RELATIVE_PATHS=1,
FLAG_BUNDLE_RESOURCES=2,
FLAG_CHANGE_PATH=4,
FLAG_OMIT_EDITOR_PROPERTIES=8,
FLAG_SAVE_BIG_ENDIAN=16,
FLAG_COMPRESS=32,
FLAG_REPLACE_SUBRESOURCE_PATHS=64,
FLAG_RELATIVE_PATHS = 1,
FLAG_BUNDLE_RESOURCES = 2,
FLAG_CHANGE_PATH = 4,
FLAG_OMIT_EDITOR_PROPERTIES = 8,
FLAG_SAVE_BIG_ENDIAN = 16,
FLAG_COMPRESS = 32,
FLAG_REPLACE_SUBRESOURCE_PATHS = 64,
};
static Error save(const String &p_path, const RES &p_resource, uint32_t p_flags = 0);
static void get_recognized_extensions(const RES &p_resource, List<String> *p_extensions);
static void add_resource_format_saver(ResourceFormatSaver *p_format_saver, bool p_at_front = false);
static Error save(const String &p_path,const RES& p_resource,uint32_t p_flags=0);
static void get_recognized_extensions(const RES& p_resource,List<String> *p_extensions);
static void add_resource_format_saver(ResourceFormatSaver *p_format_saver,bool p_at_front=false);
static void set_timestamp_on_save(bool p_timestamp) { timestamp_on_save=p_timestamp; }
static void set_timestamp_on_save(bool p_timestamp) { timestamp_on_save = p_timestamp; }
static void set_save_callback(ResourceSavedCallback p_callback);
};
#endif

View File

@ -29,21 +29,21 @@
#include "stream_peer.h"
#include "io/marshalls.h"
Error StreamPeer::_put_data(const DVector<uint8_t>& p_data) {
Error StreamPeer::_put_data(const DVector<uint8_t> &p_data) {
int len = p_data.size();
if (len==0)
if (len == 0)
return OK;
DVector<uint8_t>::Read r = p_data.read();
return put_data(&r[0],len);
return put_data(&r[0], len);
}
Array StreamPeer::_put_partial_data(const DVector<uint8_t>& p_data) {
Array StreamPeer::_put_partial_data(const DVector<uint8_t> &p_data) {
Array ret;
int len = p_data.size();
if (len==0) {
if (len == 0) {
ret.push_back(OK);
ret.push_back(0);
return ret;
@ -51,24 +51,23 @@ Array StreamPeer::_put_partial_data(const DVector<uint8_t>& p_data) {
DVector<uint8_t>::Read r = p_data.read();
int sent;
Error err = put_partial_data(&r[0],len,sent);
Error err = put_partial_data(&r[0], len, sent);
if (err!=OK) {
sent=0;
if (err != OK) {
sent = 0;
}
ret.push_back(err);
ret.push_back(sent);
return ret;
}
Array StreamPeer::_get_data(int p_bytes) {
Array ret;
DVector<uint8_t> data;
data.resize(p_bytes);
if (data.size()!=p_bytes) {
if (data.size() != p_bytes) {
ret.push_back(ERR_OUT_OF_MEMORY);
ret.push_back(DVector<uint8_t>());
@ -76,12 +75,11 @@ Array StreamPeer::_get_data(int p_bytes) {
}
DVector<uint8_t>::Write w = data.write();
Error err = get_data(&w[0],p_bytes);
Error err = get_data(&w[0], p_bytes);
w = DVector<uint8_t>::Write();
ret.push_back(err);
ret.push_back(data);
return ret;
}
Array StreamPeer::_get_partial_data(int p_bytes) {
@ -90,7 +88,7 @@ Array StreamPeer::_get_partial_data(int p_bytes) {
DVector<uint8_t> data;
data.resize(p_bytes);
if (data.size()!=p_bytes) {
if (data.size() != p_bytes) {
ret.push_back(ERR_OUT_OF_MEMORY);
ret.push_back(DVector<uint8_t>());
@ -99,12 +97,12 @@ Array StreamPeer::_get_partial_data(int p_bytes) {
DVector<uint8_t>::Write w = data.write();
int received;
Error err = get_partial_data(&w[0],p_bytes,received);
Error err = get_partial_data(&w[0], p_bytes, received);
w = DVector<uint8_t>::Write();
if (err!=OK) {
if (err != OK) {
data.resize(0);
} else if (received!=data.size()) {
} else if (received != data.size()) {
data.resize(received);
}
@ -112,12 +110,11 @@ Array StreamPeer::_get_partial_data(int p_bytes) {
ret.push_back(err);
ret.push_back(data);
return ret;
}
void StreamPeer::set_big_endian(bool p_enable) {
big_endian=p_enable;
big_endian = p_enable;
}
bool StreamPeer::is_big_endian_enabled() const {
@ -125,298 +122,274 @@ bool StreamPeer::is_big_endian_enabled() const {
return big_endian;
}
void StreamPeer::put_u8(uint8_t p_val) {
put_data((const uint8_t*)&p_val,1);
put_data((const uint8_t *)&p_val, 1);
}
void StreamPeer::put_8(int8_t p_val){
void StreamPeer::put_8(int8_t p_val) {
put_data((const uint8_t*)&p_val,1);
put_data((const uint8_t *)&p_val, 1);
}
void StreamPeer::put_u16(uint16_t p_val){
void StreamPeer::put_u16(uint16_t p_val) {
if (big_endian) {
p_val=BSWAP16(p_val);
p_val = BSWAP16(p_val);
}
uint8_t buf[2];
encode_uint16(p_val,buf);
put_data(buf,2);
encode_uint16(p_val, buf);
put_data(buf, 2);
}
void StreamPeer::put_16(int16_t p_val){
void StreamPeer::put_16(int16_t p_val) {
if (big_endian) {
p_val=BSWAP16(p_val);
p_val = BSWAP16(p_val);
}
uint8_t buf[2];
encode_uint16(p_val,buf);
put_data(buf,2);
encode_uint16(p_val, buf);
put_data(buf, 2);
}
void StreamPeer::put_u32(uint32_t p_val){
void StreamPeer::put_u32(uint32_t p_val) {
if (big_endian) {
p_val=BSWAP32(p_val);
p_val = BSWAP32(p_val);
}
uint8_t buf[4];
encode_uint32(p_val,buf);
put_data(buf,4);
encode_uint32(p_val, buf);
put_data(buf, 4);
}
void StreamPeer::put_32(int32_t p_val){
void StreamPeer::put_32(int32_t p_val) {
if (big_endian) {
p_val=BSWAP32(p_val);
p_val = BSWAP32(p_val);
}
uint8_t buf[4];
encode_uint32(p_val,buf);
put_data(buf,4);
encode_uint32(p_val, buf);
put_data(buf, 4);
}
void StreamPeer::put_u64(uint64_t p_val){
void StreamPeer::put_u64(uint64_t p_val) {
if (big_endian) {
p_val=BSWAP64(p_val);
p_val = BSWAP64(p_val);
}
uint8_t buf[8];
encode_uint64(p_val,buf);
put_data(buf,8);
encode_uint64(p_val, buf);
put_data(buf, 8);
}
void StreamPeer::put_64(int64_t p_val){
void StreamPeer::put_64(int64_t p_val) {
if (big_endian) {
p_val=BSWAP64(p_val);
p_val = BSWAP64(p_val);
}
uint8_t buf[8];
encode_uint64(p_val,buf);
put_data(buf,8);
encode_uint64(p_val, buf);
put_data(buf, 8);
}
void StreamPeer::put_float(float p_val){
void StreamPeer::put_float(float p_val) {
uint8_t buf[4];
encode_float(p_val,buf);
encode_float(p_val, buf);
if (big_endian) {
uint32_t *p32=(uint32_t *)buf;
*p32=BSWAP32(*p32);
uint32_t *p32 = (uint32_t *)buf;
*p32 = BSWAP32(*p32);
}
put_data(buf,4);
put_data(buf, 4);
}
void StreamPeer::put_double(double p_val){
void StreamPeer::put_double(double p_val) {
uint8_t buf[8];
encode_double(p_val,buf);
encode_double(p_val, buf);
if (big_endian) {
uint64_t *p64=(uint64_t *)buf;
*p64=BSWAP64(*p64);
uint64_t *p64 = (uint64_t *)buf;
*p64 = BSWAP64(*p64);
}
put_data(buf,8);
put_data(buf, 8);
}
void StreamPeer::put_utf8_string(const String& p_string) {
CharString cs=p_string.utf8();
put_data((const uint8_t*)cs.get_data(),cs.length());
void StreamPeer::put_utf8_string(const String &p_string) {
CharString cs = p_string.utf8();
put_data((const uint8_t *)cs.get_data(), cs.length());
}
void StreamPeer::put_var(const Variant& p_variant){
void StreamPeer::put_var(const Variant &p_variant) {
int len=0;
int len = 0;
Vector<uint8_t> buf;
encode_variant(p_variant,NULL,len);
encode_variant(p_variant, NULL, len);
buf.resize(len);
put_32(len);
encode_variant(p_variant,buf.ptr(),len);
put_data(buf.ptr(),buf.size());
encode_variant(p_variant, buf.ptr(), len);
put_data(buf.ptr(), buf.size());
}
uint8_t StreamPeer::get_u8(){
uint8_t StreamPeer::get_u8() {
uint8_t buf[1];
get_data(buf,1);
get_data(buf, 1);
return buf[0];
}
int8_t StreamPeer::get_8(){
int8_t StreamPeer::get_8() {
uint8_t buf[1];
get_data(buf,1);
get_data(buf, 1);
return buf[0];
}
uint16_t StreamPeer::get_u16(){
uint16_t StreamPeer::get_u16() {
uint8_t buf[2];
get_data(buf,2);
get_data(buf, 2);
uint16_t r = decode_uint16(buf);
if (big_endian) {
r=BSWAP16(r);
r = BSWAP16(r);
}
return r;
}
int16_t StreamPeer::get_16(){
int16_t StreamPeer::get_16() {
uint8_t buf[2];
get_data(buf,2);
get_data(buf, 2);
uint16_t r = decode_uint16(buf);
if (big_endian) {
r=BSWAP16(r);
r = BSWAP16(r);
}
return r;
}
uint32_t StreamPeer::get_u32(){
uint32_t StreamPeer::get_u32() {
uint8_t buf[4];
get_data(buf,4);
get_data(buf, 4);
uint32_t r = decode_uint32(buf);
if (big_endian) {
r=BSWAP32(r);
r = BSWAP32(r);
}
return r;
}
int32_t StreamPeer::get_32(){
int32_t StreamPeer::get_32() {
uint8_t buf[4];
get_data(buf,4);
get_data(buf, 4);
uint32_t r = decode_uint32(buf);
if (big_endian) {
r=BSWAP32(r);
r = BSWAP32(r);
}
return r;
}
uint64_t StreamPeer::get_u64(){
uint64_t StreamPeer::get_u64() {
uint8_t buf[8];
get_data(buf,8);
get_data(buf, 8);
uint64_t r = decode_uint64(buf);
if (big_endian) {
r=BSWAP64(r);
r = BSWAP64(r);
}
return r;
}
int64_t StreamPeer::get_64(){
int64_t StreamPeer::get_64() {
uint8_t buf[8];
get_data(buf,8);
get_data(buf, 8);
uint64_t r = decode_uint64(buf);
if (big_endian) {
r=BSWAP64(r);
r = BSWAP64(r);
}
return r;
}
float StreamPeer::get_float(){
float StreamPeer::get_float() {
uint8_t buf[4];
get_data(buf,4);
get_data(buf, 4);
if (big_endian) {
uint32_t *p32=(uint32_t *)buf;
*p32=BSWAP32(*p32);
uint32_t *p32 = (uint32_t *)buf;
*p32 = BSWAP32(*p32);
}
return decode_float(buf);
}
float StreamPeer::get_double(){
float StreamPeer::get_double() {
uint8_t buf[8];
get_data(buf,8);
get_data(buf, 8);
if (big_endian) {
uint64_t *p64=(uint64_t *)buf;
*p64=BSWAP64(*p64);
uint64_t *p64 = (uint64_t *)buf;
*p64 = BSWAP64(*p64);
}
return decode_double(buf);
}
String StreamPeer::get_string(int p_bytes){
String StreamPeer::get_string(int p_bytes) {
ERR_FAIL_COND_V(p_bytes<0,String());
ERR_FAIL_COND_V(p_bytes < 0, String());
Vector<char> buf;
buf.resize(p_bytes+1);
get_data((uint8_t*)&buf[0],p_bytes);
buf[p_bytes]=0;
buf.resize(p_bytes + 1);
get_data((uint8_t *)&buf[0], p_bytes);
buf[p_bytes] = 0;
return buf.ptr();
}
String StreamPeer::get_utf8_string(int p_bytes){
String StreamPeer::get_utf8_string(int p_bytes) {
ERR_FAIL_COND_V(p_bytes<0,String());
ERR_FAIL_COND_V(p_bytes < 0, String());
Vector<uint8_t> buf;
buf.resize(p_bytes);
get_data(buf.ptr(),p_bytes);
get_data(buf.ptr(), p_bytes);
String ret;
ret.parse_utf8((const char*)buf.ptr(),buf.size());
ret.parse_utf8((const char *)buf.ptr(), buf.size());
return ret;
}
Variant StreamPeer::get_var(){
Variant StreamPeer::get_var() {
int len = get_32();
Vector<uint8_t> var;
var.resize(len);
get_data(var.ptr(),len);
get_data(var.ptr(), len);
Variant ret;
decode_variant(ret,var.ptr(),len);
decode_variant(ret, var.ptr(), len);
return ret;
}
void StreamPeer::_bind_methods() {
ObjectTypeDB::bind_method(_MD("put_data","data"),&StreamPeer::_put_data);
ObjectTypeDB::bind_method(_MD("put_partial_data","data"),&StreamPeer::_put_partial_data);
ObjectTypeDB::bind_method(_MD("put_data", "data"), &StreamPeer::_put_data);
ObjectTypeDB::bind_method(_MD("put_partial_data", "data"), &StreamPeer::_put_partial_data);
ObjectTypeDB::bind_method(_MD("get_data","bytes"),&StreamPeer::_get_data);
ObjectTypeDB::bind_method(_MD("get_partial_data","bytes"),&StreamPeer::_get_partial_data);
ObjectTypeDB::bind_method(_MD("get_data", "bytes"), &StreamPeer::_get_data);
ObjectTypeDB::bind_method(_MD("get_partial_data", "bytes"), &StreamPeer::_get_partial_data);
ObjectTypeDB::bind_method(_MD("get_available_bytes"),&StreamPeer::get_available_bytes);
ObjectTypeDB::bind_method(_MD("get_available_bytes"), &StreamPeer::get_available_bytes);
ObjectTypeDB::bind_method(_MD("set_big_endian","enable"),&StreamPeer::set_big_endian);
ObjectTypeDB::bind_method(_MD("is_big_endian_enabled"),&StreamPeer::is_big_endian_enabled);
ObjectTypeDB::bind_method(_MD("set_big_endian", "enable"), &StreamPeer::set_big_endian);
ObjectTypeDB::bind_method(_MD("is_big_endian_enabled"), &StreamPeer::is_big_endian_enabled);
ObjectTypeDB::bind_method(_MD("put_8","val"),&StreamPeer::put_8);
ObjectTypeDB::bind_method(_MD("put_u8","val"),&StreamPeer::put_u8);
ObjectTypeDB::bind_method(_MD("put_16","val"),&StreamPeer::put_16);
ObjectTypeDB::bind_method(_MD("put_u16","val"),&StreamPeer::put_u16);
ObjectTypeDB::bind_method(_MD("put_32","val"),&StreamPeer::put_32);
ObjectTypeDB::bind_method(_MD("put_u32","val"),&StreamPeer::put_u32);
ObjectTypeDB::bind_method(_MD("put_64","val"),&StreamPeer::put_64);
ObjectTypeDB::bind_method(_MD("put_u64","val"),&StreamPeer::put_u64);
ObjectTypeDB::bind_method(_MD("put_float","val"),&StreamPeer::put_float);
ObjectTypeDB::bind_method(_MD("put_double","val"),&StreamPeer::put_double);
ObjectTypeDB::bind_method(_MD("put_utf8_string","val"),&StreamPeer::put_utf8_string);
ObjectTypeDB::bind_method(_MD("put_var","val:Variant"),&StreamPeer::put_var);
ObjectTypeDB::bind_method(_MD("put_8", "val"), &StreamPeer::put_8);
ObjectTypeDB::bind_method(_MD("put_u8", "val"), &StreamPeer::put_u8);
ObjectTypeDB::bind_method(_MD("put_16", "val"), &StreamPeer::put_16);
ObjectTypeDB::bind_method(_MD("put_u16", "val"), &StreamPeer::put_u16);
ObjectTypeDB::bind_method(_MD("put_32", "val"), &StreamPeer::put_32);
ObjectTypeDB::bind_method(_MD("put_u32", "val"), &StreamPeer::put_u32);
ObjectTypeDB::bind_method(_MD("put_64", "val"), &StreamPeer::put_64);
ObjectTypeDB::bind_method(_MD("put_u64", "val"), &StreamPeer::put_u64);
ObjectTypeDB::bind_method(_MD("put_float", "val"), &StreamPeer::put_float);
ObjectTypeDB::bind_method(_MD("put_double", "val"), &StreamPeer::put_double);
ObjectTypeDB::bind_method(_MD("put_utf8_string", "val"), &StreamPeer::put_utf8_string);
ObjectTypeDB::bind_method(_MD("put_var", "val:Variant"), &StreamPeer::put_var);
ObjectTypeDB::bind_method(_MD("get_8"),&StreamPeer::get_8);
ObjectTypeDB::bind_method(_MD("get_u8"),&StreamPeer::get_u8);
ObjectTypeDB::bind_method(_MD("get_16"),&StreamPeer::get_16);
ObjectTypeDB::bind_method(_MD("get_u16"),&StreamPeer::get_u16);
ObjectTypeDB::bind_method(_MD("get_32"),&StreamPeer::get_32);
ObjectTypeDB::bind_method(_MD("get_u32"),&StreamPeer::get_u32);
ObjectTypeDB::bind_method(_MD("get_64"),&StreamPeer::get_64);
ObjectTypeDB::bind_method(_MD("get_u64"),&StreamPeer::get_u64);
ObjectTypeDB::bind_method(_MD("get_float"),&StreamPeer::get_float);
ObjectTypeDB::bind_method(_MD("get_double"),&StreamPeer::get_double);
ObjectTypeDB::bind_method(_MD("get_string","bytes"),&StreamPeer::get_string);
ObjectTypeDB::bind_method(_MD("get_utf8_string","bytes"),&StreamPeer::get_utf8_string);
ObjectTypeDB::bind_method(_MD("get_var:Variant"),&StreamPeer::get_var);
ObjectTypeDB::bind_method(_MD("get_8"), &StreamPeer::get_8);
ObjectTypeDB::bind_method(_MD("get_u8"), &StreamPeer::get_u8);
ObjectTypeDB::bind_method(_MD("get_16"), &StreamPeer::get_16);
ObjectTypeDB::bind_method(_MD("get_u16"), &StreamPeer::get_u16);
ObjectTypeDB::bind_method(_MD("get_32"), &StreamPeer::get_32);
ObjectTypeDB::bind_method(_MD("get_u32"), &StreamPeer::get_u32);
ObjectTypeDB::bind_method(_MD("get_64"), &StreamPeer::get_64);
ObjectTypeDB::bind_method(_MD("get_u64"), &StreamPeer::get_u64);
ObjectTypeDB::bind_method(_MD("get_float"), &StreamPeer::get_float);
ObjectTypeDB::bind_method(_MD("get_double"), &StreamPeer::get_double);
ObjectTypeDB::bind_method(_MD("get_string", "bytes"), &StreamPeer::get_string);
ObjectTypeDB::bind_method(_MD("get_utf8_string", "bytes"), &StreamPeer::get_utf8_string);
ObjectTypeDB::bind_method(_MD("get_var:Variant"), &StreamPeer::get_var);
}

View File

@ -32,14 +32,15 @@
#include "reference.h"
class StreamPeer : public Reference {
OBJ_TYPE( StreamPeer, Reference );
OBJ_TYPE(StreamPeer, Reference);
OBJ_CATEGORY("Networking");
protected:
static void _bind_methods();
//bind helpers
Error _put_data(const DVector<uint8_t>& p_data);
Array _put_partial_data(const DVector<uint8_t>& p_data);
Error _put_data(const DVector<uint8_t> &p_data);
Array _put_partial_data(const DVector<uint8_t> &p_data);
Array _get_data(int p_bytes);
Array _get_partial_data(int p_bytes);
@ -47,14 +48,13 @@ protected:
bool big_endian;
public:
virtual Error put_data(const uint8_t *p_data, int p_bytes) = 0; ///< put a whole chunk of data, blocking until it sent
virtual Error put_partial_data(const uint8_t *p_data, int p_bytes, int &r_sent) = 0; ///< put as much data as possible, without blocking.
virtual Error put_data(const uint8_t* p_data,int p_bytes)=0; ///< put a whole chunk of data, blocking until it sent
virtual Error put_partial_data(const uint8_t* p_data,int p_bytes, int &r_sent)=0; ///< put as much data as possible, without blocking.
virtual Error get_data(uint8_t *p_buffer, int p_bytes) = 0; ///< read p_bytes of data, if p_bytes > available, it will block
virtual Error get_partial_data(uint8_t *p_buffer, int p_bytes, int &r_received) = 0; ///< read as much data as p_bytes into buffer, if less was read, return in r_received
virtual Error get_data(uint8_t* p_buffer, int p_bytes)=0; ///< read p_bytes of data, if p_bytes > available, it will block
virtual Error get_partial_data(uint8_t* p_buffer, int p_bytes,int &r_received)=0; ///< read as much data as p_bytes into buffer, if less was read, return in r_received
virtual int get_available_bytes() const=0;
virtual int get_available_bytes() const = 0;
void set_big_endian(bool p_enable);
bool is_big_endian_enabled() const;
@ -69,8 +69,8 @@ public:
void put_u64(uint64_t p_val);
void put_float(float p_val);
void put_double(double p_val);
void put_utf8_string(const String& p_string);
void put_var(const Variant& p_variant);
void put_utf8_string(const String &p_string);
void put_var(const Variant &p_variant);
uint8_t get_u8();
int8_t get_8();
@ -86,9 +86,7 @@ public:
String get_utf8_string(int p_bytes);
Variant get_var();
StreamPeer() { big_endian=false; }
StreamPeer() { big_endian = false; }
};
#endif // STREAM_PEER_H

View File

@ -28,24 +28,18 @@
/*************************************************************************/
#include "stream_peer_ssl.h"
StreamPeerSSL* (*StreamPeerSSL::_create)()=NULL;
StreamPeerSSL *(*StreamPeerSSL::_create)() = NULL;
StreamPeerSSL *StreamPeerSSL::create() {
return _create();
}
StreamPeerSSL::LoadCertsFromMemory StreamPeerSSL::load_certs_func = NULL;
bool StreamPeerSSL::available = false;
bool StreamPeerSSL::initialize_certs = true;
StreamPeerSSL::LoadCertsFromMemory StreamPeerSSL::load_certs_func=NULL;
bool StreamPeerSSL::available=false;
bool StreamPeerSSL::initialize_certs=true;
void StreamPeerSSL::load_certs_from_memory(const ByteArray& p_memory) {
void StreamPeerSSL::load_certs_from_memory(const ByteArray &p_memory) {
if (load_certs_func)
load_certs_func(p_memory);
}
@ -56,18 +50,15 @@ bool StreamPeerSSL::is_available() {
void StreamPeerSSL::_bind_methods() {
ObjectTypeDB::bind_method(_MD("accept:Error","stream:StreamPeer"),&StreamPeerSSL::accept);
ObjectTypeDB::bind_method(_MD("connect:Error","stream:StreamPeer","validate_certs","for_hostname"),&StreamPeerSSL::connect,DEFVAL(false),DEFVAL(String()));
ObjectTypeDB::bind_method(_MD("get_status"),&StreamPeerSSL::get_status);
ObjectTypeDB::bind_method(_MD("disconnect"),&StreamPeerSSL::disconnect);
BIND_CONSTANT( STATUS_DISCONNECTED );
BIND_CONSTANT( STATUS_CONNECTED );
BIND_CONSTANT( STATUS_ERROR_NO_CERTIFICATE );
BIND_CONSTANT( STATUS_ERROR_HOSTNAME_MISMATCH );
ObjectTypeDB::bind_method(_MD("accept:Error", "stream:StreamPeer"), &StreamPeerSSL::accept);
ObjectTypeDB::bind_method(_MD("connect:Error", "stream:StreamPeer", "validate_certs", "for_hostname"), &StreamPeerSSL::connect, DEFVAL(false), DEFVAL(String()));
ObjectTypeDB::bind_method(_MD("get_status"), &StreamPeerSSL::get_status);
ObjectTypeDB::bind_method(_MD("disconnect"), &StreamPeerSSL::disconnect);
BIND_CONSTANT(STATUS_DISCONNECTED);
BIND_CONSTANT(STATUS_CONNECTED);
BIND_CONSTANT(STATUS_ERROR_NO_CERTIFICATE);
BIND_CONSTANT(STATUS_ERROR_HOSTNAME_MISMATCH);
}
StreamPeerSSL::StreamPeerSSL()
{
StreamPeerSSL::StreamPeerSSL() {
}

View File

@ -32,24 +32,22 @@
#include "io/stream_peer.h"
class StreamPeerSSL : public StreamPeer {
OBJ_TYPE(StreamPeerSSL,StreamPeer);
public:
OBJ_TYPE(StreamPeerSSL, StreamPeer);
public:
typedef void (*LoadCertsFromMemory)(const ByteArray &p_certs);
typedef void (*LoadCertsFromMemory)(const ByteArray& p_certs);
protected:
static StreamPeerSSL* (*_create)();
static StreamPeerSSL *(*_create)();
static void _bind_methods();
static LoadCertsFromMemory load_certs_func;
static bool available;
friend class Main;
friend class Main;
static bool initialize_certs;
public:
enum Status {
STATUS_DISCONNECTED,
STATUS_CONNECTED,
@ -57,20 +55,20 @@ public:
STATUS_ERROR_HOSTNAME_MISMATCH
};
virtual Error accept(Ref<StreamPeer> p_base)=0;
virtual Error connect(Ref<StreamPeer> p_base,bool p_validate_certs=false,const String& p_for_hostname=String())=0;
virtual Status get_status() const=0;
virtual Error accept(Ref<StreamPeer> p_base) = 0;
virtual Error connect(Ref<StreamPeer> p_base, bool p_validate_certs = false, const String &p_for_hostname = String()) = 0;
virtual Status get_status() const = 0;
virtual void disconnect()=0;
virtual void disconnect() = 0;
static StreamPeerSSL* create();
static StreamPeerSSL *create();
static void load_certs_from_memory(const ByteArray& p_memory);
static void load_certs_from_memory(const ByteArray &p_memory);
static bool is_available();
StreamPeerSSL();
};
VARIANT_ENUM_CAST( StreamPeerSSL::Status );
VARIANT_ENUM_CAST(StreamPeerSSL::Status);
#endif // STREAM_PEER_SSL_H

View File

@ -28,20 +28,20 @@
/*************************************************************************/
#include "stream_peer_tcp.h"
StreamPeerTCP* (*StreamPeerTCP::_create)()=NULL;
StreamPeerTCP *(*StreamPeerTCP::_create)() = NULL;
Error StreamPeerTCP::_connect(const String& p_address,int p_port) {
Error StreamPeerTCP::_connect(const String &p_address, int p_port) {
IP_Address ip;
if (p_address.is_valid_ip_address()) {
ip=p_address;
ip = p_address;
} else {
ip=IP::get_singleton()->resolve_hostname(p_address, ip_type);
if (ip==IP_Address())
ip = IP::get_singleton()->resolve_hostname(p_address, ip_type);
if (ip == IP_Address())
return ERR_CANT_RESOLVE;
}
connect(ip,p_port);
connect(ip, p_port);
return OK;
}
@ -52,19 +52,18 @@ void StreamPeerTCP::set_ip_type(IP::Type p_type) {
void StreamPeerTCP::_bind_methods() {
ObjectTypeDB::bind_method(_MD("set_ip_type","ip_type"),&StreamPeerTCP::set_ip_type);
ObjectTypeDB::bind_method(_MD("connect","host","port"),&StreamPeerTCP::_connect);
ObjectTypeDB::bind_method(_MD("is_connected"),&StreamPeerTCP::is_connected);
ObjectTypeDB::bind_method(_MD("get_status"),&StreamPeerTCP::get_status);
ObjectTypeDB::bind_method(_MD("get_connected_host"),&StreamPeerTCP::get_connected_host);
ObjectTypeDB::bind_method(_MD("get_connected_port"),&StreamPeerTCP::get_connected_port);
ObjectTypeDB::bind_method(_MD("disconnect"),&StreamPeerTCP::disconnect);
BIND_CONSTANT( STATUS_NONE );
BIND_CONSTANT( STATUS_CONNECTING );
BIND_CONSTANT( STATUS_CONNECTED );
BIND_CONSTANT( STATUS_ERROR );
ObjectTypeDB::bind_method(_MD("set_ip_type", "ip_type"), &StreamPeerTCP::set_ip_type);
ObjectTypeDB::bind_method(_MD("connect", "host", "port"), &StreamPeerTCP::_connect);
ObjectTypeDB::bind_method(_MD("is_connected"), &StreamPeerTCP::is_connected);
ObjectTypeDB::bind_method(_MD("get_status"), &StreamPeerTCP::get_status);
ObjectTypeDB::bind_method(_MD("get_connected_host"), &StreamPeerTCP::get_connected_host);
ObjectTypeDB::bind_method(_MD("get_connected_port"), &StreamPeerTCP::get_connected_port);
ObjectTypeDB::bind_method(_MD("disconnect"), &StreamPeerTCP::disconnect);
BIND_CONSTANT(STATUS_NONE);
BIND_CONSTANT(STATUS_CONNECTING);
BIND_CONSTANT(STATUS_CONNECTED);
BIND_CONSTANT(STATUS_ERROR);
}
Ref<StreamPeerTCP> StreamPeerTCP::create_ref() {
@ -74,7 +73,7 @@ Ref<StreamPeerTCP> StreamPeerTCP::create_ref() {
return Ref<StreamPeerTCP>(_create());
}
StreamPeerTCP* StreamPeerTCP::create() {
StreamPeerTCP *StreamPeerTCP::create() {
if (!_create)
return NULL;
@ -86,7 +85,6 @@ StreamPeerTCP::StreamPeerTCP() {
ip_type = IP::TYPE_ANY;
}
StreamPeerTCP::~StreamPeerTCP() {
StreamPeerTCP::~StreamPeerTCP(){
};

View File

@ -31,16 +31,15 @@
#include "stream_peer.h"
#include "ip_address.h"
#include "io/ip.h"
#include "ip_address.h"
class StreamPeerTCP : public StreamPeer {
OBJ_TYPE( StreamPeerTCP, StreamPeer );
OBJ_TYPE(StreamPeerTCP, StreamPeer);
OBJ_CATEGORY("Networking");
public:
enum Status {
STATUS_NONE,
@ -50,34 +49,32 @@ public:
};
protected:
IP::Type ip_type;
virtual Error _connect(const String& p_address, int p_port);
static StreamPeerTCP* (*_create)();
virtual Error _connect(const String &p_address, int p_port);
static StreamPeerTCP *(*_create)();
static void _bind_methods();
public:
virtual void set_ip_type(IP::Type p_type);
virtual Error connect(const IP_Address& p_host, uint16_t p_port)=0;
virtual Error connect(const IP_Address &p_host, uint16_t p_port) = 0;
//read/write from streampeer
virtual bool is_connected() const=0;
virtual Status get_status() const=0;
virtual void disconnect()=0;
virtual IP_Address get_connected_host() const=0;
virtual uint16_t get_connected_port() const=0;
virtual void set_nodelay(bool p_enabled)=0;
virtual bool is_connected() const = 0;
virtual Status get_status() const = 0;
virtual void disconnect() = 0;
virtual IP_Address get_connected_host() const = 0;
virtual uint16_t get_connected_port() const = 0;
virtual void set_nodelay(bool p_enabled) = 0;
static Ref<StreamPeerTCP> create_ref();
static StreamPeerTCP* create();
static StreamPeerTCP *create();
StreamPeerTCP();
~StreamPeerTCP();
};
VARIANT_ENUM_CAST( StreamPeerTCP::Status );
VARIANT_ENUM_CAST(StreamPeerTCP::Status);
#endif

View File

@ -28,7 +28,7 @@
/*************************************************************************/
#include "tcp_server.h"
TCP_Server* (*TCP_Server::_create)()=NULL;
TCP_Server *(*TCP_Server::_create)() = NULL;
Ref<TCP_Server> TCP_Server::create_ref() {
@ -37,7 +37,7 @@ Ref<TCP_Server> TCP_Server::create_ref() {
return Ref<TCP_Server>(_create());
}
TCP_Server* TCP_Server::create() {
TCP_Server *TCP_Server::create() {
if (!_create)
return NULL;
@ -47,11 +47,10 @@ TCP_Server* TCP_Server::create() {
Error TCP_Server::_listen(uint16_t p_port, DVector<String> p_accepted_hosts) {
List<String> hosts;
for(int i=0;i<p_accepted_hosts.size();i++)
for (int i = 0; i < p_accepted_hosts.size(); i++)
hosts.push_back(p_accepted_hosts.get(i));
return listen(p_port, hosts.size()?&hosts:NULL);
return listen(p_port, hosts.size() ? &hosts : NULL);
}
void TCP_Server::set_ip_type(IP::Type p_type) {
@ -61,16 +60,13 @@ void TCP_Server::set_ip_type(IP::Type p_type) {
void TCP_Server::_bind_methods() {
ObjectTypeDB::bind_method(_MD("set_ip_type","ip_type"),&TCP_Server::set_ip_type);
ObjectTypeDB::bind_method(_MD("listen","port","accepted_hosts"),&TCP_Server::_listen,DEFVAL(DVector<String>()));
ObjectTypeDB::bind_method(_MD("is_connection_available"),&TCP_Server::is_connection_available);
ObjectTypeDB::bind_method(_MD("take_connection"),&TCP_Server::take_connection);
ObjectTypeDB::bind_method(_MD("stop"),&TCP_Server::stop);
ObjectTypeDB::bind_method(_MD("set_ip_type", "ip_type"), &TCP_Server::set_ip_type);
ObjectTypeDB::bind_method(_MD("listen", "port", "accepted_hosts"), &TCP_Server::_listen, DEFVAL(DVector<String>()));
ObjectTypeDB::bind_method(_MD("is_connection_available"), &TCP_Server::is_connection_available);
ObjectTypeDB::bind_method(_MD("take_connection"), &TCP_Server::take_connection);
ObjectTypeDB::bind_method(_MD("stop"), &TCP_Server::stop);
}
TCP_Server::TCP_Server()
{
TCP_Server::TCP_Server() {
ip_type = IP::TYPE_ANY;
}

View File

@ -29,33 +29,33 @@
#ifndef TCP_SERVER_H
#define TCP_SERVER_H
#include "io/stream_peer.h"
#include "io/ip.h"
#include "io/stream_peer.h"
#include "stream_peer_tcp.h"
class TCP_Server : public Reference {
OBJ_TYPE( TCP_Server, Reference );
protected:
OBJ_TYPE(TCP_Server, Reference);
protected:
IP::Type ip_type;
static TCP_Server* (*_create)();
static TCP_Server *(*_create)();
//bind helper
Error _listen(uint16_t p_port, DVector<String> p_accepted_hosts=DVector<String>());
Error _listen(uint16_t p_port, DVector<String> p_accepted_hosts = DVector<String>());
static void _bind_methods();
public:
virtual void set_ip_type(IP::Type p_type);
virtual Error listen(uint16_t p_port, const List<String> *p_accepted_hosts=NULL)=0;
virtual bool is_connection_available() const=0;
virtual Ref<StreamPeerTCP> take_connection()=0;
virtual Error listen(uint16_t p_port, const List<String> *p_accepted_hosts = NULL) = 0;
virtual bool is_connection_available() const = 0;
virtual Ref<StreamPeerTCP> take_connection() = 0;
virtual void stop()=0; //stop listening
virtual void stop() = 0; //stop listening
static Ref<TCP_Server> create_ref();
static TCP_Server* create();
static TCP_Server *create();
TCP_Server();
};

View File

@ -30,7 +30,6 @@
#include "os/file_access.h"
#include "translation.h"
RES TranslationLoaderPO::load_translation(FileAccess *f, Error *r_error, const String &p_path) {
enum Status {
@ -40,175 +39,169 @@ RES TranslationLoaderPO::load_translation(FileAccess *f, Error *r_error, const S
STATUS_READING_STRING,
};
Status status=STATUS_NONE;
Status status = STATUS_NONE;
String msg_id;
String msg_str;
String config;
if (r_error)
*r_error=ERR_FILE_CORRUPT;
*r_error = ERR_FILE_CORRUPT;
Ref<Translation> translation = Ref<Translation>( memnew( Translation ));
Ref<Translation> translation = Ref<Translation>(memnew(Translation));
int line = 1;
while(true) {
while (true) {
String l = f->get_line();
if (f->eof_reached()) {
if ( status == STATUS_READING_STRING) {
if (status == STATUS_READING_STRING) {
if (msg_id!="")
translation->add_message(msg_id,msg_str);
else if (config=="")
config=msg_str;
if (msg_id != "")
translation->add_message(msg_id, msg_str);
else if (config == "")
config = msg_str;
break;
} else if ( status==STATUS_NONE)
} else if (status == STATUS_NONE)
break;
memdelete(f);
ERR_EXPLAIN(p_path+":"+itos(line)+" Unexpected EOF while reading 'msgid' at file: ");
ERR_EXPLAIN(p_path + ":" + itos(line) + " Unexpected EOF while reading 'msgid' at file: ");
ERR_FAIL_V(RES());
}
l=l.strip_edges();
l = l.strip_edges();
if (l.begins_with("msgid")) {
if (status==STATUS_READING_ID) {
if (status == STATUS_READING_ID) {
memdelete(f);
ERR_EXPLAIN(p_path+":"+itos(line)+" Unexpected 'msgid', was expecting 'msgstr' while parsing: ");
ERR_EXPLAIN(p_path + ":" + itos(line) + " Unexpected 'msgid', was expecting 'msgstr' while parsing: ");
ERR_FAIL_V(RES());
}
if (msg_id!="")
translation->add_message(msg_id,msg_str);
else if (config=="")
config=msg_str;
if (msg_id != "")
translation->add_message(msg_id, msg_str);
else if (config == "")
config = msg_str;
l=l.substr(5,l.length()).strip_edges();
status=STATUS_READING_ID;
msg_id="";
msg_str="";
l = l.substr(5, l.length()).strip_edges();
status = STATUS_READING_ID;
msg_id = "";
msg_str = "";
}
if (l.begins_with("msgstr")) {
if (status!=STATUS_READING_ID) {
if (status != STATUS_READING_ID) {
memdelete(f);
ERR_EXPLAIN(p_path+":"+itos(line)+" Unexpected 'msgstr', was expecting 'msgid' while parsing: ");
ERR_EXPLAIN(p_path + ":" + itos(line) + " Unexpected 'msgstr', was expecting 'msgid' while parsing: ");
ERR_FAIL_V(RES());
}
l=l.substr(6,l.length()).strip_edges();
status=STATUS_READING_STRING;
l = l.substr(6, l.length()).strip_edges();
status = STATUS_READING_STRING;
}
if (l=="" || l.begins_with("#")) {
if (l == "" || l.begins_with("#")) {
line++;
continue; //nothing to read or comment
}
if (!l.begins_with("\"") || status==STATUS_NONE) {
if (!l.begins_with("\"") || status == STATUS_NONE) {
//not a string? failure!
ERR_EXPLAIN(p_path+":"+itos(line)+" Invalid line '"+l+"' while parsing: ");
ERR_EXPLAIN(p_path + ":" + itos(line) + " Invalid line '" + l + "' while parsing: ");
ERR_FAIL_V(RES());
}
l=l.substr(1,l.length());
l = l.substr(1, l.length());
//find final quote
int end_pos=-1;
for(int i=0;i<l.length();i++) {
int end_pos = -1;
for (int i = 0; i < l.length(); i++) {
if (l[i]=='"' && (i==0 || l[i-1]!='\\')) {
end_pos=i;
if (l[i] == '"' && (i == 0 || l[i - 1] != '\\')) {
end_pos = i;
break;
}
}
if (end_pos==-1) {
ERR_EXPLAIN(p_path+":"+itos(line)+" Expected '\"' at end of message while parsing file: ");
if (end_pos == -1) {
ERR_EXPLAIN(p_path + ":" + itos(line) + " Expected '\"' at end of message while parsing file: ");
ERR_FAIL_V(RES());
}
l=l.substr(0,end_pos);
l=l.c_unescape();
l = l.substr(0, end_pos);
l = l.c_unescape();
if (status==STATUS_READING_ID)
msg_id+=l;
if (status == STATUS_READING_ID)
msg_id += l;
else
msg_str+=l;
msg_str += l;
line++;
}
f->close();
memdelete(f);
if (config=="") {
ERR_EXPLAIN("No config found in file: "+p_path);
if (config == "") {
ERR_EXPLAIN("No config found in file: " + p_path);
ERR_FAIL_V(RES());
}
Vector<String> configs = config.split("\n");
for(int i=0;i<configs.size();i++) {
for (int i = 0; i < configs.size(); i++) {
String c = configs[i].strip_edges();
int p = c.find(":");
if (p==-1)
if (p == -1)
continue;
String prop = c.substr(0,p).strip_edges();
String value = c.substr(p+1,c.length()).strip_edges();
String prop = c.substr(0, p).strip_edges();
String value = c.substr(p + 1, c.length()).strip_edges();
if (prop=="X-Language") {
if (prop == "X-Language") {
translation->set_locale(value);
}
}
if (r_error)
*r_error=OK;
*r_error = OK;
return translation;
}
RES TranslationLoaderPO::load(const String &p_path, const String& p_original_path, Error *r_error) {
RES TranslationLoaderPO::load(const String &p_path, const String &p_original_path, Error *r_error) {
if (r_error)
*r_error=ERR_CANT_OPEN;
*r_error = ERR_CANT_OPEN;
FileAccess *f=FileAccess::open(p_path,FileAccess::READ);
ERR_FAIL_COND_V(!f,RES());
return load_translation(f,r_error);
FileAccess *f = FileAccess::open(p_path, FileAccess::READ);
ERR_FAIL_COND_V(!f, RES());
return load_translation(f, r_error);
}
void TranslationLoaderPO::get_recognized_extensions(List<String> *p_extensions) const{
void TranslationLoaderPO::get_recognized_extensions(List<String> *p_extensions) const {
p_extensions->push_back("po");
//p_extensions->push_back("mo"); //mo in the future...
}
bool TranslationLoaderPO::handles_type(const String& p_type) const{
bool TranslationLoaderPO::handles_type(const String &p_type) const {
return (p_type=="Translation");
return (p_type == "Translation");
}
String TranslationLoaderPO::get_resource_type(const String &p_path) const {
if (p_path.extension().to_lower()=="po")
if (p_path.extension().to_lower() == "po")
return "Translation";
return "";
}
TranslationLoaderPO::TranslationLoaderPO()
{
TranslationLoaderPO::TranslationLoaderPO() {
}

View File

@ -30,18 +30,16 @@
#define TRANSLATION_LOADER_PO_H
#include "io/resource_loader.h"
#include "translation.h"
#include "os/file_access.h"
#include "translation.h"
class TranslationLoaderPO : public ResourceFormatLoader {
public:
static RES load_translation(FileAccess *f, Error *r_error,const String& p_path=String());
virtual RES load(const String &p_path,const String& p_original_path="",Error *r_error=NULL);
static RES load_translation(FileAccess *f, Error *r_error, const String &p_path = String());
virtual RES load(const String &p_path, const String &p_original_path = "", Error *r_error = NULL);
virtual void get_recognized_extensions(List<String> *p_extensions) const;
virtual bool handles_type(const String& p_type) const;
virtual bool handles_type(const String &p_type) const;
virtual String get_resource_type(const String &p_path) const;
TranslationLoaderPO();
};

View File

@ -32,19 +32,18 @@
VARIANT_ENUM_CAST(XMLParser::NodeType);
static bool _equalsn(const CharType* str1, const CharType* str2, int len) {
static bool _equalsn(const CharType *str1, const CharType *str2, int len) {
int i;
for(i=0; i < len && str1[i] && str2[i] ; ++i)
if (str1[i] != str2[i])
return false;
for (i = 0; i < len && str1[i] && str2[i]; ++i)
if (str1[i] != str2[i])
return false;
// if one (or both) of the strings was smaller then they
// are only equal if they have the same lenght
return (i == len) || (str1[i] == 0 && str2[i] == 0);
}
String XMLParser::_replace_special_characters(const String& origstr) {
String XMLParser::_replace_special_characters(const String &origstr) {
int pos = origstr.find("&");
int oldPos = 0;
@ -54,30 +53,25 @@ String XMLParser::_replace_special_characters(const String& origstr) {
String newstr;
while(pos != -1 && pos < origstr.length()-2) {
while (pos != -1 && pos < origstr.length() - 2) {
// check if it is one of the special characters
int specialChar = -1;
for (int i=0; i<(int)special_characters.size(); ++i)
{
const CharType* p = &origstr[pos]+1;
for (int i = 0; i < (int)special_characters.size(); ++i) {
const CharType *p = &origstr[pos] + 1;
if (_equalsn(&special_characters[i][1], p, special_characters[i].length()-1))
{
if (_equalsn(&special_characters[i][1], p, special_characters[i].length() - 1)) {
specialChar = i;
break;
}
}
if (specialChar != -1)
{
newstr+=(origstr.substr(oldPos, pos - oldPos));
newstr+=(special_characters[specialChar][0]);
if (specialChar != -1) {
newstr += (origstr.substr(oldPos, pos - oldPos));
newstr += (special_characters[specialChar][0]);
pos += special_characters[specialChar].length();
}
else
{
newstr+=(origstr.substr(oldPos, pos - oldPos + 1));
} else {
newstr += (origstr.substr(oldPos, pos - oldPos + 1));
pos += 1;
}
@ -86,27 +80,23 @@ String XMLParser::_replace_special_characters(const String& origstr) {
pos = origstr.find("&", pos);
}
if (oldPos < origstr.length()-1)
newstr+=(origstr.substr(oldPos, origstr.length()-oldPos));
if (oldPos < origstr.length() - 1)
newstr += (origstr.substr(oldPos, origstr.length() - oldPos));
return newstr;
}
static inline bool _is_white_space(char c)
{
return (c==' ' || c=='\t' || c=='\n' || c=='\r');
static inline bool _is_white_space(char c) {
return (c == ' ' || c == '\t' || c == '\n' || c == '\r');
}
//! sets the state that text was found. Returns true if set should be set
bool XMLParser::_set_text(char* start, char* end) {
bool XMLParser::_set_text(char *start, char *end) {
// check if text is more than 2 characters, and if not, check if there is
// only white space, so that this text won't be reported
if (end - start < 3)
{
char* p = start;
for(; p != end; ++p)
if (end - start < 3) {
char *p = start;
for (; p != end; ++p)
if (!_is_white_space(*p))
break;
@ -130,14 +120,14 @@ void XMLParser::_parse_closing_xml_element() {
attributes.clear();
++P;
const char* pBeginClose = P;
const char *pBeginClose = P;
while(*P != '>')
while (*P != '>')
++P;
node_name = String::utf8(pBeginClose, (int)(P - pBeginClose));
#ifdef DEBUG_XML
print_line("XML CLOSE: "+node_name);
print_line("XML CLOSE: " + node_name);
#endif
++P;
}
@ -145,25 +135,24 @@ void XMLParser::_parse_closing_xml_element() {
void XMLParser::_ignore_definition() {
node_type = NODE_UNKNOWN;
char *F=P;
char *F = P;
// move until end marked with '>' reached
while(*P != '>')
while (*P != '>')
++P;
node_name.parse_utf8(F,P-F);
node_name.parse_utf8(F, P - F);
++P;
}
bool XMLParser::_parse_cdata() {
if (*(P+1) != '[')
if (*(P + 1) != '[')
return false;
node_type = NODE_CDATA;
// skip '<![CDATA['
int count=0;
while( *P && count<8 )
{
int count = 0;
while (*P && count < 8) {
++P;
++count;
}
@ -175,23 +164,22 @@ bool XMLParser::_parse_cdata() {
char *cDataEnd = 0;
// find end of CDATA
while(*P && !cDataEnd) {
while (*P && !cDataEnd) {
if (*P == '>' &&
(*(P-1) == ']') &&
(*(P-2) == ']'))
{
(*(P - 1) == ']') &&
(*(P - 2) == ']')) {
cDataEnd = P - 2;
}
++P;
}
if ( cDataEnd )
if (cDataEnd)
node_name = String::utf8(cDataBegin, (int)(cDataEnd - cDataBegin));
else
node_name = "";
#ifdef DEBUG_XML
print_line("XML CDATA: "+node_name);
print_line("XML CDATA: " + node_name);
#endif
return true;
@ -207,24 +195,21 @@ void XMLParser::_parse_comment() {
int count = 1;
// move until end of comment reached
while(count)
{
while (count) {
if (*P == '>')
--count;
else
if (*P == '<')
else if (*P == '<')
++count;
++P;
}
P -= 3;
node_name = String::utf8(pCommentBegin+2, (int)(P - pCommentBegin-2));
node_name = String::utf8(pCommentBegin + 2, (int)(P - pCommentBegin - 2));
P += 3;
#ifdef DEBUG_XML
print_line("XML COMMENT: "+node_name);
print_line("XML COMMENT: " + node_name);
#endif
}
void XMLParser::_parse_opening_xml_element() {
@ -234,37 +219,34 @@ void XMLParser::_parse_opening_xml_element() {
attributes.clear();
// find name
const char* startName = P;
const char *startName = P;
// find end of element
while(*P != '>' && !_is_white_space(*P))
while (*P != '>' && !_is_white_space(*P))
++P;
const char* endName = P;
const char *endName = P;
// find attributes
while(*P != '>')
{
while (*P != '>') {
if (_is_white_space(*P))
++P;
else
{
if (*P != '/')
{
else {
if (*P != '/') {
// we've got an attribute
// read the attribute names
const char* attributeNameBegin = P;
const char *attributeNameBegin = P;
while(!_is_white_space(*P) && *P != '=')
while (!_is_white_space(*P) && *P != '=')
++P;
const char* attributeNameEnd = P;
const char *attributeNameEnd = P;
++P;
// read the attribute value
// check for quotes and single quotes, thx to murphy
while( (*P != '\"') && (*P != '\'') && *P)
while ((*P != '\"') && (*P != '\'') && *P)
++P;
if (!*P) // malformatted xml file
@ -273,29 +255,27 @@ void XMLParser::_parse_opening_xml_element() {
const char attributeQuoteChar = *P;
++P;
const char* attributeValueBegin = P;
const char *attributeValueBegin = P;
while(*P != attributeQuoteChar && *P)
while (*P != attributeQuoteChar && *P)
++P;
if (!*P) // malformatted xml file
return;
const char* attributeValueEnd = P;
const char *attributeValueEnd = P;
++P;
Attribute attr;
attr.name = String::utf8(attributeNameBegin,
(int)(attributeNameEnd - attributeNameBegin));
(int)(attributeNameEnd - attributeNameBegin));
String s =String::utf8(attributeValueBegin,
(int)(attributeValueEnd - attributeValueBegin));
String s = String::utf8(attributeValueBegin,
(int)(attributeValueEnd - attributeValueBegin));
attr.value = _replace_special_characters(s);
attributes.push_back(attr);
}
else
{
} else {
// tag is closed directly
++P;
node_empty = true;
@ -305,8 +285,7 @@ void XMLParser::_parse_opening_xml_element() {
}
// check if this tag is closing directly
if (endName > startName && *(endName-1) == '/')
{
if (endName > startName && *(endName - 1) == '/') {
// directly closing tag
node_empty = true;
endName--;
@ -314,27 +293,25 @@ void XMLParser::_parse_opening_xml_element() {
node_name = String::utf8(startName, (int)(endName - startName));
#ifdef DEBUG_XML
print_line("XML OPEN: "+node_name);
print_line("XML OPEN: " + node_name);
#endif
++P;
}
void XMLParser::_parse_current_node() {
char* start = P;
char *start = P;
node_offset = P - data;
// more forward until '<' found
while(*P != '<' && *P)
while (*P != '<' && *P)
++P;
if (!*P)
return;
if (P - start > 0)
{
if (P - start > 0) {
// we found some text, store it
if (_set_text(start, P))
return;
@ -343,25 +320,23 @@ void XMLParser::_parse_current_node() {
++P;
// based on current token, parse and report next element
switch(*P)
{
case '/':
_parse_closing_xml_element();
break;
case '?':
_ignore_definition();
break;
case '!':
if (!_parse_cdata())
_parse_comment();
break;
default:
_parse_opening_xml_element();
break;
switch (*P) {
case '/':
_parse_closing_xml_element();
break;
case '?':
_ignore_definition();
break;
case '!':
if (!_parse_cdata())
_parse_comment();
break;
default:
_parse_opening_xml_element();
break;
}
}
uint64_t XMLParser::get_node_offset() const {
return node_offset;
@ -379,41 +354,37 @@ Error XMLParser::seek(uint64_t p_pos) {
void XMLParser::_bind_methods() {
ObjectTypeDB::bind_method(_MD("read"),&XMLParser::read);
ObjectTypeDB::bind_method(_MD("get_node_type"),&XMLParser::get_node_type);
ObjectTypeDB::bind_method(_MD("get_node_name"),&XMLParser::get_node_name);
ObjectTypeDB::bind_method(_MD("get_node_data"),&XMLParser::get_node_data);
ObjectTypeDB::bind_method(_MD("get_node_offset"),&XMLParser::get_node_offset);
ObjectTypeDB::bind_method(_MD("get_attribute_count"),&XMLParser::get_attribute_count);
ObjectTypeDB::bind_method(_MD("get_attribute_name","idx"),&XMLParser::get_attribute_name);
ObjectTypeDB::bind_method(_MD("get_attribute_value","idx"),(String (XMLParser::*)(int) const) &XMLParser::get_attribute_value);
ObjectTypeDB::bind_method(_MD("has_attribute","name"),&XMLParser::has_attribute);
ObjectTypeDB::bind_method(_MD("get_named_attribute_value","name"), (String (XMLParser::*)(const String&) const) &XMLParser::get_attribute_value);
ObjectTypeDB::bind_method(_MD("get_named_attribute_value_safe","name"), &XMLParser::get_attribute_value_safe);
ObjectTypeDB::bind_method(_MD("is_empty"),&XMLParser::is_empty);
ObjectTypeDB::bind_method(_MD("get_current_line"),&XMLParser::get_current_line);
ObjectTypeDB::bind_method(_MD("skip_section"),&XMLParser::skip_section);
ObjectTypeDB::bind_method(_MD("seek","pos"),&XMLParser::seek);
ObjectTypeDB::bind_method(_MD("open","file"),&XMLParser::open);
ObjectTypeDB::bind_method(_MD("open_buffer","buffer"),&XMLParser::open_buffer);
BIND_CONSTANT( NODE_NONE );
BIND_CONSTANT( NODE_ELEMENT );
BIND_CONSTANT( NODE_ELEMENT_END );
BIND_CONSTANT( NODE_TEXT );
BIND_CONSTANT( NODE_COMMENT );
BIND_CONSTANT( NODE_CDATA );
BIND_CONSTANT( NODE_UNKNOWN );
ObjectTypeDB::bind_method(_MD("read"), &XMLParser::read);
ObjectTypeDB::bind_method(_MD("get_node_type"), &XMLParser::get_node_type);
ObjectTypeDB::bind_method(_MD("get_node_name"), &XMLParser::get_node_name);
ObjectTypeDB::bind_method(_MD("get_node_data"), &XMLParser::get_node_data);
ObjectTypeDB::bind_method(_MD("get_node_offset"), &XMLParser::get_node_offset);
ObjectTypeDB::bind_method(_MD("get_attribute_count"), &XMLParser::get_attribute_count);
ObjectTypeDB::bind_method(_MD("get_attribute_name", "idx"), &XMLParser::get_attribute_name);
ObjectTypeDB::bind_method(_MD("get_attribute_value", "idx"), (String(XMLParser::*)(int) const) & XMLParser::get_attribute_value);
ObjectTypeDB::bind_method(_MD("has_attribute", "name"), &XMLParser::has_attribute);
ObjectTypeDB::bind_method(_MD("get_named_attribute_value", "name"), (String(XMLParser::*)(const String &) const) & XMLParser::get_attribute_value);
ObjectTypeDB::bind_method(_MD("get_named_attribute_value_safe", "name"), &XMLParser::get_attribute_value_safe);
ObjectTypeDB::bind_method(_MD("is_empty"), &XMLParser::is_empty);
ObjectTypeDB::bind_method(_MD("get_current_line"), &XMLParser::get_current_line);
ObjectTypeDB::bind_method(_MD("skip_section"), &XMLParser::skip_section);
ObjectTypeDB::bind_method(_MD("seek", "pos"), &XMLParser::seek);
ObjectTypeDB::bind_method(_MD("open", "file"), &XMLParser::open);
ObjectTypeDB::bind_method(_MD("open_buffer", "buffer"), &XMLParser::open_buffer);
BIND_CONSTANT(NODE_NONE);
BIND_CONSTANT(NODE_ELEMENT);
BIND_CONSTANT(NODE_ELEMENT_END);
BIND_CONSTANT(NODE_TEXT);
BIND_CONSTANT(NODE_COMMENT);
BIND_CONSTANT(NODE_CDATA);
BIND_CONSTANT(NODE_UNKNOWN);
};
Error XMLParser::read() {
// if not end reached, parse the node
if (P && (P - data) < length - 1 && *P != 0)
{
if (P && (P - data) < length - 1 && *P != 0) {
_parse_current_node();
return OK;
}
@ -427,12 +398,12 @@ XMLParser::NodeType XMLParser::get_node_type() {
}
String XMLParser::get_node_data() const {
ERR_FAIL_COND_V( node_type != NODE_TEXT, "");
ERR_FAIL_COND_V(node_type != NODE_TEXT, "");
return node_name;
}
String XMLParser::get_node_name() const {
ERR_FAIL_COND_V( node_type == NODE_TEXT, "");
ERR_FAIL_COND_V(node_type == NODE_TEXT, "");
return node_name;
}
int XMLParser::get_attribute_count() const {
@ -441,95 +412,91 @@ int XMLParser::get_attribute_count() const {
}
String XMLParser::get_attribute_name(int p_idx) const {
ERR_FAIL_INDEX_V(p_idx,attributes.size(),"");
ERR_FAIL_INDEX_V(p_idx, attributes.size(), "");
return attributes[p_idx].name;
}
String XMLParser::get_attribute_value(int p_idx) const {
ERR_FAIL_INDEX_V(p_idx,attributes.size(),"");
ERR_FAIL_INDEX_V(p_idx, attributes.size(), "");
return attributes[p_idx].value;
}
bool XMLParser::has_attribute(const String& p_name) const {
bool XMLParser::has_attribute(const String &p_name) const {
for(int i=0;i<attributes.size();i++) {
if (attributes[i].name==p_name)
for (int i = 0; i < attributes.size(); i++) {
if (attributes[i].name == p_name)
return true;
}
return false;
}
String XMLParser::get_attribute_value(const String& p_name) const {
String XMLParser::get_attribute_value(const String &p_name) const {
int idx=-1;
for(int i=0;i<attributes.size();i++) {
if (attributes[i].name==p_name) {
idx=i;
int idx = -1;
for (int i = 0; i < attributes.size(); i++) {
if (attributes[i].name == p_name) {
idx = i;
break;
}
}
if (idx<0) {
ERR_EXPLAIN("Attribute not found: "+p_name);
if (idx < 0) {
ERR_EXPLAIN("Attribute not found: " + p_name);
}
ERR_FAIL_COND_V(idx<0,"");
ERR_FAIL_COND_V(idx < 0, "");
return attributes[idx].value;
}
String XMLParser::get_attribute_value_safe(const String& p_name) const {
String XMLParser::get_attribute_value_safe(const String &p_name) const {
int idx=-1;
for(int i=0;i<attributes.size();i++) {
if (attributes[i].name==p_name) {
idx=i;
int idx = -1;
for (int i = 0; i < attributes.size(); i++) {
if (attributes[i].name == p_name) {
idx = i;
break;
}
}
if (idx<0)
if (idx < 0)
return "";
return attributes[idx].value;
}
bool XMLParser::is_empty() const {
return node_empty;
}
Error XMLParser::open_buffer(const Vector<uint8_t>& p_buffer) {
Error XMLParser::open_buffer(const Vector<uint8_t> &p_buffer) {
ERR_FAIL_COND_V(p_buffer.size()==0,ERR_INVALID_DATA);
ERR_FAIL_COND_V(p_buffer.size() == 0, ERR_INVALID_DATA);
length = p_buffer.size();
data = memnew_arr( char, length+1);
copymem(data,p_buffer.ptr(),length);
data[length]=0;
P=data;
data = memnew_arr(char, length + 1);
copymem(data, p_buffer.ptr(), length);
data[length] = 0;
P = data;
return OK;
}
Error XMLParser::open(const String& p_path) {
Error XMLParser::open(const String &p_path) {
Error err;
FileAccess * file = FileAccess::open(p_path,FileAccess::READ,&err);
FileAccess *file = FileAccess::open(p_path, FileAccess::READ, &err);
if (err) {
ERR_FAIL_COND_V(err!=OK,err);
ERR_FAIL_COND_V(err != OK, err);
}
length = file->get_len();
ERR_FAIL_COND_V(length<1, ERR_FILE_CORRUPT);
ERR_FAIL_COND_V(length < 1, ERR_FILE_CORRUPT);
data = memnew_arr( char, length+1);
file->get_buffer((uint8_t*)data,length);
data[length]=0;
P=data;
data = memnew_arr(char, length + 1);
file->get_buffer((uint8_t *)data, length);
data[length] = 0;
P = data;
memdelete(file);
return OK;
}
void XMLParser::skip_section() {
@ -541,29 +508,24 @@ void XMLParser::skip_section() {
// read until we've reached the last element in this section
int tagcount = 1;
while(tagcount && read()==OK)
{
while (tagcount && read() == OK) {
if (get_node_type() == XMLParser::NODE_ELEMENT &&
!is_empty())
{
!is_empty()) {
++tagcount;
}
else
if (get_node_type() == XMLParser::NODE_ELEMENT_END)
} else if (get_node_type() == XMLParser::NODE_ELEMENT_END)
--tagcount;
}
}
void XMLParser::close() {
if (data)
memdelete_arr(data);
data=NULL;
length=0;
P=NULL;
node_empty=false;
node_type=NODE_NONE;
data = NULL;
length = 0;
P = NULL;
node_empty = false;
node_type = NODE_NONE;
node_offset = 0;
}
@ -574,19 +536,16 @@ int XMLParser::get_current_line() const {
XMLParser::XMLParser() {
data=NULL;
data = NULL;
close();
special_characters.push_back("&amp;");
special_characters.push_back("<lt;");
special_characters.push_back(">gt;");
special_characters.push_back("\"quot;");
special_characters.push_back("'apos;");
}
XMLParser::~XMLParser() {
if (data)
memdelete_arr(data);
}

View File

@ -29,10 +29,10 @@
#ifndef XML_PARSER_H
#define XML_PARSER_H
#include "ustring.h"
#include "vector.h"
#include "os/file_access.h"
#include "reference.h"
#include "ustring.h"
#include "vector.h"
/*
Based on irrXML (see their zlib license). Added mainly for compatibility with their Collada loader.
@ -40,7 +40,8 @@
class XMLParser : public Reference {
OBJ_TYPE( XMLParser, Reference );
OBJ_TYPE(XMLParser, Reference);
public:
//! Enumeration of all supported source text file formats
enum SourceFormat {
@ -63,11 +64,10 @@ public:
};
private:
char *data;
char *P;
int length;
void unescape(String& p_str);
void unescape(String &p_str);
Vector<String> special_characters;
String node_name;
bool node_empty;
@ -81,8 +81,8 @@ private:
Vector<Attribute> attributes;
String _replace_special_characters(const String& origstr);
bool _set_text(char* start, char* end);
String _replace_special_characters(const String &origstr);
bool _set_text(char *start, char *end);
void _parse_closing_xml_element();
void _ignore_definition();
bool _parse_cdata();
@ -93,8 +93,6 @@ private:
static void _bind_methods();
public:
Error read();
NodeType get_node_type();
String get_node_name() const;
@ -103,17 +101,17 @@ public:
int get_attribute_count() const;
String get_attribute_name(int p_idx) const;
String get_attribute_value(int p_idx) const;
bool has_attribute(const String& p_name) const;
String get_attribute_value(const String& p_name) const;
String get_attribute_value_safe(const String& p_name) const; // do not print error if doesn't exist
bool has_attribute(const String &p_name) const;
String get_attribute_value(const String &p_name) const;
String get_attribute_value_safe(const String &p_name) const; // do not print error if doesn't exist
bool is_empty() const;
int get_current_line() const;
void skip_section();
Error seek(uint64_t p_pos);
Error open(const String& p_path);
Error open_buffer(const Vector<uint8_t>& p_buffer);
Error open(const String &p_path);
Error open_buffer(const Vector<uint8_t> &p_buffer);
void close();
@ -122,4 +120,3 @@ public:
};
#endif

View File

@ -29,69 +29,65 @@
#ifndef ZIP_IO_H
#define ZIP_IO_H
#include "io/zip.h"
#include "io/unzip.h"
#include "os/file_access.h"
#include "io/zip.h"
#include "os/copymem.h"
#include "os/file_access.h"
static void *zipio_open(void *data, const char *p_fname, int mode) {
static void* zipio_open(void* data, const char* p_fname, int mode) {
FileAccess *&f = *(FileAccess**)data;
FileAccess *&f = *(FileAccess **)data;
String fname;
fname.parse_utf8(p_fname);
if (mode & ZLIB_FILEFUNC_MODE_WRITE) {
f = FileAccess::open(fname,FileAccess::WRITE);
f = FileAccess::open(fname, FileAccess::WRITE);
} else {
f = FileAccess::open(fname,FileAccess::READ);
f = FileAccess::open(fname, FileAccess::READ);
}
if (!f)
return NULL;
return data;
};
static uLong zipio_read(void* data, void* fdata, void* buf, uLong size) {
FileAccess* f = *(FileAccess**)data;
return f->get_buffer((uint8_t*)buf, size);
static uLong zipio_read(void *data, void *fdata, void *buf, uLong size) {
FileAccess *f = *(FileAccess **)data;
return f->get_buffer((uint8_t *)buf, size);
};
static uLong zipio_write(voidpf opaque, voidpf stream, const void* buf, uLong size) {
static uLong zipio_write(voidpf opaque, voidpf stream, const void *buf, uLong size) {
FileAccess* f = *(FileAccess**)opaque;
f->store_buffer((uint8_t*)buf, size);
FileAccess *f = *(FileAccess **)opaque;
f->store_buffer((uint8_t *)buf, size);
return size;
};
static long zipio_tell(voidpf opaque, voidpf stream) {
static long zipio_tell (voidpf opaque, voidpf stream) {
FileAccess* f = *(FileAccess**)opaque;
FileAccess *f = *(FileAccess **)opaque;
return f->get_pos();
};
static long zipio_seek(voidpf opaque, voidpf stream, uLong offset, int origin) {
FileAccess* f = *(FileAccess**)opaque;
FileAccess *f = *(FileAccess **)opaque;
int pos = offset;
switch (origin) {
case ZLIB_FILEFUNC_SEEK_CUR:
pos = f->get_pos() + offset;
break;
case ZLIB_FILEFUNC_SEEK_END:
pos = f->get_len() + offset;
break;
default:
break;
case ZLIB_FILEFUNC_SEEK_CUR:
pos = f->get_pos() + offset;
break;
case ZLIB_FILEFUNC_SEEK_END:
pos = f->get_len() + offset;
break;
default:
break;
};
f->seek(pos);
@ -100,36 +96,32 @@ static long zipio_seek(voidpf opaque, voidpf stream, uLong offset, int origin) {
static int zipio_close(voidpf opaque, voidpf stream) {
FileAccess*& f = *(FileAccess**)opaque;
FileAccess *&f = *(FileAccess **)opaque;
if (f) {
f->close();
f=NULL;
f = NULL;
}
return 0;
};
static int zipio_testerror(voidpf opaque, voidpf stream) {
FileAccess* f = *(FileAccess**)opaque;
return (f && f->get_error()!=OK)?1:0;
FileAccess *f = *(FileAccess **)opaque;
return (f && f->get_error() != OK) ? 1 : 0;
};
static voidpf zipio_alloc(voidpf opaque, uInt items, uInt size) {
voidpf ptr =memalloc(items*size);
zeromem(ptr,items*size);
voidpf ptr = memalloc(items * size);
zeromem(ptr, items * size);
return ptr;
}
static void zipio_free(voidpf opaque, voidpf address) {
memfree(address);
}
static zlib_filefunc_def zipio_create_io_from_file(FileAccess **p_file) {
zlib_filefunc_def io;
@ -141,11 +133,9 @@ static zlib_filefunc_def zipio_create_io_from_file(FileAccess **p_file) {
io.zseek_file = zipio_seek;
io.zclose_file = zipio_close;
io.zerror_file = zipio_testerror;
io.alloc_mem=zipio_alloc;
io.free_mem=zipio_free;
io.alloc_mem = zipio_alloc;
io.free_mem = zipio_free;
return io;
}
#endif // ZIP_IO_H

View File

@ -40,34 +40,33 @@
* from the iterator.
*/
template <class T,class A=DefaultAllocator>
template <class T, class A = DefaultAllocator>
class List {
struct _Data;
public:
class Element {
private:
friend class List<T,A>;
friend class List<T, A>;
T value;
Element* next_ptr;
Element* prev_ptr;
Element *next_ptr;
Element *prev_ptr;
_Data *data;
public:
public:
/**
* Get NEXT Element iterator, for constant lists.
*/
_FORCE_INLINE_ const Element* next() const {
_FORCE_INLINE_ const Element *next() const {
return next_ptr;
};
/**
* Get NEXT Element iterator,
*/
_FORCE_INLINE_ Element* next() {
_FORCE_INLINE_ Element *next() {
return next_ptr;
};
@ -75,14 +74,14 @@ public:
/**
* Get PREV Element iterator, for constant lists.
*/
_FORCE_INLINE_ const Element* prev() const {
_FORCE_INLINE_ const Element *prev() const {
return prev_ptr;
};
/**
* Get PREV Element iterator,
*/
_FORCE_INLINE_ Element* prev() {
_FORCE_INLINE_ Element *prev() {
return prev_ptr;
};
@ -90,47 +89,47 @@ public:
/**
* * operator, for using as *iterator, when iterators are defined on stack.
*/
_FORCE_INLINE_ const T& operator *() const {
_FORCE_INLINE_ const T &operator*() const {
return value;
};
/**
* operator->, for using as iterator->, when iterators are defined on stack, for constant lists.
*/
_FORCE_INLINE_ const T* operator->() const {
_FORCE_INLINE_ const T *operator->() const {
return &value;
};
/**
* * operator, for using as *iterator, when iterators are defined on stack,
*/
_FORCE_INLINE_ T& operator *() {
_FORCE_INLINE_ T &operator*() {
return value;
};
/**
* operator->, for using as iterator->, when iterators are defined on stack, for constant lists.
*/
_FORCE_INLINE_ T* operator->() {
_FORCE_INLINE_ T *operator->() {
return &value;
};
/**
* get the value stored in this element.
*/
_FORCE_INLINE_ T& get() {
_FORCE_INLINE_ T &get() {
return value;
};
/**
* get the value stored in this element, for constant lists
*/
_FORCE_INLINE_ const T& get() const {
_FORCE_INLINE_ const T &get() const {
return value;
};
/**
* set the value stored in this element.
*/
_FORCE_INLINE_ void set(const T& p_value) {
value = (T&)p_value;
};
_FORCE_INLINE_ void set(const T &p_value) {
value = (T &)p_value;
};
void erase() {
@ -140,38 +139,36 @@ public:
_FORCE_INLINE_ Element() {
next_ptr = 0;
prev_ptr = 0;
data=NULL;
data = NULL;
};
};
private:
struct _Data {
Element* first;
Element* last;
Element *first;
Element *last;
int size_cache;
bool erase(const Element *p_I) {
bool erase(const Element* p_I) {
ERR_FAIL_COND_V(!p_I, false);
ERR_FAIL_COND_V(p_I->data != this, false);
ERR_FAIL_COND_V(!p_I,false);
ERR_FAIL_COND_V(p_I->data!=this,false);
if (first==p_I) {
first=p_I->next_ptr;
if (first == p_I) {
first = p_I->next_ptr;
};
if (last==p_I)
last=p_I->prev_ptr;
if (last == p_I)
last = p_I->prev_ptr;
if (p_I->prev_ptr)
p_I->prev_ptr->next_ptr=p_I->next_ptr;
p_I->prev_ptr->next_ptr = p_I->next_ptr;
if (p_I->next_ptr)
p_I->next_ptr->prev_ptr=p_I->prev_ptr;
p_I->next_ptr->prev_ptr = p_I->prev_ptr;
memdelete_allocator<Element,A>( const_cast<Element*>(p_I) );
memdelete_allocator<Element, A>(const_cast<Element *>(p_I));
size_cache--;
return true;
@ -180,69 +177,67 @@ private:
_Data *_data;
public:
/**
* return an const iterator to the begining of the list.
*/
_FORCE_INLINE_ const Element* front() const {
_FORCE_INLINE_ const Element *front() const {
return _data?_data->first:0;
return _data ? _data->first : 0;
};
/**
* return an iterator to the begining of the list.
*/
_FORCE_INLINE_ Element* front() {
return _data?_data->first:0;
_FORCE_INLINE_ Element *front() {
return _data ? _data->first : 0;
};
/**
* return an const iterator to the last member of the list.
*/
_FORCE_INLINE_ const Element* back() const {
_FORCE_INLINE_ const Element *back() const {
return _data?_data->last:0;
return _data ? _data->last : 0;
};
/**
* return an iterator to the last member of the list.
*/
_FORCE_INLINE_ Element* back() {
_FORCE_INLINE_ Element *back() {
return _data?_data->last:0;
return _data ? _data->last : 0;
};
/**
* store a new element at the end of the list
*/
Element* push_back(const T& value) {
Element *push_back(const T &value) {
if (!_data) {
_data=memnew_allocator(_Data,A);
_data->first=NULL;
_data->last=NULL;
_data->size_cache=0;
_data = memnew_allocator(_Data, A);
_data->first = NULL;
_data->last = NULL;
_data->size_cache = 0;
}
Element* n = memnew_allocator(Element,A);
n->value = (T&)value;
Element *n = memnew_allocator(Element, A);
n->value = (T &)value;
n->prev_ptr=_data->last;
n->next_ptr=0;
n->data=_data;
n->prev_ptr = _data->last;
n->next_ptr = 0;
n->data = _data;
if (_data->last) {
_data->last->next_ptr=n;
_data->last->next_ptr = n;
}
_data->last = n;
if (!_data->first)
_data->first=n;
_data->first = n;
_data->size_cache++;
@ -258,31 +253,31 @@ public:
/**
* store a new element at the begining of the list
*/
Element* push_front(const T& value) {
Element *push_front(const T &value) {
if (!_data) {
_data=memnew_allocator(_Data,A);
_data->first=NULL;
_data->last=NULL;
_data->size_cache=0;
_data = memnew_allocator(_Data, A);
_data->first = NULL;
_data->last = NULL;
_data->size_cache = 0;
}
Element* n = memnew_allocator(Element,A);
n->value = (T&)value;
Element *n = memnew_allocator(Element, A);
n->value = (T &)value;
n->prev_ptr = 0;
n->next_ptr = _data->first;
n->data=_data;
n->data = _data;
if (_data->first) {
_data->first->prev_ptr=n;
_data->first->prev_ptr = n;
}
_data->first = n;
if (!_data->last)
_data->last=n;
_data->last = n;
_data->size_cache++;
@ -298,10 +293,10 @@ public:
/**
* find an element in the list,
*/
template<class T_v>
Element* find(const T_v& p_val) {
template <class T_v>
Element *find(const T_v &p_val) {
Element* it = front();
Element *it = front();
while (it) {
if (it->value == p_val) return it;
it = it->next();
@ -313,14 +308,14 @@ public:
/**
* erase an element in the list, by iterator pointing to it. Return true if it was found/erased.
*/
bool erase(const Element* p_I) {
bool erase(const Element *p_I) {
if (_data) {
bool ret = _data->erase(p_I);
bool ret = _data->erase(p_I);
if (_data->size_cache==0) {
memdelete_allocator<_Data,A>(_data);
_data=NULL;
if (_data->size_cache == 0) {
memdelete_allocator<_Data, A>(_data);
_data = NULL;
}
return ret;
@ -332,9 +327,9 @@ public:
/**
* erase the first element in the list, that contains value
*/
bool erase(const T& value) {
bool erase(const T &value) {
Element* I = find(value);
Element *I = find(value);
return erase(I);
};
@ -358,121 +353,115 @@ public:
_FORCE_INLINE_ int size() const {
return _data?_data->size_cache:0;
return _data ? _data->size_cache : 0;
}
void swap(Element* p_A, Element *p_B) {
void swap(Element *p_A, Element *p_B) {
ERR_FAIL_COND(!p_A || !p_B);
ERR_FAIL_COND(p_A->data!=_data);
ERR_FAIL_COND(p_B->data!=_data);
ERR_FAIL_COND(p_A->data != _data);
ERR_FAIL_COND(p_B->data != _data);
Element* A_prev=p_A->prev_ptr;
Element* A_next=p_A->next_ptr;
Element *A_prev = p_A->prev_ptr;
Element *A_next = p_A->next_ptr;
p_A->next_ptr=p_B->next_ptr;
p_A->prev_ptr=p_B->prev_ptr;
p_A->next_ptr = p_B->next_ptr;
p_A->prev_ptr = p_B->prev_ptr;
p_B->next_ptr=A_next;
p_B->prev_ptr=A_prev;
p_B->next_ptr = A_next;
p_B->prev_ptr = A_prev;
if (p_A->prev_ptr)
p_A->prev_ptr->next_ptr=p_A;
p_A->prev_ptr->next_ptr = p_A;
if (p_A->next_ptr)
p_A->next_ptr->prev_ptr=p_A;
p_A->next_ptr->prev_ptr = p_A;
if (p_B->prev_ptr)
p_B->prev_ptr->next_ptr=p_B;
p_B->prev_ptr->next_ptr = p_B;
if (p_B->next_ptr)
p_B->next_ptr->prev_ptr=p_B;
p_B->next_ptr->prev_ptr = p_B;
}
/**
* copy the list
*/
void operator=(const List& p_list) {
void operator=(const List &p_list) {
clear();
const Element *it=p_list.front();
const Element *it = p_list.front();
while (it) {
push_back( it->get() );
it=it->next();
push_back(it->get());
it = it->next();
}
}
T& operator[](int p_index) {
T &operator[](int p_index) {
if (p_index<0 || p_index>=size()) {
T& aux=*((T*)0); //nullreturn
ERR_FAIL_COND_V(p_index<0 || p_index>=size(),aux);
if (p_index < 0 || p_index >= size()) {
T &aux = *((T *)0); //nullreturn
ERR_FAIL_COND_V(p_index < 0 || p_index >= size(), aux);
}
Element *I=front();
int c=0;
while(I) {
Element *I = front();
int c = 0;
while (I) {
if (c==p_index) {
if (c == p_index) {
return I->get();
}
I=I->next();
I = I->next();
c++;
}
ERR_FAIL_V( *((T*)0) ); // bug!!
ERR_FAIL_V(*((T *)0)); // bug!!
}
const T& operator[](int p_index) const {
const T &operator[](int p_index) const {
if (p_index<0 || p_index>=size()) {
T& aux=*((T*)0); //nullreturn
ERR_FAIL_COND_V(p_index<0 || p_index>=size(),aux);
if (p_index < 0 || p_index >= size()) {
T &aux = *((T *)0); //nullreturn
ERR_FAIL_COND_V(p_index < 0 || p_index >= size(), aux);
}
const Element *I=front();
int c=0;
while(I) {
const Element *I = front();
int c = 0;
while (I) {
if (c==p_index) {
if (c == p_index) {
return I->get();
}
I=I->next();
I = I->next();
c++;
}
ERR_FAIL_V( *((T*)0) ); // bug!
ERR_FAIL_V(*((T *)0)); // bug!
}
void move_to_back(Element *p_I) {
void move_to_back(Element* p_I) {
ERR_FAIL_COND(p_I->data!=_data);
ERR_FAIL_COND(p_I->data != _data);
if (!p_I->next_ptr)
return;
if (_data->first==p_I) {
_data->first=p_I->next_ptr;
if (_data->first == p_I) {
_data->first = p_I->next_ptr;
};
if (_data->last==p_I)
_data->last=p_I->prev_ptr;
if (_data->last == p_I)
_data->last = p_I->prev_ptr;
if (p_I->prev_ptr)
p_I->prev_ptr->next_ptr=p_I->next_ptr;
p_I->prev_ptr->next_ptr = p_I->next_ptr;
if (p_I->next_ptr)
p_I->next_ptr->prev_ptr=p_I->prev_ptr;
_data->last->next_ptr=p_I;
p_I->prev_ptr=_data->last;
p_I->next_ptr=NULL;
_data->last=p_I;
p_I->next_ptr->prev_ptr = p_I->prev_ptr;
_data->last->next_ptr = p_I;
p_I->prev_ptr = _data->last;
p_I->next_ptr = NULL;
_data->last = p_I;
}
void invert() {
@ -480,52 +469,49 @@ public:
int s = size() / 2;
Element *F = front();
Element *B = back();
for(int i=0;i<s;i++) {
for (int i = 0; i < s; i++) {
SWAP( F->value, B->value );
F=F->next();
B=B->prev();
SWAP(F->value, B->value);
F = F->next();
B = B->prev();
}
}
void move_to_front(Element* p_I) {
void move_to_front(Element *p_I) {
ERR_FAIL_COND(p_I->data!=_data);
ERR_FAIL_COND(p_I->data != _data);
if (!p_I->prev_ptr)
return;
if (_data->first==p_I) {
_data->first=p_I->next_ptr;
if (_data->first == p_I) {
_data->first = p_I->next_ptr;
};
if (_data->last==p_I)
_data->last=p_I->prev_ptr;
if (_data->last == p_I)
_data->last = p_I->prev_ptr;
if (p_I->prev_ptr)
p_I->prev_ptr->next_ptr=p_I->next_ptr;
p_I->prev_ptr->next_ptr = p_I->next_ptr;
if (p_I->next_ptr)
p_I->next_ptr->prev_ptr=p_I->prev_ptr;
_data->first->prev_ptr=p_I;
p_I->next_ptr=_data->first;
p_I->prev_ptr=NULL;
_data->first=p_I;
p_I->next_ptr->prev_ptr = p_I->prev_ptr;
_data->first->prev_ptr = p_I;
p_I->next_ptr = _data->first;
p_I->prev_ptr = NULL;
_data->first = p_I;
}
void move_before(Element* value, Element* where) {
void move_before(Element *value, Element *where) {
if (value->prev_ptr) {
value->prev_ptr->next_ptr = value->next_ptr;
}
else {
} else {
_data->first = value->next_ptr;
}
if (value->next_ptr) {
value->next_ptr->prev_ptr = value->prev_ptr;
}
else {
} else {
_data->last = value->prev_ptr;
}
@ -553,138 +539,133 @@ public:
void sort() {
sort_custom< Comparator<T> >();
sort_custom<Comparator<T> >();
}
template<class C>
template <class C>
void sort_custom_inplace() {
if(size()<2)
if (size() < 2)
return;
Element *from=front();
Element *current=from;
Element *to=from;
Element *from = front();
Element *current = from;
Element *to = from;
while(current) {
while (current) {
Element *next=current->next_ptr;
Element *next = current->next_ptr;
//disconnect
current->next_ptr=NULL;
current->next_ptr = NULL;
if (from!=current) {
if (from != current) {
current->prev_ptr=NULL;
current->next_ptr=from;
current->prev_ptr = NULL;
current->next_ptr = from;
Element *find=from;
Element *find = from;
C less;
while( find && less(find->value,current->value) ) {
while (find && less(find->value, current->value)) {
current->prev_ptr=find;
current->next_ptr=find->next_ptr;
find=find->next_ptr;
current->prev_ptr = find;
current->next_ptr = find->next_ptr;
find = find->next_ptr;
}
if (current->prev_ptr)
current->prev_ptr->next_ptr=current;
current->prev_ptr->next_ptr = current;
else
from=current;
from = current;
if (current->next_ptr)
current->next_ptr->prev_ptr=current;
current->next_ptr->prev_ptr = current;
else
to=current;
to = current;
} else {
current->prev_ptr=NULL;
current->next_ptr=NULL;
current->prev_ptr = NULL;
current->next_ptr = NULL;
}
current=next;
current = next;
}
_data->first=from;
_data->last=to;
_data->first = from;
_data->last = to;
}
template<class C>
template <class C>
struct AuxiliaryComparator {
C compare;
_FORCE_INLINE_ bool operator()(const Element *a,const Element* b) const {
_FORCE_INLINE_ bool operator()(const Element *a, const Element *b) const {
return compare(a->value,b->value);
return compare(a->value, b->value);
}
};
template<class C>
template <class C>
void sort_custom() {
//this version uses auxiliary memory for speed.
//if you don't want to use auxiliary memory, use the in_place version
int s = size();
if(s<2)
if (s < 2)
return;
Element **aux_buffer = memnew_arr(Element *, s);
Element **aux_buffer = memnew_arr(Element*,s);
int idx = 0;
for (Element *E = front(); E; E = E->next_ptr) {
int idx=0;
for(Element *E=front();E;E=E->next_ptr) {
aux_buffer[idx]=E;
aux_buffer[idx] = E;
idx++;
}
SortArray<Element*,AuxiliaryComparator<C> > sort;
sort.sort(aux_buffer,s);
SortArray<Element *, AuxiliaryComparator<C> > sort;
sort.sort(aux_buffer, s);
_data->first=aux_buffer[0];
aux_buffer[0]->prev_ptr=NULL;
aux_buffer[0]->next_ptr=aux_buffer[1];
_data->first = aux_buffer[0];
aux_buffer[0]->prev_ptr = NULL;
aux_buffer[0]->next_ptr = aux_buffer[1];
_data->last=aux_buffer[s-1];
aux_buffer[s-1]->prev_ptr=aux_buffer[s-2];
aux_buffer[s-1]->next_ptr=NULL;
_data->last = aux_buffer[s - 1];
aux_buffer[s - 1]->prev_ptr = aux_buffer[s - 2];
aux_buffer[s - 1]->next_ptr = NULL;
for(int i=1;i<s-1;i++) {
aux_buffer[i]->prev_ptr=aux_buffer[i-1];
aux_buffer[i]->next_ptr=aux_buffer[i+1];
for (int i = 1; i < s - 1; i++) {
aux_buffer[i]->prev_ptr = aux_buffer[i - 1];
aux_buffer[i]->next_ptr = aux_buffer[i + 1];
}
memdelete_arr(aux_buffer);
}
/**
* copy constructor for the list
*/
List(const List& p_list) {
List(const List &p_list) {
_data=NULL;
const Element *it=p_list.front();
_data = NULL;
const Element *it = p_list.front();
while (it) {
push_back( it->get() );
it=it->next();
push_back(it->get());
it = it->next();
}
}
List() {
_data=NULL;
_data = NULL;
};
~List() {
clear();
if (_data) {
ERR_FAIL_COND(_data->size_cache);
memdelete_allocator<_Data,A>(_data);
memdelete_allocator<_Data, A>(_data);
}
};
};

Some files were not shown because too many files have changed in this diff Show More