Generate very simple static functions to find objects in global vectors.

develop
Alexander Gavrilov 2011-12-24 16:22:10 +04:00
parent 79ac2a781a
commit 81ad287c06
14 changed files with 117 additions and 69 deletions

@ -1,5 +1,17 @@
#include "Internal.h" #include "Internal.h"
#include "dfhack/DataDefs.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<class T>
inline T &_toref(T &r) { return r; }
template<class T>
inline T &_toref(T *&p) { return *p; }
}
// Instantiate all the static objects // Instantiate all the static objects
#include "dfhack/df/static.inc" #include "dfhack/df/static.inc"

@ -187,6 +187,7 @@ void print_bits ( T val, DFHack::Console& out )
strs << endl; strs << endl;
out.print(strs.str().c_str()); out.print(strs.str().c_str());
} }
/* /*
// this is probably completely bogus // this is probably completely bogus
std::string PrintSplatterType (int16_t mat1, int32_t mat2, vector<DFHack::t_matgloss> &creature_types) std::string PrintSplatterType (int16_t mat1, int32_t mat2, vector<DFHack::t_matgloss> &creature_types)
@ -247,4 +248,21 @@ std::string PrintSplatterType (int16_t mat1, int32_t mat2, vector<DFHack::t_matg
} }
*/ */
template <typename CT, typename FT, typename AT = FT>
CT *binsearch_in_vector(std::vector<CT*> &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;
}
}

