<pclass="purpose">Though a plugin, for convenience of implementation, this code is always active and provides for efficient loops through instances at runtime.</p>
<ulclass="toc"><li><ahref="2-ic.html#SP1">§1. Plugin startup</a></li><li><ahref="2-ic.html#SP5">§5. The IK-count</a></li><li><ahref="2-ic.html#SP7">§7. The IK-sequence</a></li><li><ahref="2-ic.html#SP9">§9. The KD-count</a></li><li><ahref="2-ic.html#SP10">§10. Properties of instances</a></li><li><ahref="2-ic.html#SP11">§11. Loop optimisation</a></li></ul><hrclass="tocbar">
<pclass="commentary firstcommentary"><aid="SP1"class="paragraph-anchor"></a><b>§1. Plugin startup. </b>Being a plugin, this needs a startup function, and here it is. It is in fact
called on every run: see <ahref="../core-module/1-cm.html"class="internal">Core Module (in core)</a>.
<pclass="commentary firstcommentary"><aid="SP2"class="paragraph-anchor"></a><b>§2. </b>Being a plugin, this code can provide extra data on inference subjects. It
will in practice use that only for subjects representing kinds:
<spanclass="plain-syntax"></span><spanclass="reserved-syntax">int</span><spanclass="plain-syntax"></span><spanclass="identifier-syntax">has_instances</span><spanclass="plain-syntax">; </span><spanclass="comment-syntax"> are there any instances of this kind?</span>
<spanclass="plain-syntax"></span><spanclass="reserved-syntax">struct</span><spanclass="plain-syntax"></span><spanclass="identifier-syntax">property</span><spanclass="plain-syntax"> *</span><spanclass="identifier-syntax">next_in_IK_sequence_prop</span><spanclass="plain-syntax">; </span><spanclass="comment-syntax"> the IK-Link property for this kind</span>
<spanclass="reserved-syntax">int</span><spanclass="plain-syntax"></span><spanclass="function-syntax">InstanceCounting::counting_new_subject_notify</span><buttonclass="popup"onclick="togglePopup('usagePopup1')"><spanclass="comment-syntax">?</span><spanclass="popuptext"id="usagePopup1">Usage of <spanclass="code-font"><spanclass="function-syntax">InstanceCounting::counting_new_subject_notify</span></span>:<br/><ahref="2-ic.html#SP1">§1</a></span></button><spanclass="plain-syntax">(</span><spanclass="identifier-syntax">inference_subject</span><spanclass="plain-syntax"> *</span><spanclass="identifier-syntax">subj</span><spanclass="plain-syntax">) {</span>
<pclass="commentary firstcommentary"><aid="SP5"class="paragraph-anchor"></a><b>§5. The IK-count. </b>The IK-count for an instance I of kind K is the result of numbering instances
of that kind upwards from 0. This depends on both I and K, hence the name:
for example, a red car might be thing number 17 but vehicle number 2. Within
each kind, instances are numbered in creation order by the source text.
</p>
<pclass="commentary">Before we can store this, we must calculate it, which we do with this less
<spanclass="reserved-syntax">void</span><spanclass="plain-syntax"></span><spanclass="function-syntax">InstanceCounting::calculate_IK_counts</span><buttonclass="popup"onclick="togglePopup('usagePopup3')"><spanclass="comment-syntax">?</span><spanclass="popuptext"id="usagePopup3">Usage of <spanclass="code-font"><spanclass="function-syntax">InstanceCounting::calculate_IK_counts</span></span>:<br/><ahref="2-ic.html#SP10">§10</a></span></button><spanclass="plain-syntax">(</span><spanclass="reserved-syntax">void</span><spanclass="plain-syntax">) {</span>
<spanclass="plain-syntax"></span><spanclass="named-paragraph-container code-font"><ahref="2-ic.html#SP5_1"class="named-paragraph-link"><spanclass="named-paragraph">Allocate the instance count array in memory</span><spanclass="named-paragraph-number">5.1</span></a></span><spanclass="plain-syntax">;</span>
<spanclass="plain-syntax"></span><spanclass="named-paragraph-container code-font"><ahref="2-ic.html#SP5_2"class="named-paragraph-link"><spanclass="named-paragraph">Compute the instance count array</span><spanclass="named-paragraph-number">5.2</span></a></span><spanclass="plain-syntax">;</span>
<spanclass="plain-syntax">}</span>
</pre>
<pclass="commentary firstcommentary"><aid="SP5_1"class="paragraph-anchor"></a><b>§5.1. </b><spanclass="named-paragraph-container code-font"><spanclass="named-paragraph-defn">Allocate the instance count array in memory</span><spanclass="named-paragraph-number">5.1</span></span><spanclass="comment-syntax"> =</span>
<ulclass="endnotetexts"><li>This code is used in <ahref="2-ic.html#SP5">§5</a>.</li></ul>
<pclass="commentary firstcommentary"><aid="SP5_2"class="paragraph-anchor"></a><b>§5.2. </b>The following is quadratic in the number of objects, but this has never been
a problem in practice; the number seldom exceeds a few hundred.
</p>
<pclass="commentary"><spanclass="named-paragraph-container code-font"><spanclass="named-paragraph-defn">Compute the instance count array</span><spanclass="named-paragraph-number">5.2</span></span><spanclass="comment-syntax"> =</span>
<ulclass="endnotetexts"><li>This code is used in <ahref="2-ic.html#SP5">§5</a>.</li></ul>
<pclass="commentary firstcommentary"><aid="SP6"class="paragraph-anchor"></a><b>§6. </b>Instance counts are actually useful to several other plugins, so we provide
the following. Note that if I is not in fact an instance of K then its IK-count
<spanclass="plain-syntax"></span><spanclass="reserved-syntax">if</span><spanclass="plain-syntax"> (</span><spanclass="identifier-syntax">kind_instance_counts</span><spanclass="plain-syntax"> == </span><spanclass="identifier-syntax">NULL</span><spanclass="plain-syntax">) </span><spanclass="identifier-syntax">internal_error</span><spanclass="plain-syntax">(</span><spanclass="string-syntax">"instance counts not available"</span><spanclass="plain-syntax">);</span>
<spanclass="plain-syntax"></span><spanclass="reserved-syntax">if</span><spanclass="plain-syntax"> (</span><spanclass="identifier-syntax">K</span><spanclass="plain-syntax"> == </span><spanclass="identifier-syntax">NULL</span><spanclass="plain-syntax">) </span><spanclass="identifier-syntax">internal_error</span><spanclass="plain-syntax">(</span><spanclass="string-syntax">"instance counts available only for objects"</span><spanclass="plain-syntax">);</span>
<pclass="commentary firstcommentary"><aid="SP7"class="paragraph-anchor"></a><b>§7. The IK-sequence. </b>Within each kind K, we form the instances in a linked list called the "IK-sequence".
Again, the list position of I depends on K: the red car might be in one position
in the list of things, and another in the list of vehicles.
</p>
<pclass="commentary">This sequence will be in "declaration order", that is, it will match the order
in which instances are declared in Inter. This is not the same as their creation
order in Inform 7 source text, though it tends to be roughly similar.<supid="fnref:1"><ahref="#fn:1"rel="footnote">1</a></sup>
</p>
<pclass="commentary">The following function abstracts the list, returning the first instance if <spanclass="extract"><spanclass="extract-syntax">I</span></span>
is <spanclass="extract"><spanclass="extract-syntax">NULL</span></span>, and otherwise the next after <spanclass="extract"><spanclass="extract-syntax">I</span></span>. Note that it excludes instances which
have been "diverted".<supid="fnref:2"><ahref="#fn:2"rel="footnote">2</a></sup>
</p>
<ulclass="footnotetexts"><liclass="footnote"id="fn:1"><pclass="inwebfootnote"><supid="fnref:1"><ahref="#fn:1"rel="footnote">1</a></sup> Declaration order is more trouble to arrange, but we do it so that an optimised
and an unoptimised loop to perform the same search will not only iterate through
the same set of objects, but in the same order.
<ahref="#fnref:1"title="return to text">↩</a></p></li><liclass="footnote"id="fn:2"><pclass="inwebfootnote"><supid="fnref:2"><ahref="#fn:2"rel="footnote">2</a></sup> This is used to get rid of the <spanclass="extract"><spanclass="extract-syntax">selfobj</span></span> object in cases where the source text
creates an explicit player.
<ahref="#fnref:2"title="return to text">↩</a></p></li></ul>
<spanclass="plain-syntax"></span><spanclass="reserved-syntax">continue</span><spanclass="plain-syntax">; </span><spanclass="comment-syntax"></span><spanclass="extract"><spanclass="extract-syntax">selfobj</span></span><spanclass="comment-syntax"> may not count</span>
<pclass="commentary firstcommentary"><aid="SP8"class="paragraph-anchor"></a><b>§8. </b>At runtime, we will store the IK sequences by defining their first entries
as constants,<supid="fnref:3"><ahref="#fn:3"rel="footnote">3</a></sup> and their subsequent entries as property values of instances.
The constants are declared here, and see <ahref="2-ic.html#SP10"class="internal">InstanceCounting::counting_complete_model</a>
below for the properties.
</p>
<ulclass="footnotetexts"><liclass="footnote"id="fn:3"><pclass="inwebfootnote"><supid="fnref:3"><ahref="#fn:3"rel="footnote">3</a></sup> We don't need to store these list origins in some table in memory at
runtime because Inform always compiles code which knows which kind it's looping
over: so it never needs to look up an IK-sequence where K is not known at
compile time.
<ahref="#fnref:3"title="return to text">↩</a></p></li></ul>
<spanclass="reserved-syntax">void</span><spanclass="plain-syntax"></span><spanclass="function-syntax">InstanceCounting::define_IK_sequence_start_constants</span><buttonclass="popup"onclick="togglePopup('usagePopup5')"><spanclass="comment-syntax">?</span><spanclass="popuptext"id="usagePopup5">Usage of <spanclass="code-font"><spanclass="function-syntax">InstanceCounting::define_IK_sequence_start_constants</span></span>:<br/><ahref="2-ic.html#SP1">§1</a></span></button><spanclass="plain-syntax">(</span><spanclass="reserved-syntax">void</span><spanclass="plain-syntax">) {</span>
<pclass="commentary firstcommentary"><aid="SP9"class="paragraph-anchor"></a><b>§9. The KD-count. </b>This section is supposedly for instance-counting, but it also does a little
kind-counting: specifically we number the subkinds of object. The KD-count of a
kind is this number.<supid="fnref:4"><ahref="#fn:4"rel="footnote">4</a></sup>
</p>
<ulclass="footnotetexts"><liclass="footnote"id="fn:4"><pclass="inwebfootnote"><supid="fnref:4"><ahref="#fn:4"rel="footnote">4</a></sup> I have completely forgotten what the D stood for. KD-counts are in creation
order, not declaration order, so it can't be D for declaration.
<ahref="#fnref:4"title="return to text">↩</a></p></li></ul>
<spanclass="reserved-syntax">int</span><spanclass="plain-syntax"></span><spanclass="function-syntax">InstanceCounting::KD_count</span><buttonclass="popup"onclick="togglePopup('usagePopup6')"><spanclass="comment-syntax">?</span><spanclass="popuptext"id="usagePopup6">Usage of <spanclass="code-font"><spanclass="function-syntax">InstanceCounting::KD_count</span></span>:<br/><ahref="2-ic.html#SP10_3">§10.3</a></span></button><spanclass="plain-syntax">(</span><spanclass="identifier-syntax">kind</span><spanclass="plain-syntax"> *</span><spanclass="identifier-syntax">K</span><spanclass="plain-syntax">) {</span>
<pclass="commentary firstcommentary"><aid="SP10"class="paragraph-anchor"></a><b>§10. Properties of instances. </b>At model completion time, then, we assign a set of low-level properties to
all the object instances. These consume memory without even being visible in
Inform 7 source text: they are all basically optimisations, and are a classic
trade-off of memory for speed. For the most part we care more about memory in
the Inform runtime (one of our target VMs has a very low memory ceiling), but
search loops must run as fast as they possibly can.
<spanclass="reserved-syntax">int</span><spanclass="plain-syntax"></span><spanclass="function-syntax">InstanceCounting::counting_complete_model</span><buttonclass="popup"onclick="togglePopup('usagePopup7')"><spanclass="comment-syntax">?</span><spanclass="popuptext"id="usagePopup7">Usage of <spanclass="code-font"><spanclass="function-syntax">InstanceCounting::counting_complete_model</span></span>:<br/><ahref="2-ic.html#SP1">§1</a></span></button><spanclass="plain-syntax">(</span><spanclass="reserved-syntax">int</span><spanclass="plain-syntax"></span><spanclass="identifier-syntax">stage</span><spanclass="plain-syntax">) {</span>
<spanclass="plain-syntax"></span><spanclass="named-paragraph-container code-font"><ahref="2-ic.html#SP10_1"class="named-paragraph-link"><spanclass="named-paragraph">Create and assert zero values of the vector property</span><spanclass="named-paragraph-number">10.1</span></a></span><spanclass="plain-syntax">;</span>
<spanclass="plain-syntax"></span><spanclass="named-paragraph-container code-font"><ahref="2-ic.html#SP10_2"class="named-paragraph-link"><spanclass="named-paragraph">Create the two instance properties for each kind of object</span><spanclass="named-paragraph-number">10.2</span></a></span><spanclass="plain-syntax">;</span>
<spanclass="plain-syntax"></span><spanclass="named-paragraph-container code-font"><ahref="2-ic.html#SP10_3"class="named-paragraph-link"><spanclass="named-paragraph">Assert the KD count property for I</span><spanclass="named-paragraph-number">10.3</span></a></span><spanclass="plain-syntax">;</span>
<spanclass="plain-syntax"></span><spanclass="named-paragraph-container code-font"><ahref="2-ic.html#SP10_4"class="named-paragraph-link"><spanclass="named-paragraph">Assert values of the two instance properties for I</span><spanclass="named-paragraph-number">10.4</span></a></span><spanclass="plain-syntax">;</span>
<pclass="commentary firstcommentary"><aid="SP10_1"class="paragraph-anchor"></a><b>§10.1. </b>The <spanclass="extract"><spanclass="extract-syntax">vector</span></span> property provides workspace for the relation-route-finding code
at runtime: it doesn't actually have anything to do with instance counting as
such, but then again it doesn't deserve its own section of code.
</p>
<pclass="commentary"><spanclass="named-paragraph-container code-font"><spanclass="named-paragraph-defn">Create and assert zero values of the vector property</span><spanclass="named-paragraph-number">10.1</span></span><spanclass="comment-syntax"> =</span>
<ulclass="endnotetexts"><li>This code is used in <ahref="2-ic.html#SP10">§10</a>.</li></ul>
<pclass="commentary firstcommentary"><aid="SP10_2"class="paragraph-anchor"></a><b>§10.2. </b>For each subkind of object K to which an instance I belongs, we will store the
IK-count in a numerical property. So the red car, for example, would be given two
property values: one for (red car, thing), one for (red car, vehicle). The
properties in question are the <spanclass="extract"><spanclass="extract-syntax">IK_count_prop</span></span> for thing and vehicle.
</p>
<pclass="commentary">Similarly for the next terms in the IK-sequences, where the properties are
the <spanclass="extract"><spanclass="extract-syntax">
</span></span></p>
<pclass="commentary"><spanclass="named-paragraph-container code-font"><spanclass="named-paragraph-defn">Create the two instance properties for each kind of object</span><spanclass="named-paragraph-number">10.2</span></span><spanclass="comment-syntax"> =</span>
<ulclass="endnotetexts"><li>This code is used in <ahref="2-ic.html#SP10">§10</a>.</li></ul>
<pclass="commentary firstcommentary"><aid="SP10_3"class="paragraph-anchor"></a><b>§10.3. </b>For any object instance, the property <spanclass="extract"><spanclass="extract-syntax">KD_Count</span></span> holds the KD-count for its
immediate kind. For a red car which was both vehicle and thing, therefore, this
would be the number for "vehicle", not for "thing".
</p>
<pclass="commentary"><spanclass="named-paragraph-container code-font"><spanclass="named-paragraph-defn">Assert the KD count property for I</span><spanclass="named-paragraph-number">10.3</span></span><spanclass="comment-syntax"> =</span>
<ulclass="endnotetexts"><li>This code is used in <ahref="2-ic.html#SP10">§10</a>.</li></ul>
<pclass="commentary firstcommentary"><aid="SP10_4"class="paragraph-anchor"></a><b>§10.4. </b><spanclass="named-paragraph-container code-font"><spanclass="named-paragraph-defn">Assert values of the two instance properties for I</span><spanclass="named-paragraph-number">10.4</span></span><spanclass="comment-syntax"> =</span>
<spanclass="plain-syntax"></span><spanclass="named-paragraph-container code-font"><ahref="2-ic.html#SP10_4_1"class="named-paragraph-link"><spanclass="named-paragraph">Fill in this IK-count property</span><spanclass="named-paragraph-number">10.4.1</span></a></span><spanclass="plain-syntax">;</span>
<spanclass="plain-syntax"></span><spanclass="named-paragraph-container code-font"><ahref="2-ic.html#SP10_4_2"class="named-paragraph-link"><spanclass="named-paragraph">Fill in this IK-sequence property</span><spanclass="named-paragraph-number">10.4.2</span></a></span><spanclass="plain-syntax">;</span>
<spanclass="plain-syntax"> }</span>
<spanclass="plain-syntax"> }</span>
</pre>
<ulclass="endnotetexts"><li>This code is used in <ahref="2-ic.html#SP10">§10</a>.</li></ul>
<pclass="commentary firstcommentary"><aid="SP10_4_1"class="paragraph-anchor"></a><b>§10.4.1. </b>And otherwise, for every kind that the instance belongs to (directly or
indirectly) it gets the relevant instance count as a property value. For
example, the red door might have <spanclass="extract"><spanclass="extract-syntax">IK4_Count</span></span> set to 3 — it's door number 3,
let's suppose — and <spanclass="extract"><spanclass="extract-syntax">IK2_Count</span></span> set to 19 — it's thing number 19. It doesn't
have an <spanclass="extract"><spanclass="extract-syntax">IK7_Count</span></span> property at all, since it isn't a backdrop (kind number 7),
and so on for all other kinds.
</p>
<pclass="commentary"><spanclass="named-paragraph-container code-font"><spanclass="named-paragraph-defn">Fill in this IK-count property</span><spanclass="named-paragraph-number">10.4.1</span></span><spanclass="comment-syntax"> =</span>
<ulclass="endnotetexts"><li>This code is used in <ahref="2-ic.html#SP10_4">§10.4</a>.</li></ul>
<pclass="commentary firstcommentary"><aid="SP10_4_2"class="paragraph-anchor"></a><b>§10.4.2. </b>The IK-Link property is never set for kind 0, so there's no special case. It
records the next instance in compilation order:
</p>
<pclass="commentary"><spanclass="named-paragraph-container code-font"><spanclass="named-paragraph-defn">Fill in this IK-sequence property</span><spanclass="named-paragraph-number">10.4.2</span></span><spanclass="comment-syntax"> =</span>
<ulclass="endnotetexts"><li>This code is used in <ahref="2-ic.html#SP10_4">§10.4</a>.</li></ul>
<pclass="commentary firstcommentary"><aid="SP11"class="paragraph-anchor"></a><b>§11. Loop optimisation. </b>Lastly, then, the coup de grace: here's where we define loop schemas to
perform loops through kinds quickly at run-time. We start from the First
constants, and use the Next constants to progress; and we stop at <spanclass="extract"><spanclass="extract-syntax">nothing</span></span>.
</p>
<pclass="commentary">There is no actual need to compile the schema differently in the case of
an empty loop, where there are no instances of the kind <spanclass="extract"><spanclass="extract-syntax">K</span></span> to loop over:
the regular schema would work fine. But it would make the code somehow