From 27824642d90a8bca445af4e6f5d51a89d8317708 Mon Sep 17 00:00:00 2001 From: Alexander Gavrilov Date: Thu, 22 Mar 2012 10:56:32 +0400 Subject: [PATCH] Minor refactoring of container indexing and object allocation. --- library/DataDefs.cpp | 39 +++++++++++++++++++++++++--- library/LuaWrapper.cpp | 25 +++++------------- library/include/DataDefs.h | 47 ++++++++++++++++++++-------------- library/include/DataIdentity.h | 38 +++++++++++++++++---------- library/xml | 2 +- 5 files changed, 95 insertions(+), 56 deletions(-) diff --git a/library/DataDefs.cpp b/library/DataDefs.cpp index 9576afb7b..6fcd1141a 100644 --- a/library/DataDefs.cpp +++ b/library/DataDefs.cpp @@ -40,6 +40,37 @@ distribution. using namespace DFHack; + +void *type_identity::do_allocate_pod() { + void *p = malloc(size); + memset(p, 0, size); + return p; +} + +void type_identity::do_copy_pod(void *tgt, const void *src) { + memmove(tgt, src, size); +}; + +void *type_identity::allocate() { + if (can_allocate()) + return do_allocate(); + else + return NULL; +} + +bool type_identity::copy(void *tgt, const void *src) { + if (can_allocate() && tgt && src) + do_copy(tgt, src); + else + return false; +} + +void *enum_identity::do_allocate() { + void *p = malloc(byte_size()); + memcpy(p, &first_item_value, std::min(byte_size(), sizeof(int64_t))); + return p; +} + /* The order of global object constructor calls is * undefined between compilation units. Therefore, * this list has to be plain data, so that it gets @@ -95,19 +126,19 @@ void compound_identity::Init(Core *core) */ } -bitfield_identity::bitfield_identity(size_t size, TAllocateFn alloc, +bitfield_identity::bitfield_identity(size_t size, compound_identity *scope_parent, const char *dfhack_name, int num_bits, const bitfield_item_info *bits) - : compound_identity(size, alloc, scope_parent, dfhack_name), bits(bits), num_bits(num_bits) + : compound_identity(size, NULL, scope_parent, dfhack_name), bits(bits), num_bits(num_bits) { } -enum_identity::enum_identity(size_t size, TAllocateFn alloc, +enum_identity::enum_identity(size_t size, compound_identity *scope_parent, const char *dfhack_name, type_identity *base_type, int64_t first_item_value, int64_t last_item_value, const char *const *keys) - : compound_identity(size, alloc, scope_parent, dfhack_name), + : compound_identity(size, NULL, scope_parent, dfhack_name), first_item_value(first_item_value), last_item_value(last_item_value), keys(keys), base_type(base_type) { diff --git a/library/LuaWrapper.cpp b/library/LuaWrapper.cpp index a7d830474..770f8f5af 100644 --- a/library/LuaWrapper.cpp +++ b/library/LuaWrapper.cpp @@ -265,29 +265,29 @@ int container_identity::lua_item_count(lua_State *state, void *ptr) int container_identity::lua_item_read(lua_State *state, int fname_idx, void *ptr, int idx) { - void *pitem = item_pointer(ptr, idx); auto id = (type_identity*)lua_touserdata(state, UPVAL_ITEM_ID); + void *pitem = item_pointer(id, ptr, idx); return id->lua_read(state, fname_idx, pitem); } void container_identity::lua_item_write(lua_State *state, int fname_idx, void *ptr, int idx, int val_index) { - void *pitem = item_pointer(ptr, idx); auto id = (type_identity*)lua_touserdata(state, UPVAL_ITEM_ID); + void *pitem = item_pointer(id, ptr, idx); id->lua_write(state, fname_idx, pitem, val_index); } int ptr_container_identity::lua_item_read(lua_State *state, int fname_idx, void *ptr, int idx) { - void *pitem = item_pointer(ptr, idx); auto id = (type_identity*)lua_touserdata(state, UPVAL_ITEM_ID); + void *pitem = item_pointer(&df::identity_traits::identity, ptr, idx); return df::pointer_identity::lua_read(state, fname_idx, pitem, id); } void ptr_container_identity::lua_item_write(lua_State *state, int fname_idx, void *ptr, int idx, int val_index) { - void *pitem = item_pointer(ptr, idx); auto id = (type_identity*)lua_touserdata(state, UPVAL_ITEM_ID); + void *pitem = item_pointer(&df::identity_traits::identity, ptr, idx); df::pointer_identity::lua_write(state, fname_idx, pitem, id, val_index); } @@ -307,25 +307,12 @@ void bit_container_identity::lua_item_write(lua_State *state, int fname_idx, voi field_error(state, fname_idx, "boolean or number expected", "write"); } -int df::buffer_container_identity::lua_item_read(lua_State *state, int fname_idx, void *ptr, int idx) -{ - auto id = (type_identity*)lua_touserdata(state, UPVAL_ITEM_ID); - void *pitem = ((uint8_t*)ptr) + idx * id->byte_size(); - return id->lua_read(state, fname_idx, pitem); -} - -void df::buffer_container_identity::lua_item_write(lua_State *state, int fname_idx, void *ptr, int idx, int val_index) -{ - auto id = (type_identity*)lua_touserdata(state, UPVAL_ITEM_ID); - void *pitem = ((uint8_t*)ptr) + idx * id->byte_size(); - id->lua_write(state, fname_idx, pitem, val_index); -} - /* */ static int change_error(lua_State *state) { luaL_error(state, "Attempt to change a read-only table.\n"); + return 0; } /** @@ -618,6 +605,8 @@ static int read_field(lua_State *state, const struct_field_info *field, void *pt case struct_field_info::END: return 0; } + + return 0; } static void write_field(lua_State *state, const struct_field_info *field, void *ptr, int value_idx) diff --git a/library/include/DataDefs.h b/library/include/DataDefs.h index 9ec266fab..da9ffd4b5 100644 --- a/library/include/DataDefs.h +++ b/library/include/DataDefs.h @@ -69,14 +69,12 @@ namespace DFHack protected: type_identity(size_t size) : size(size) {}; - virtual void *do_instantiate() { - void *p = malloc(size); - memset(p, 0, size); - return p; - } - virtual void do_copy(void *tgt, const void *src) { - memmove(tgt, src, size); - }; + void *do_allocate_pod(); + void do_copy_pod(void *tgt, const void *src); + + virtual bool can_allocate() { return true; } + virtual void *do_allocate() { return do_allocate_pod(); } + virtual void do_copy(void *tgt, const void *src) { do_copy_pod(tgt, src); } public: virtual ~type_identity() {} @@ -93,6 +91,9 @@ namespace DFHack virtual void build_metatable(lua_State *state); virtual bool isContainer() { return false; } + + void *allocate(); + bool copy(void *tgt, const void *src); }; class DFHACK_EXPORT constructed_identity : public type_identity { @@ -102,13 +103,9 @@ namespace DFHack constructed_identity(size_t size, TAllocateFn alloc) : type_identity(size), allocator(alloc) {}; - virtual void *do_instantiate() { - return allocator ? allocator(NULL,NULL) : type_identity::do_instantiate(); - } - virtual void do_copy(void *tgt, const void *src) { - if (allocator) allocator(tgt,src); - else type_identity::do_copy(tgt, src); - }; + virtual bool can_allocate() { return (allocator != NULL); } + virtual void *do_allocate() { return allocator(NULL,NULL); } + virtual void do_copy(void *tgt, const void *src) { allocator(tgt,src); } virtual int lua_read(lua_State *state, int fname_idx, void *ptr); virtual void lua_write(lua_State *state, int fname_idx, void *ptr, int val_index); @@ -151,8 +148,13 @@ namespace DFHack const bitfield_item_info *bits; int num_bits; + protected: + virtual bool can_allocate() { return true; } + virtual void *do_allocate() { return do_allocate_pod(); } + virtual void do_copy(void *tgt, const void *src) { do_copy_pod(tgt, src); } + public: - bitfield_identity(size_t size, TAllocateFn alloc, + bitfield_identity(size_t size, compound_identity *scope_parent, const char *dfhack_name, int num_bits, const bitfield_item_info *bits); @@ -171,8 +173,13 @@ namespace DFHack type_identity *base_type; + protected: + virtual bool can_allocate() { return true; } + virtual void *do_allocate(); + virtual void do_copy(void *tgt, const void *src) { do_copy_pod(tgt, src); } + public: - enum_identity(size_t size, TAllocateFn alloc, + enum_identity(size_t size, compound_identity *scope_parent, const char *dfhack_name, type_identity *base_type, int64_t first_item_value, int64_t last_item_value, @@ -266,6 +273,8 @@ namespace DFHack static void *get_vtable(virtual_ptr instance_ptr) { return *(void**)instance_ptr; } + bool can_allocate() { return struct_identity::can_allocate() && (vtable_ptr != NULL); } + public: virtual_identity(size_t size, TAllocateFn alloc, const char *dfhack_name, const char *original_name, @@ -295,8 +304,8 @@ namespace DFHack } public: - bool can_instantiate() { return (vtable_ptr != NULL); } - virtual_ptr instantiate() { return can_instantiate() ? (virtual_ptr)do_instantiate() : NULL; } + bool can_instantiate() { return can_allocate(); } + virtual_ptr instantiate() { return can_instantiate() ? (virtual_ptr)do_allocate() : NULL; } static virtual_ptr clone(virtual_ptr obj); public: diff --git a/library/include/DataIdentity.h b/library/include/DataIdentity.h index ac5903beb..987793828 100644 --- a/library/include/DataIdentity.h +++ b/library/include/DataIdentity.h @@ -92,7 +92,7 @@ namespace DFHack protected: virtual int item_count(void *ptr) = 0; - virtual void *item_pointer(void *ptr, int idx) = 0; + virtual void *item_pointer(type_identity *item, void *ptr, int idx) = 0; }; class DFHACK_EXPORT ptr_container_identity : public container_identity { @@ -122,7 +122,7 @@ namespace DFHack virtual void lua_item_write(lua_State *state, int fname_idx, void *ptr, int idx, int val_index); protected: - virtual void *item_pointer(void *, int) { return NULL; } + virtual void *item_pointer(type_identity *, void *, int) { return NULL; } virtual bool get_item(void *ptr, int idx) = 0; virtual void set_item(void *ptr, int idx, bool val) = 0; @@ -185,6 +185,11 @@ namespace df class stl_ptr_vector_identity : public ptr_container_identity { public: + /* + * This class assumes that std::vector is equivalent + * in layout and behavior to std::vector for any T. + */ + stl_ptr_vector_identity(type_identity *item = NULL, enum_identity *ienum = NULL) : ptr_container_identity(sizeof(std::vector),allocator_fn >,item, ienum) {}; @@ -199,7 +204,7 @@ namespace df virtual int item_count(void *ptr) { return ((std::vector*)ptr)->size(); }; - virtual void *item_pointer(void *ptr, int idx) { + virtual void *item_pointer(type_identity *, void *ptr, int idx) { return &(*(std::vector*)ptr)[idx]; } }; @@ -220,12 +225,11 @@ namespace df static buffer_container_identity base_instance; - virtual int lua_item_read(lua_State *state, int fname_idx, void *ptr, int idx); - virtual void lua_item_write(lua_State *state, int fname_idx, void *ptr, int idx, int val_index); - protected: virtual int item_count(void *ptr) { return size; } - virtual void *item_pointer(void *ptr, int idx) { return NULL; } + virtual void *item_pointer(type_identity *item, void *ptr, int idx) { + return ((uint8_t*)ptr) + idx * item->byte_size(); + } }; template @@ -243,29 +247,35 @@ namespace df protected: virtual int item_count(void *ptr) { return ((T*)ptr)->size(); } - virtual void *item_pointer(void *ptr, int idx) { return &(*(T*)ptr)[idx]; } + virtual void *item_pointer(type_identity *item, void *ptr, int idx) { + return &(*(T*)ptr)[idx]; + } }; - template class bit_array_identity : public bit_container_identity { public: - typedef BitArray container; + /* + * This class assumes that BitArray is equivalent + * in layout and behavior to BitArray for any T. + */ + + typedef BitArray container; bit_array_identity(enum_identity *ienum = NULL) : bit_container_identity(sizeof(container), &allocator_fn, ienum) {} std::string getFullName(type_identity *item) { - return "BitArray" + bit_container_identity::getFullName(item); + return "BitArray<>"; } protected: virtual int item_count(void *ptr) { return ((container*)ptr)->size * 8; } virtual bool get_item(void *ptr, int idx) { - return ((container*)ptr)->is_set(T(idx)); + return ((container*)ptr)->is_set(idx); } virtual void set_item(void *ptr, int idx, bool val) { - ((container*)ptr)->set(T(idx), val); + ((container*)ptr)->set(idx, val); } }; @@ -412,7 +422,7 @@ namespace df bit_container_identity *identity_traits >::get() { static type_identity *eid = identity_traits::get(); static enum_identity *reid = eid->type() == DFHack::IDTYPE_ENUM ? (enum_identity*)eid : NULL; - static bit_array_identity identity(reid); + static bit_array_identity identity(reid); return &identity; } diff --git a/library/xml b/library/xml index c90a2d499..b28296a8c 160000 --- a/library/xml +++ b/library/xml @@ -1 +1 @@ -Subproject commit c90a2d499024319ea9aa4f98b3b61df7bba2fc62 +Subproject commit b28296a8c0c2e5aaa522840598738109018f0146