diff --git a/library/CMakeLists.txt b/library/CMakeLists.txt index 8b1b7f65d..2ea2d830f 100644 --- a/library/CMakeLists.txt +++ b/library/CMakeLists.txt @@ -62,6 +62,7 @@ set(MAIN_SOURCES ColorText.cpp CompilerWorkAround.cpp DataDefs.cpp + DataIdentity.cpp Debug.cpp Error.cpp VTableInterpose.cpp @@ -71,7 +72,6 @@ set(MAIN_SOURCES LuaApi.cpp DataStatics.cpp DataStaticsCtor.cpp - DataStaticsFields.cpp MiscUtils.cpp Types.cpp PluginManager.cpp @@ -186,8 +186,7 @@ foreach(GROUP other a b c d e f g h i j k l m n o p q r s t u v w x y z) set(STATIC_FIELDS_INC_FILENAME "df/static.fields-${GROUP}.inc") endif() file(WRITE ${STATIC_FIELDS_FILENAME}.tmp - "#define STATIC_FIELDS_GROUP\n" - "#include \"../DataStaticsFields.cpp\"\n" + "#include \"DataStaticsFields.inc\"\n" "#include \"${STATIC_FIELDS_INC_FILENAME}\"\n" ) execute_process(COMMAND ${CMAKE_COMMAND} -E copy_if_different @@ -294,15 +293,15 @@ add_custom_target(generate_headers if(REMOVE_SYMBOLS_FROM_DF_STUBS) if(UNIX) # Don't produce debug info for generated stubs - set_source_files_properties(DataStatics.cpp DataStaticsCtor.cpp DataStaticsFields.cpp ${STATIC_FIELDS_FILES} + set_source_files_properties(DataStatics.cpp DataStaticsCtor.cpp ${STATIC_FIELDS_FILES} PROPERTIES COMPILE_FLAGS "-g0 -O1") else(WIN32) - set_source_files_properties(DataStatics.cpp DataStaticsCtor.cpp DataStaticsFields.cpp ${STATIC_FIELDS_FILES} + set_source_files_properties(DataStatics.cpp DataStaticsCtor.cpp ${STATIC_FIELDS_FILES} PROPERTIES COMPILE_FLAGS "/O1 /bigobj") endif() else() if(WIN32) - set_source_files_properties(DataStatics.cpp DataStaticsCtor.cpp DataStaticsFields.cpp ${STATIC_FIELDS_FILES} + set_source_files_properties(DataStatics.cpp DataStaticsCtor.cpp ${STATIC_FIELDS_FILES} PROPERTIES COMPILE_FLAGS "/Od /bigobj") endif() endif() diff --git a/library/DataStaticsFields.cpp b/library/DataIdentity.cpp similarity index 61% rename from library/DataStaticsFields.cpp rename to library/DataIdentity.cpp index 8318b523d..03851520c 100644 --- a/library/DataStaticsFields.cpp +++ b/library/DataIdentity.cpp @@ -1,22 +1,22 @@ #include +#include #include - -#ifndef STATIC_FIELDS_GROUP -#include "DataDefs.h" -#endif +#include +#include +#include #include "DataFuncs.h" - -#ifdef __GNUC__ -#pragma GCC diagnostic ignored "-Winvalid-offsetof" -#endif +#include "DataIdentity.h" namespace df { #define NUMBER_IDENTITY_TRAITS(category, type, name) \ category##_identity identity_traits::identity(name); #define INTEGER_IDENTITY_TRAITS(type, name) NUMBER_IDENTITY_TRAITS(integer, type, name) #define FLOAT_IDENTITY_TRAITS(type) NUMBER_IDENTITY_TRAITS(float, type, #type) +#define OPAQUE_IDENTITY_TRAITS_NAME(type, name) \ + opaque_identity identity_traits::identity(sizeof(type), allocator_noassign_fn, name) +#define STL_OPAQUE_IDENTITY_TRAITS(type) OPAQUE_IDENTITY_TRAITS_NAME(std::type, #type) #ifndef STATIC_FIELDS_GROUP INTEGER_IDENTITY_TRAITS(char, "char"); @@ -42,25 +42,10 @@ namespace df { stl_bit_vector_identity identity_traits >::identity; bit_array_identity identity_traits >::identity; - static void *fstream_allocator_fn(void *out, const void *in) { - if (out) { /* *(T*)out = *(const T*)in;*/ return NULL; } - else if (in) { delete (std::fstream*)in; return (std::fstream*)in; } - else return new std::fstream(); - } - opaque_identity identity_traits::identity( - sizeof(std::fstream), fstream_allocator_fn, "fstream"); + STL_OPAQUE_IDENTITY_TRAITS(condition_variable); + STL_OPAQUE_IDENTITY_TRAITS(fstream); + STL_OPAQUE_IDENTITY_TRAITS(mutex); buffer_container_identity buffer_container_identity::base_instance; #endif -#undef NUMBER_IDENTITY_TRAITS -#undef INTEGER_IDENTITY_TRAITS -#undef FLOAT_IDENTITY_TRAITS } - -#define TID(type) (&identity_traits< type >::identity) - -#define FLD(mode, name) struct_field_info::mode, #name, offsetof(CUR_STRUCT, name) -#define GFLD(mode, name) struct_field_info::mode, #name, (size_t)&df::global::name -#define METHOD(mode, name) struct_field_info::mode, #name, 0, wrap_function(&CUR_STRUCT::name) -#define METHOD_N(mode, func, name) struct_field_info::mode, #name, 0, wrap_function(&CUR_STRUCT::func) -#define FLD_END struct_field_info::END diff --git a/library/include/DataDefs.h b/library/include/DataDefs.h index 174156e76..e03e9a0a8 100644 --- a/library/include/DataDefs.h +++ b/library/include/DataDefs.h @@ -497,11 +497,29 @@ namespace df using DFHack::DfLinkedList; using DFHack::DfOtherVectors; + template + typename std::enable_if< + std::is_copy_assignable::value, + void* + >::type allocator_try_assign(void *out, const void *in) { + *(T*)out = *(const T*)in; + return out; + } + + template + typename std::enable_if< + !std::is_copy_assignable::value, + void* + >::type allocator_try_assign(void *out, const void *in) { + // assignment is not possible; do nothing + return NULL; + } + #pragma GCC diagnostic push #pragma GCC diagnostic ignored "-Wdelete-non-virtual-dtor" template void *allocator_fn(void *out, const void *in) { - if (out) { *(T*)out = *(const T*)in; return out; } + if (out) { return allocator_try_assign(out, in); } else if (in) { delete (T*)in; return (T*)in; } else return new T(); } @@ -514,6 +532,13 @@ namespace df else return new T(); } + template + void *allocator_noassign_fn(void *out, const void *in) { + if (out) { return NULL; } + else if (in) { delete (T*)in; return (T*)in; } + else return new T(); + } + template struct identity_traits { static compound_identity *get() { return &T::_identity; } diff --git a/library/include/DataIdentity.h b/library/include/DataIdentity.h index fd47429b9..be5466444 100644 --- a/library/include/DataIdentity.h +++ b/library/include/DataIdentity.h @@ -25,13 +25,18 @@ distribution. #pragma once #include -#include +#include #include +#include #include -#include #include "DataDefs.h" +namespace std { + class condition_variable; + class mutex; +}; + /* * Definitions of DFHack namespace structs used by generated headers. */ @@ -541,6 +546,12 @@ namespace df #define INTEGER_IDENTITY_TRAITS(type) NUMBER_IDENTITY_TRAITS(integer, type) #define FLOAT_IDENTITY_TRAITS(type) NUMBER_IDENTITY_TRAITS(float, type) +#define OPAQUE_IDENTITY_TRAITS(type) \ + template<> struct DFHACK_EXPORT identity_traits { \ + static opaque_identity identity; \ + static opaque_identity *get() { return &identity; } \ + }; + INTEGER_IDENTITY_TRAITS(char); INTEGER_IDENTITY_TRAITS(signed char); INTEGER_IDENTITY_TRAITS(unsigned char); @@ -554,6 +565,9 @@ namespace df INTEGER_IDENTITY_TRAITS(unsigned long long); FLOAT_IDENTITY_TRAITS(float); FLOAT_IDENTITY_TRAITS(double); + OPAQUE_IDENTITY_TRAITS(std::condition_variable); + OPAQUE_IDENTITY_TRAITS(std::fstream); + OPAQUE_IDENTITY_TRAITS(std::mutex); template<> struct DFHACK_EXPORT identity_traits { static bool_identity identity; @@ -565,11 +579,6 @@ namespace df static stl_string_identity *get() { return &identity; } }; - template<> struct DFHACK_EXPORT identity_traits { - static opaque_identity identity; - static opaque_identity *get() { return &identity; } - }; - template<> struct DFHACK_EXPORT identity_traits { static ptr_string_identity identity; static ptr_string_identity *get() { return &identity; } @@ -598,6 +607,7 @@ namespace df #undef NUMBER_IDENTITY_TRAITS #undef INTEGER_IDENTITY_TRAITS #undef FLOAT_IDENTITY_TRAITS +#undef OPAQUE_IDENTITY_TRAITS // Container declarations diff --git a/library/include/DataStaticsFields.inc b/library/include/DataStaticsFields.inc new file mode 100644 index 000000000..97a036b58 --- /dev/null +++ b/library/include/DataStaticsFields.inc @@ -0,0 +1,15 @@ +#include + +#include "DataFuncs.h" + +#ifdef __GNUC__ +#pragma GCC diagnostic ignored "-Winvalid-offsetof" +#endif + +#define TID(type) (&identity_traits< type >::identity) + +#define FLD(mode, name) struct_field_info::mode, #name, offsetof(CUR_STRUCT, name) +#define GFLD(mode, name) struct_field_info::mode, #name, (size_t)&df::global::name +#define METHOD(mode, name) struct_field_info::mode, #name, 0, wrap_function(&CUR_STRUCT::name) +#define METHOD_N(mode, func, name) struct_field_info::mode, #name, 0, wrap_function(&CUR_STRUCT::func) +#define FLD_END struct_field_info::END diff --git a/library/modules/Screen.cpp b/library/modules/Screen.cpp index c7ef88c60..2ee91a089 100644 --- a/library/modules/Screen.cpp +++ b/library/modules/Screen.cpp @@ -1092,8 +1092,7 @@ df::plant *dfhack_lua_viewscreen::getSelectedPlant() return Lua::GetDFObject(Lua::Core::State, -1); } -#define STATIC_FIELDS_GROUP -#include "../DataStaticsFields.cpp" +#include "DataStaticsFields.inc" using df::identity_traits;