diff --git a/library/DataDefs.cpp b/library/DataDefs.cpp index 7b4af8479..2f1f9c238 100644 --- a/library/DataDefs.cpp +++ b/library/DataDefs.cpp @@ -56,7 +56,7 @@ virtual_identity::virtual_identity(const char *dfhack_name, const char *original static tthread::mutex *known_mutex = NULL; std::map virtual_identity::known; -virtual_identity *virtual_identity::get(virtual_class *instance_ptr) +virtual_identity *virtual_identity::get(virtual_ptr instance_ptr) { if (!instance_ptr) return NULL; @@ -87,7 +87,7 @@ virtual_identity *virtual_identity::get(virtual_class *instance_ptr) return NULL; } -bool virtual_identity::check_instance(virtual_class *instance_ptr, bool allow_subclasses) +bool virtual_identity::check_instance(virtual_ptr instance_ptr, bool allow_subclasses) { virtual_identity *actual = get(instance_ptr); diff --git a/library/DataStatics.cpp b/library/DataStatics.cpp index 57aeb779c..e3a448eac 100644 --- a/library/DataStatics.cpp +++ b/library/DataStatics.cpp @@ -1,5 +1,17 @@ #include "Internal.h" #include "dfhack/DataDefs.h" +#include "dfhack/MiscUtils.h" + +#include "dfhack/df/world.h" +#include "dfhack/df/world_data.h" +#include "dfhack/df/ui.h" + +namespace { + template + inline T &_toref(T &r) { return r; } + template + inline T &_toref(T *&p) { return *p; } +} // Instantiate all the static objects #include "dfhack/df/static.inc" diff --git a/library/include/dfhack/DataDefs.h b/library/include/dfhack/DataDefs.h index 5ffd9be7e..4308ea3ed 100644 --- a/library/include/dfhack/DataDefs.h +++ b/library/include/dfhack/DataDefs.h @@ -40,6 +40,12 @@ namespace DFHack { class virtual_class {}; +#ifdef _MSC_VER + typedef void *virtual_ptr; +#else + typedef virtual_class *virtual_ptr; +#endif + class DFHACK_EXPORT virtual_identity { static virtual_identity *list; static std::map known; @@ -56,9 +62,9 @@ namespace DFHack protected: virtual_identity(const char *dfhack_name, const char *original_name, virtual_identity *parent); - bool check_instance(virtual_class *instance_ptr, bool allow_subclasses); + bool check_instance(virtual_ptr instance_ptr, bool allow_subclasses); - static void *get_vtable(virtual_class *instance_ptr) { return *(void**)instance_ptr; } + static void *get_vtable(virtual_ptr instance_ptr) { return *(void**)instance_ptr; } public: const char *getName() { return dfhack_name; } @@ -67,9 +73,9 @@ namespace DFHack virtual_identity *getParent() { return parent; } const std::vector &getChildren() { return children; } - static virtual_identity *get(virtual_class *instance_ptr); + static virtual_identity *get(virtual_ptr instance_ptr); - bool is_instance(virtual_class *instance_ptr) { + bool is_instance(virtual_ptr instance_ptr) { if (!instance_ptr) return false; if (vtable_ptr) { void *vtable = get_vtable(instance_ptr); @@ -79,7 +85,7 @@ namespace DFHack return check_instance(instance_ptr, true); } - bool is_direct_instance(virtual_class *instance_ptr) { + bool is_direct_instance(virtual_ptr instance_ptr) { if (!instance_ptr) return false; return vtable_ptr ? (vtable_ptr == get_vtable(instance_ptr)) : check_instance(instance_ptr, false); @@ -89,12 +95,12 @@ namespace DFHack }; template - inline T *virtual_cast(virtual_class *ptr) { + inline T *virtual_cast(virtual_ptr ptr) { return T::_identity.is_instance(ptr) ? static_cast(ptr) : NULL; } template - inline T *strict_virtual_cast(virtual_class *ptr) { + inline T *strict_virtual_cast(virtual_ptr ptr) { return T::_identity.is_direct_instance(ptr) ? static_cast(ptr) : NULL; } diff --git a/library/include/dfhack/MiscUtils.h b/library/include/dfhack/MiscUtils.h index 2bdab10c6..dfac76665 100644 --- a/library/include/dfhack/MiscUtils.h +++ b/library/include/dfhack/MiscUtils.h @@ -187,6 +187,7 @@ void print_bits ( T val, DFHack::Console& out ) strs << endl; out.print(strs.str().c_str()); } + /* // this is probably completely bogus std::string PrintSplatterType (int16_t mat1, int32_t mat2, vector &creature_types) @@ -247,4 +248,21 @@ std::string PrintSplatterType (int16_t mat1, int32_t mat2, vector +CT *binsearch_in_vector(std::vector &vec, FT CT::*field, AT value) { + int min = -1, max = (int)vec.size(); + CT **p = vec.data(); + FT key = (FT)value; + for (;;) { + int mid = (min + max)>>1; + if (mid == min) + return NULL; + FT midv = p[mid]->*field; + if (midv == key) + return p[mid]; + else if (midv < key) + min = mid; + else + max = mid; + } +} diff --git a/library/xml/codegen.pl b/library/xml/codegen.pl index 33210f616..05684732b 100755 --- a/library/xml/codegen.pl +++ b/library/xml/codegen.pl @@ -56,6 +56,17 @@ sub type_header_def($) { return uc($main_namespace).'_'.uc($name).'_H'; } +sub translate_lookup($) { + my ($str) = @_; + return undef unless $str && $str =~ /^\$global((\.[_a-zA-Z0-9]+)+)$/; + my @fields = split /\./, substr($1,1); + my $expr = "df::global::".shift(@fields); + for my $fn (@fields) { + $expr = "_toref($expr).$fn"; + } + return $expr; +} + # Text generation with indentation our @lines; @@ -730,6 +741,32 @@ sub get_df_flagarray_type($) { ); $struct_field_handlers{$_} ||= \&get_primitive_field_type for @primitive_type_list; +sub emit_find_instance { + my ($tag) = @_; + + my $instance_vector = translate_lookup $tag->getAttribute('instance-vector'); + if ($instance_vector) { + emit "static std::vector<$typename*> &get_vector();"; + emit "static $typename *find(int id);"; + + with_emit_static { + emit_block { + emit "return ", $instance_vector, ";"; + } "std::vector<$typename*>& ${typename}::get_vector() "; + + emit_block { + emit "std::vector<$typename*> &vec_ = get_vector();"; + + if (my $id = $tag->getAttribute('key-field')) { + emit "return binsearch_in_vector(vec_, &${typename}::$id, id_);"; + } else { + emit "return (id_ >= 0 && id_ < vec_.size()) ? vec_[id_] : NULL;"; + } + } "$typename *${typename}::find(int id_) "; + } + } +} + sub render_struct_type { my ($tag) = @_; @@ -750,6 +787,8 @@ sub render_struct_type { with_struct_block { render_struct_field($_) for get_struct_fields($tag); + emit_find_instance($tag); + if ($has_methods) { if ($is_class) { emit "static class_virtual_identity<$typename> _identity;"; diff --git a/library/xml/df.buildings.xml b/library/xml/df.buildings.xml index f54c76eb8..74df09eb7 100644 --- a/library/xml/df.buildings.xml +++ b/library/xml/df.buildings.xml @@ -7,8 +7,8 @@ - - (find-by-id $global.world.buildings.all $id $) + diff --git a/library/xml/df.history.xml b/library/xml/df.history.xml index 78dd33a3b..700329ea8 100644 --- a/library/xml/df.history.xml +++ b/library/xml/df.history.xml @@ -1,5 +1,5 @@ - + @@ -17,8 +17,6 @@ - (find-by-id $global.world.history.figures $id $) - (describe-obj $.name) (awhen (find-creature $.race) @@ -44,6 +42,14 @@ + + + + + + + diff --git a/library/xml/df.items.xml b/library/xml/df.items.xml index a49c35ff5..c1b989b23 100644 --- a/library/xml/df.items.xml +++ b/library/xml/df.items.xml @@ -66,9 +66,8 @@ -- CORE ITEM - - (find-by-id $global.world.items.all $id $) - + diff --git a/library/xml/df.jobs.xml b/library/xml/df.jobs.xml index 48163fc48..8c6c6d849 100644 --- a/library/xml/df.jobs.xml +++ b/library/xml/df.jobs.xml @@ -190,9 +190,7 @@ - - (find-by-id $global.world.activities.all $id $) - + diff --git a/library/xml/df.language.xml b/library/xml/df.language.xml index 347946602..961057f2d 100644 --- a/library/xml/df.language.xml +++ b/library/xml/df.language.xml @@ -18,28 +18,24 @@ - - - - $global.world.raws.language_words[$] - - - - - - + + + + + + + + + + + - + + - + $.word - - - - - - - + @@ -48,10 +44,10 @@ - + - $global.world.raws.translations[$] + $.name @@ -78,7 +74,9 @@ - + + + diff --git a/library/xml/df.legends.xml b/library/xml/df.legends.xml index 0b8b8c926..a9d2e4a65 100644 --- a/library/xml/df.legends.xml +++ b/library/xml/df.legends.xml @@ -1,5 +1,5 @@ - + @@ -9,8 +9,6 @@ - (find-by-id $global.world.entities.all $id $) - (describe-obj $.name) (describe-obj (find-creature $.race)) @@ -225,10 +223,9 @@ - + - (find-by-id $global.world.entity_populations $id $) (describe-obj $.name) @@ -258,11 +255,9 @@ - + - (find-by-id $global.world.nemesis.all $id $) - @@ -284,11 +279,9 @@ - + - (find-by-id $global.world.artifacts.all $id $) - (describe-obj $.name) @@ -298,15 +291,6 @@ - - - - - - - - (find-by-id $global.world.history.events $id $) -