@ -56,6 +56,17 @@ sub type_header_def($) {
return uc($main_namespace).'_'.uc($name).'_H'; 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 # Text generation with indentation
our @lines; our @lines;
@ -730,6 +741,32 @@ sub get_df_flagarray_type($) {
); );
$struct_field_handlers{$_} ||= \&get_primitive_field_type for @primitive_type_list; $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 { sub render_struct_type {
my ($tag) = @_; my ($tag) = @_;
@ -750,6 +787,8 @@ sub render_struct_type {
with_struct_block { with_struct_block {
render_struct_field($_) for get_struct_fields($tag); render_struct_field($_) for get_struct_fields($tag);
emit_find_instance($tag);
if ($has_methods) { if ($has_methods) {
if ($is_class) { if ($is_class) {
emit "static class_virtual_identity<$typename> _identity;"; emit "static class_virtual_identity<$typename> _identity;";

@ -7,8 +7,8 @@
<flag-bit name='justice'/> <flag-bit name='justice'/>
</bitfield-type> </bitfield-type>
<class-type type-name='building' original-name='buildingst' key-field='id'> <class-type type-name='building' original-name='buildingst'
<code-helper name='find-instance'>(find-by-id $global.world.buildings.all $id $)</code-helper> instance-vector='$global.world.buildings.all' key-field='id'>
<int32_t name='x1' comment='left'/> <int32_t name='x1' comment='left'/>
<int32_t name='y1'/> <int32_t name='y1'/>

@ -1,5 +1,5 @@
<data-definition> <data-definition>
<struct-type type-name='historical_figure' key-field='id'> <struct-type type-name='historical_figure' instance-vector='$global.world.history.figures' key-field='id'>
<enum base-type='int16_t' name='profession' type-name='profession'/> <enum base-type='int16_t' name='profession' type-name='profession'/>
<int16_t name='race' ref-target='creature_raw'/> <int16_t name='race' ref-target='creature_raw'/>
@ -17,8 +17,6 @@
<compound type-name='language_name' name='name'/> <compound type-name='language_name' name='name'/>
<code-helper name='find-instance'>(find-by-id $global.world.history.figures $id $)</code-helper>
<code-helper name='describe'> <code-helper name='describe'>
(describe-obj $.name) (describe-obj $.name)
(awhen (find-creature $.race) (awhen (find-creature $.race)
@ -44,6 +42,14 @@
<static-array name='unk7' count='5' type-name='int32_t' comment='empty'/> <static-array name='unk7' count='5' type-name='int32_t' comment='empty'/>
</struct-type> </struct-type>
<class-type type-name='history_event' original-name='history_eventst'
instance-vector='$global.world.history.events' key-field='id'>
<int32_t name='year'/>
<int32_t name='seconds'/>
<df-flagarray name='flags'/>
<int32_t name='id'/>
</class-type>
<class-type type-name='history_event_masterpiece_createdst' inherits-from='history_event'> <class-type type-name='history_event_masterpiece_createdst' inherits-from='history_event'>
<int32_t name='maker' ref-target='historical_figure'/> <int32_t name='maker' ref-target='historical_figure'/>
<int32_t name='maker_entity' ref-target='historical_entity'/> <int32_t name='maker_entity' ref-target='historical_entity'/>

@ -66,9 +66,8 @@
-- CORE ITEM -- CORE ITEM
<class-type type-name='item' original-name='itemst' key-field='id'> <class-type type-name='item' original-name='itemst'
<code-helper name='find-instance'>(find-by-id $global.world.items.all $id $)</code-helper> instance-vector='$global.world.items.all' key-field='id'>
<int16_t name='x'/> <int16_t name='x'/>
<int16_t name='y'/> <int16_t name='y'/>
<int16_t name='z'/> <int16_t name='z'/>

@ -190,9 +190,7 @@
<uint8_t name='unk5'/> <uint8_t name='unk5'/>
</struct-type> </struct-type>
<struct-type type-name='activity_entry' key-field='id'> <struct-type type-name='activity_entry' instance-vector='$global.world.activities.all' key-field='id'>
<code-helper name='find-instance'>(find-by-id $global.world.activities.all $id $)</code-helper>
<int32_t name='id'/> <int32_t name='id'/>
<int16_t name='is_individual'/> <int16_t name='is_individual'/>
<stl-vector name='events'> <stl-vector name='events'>

@ -18,28 +18,24 @@
<enum-item name='STANDARD_VERB'/> <enum-item name='STANDARD_VERB'/>
</enum-type> </enum-type>
<struct-type type-name='language_word' key-field='word'> <enum-type type-name='part_of_speech'>
<stl-string name='word'/> <enum-item name='Noun'/>
<enum-item name='NounPlural'/>
<code-helper name='find-instance'>$global.world.raws.language_words[$]</code-helper> <enum-item name='Adjective'/>
<enum-item name='Prefix'/>
<compound name='forms' is-union='true'> <enum-item name='Verb'/>
<static-array type-name='stl-string' name='all' count='9'/> <enum-item name='Verb3rdPerson'/>
<compound> <enum-item name='VerbPast'/>
<stl-string name='noun'/> <enum-item name='VerbPassive'/>
<stl-string name='noun_plural'/> <enum-item name='VerbGerund'/>
</enum-type>
<stl-string name='adjective'/> <struct-type type-name='language_word' instance-vector='$global.world.raws.language_words'>
<stl-string name='word'/>
<stl-string name='prefix'/> <code-helper name='describe'>$.word</code-helper>
<stl-string name='verb'/> <static-array type-name='stl-string' name='forms' count='9' index-enum='part_of_speech'/>
<stl-string name='verb_3rd_person'/>
<stl-string name='verb_past'/>
<stl-string name='verb_passive'/>
<stl-string name='verb_gerund'/>
</compound>
</compound>
<uint8_t name='adj_dist'/> <uint8_t name='adj_dist'/>
@ -48,10 +44,10 @@
<df-flagarray name='flags' index-enum='language_word_flags'/> <df-flagarray name='flags' index-enum='language_word_flags'/>
</struct-type> </struct-type>
<struct-type type-name='language_translation' key-field='name'> <struct-type type-name='language_translation' instance-vector='$global.world.raws.translations'>
<stl-string name='name'/> <stl-string name='name'/>
<code-helper name='find-instance'>$global.world.raws.translations[$]</code-helper> <code-helper name='describe'>$.name</code-helper>
<stl-vector name='unknown1' comment='empty'/> <stl-vector name='unknown1' comment='empty'/>
<stl-vector name='unknown2' comment='empty'/> <stl-vector name='unknown2' comment='empty'/>
@ -78,7 +74,9 @@
<static-array name='words' count='7'> <static-array name='words' count='7'>
<int32_t ref-target='language_word'/> <int32_t ref-target='language_word'/>
</static-array> </static-array>
<static-array name='parts_of_speech' count='7' type-name='int16_t'/> <static-array name='parts_of_speech' count='7'>
<enum base-type='int16_t' type-name='part_of_speech'/>
</static-array>
<int32_t name='language' ref-target='language_translation'/> <int32_t name='language' ref-target='language_translation'/>
<int16_t name='unknown'/> <int16_t name='unknown'/>

@ -1,5 +1,5 @@
<data-definition> <data-definition>
<struct-type type-name='historical_entity' key-field='id'> <struct-type type-name='historical_entity' key-field='id' instance-vector='$global.world.entities.all'>
<int16_t name='unk1'/> <int16_t name='unk1'/>
<int32_t name='id' comment='index in the array'/> <int32_t name='id' comment='index in the array'/>
<pointer name='entity_raw'/> <pointer name='entity_raw'/>
@ -9,8 +9,6 @@
<compound name='name' type-name='language_name'/> <compound name='name' type-name='language_name'/>
<code-helper name='find-instance'>(find-by-id $global.world.entities.all $id $)</code-helper>
<code-helper name='describe'> <code-helper name='describe'>
(describe-obj $.name) (describe-obj $.name)
(describe-obj (find-creature $.race)) (describe-obj (find-creature $.race))
@ -225,10 +223,9 @@
</compound> </compound>
</struct-type> </struct-type>
<struct-type type-name='entity_population' key-field='id'> <struct-type type-name='entity_population' key-field='id' instance-vector='$global.world.entity_populations'>
<compound name='name' type-name='language_name'/> <compound name='name' type-name='language_name'/>
<code-helper name='find-instance'>(find-by-id $global.world.entity_populations $id $)</code-helper>
<code-helper name='describe'> <code-helper name='describe'>
(describe-obj $.name) (describe-obj $.name)
</code-helper> </code-helper>
@ -258,11 +255,9 @@
<int32_t name='civ_id' ref-target='historical_entity'/> <int32_t name='civ_id' ref-target='historical_entity'/>
</struct-type> </struct-type>
<struct-type type-name='nemesis_record' key-field='id'> <struct-type type-name='nemesis_record' key-field='id' instance-vector='$global.world.nemesis.all'>
<int32_t name='id' comment='sequential index in the array'/> <int32_t name='id' comment='sequential index in the array'/>
<code-helper name='find-instance'>(find-by-id $global.world.nemesis.all $id $)</code-helper>
<int32_t name='unit_id' ref-target='unit'/> <int32_t name='unit_id' ref-target='unit'/>
<int32_t name='save_file_id' comment='unit-*.dat'/> <int32_t name='save_file_id' comment='unit-*.dat'/>
@ -284,11 +279,9 @@
<stl-vector name='unk13' type-name='pointer' comment='empty'/> <stl-vector name='unk13' type-name='pointer' comment='empty'/>
</struct-type> </struct-type>
<struct-type type-name='artifact_record' key-field='id'> <struct-type type-name='artifact_record' key-field='id' instance-vector='$global.world.artifacts.all'>
<int32_t name='id'/> <int32_t name='id'/>
<code-helper name='find-instance'>(find-by-id $global.world.artifacts.all $id $)</code-helper>
<code-helper name='describe'> <code-helper name='describe'>
(describe-obj $.name) (describe-obj $.name)
</code-helper> </code-helper>
@ -298,15 +291,6 @@
<int32_t name='unk2'/> <int32_t name='unk2'/>
<pointer name='item' type-name='item'/> <pointer name='item' type-name='item'/>
</struct-type> </struct-type>
<class-type type-name='history_event' original-name='history_eventst' key-field='id'>
<int32_t name='year'/>
<int32_t name='seconds'/>
<df-flagarray name='flags'/>
<int32_t name='id'/>
<code-helper name='find-instance'>(find-by-id $global.world.history.events $id $)</code-helper>
</class-type>
</data-definition> </data-definition>
<!-- <!--

@ -1,15 +1,14 @@
<data-definition> <data-definition>
-- MACHINE -- MACHINE
<class-type type-name='machine' original-name='machinest' key-field='id'> <class-type type-name='machine' original-name='machinest'
instance-vector='$global.world.machines.all' key-field='id'>
<int32_t name="x"/> <int32_t name="x"/>
<int32_t name="y"/> <int32_t name="y"/>
<int32_t name="z"/> <int32_t name="z"/>
<int32_t name="id"/> <int32_t name="id"/>
<code-helper name='find-instance'>(find-by-id $global.world.machines.all $id $)</code-helper>
<stl-vector name="components"> <stl-vector name="components">
<pointer> <pointer>
<int32_t name="building_id" ref-target='building'/> <int32_t name="building_id" ref-target='building'/>

@ -126,10 +126,10 @@
<static-array name='state_color_str' type-name='stl-string' count='6'/> <static-array name='state_color_str' type-name='stl-string' count='6'/>
</struct-type> </struct-type>
<struct-type type-name='material_plant' key-field='id'> <struct-type type-name='material_plant' instance-vector='$global.world.raws.plants.all'>
<stl-string name='id'/> <stl-string name='id'/>
<code-helper name='find-instance'>$global.world.raws.plants.all[$]</code-helper> <code-helper name='describe'>$.id</code-helper>
<df-flagarray name='flags'/> <df-flagarray name='flags'/>
@ -234,10 +234,10 @@
<int32_t name='underground_depth_max'/> <int32_t name='underground_depth_max'/>
</struct-type> </struct-type>
<struct-type type-name='material_inorganic' key-field='id'> <struct-type type-name='material_inorganic' instance-vector='$global.world.raws.inorganics'>
<stl-string name='id'/> <stl-string name='id'/>
<code-helper name='find-instance'>$global.world.raws.inorganics.all[$]</code-helper> <code-helper name='describe'>$.id</code-helper>
<df-flagarray name='flags'/> <df-flagarray name='flags'/>

@ -111,11 +111,9 @@
<int32_t name="unk_11c"/> <int32_t name="unk_11c"/>
</struct-type> </struct-type>
<struct-type type-name='squad' key-field='id'> <struct-type type-name='squad' key-field='id' instance-vector='$global.world.squads.all'>
<int32_t name='id'/> <int32_t name='id'/>
<code-helper name='find-instance'>(find-by-id $global.world.squads.all $id $)</code-helper>
<compound name='name' type-name='language_name'/> <compound name='name' type-name='language_name'/>
<stl-string name='unk'/> <stl-string name='unk'/>

@ -7,11 +7,10 @@
<stl-string name='code' comment='DWARF_LIAISON etc'/> <stl-string name='code' comment='DWARF_LIAISON etc'/>
</struct-type> </struct-type>
<struct-type type-name='burrow' key-field='id'> <struct-type type-name='burrow' key-field='id' instance-vector='$global.ui.burrows.list'>
<int32_t name='id'/> <int32_t name='id'/>
<stl-string name='name'/> <stl-string name='name'/>
<code-helper name='find-instance'>(find-by-id $global.ui.burrows.list $id $)</code-helper>
<code-helper name='describe'> <code-helper name='describe'>
(describe-obj $.name) (describe-obj $.name)
</code-helper> </code-helper>

@ -114,11 +114,9 @@
<flag-bit name='ghostly'/> <flag-bit name='ghostly'/>
</bitfield-type> </bitfield-type>
<struct-type type-name='unit' key-field='id'> <struct-type type-name='unit' key-field='id' instance-vector='$global.world.units.all'>
<compound type-name='language_name' name='name'/> <compound type-name='language_name' name='name'/>
<code-helper name='find-instance'>(find-by-id $global.world.units.all $id $)</code-helper>
<code-helper name='describe'> <code-helper name='describe'>
(describe-obj $.name) (describe-obj $.name)
(awhen (find-creature $.race) (awhen (find-creature $.race)