To index instances.
define LOOP_OVER_ROOMS(R) LOOP_OVER(R, faux_instance) if (R->is_a_room) define LOOP_OVER_REGIONS(R) LOOP_OVER(R, faux_instance) if (R->is_a_region) define LOOP_OVER_DIRECTIONS(R) LOOP_OVER(R, faux_instance) if (R->is_a_direction) define LOOP_OVER_BACKDROPS(R) LOOP_OVER(R, faux_instance) if (R->is_a_backdrop) define LOOP_OVER_OBJECTS(R) LOOP_OVER(R, faux_instance)
typedef struct faux_instance { int index_appearances; how many times have I appeared thus far in the World index? struct text_stream *name; struct text_stream *printed_name; struct text_stream *abbrev; struct instance *original; int is_a_thing; int is_a_supporter; int is_a_person; int is_a_room; int is_a_door; int is_a_region; int is_a_direction; int is_a_backdrop; int is_everywhere; int is_worn; int is_a_part; int specify_kind; int direction_index; int direction_number; struct linked_list *backdrop_presences; of faux_instance struct faux_instance *region_enclosing; struct faux_instance *next_room_in_submap; struct faux_instance *opposite_direction; struct faux_instance *object_tree_sibling; struct faux_instance *object_tree_child; struct faux_instance *progenitor; struct faux_instance *incorp_tree_sibling; struct faux_instance *incorp_tree_child; struct faux_instance *other_side; struct text_stream *kind_text; struct text_stream *kind_chain; struct text_stream *anchor_text; int created_at; int kind_set_at; int region_set_at; int progenitor_set_at; struct linked_list *usages; of parse_node #ifdef CORE_MODULE inference_subject *knowledge; #endif struct fi_map_data fimd; CLASS_DEFINITION } faux_instance; typedef struct fi_map_data { struct connected_submap *submap; struct vector position; struct vector saved_gridpos; int cooled; int shifted; int zone; wchar_t *colour; an HTML colour for the room square (rooms only) wchar_t *text_colour; an HTML colour for text on that square int eps_x, eps_y; struct faux_instance *map_connection_a; struct faux_instance *map_connection_b; int exit_lengths[MAX_DIRECTIONS]; struct faux_instance *spatial_relationship[MAX_DIRECTIONS]; struct faux_instance *exits[MAX_DIRECTIONS]; struct faux_instance *lock_exits[MAX_DIRECTIONS]; int exits_set_at[MAX_DIRECTIONS]; struct map_parameter_scope local_map_parameters; temporary: used in EPS mapping } fi_map_data; fi_map_data IXInstances::new_fimd(faux_instance *FI) { fi_map_data fimd; fimd.submap = NULL; fimd.position = Zero_vector; fimd.saved_gridpos = Zero_vector; fimd.cooled = FALSE; fimd.shifted = FALSE; fimd.zone = 0; fimd.colour = NULL; fimd.eps_x = 0; fimd.eps_y = 0; fimd.map_connection_a = NULL; fimd.map_connection_b = NULL; for (int i=0; i<MAX_DIRECTIONS; i++) { fimd.exit_lengths[i] = 0; fimd.exits[i] = NULL; fimd.lock_exits[i] = NULL; fimd.spatial_relationship[i] = NULL; fimd.exits_set_at[i] = -1; } EPSMap::prepare_map_parameter_scope(&(fimd.local_map_parameters)); return fimd; }
- The structure faux_instance is accessed in 2/me, 2/prp, 2/inf, 3/spt, 3/bck, 3/rgn, 4/sm, 4/hm, 4/rem and here.
- The structure fi_map_data is accessed in 4/sm, 4/hm, 4/rem and here.
§2. When names are abbreviated for use on the World Index map (for instance, "Marble Hallway" becomes "MH") each word is tested against the following nonterminal; those which match are omitted. So, for instance, "Queen Of The South" comes out as "QS".
define ABBREV_ROOMS_TO 2
<map-name-abbreviation-omission-words> ::= in | of | <article>
- This is Preform grammar, not regular C code.
§.1. Compose the abbreviated name.1 =
wording W = Instances::get_name(I, FALSE); if (Wordings::nonempty(W)) { int c = 0; LOOP_THROUGH_WORDING(i, W) { if ((i > Wordings::first_wn(W)) && (i < Wordings::last_wn(W)) && (<map-name-abbreviation-omission-words>(Wordings::one_word(i)))) continue; wchar_t *p = Lexer::word_raw_text(i); if (c++ < ABBREV_ROOMS_TO) PUT_TO(FI->abbrev, Characters::toupper(p[0])); } LOOP_THROUGH_WORDING(i, W) { if ((i > Wordings::first_wn(W)) && (i < Wordings::last_wn(W)) && (<map-name-abbreviation-omission-words>(Wordings::one_word(i)))) continue; wchar_t *p = Lexer::word_raw_text(i); for (int j=1; p[j]; j++) if (Characters::vowel(p[j]) == FALSE) if (c++ < ABBREV_ROOMS_TO) PUT_TO(FI->abbrev, p[j]); if ((c++ < ABBREV_ROOMS_TO) && (p[1])) PUT_TO(FI->abbrev, p[1]); } }
- This code is used in §3.
faux_instance *start_faux_instance = NULL; faux_instance *faux_yourself = NULL; faux_instance *faux_benchmark = NULL; void IXInstances::make_faux(void) { instance *I; LOOP_OVER_INSTANCES(I, K_object) { faux_instance *FI = CREATE(faux_instance); FI->index_appearances = 0; FI->name = Str::new(); Instances::write_name(FI->name, I); FI->abbrev = Str::new(); Compose the abbreviated name.1; FI->original = I; FI->is_a_thing = Instances::of_kind(I, K_thing); FI->is_a_supporter = Instances::of_kind(I, K_supporter); FI->is_a_person = Instances::of_kind(I, K_person); FI->is_a_room = Spatial::object_is_a_room(I); FI->is_a_door = Map::instance_is_a_door(I); FI->is_a_region = Regions::object_is_a_region(I); FI->is_a_direction = Map::object_is_a_direction(I); FI->is_a_backdrop = Backdrops::object_is_a_backdrop(I); FI->is_everywhere = FALSE; FI->is_worn = FALSE; inference *inf; POSITIVE_KNOWLEDGE_LOOP(inf, Instances::as_subject(I), property_inf) if (PropertyInferences::get_property(inf) == P_worn) FI->is_worn = TRUE; FI->is_a_part = SPATIAL_DATA(I)->part_flag; FI->backdrop_presences = NEW_LINKED_LIST(faux_instance); FI->region_enclosing = NULL; FI->next_room_in_submap = NULL; FI->opposite_direction = NULL; FI->object_tree_sibling = NULL; FI->object_tree_child = NULL; FI->progenitor = NULL; FI->incorp_tree_sibling = NULL; FI->incorp_tree_child = NULL; FI->direction_index = MAP_DATA(I)->direction_index; FI->direction_number = InstanceCounting::IK_count(I, K_direction); kind *k = Instances::to_kind(I); FI->specify_kind = TRUE; if (Kinds::eq(k, K_thing)) FI->specify_kind = FALSE; if (Kinds::eq(k, K_room)) FI->specify_kind = FALSE; FI->other_side = NULL; FI->kind_text = Str::new(); wording W = Kinds::Behaviour::get_name_in_play(k, FALSE, Projects::get_language_of_play(Task::project())); WRITE_TO(FI->kind_text, "%+W", W); FI->kind_chain = Str::new(); kind *IK = Instances::to_kind(I); int i = 0; while ((IK != K_object) && (IK)) { i++; IK = Latticework::super(IK); } for (int j=i-1; j>=0; j--) { int k; IK = Instances::to_kind(I); for (k=0; k<j; k++) IK = Latticework::super(IK); if (j != i-1) WRITE_TO(FI->kind_chain, " > "); wording W = Kinds::Behaviour::get_name(IK, FALSE); WRITE_TO(FI->kind_chain, "%+W", W); } noun *nt = Instances::get_noun(I); FI->anchor_text = Str::duplicate(NounIdentifiers::identifier(nt)); parse_node *C = Instances::get_creating_sentence(I); if (C) FI->created_at = Wordings::first_wn(Node::get_text(C)); else FI->created_at = -1; C = Instances::get_kind_set_sentence(I); if (C) FI->kind_set_at = Wordings::first_wn(Node::get_text(C)); else FI->kind_set_at = -1; C = SPATIAL_DATA(I)->progenitor_set_at; if (C) FI->progenitor_set_at = Wordings::first_wn(Node::get_text(C)); else FI->progenitor_set_at = -1; FI->region_set_at = -1; C = REGIONS_DATA(I)->in_region_set_at; if (C) FI->region_set_at = Wordings::first_wn(Node::get_text(C)); FI->usages = I->compilation_data.usages; FI->fimd = IXInstances::new_fimd(FI); FI->fimd.colour = MAP_DATA(I)->world_index_colour; FI->fimd.text_colour = MAP_DATA(I)->world_index_text_colour; FI->fimd.eps_x = MAP_DATA(I)->eps_x; FI->fimd.eps_y = MAP_DATA(I)->eps_y; for (int i=0; i<MAX_DIRECTIONS; i++) { parse_node *at = MAP_DATA(I)->exits_set_at[i]; if (at) FI->fimd.exits_set_at[i] = Wordings::first_wn(Node::get_text(at)); } if (I == I_yourself) faux_yourself = FI; if (I == Spatial::get_benchmark_room()) faux_benchmark = FI; if (I == Player::get_start_room()) start_faux_instance = FI; TEMPORARY_TEXT(pname) parse_node *V = PropertyInferences::value_and_where( Instances::as_subject(I), P_printed_name, NULL); if ((Rvalues::is_CONSTANT_of_kind(V, K_text)) && (Wordings::nonempty(Node::get_text(V)))) { int wn = Wordings::first_wn(Node::get_text(V)); WRITE_TO(pname, "%+W", Wordings::one_word(wn)); if (Str::get_first_char(pname) == '\"') Str::delete_first_character(pname); if (Str::get_last_char(pname) == '\"') Str::delete_last_character(pname); } FI->printed_name = Str::duplicate(pname); DISCARD_TEXT(pname) #ifdef CORE_MODULE FI->knowledge = Instances::as_subject(I); #endif } faux_instance *FB; LOOP_OVER(FB, faux_instance) { if (FB->is_a_backdrop) { instance *B = FB->original; inference *inf; POSITIVE_KNOWLEDGE_LOOP(inf, Instances::as_subject(B), found_in_inf) { instance *L = Backdrops::get_inferred_location(inf); faux_instance *FL = IXInstances::fi(L); ADD_TO_LINKED_LIST(FB, faux_instance, FL->backdrop_presences); } POSITIVE_KNOWLEDGE_LOOP(inf, Instances::as_subject(B), found_everywhere_inf) { FB->is_everywhere = TRUE; } } for (int i=0; i<MAX_DIRECTIONS; i++) { FB->fimd.exits[i] = IXInstances::fi(MAP_EXIT(FB->original, i)); } } LOOP_OVER(FB, faux_instance) { FB->region_enclosing = IXInstances::fi(Regions::enclosing(FB->original)); FB->object_tree_sibling = IXInstances::fi(SPATIAL_DATA(FB->original)->object_tree_sibling); FB->object_tree_child = IXInstances::fi(SPATIAL_DATA(FB->original)->object_tree_child); FB->progenitor = IXInstances::fi(Spatial::progenitor(FB->original)); FB->incorp_tree_sibling = IXInstances::fi(SPATIAL_DATA(FB->original)->incorp_tree_sibling); FB->incorp_tree_child = IXInstances::fi(SPATIAL_DATA(FB->original)->incorp_tree_child); } faux_instance *FR; LOOP_OVER(FR, faux_instance) if (FR->is_a_direction) { FR->opposite_direction = IXInstances::fi(Map::get_value_of_opposite_property(FR->original)); } faux_instance *FD; LOOP_OVER(FD, faux_instance) if (FD->is_a_door) { parse_node *S = PropertyInferences::value_of( Instances::as_subject(I), P_other_side); FD->other_side = IXInstances::fi(Rvalues::to_object_instance(S)); FD->fimd.map_connection_a = IXInstances::fi(MAP_DATA(FD->original)->map_connection_a); FD->fimd.map_connection_b = IXInstances::fi(MAP_DATA(FD->original)->map_connection_b); } IXInstances::decode_hints(1); } void IXInstances::decode_hints(int pass) { mapping_hint *hint; LOOP_OVER(hint, mapping_hint) { if ((hint->dir) && (hint->as_dir)) { if (pass == 1) story_dir_to_page_dir[MAP_DATA(hint->dir)->direction_index] = MAP_DATA(hint->as_dir)->direction_index; } else if ((hint->from) && (hint->dir)) { if (pass == 1) PL::SpatialMap::lock_exit_in_place(IXInstances::fi(hint->from), MAP_DATA(hint->dir)->direction_index, IXInstances::fi(hint->to)); } else if (hint->name) { if (hint->scope_level != 1000000) { if (pass == 2) { map_parameter_scope *scope = NULL; EPS_map_level *eml; LOOP_OVER(eml, EPS_map_level) if ((eml->contains_rooms) && (eml->map_level - PL::SpatialMap::benchmark_level() == hint->scope_level)) scope = &(eml->map_parameters); if (scope) EPSMap::put_mp(hint->name, scope, IXInstances::fi(hint->scope_I), hint->put_string, hint->put_integer); } } else { if (pass == 1) EPSMap::put_mp(hint->name, NULL, IXInstances::fi(hint->scope_I), hint->put_string, hint->put_integer); } } else if (hint->annotation) { rubric_holder *rh = CREATE(rubric_holder); rh->annotation = hint->annotation; rh->point_size = hint->point_size; rh->font = hint->font; rh->colour = hint->colour; rh->at_offset = hint->at_offset; rh->offset_from = IXInstances::fi(hint->offset_from); } } } faux_instance *IXInstances::fi(instance *I) { faux_instance *FI; LOOP_OVER(FI, faux_instance) if (FI->original == I) return FI; return NULL; } faux_instance *IXInstances::start_room(void) { return start_faux_instance; } faux_instance *IXInstances::yourself(void) { return faux_yourself; }
text_stream *IXInstances::get_name(faux_instance *I) { if (I == NULL) return NULL; return I->name; } void IXInstances::write_name(OUTPUT_STREAM, faux_instance *I) { WRITE("%S", IXInstances::get_name(I)); } void IXInstances::write_kind(OUTPUT_STREAM, faux_instance *I) { WRITE("%S", I->kind_text); } void IXInstances::write_kind_chain(OUTPUT_STREAM, faux_instance *I) { WRITE("%S", I->kind_chain); } #ifdef CORE_MODULE inference_subject *IXInstances::as_subject(faux_instance *FI) { if (FI == NULL) return NULL; return FI->knowledge; } #endif faux_instance *IXInstances::region_of(faux_instance *FI) { if (FI == NULL) return NULL; return FI->region_enclosing; } faux_instance *IXInstances::opposite_direction(faux_instance *FR) { if (FR == NULL) return NULL; return FR->opposite_direction; } faux_instance *IXInstances::other_side_of_door(faux_instance *FR) { if (FR == NULL) return NULL; return FR->other_side; } faux_instance *IXInstances::sibling(faux_instance *FR) { if (FR == NULL) return NULL; return FR->object_tree_sibling; } faux_instance *IXInstances::child(faux_instance *FR) { if (FR == NULL) return NULL; return FR->object_tree_child; } faux_instance *IXInstances::progenitor(faux_instance *FR) { if (FR == NULL) return NULL; return FR->progenitor; } faux_instance *IXInstances::incorp_child(faux_instance *FR) { if (FR == NULL) return NULL; return FR->incorp_tree_child; } faux_instance *IXInstances::incorp_sibling(faux_instance *FR) { if (FR == NULL) return NULL; return FR->incorp_tree_sibling; } int IXInstances::is_a_direction(faux_instance *FR) { if (FR == NULL) return FALSE; return FR->is_a_direction; } int IXInstances::is_a_room(faux_instance *FR) { if (FR == NULL) return FALSE; return FR->is_a_room; } int IXInstances::is_a_door(faux_instance *FR) { if (FR == NULL) return FALSE; return FR->is_a_door; } int IXInstances::is_a_region(faux_instance *FR) { if (FR == NULL) return FALSE; return FR->is_a_region; } int IXInstances::is_a_thing(faux_instance *FR) { if (FR == NULL) return FALSE; return FR->is_a_thing; } int IXInstances::is_a_supporter(faux_instance *FR) { if (FR == NULL) return FALSE; return FR->is_a_supporter; } int IXInstances::is_a_person(faux_instance *FR) { if (FR == NULL) return FALSE; return FR->is_a_person; } void IXInstances::get_door_data(faux_instance *door, faux_instance **c1, faux_instance **c2) { if (c1) *c1 = door->fimd.map_connection_a; if (c2) *c2 = door->fimd.map_connection_b; } map_parameter_scope *IXInstances::get_parameters(faux_instance *R) { if (R == NULL) return NULL; return &(R->fimd.local_map_parameters); }
§5. Noun usage. This simply avoids repetitions in the World index:
void IXInstances::increment_indexing_count(faux_instance *I) { I->index_appearances++; } int IXInstances::indexed_yet(faux_instance *I) { if (I->index_appearances > 0) return TRUE; return FALSE; }