+ + +

Creating a simple graph of scenes, ends and connectors.

+ +

§1. As with Faux Instances, we need to make faux scenes: these more or less +reconstruct the original data structures in Inform, though they are much less +annotated. +

+ +
define MAX_SCENE_ENDS 32  this must exceed 31
+
+
+typedef struct simplified_scene {
+    struct inter_package *pack;
+    int no_ends;
+    struct simplified_end *ends[MAX_SCENE_ENDS];
+    int indexed_already;
+    CLASS_DEFINITION
+} simplified_scene;
+
+typedef struct simplified_end {
+    struct inter_package *end_pack;
+    struct simplified_connector *anchor_connectors;  linked list
+    CLASS_DEFINITION
+} simplified_end;
+
+typedef struct simplified_connector {
+    struct inter_package *con_pack;
+    struct simplified_scene *connect_to;
+    struct simplified_connector *next;  next in list of connectors for a scene end
+    CLASS_DEFINITION
+} simplified_connector;
+
+simplified_scene *FauxScenes::simplified(inter_tree *I, inter_package *sc_pack) {
+    simplified_scene *ssc = CREATE(simplified_scene);
+    ssc->pack = sc_pack;
+    ssc->no_ends = 0;
+    ssc->indexed_already = FALSE;
+    inter_package *end_pack;
+    LOOP_THROUGH_SUBPACKAGES(end_pack, sc_pack, I"_scene_end") {
+        simplified_end *se = CREATE(simplified_end);
+        se->end_pack = end_pack;
+        se->anchor_connectors = NULL;
+        inter_package *con_pack;
+        LOOP_THROUGH_SUBPACKAGES(con_pack, end_pack, I"_scene_connector") {
+            simplified_connector *scon = CREATE(simplified_connector);
+            scon->con_pack = con_pack;
+            scon->next = NULL;
+            if (se->anchor_connectors == NULL) {
+                se->anchor_connectors = scon;
+            } else {
+                simplified_connector *last = se->anchor_connectors;
+                while ((last) && (last->next)) last = last->next;
+                last->next = scon;
+            }
+            scon->connect_to = NULL;
+        }
+        if (ssc->no_ends >= MAX_SCENE_ENDS) internal_error("too many scene ends");
+        ssc->ends[ssc->no_ends++] = se;
+    }
+    return ssc;
+}
+
+int FauxScenes::is_entire_game(simplified_scene *ssc) {
+    if (Metadata::read_optional_numeric(ssc->pack, I"^is_entire_game")) return TRUE;
+    return FALSE;
+}
+
+int FauxScenes::recurs(simplified_scene *ssc) {
+    if (Metadata::read_optional_numeric(ssc->pack, I"^recurs")) return TRUE;
+    return FALSE;
+}
+
+int FauxScenes::never_ends(simplified_scene *ssc) {
+    if (Metadata::read_optional_numeric(ssc->pack, I"^never_ends")) return TRUE;
+    return FALSE;
+}
+
+int FauxScenes::starts_at_start_of_play(simplified_scene *ssc) {
+    if (Metadata::read_optional_numeric(ssc->pack, I"^starts")) return TRUE;
+    return FALSE;
+}
+
+int FauxScenes::starts_on_condition(simplified_scene *ssc) {
+    if (Metadata::read_optional_numeric(ssc->pack, I"^starts_on_condition")) return TRUE;
+    return FALSE;
+}
+
+int FauxScenes::no_ends(simplified_scene *ssc) {
+    return ssc->no_ends;
+}
+
+text_stream *FauxScenes::scene_name(simplified_scene *ssc) {
+    return Metadata::read_textual(ssc->pack, I"^name");
+}
+
+text_stream *FauxScenes::end_name(simplified_end *se) {
+    return Metadata::read_textual(se->end_pack, I"^name");
+}
+
+text_stream *FauxScenes::anchor_condition(simplified_end *se) {
+    return Metadata::read_textual(se->end_pack, I"^condition");
+}
+
+int FauxScenes::has_anchor_condition(simplified_end *se) {
+    if (Str::len(FauxScenes::anchor_condition(se)) > 0) return TRUE;
+    return FALSE;
+}
+
+int FauxScenes::anchor_condition_set_at(simplified_end *se) {
+    return (int) Metadata::read_optional_numeric(se->end_pack, I"^at");
+}
+
+inter_symbol *FauxScenes::end_rulebook(simplified_end *se) {
+    return Metadata::read_optional_symbol(se->end_pack, I"^rulebook");
+}
+
+simplified_scene *FauxScenes::connects_to(simplified_connector *scon) {
+    if (scon->connect_to) return scon->connect_to;
+    inter_symbol *sc_symbol = Metadata::read_optional_symbol(scon->con_pack, I"^to");
+    if (sc_symbol) {
+        inter_package *to_pack = Inter::Packages::container(sc_symbol->definition);
+        simplified_scene *ssc;
+        LOOP_OVER(ssc, simplified_scene)
+            if (ssc->pack == to_pack) {
+                scon->connect_to = ssc;
+                return ssc;
+            }
+    }
+    internal_error("scene metadata broken: bad connector");
+    return NULL;
+}
+
+int FauxScenes::scon_end(simplified_connector *scon) {
+    return (int) Metadata::read_numeric(scon->con_pack, I"^end");
+}
+
+int FauxScenes::scon_at(simplified_connector *scon) {
+    return (int) Metadata::read_numeric(scon->con_pack, I"^at");
+}
+
+ + + +