1
0
Fork 0
mirror of https://github.com/ganelson/inform.git synced 2024-07-08 18:14:21 +03:00
inform7/docs/core-module/16-pp.html
2019-04-22 15:42:10 +01:00

332 lines
32 KiB
HTML

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<title>16/is</title>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<meta http-equiv="Content-Language" content="en-gb">
<link href="inweb.css" rel="stylesheet" rev="stylesheet" type="text/css">
</head>
<body>
<!--Weave of '16/pp' generated by 7-->
<ul class="crumbs"><li><a href="../webs.html">&#9733;</a></li><li><a href="index.html">core</a></li><li><a href="index.html#16">Chapter 16: Inference and Model</a></li><li><b>Property Permissions</b></li></ul><p class="purpose">To enforce the domain of properties: for instance, that a door can be open or closed but that an animal cannot, or that a person can have a carrying capacity but that a door cannot.</p>
<ul class="toc"><li><a href="#SP1">&#167;1. Definitions</a></li><li><a href="#SP8">&#167;8. Searching for permission</a></li><li><a href="#SP9">&#167;9. Granting permission</a></li><li><a href="#SP10">&#167;10. Miscellaneous</a></li></ul><hr class="tocbar">
<p class="inwebparagraph"><a id="SP1"></a><b>&#167;1. Definitions. </b></p>
<p class="inwebparagraph"><a id="SP2"></a><b>&#167;2. </b>Properties are pieces of data attached to their "owners", but they also
have a common identity wherever they turn up. For example, the property
"carrying capacity" is owned by any person and also by any container, but
it has a common meaning in each case, and in each case it's a number.
</p>
<p class="inwebparagraph">Only values can own properties at run-time, but kinds can own properties
during compilation. Thus the Standard Rules declare that the kinds "person"
and "container" have a number called "carrying capacity", and we record
that as a single property which has two owners, both kinds. In the final
story file as compiled, each individual person and container then inherits
the property.
</p>
<p class="inwebparagraph">So "value" is not quite the correct concept for "something which owns a
property" &mdash; not only does that fail to allow for kinds, it also puts in
too much; the number 176 is a value, but cannot own properties. Similarly,
"specification" is far too broad a category. But "inference-subject" is
a natural choice, because actual and potential property ownership are
so closely tied together.
</p>
<p class="inwebparagraph"><a id="SP3"></a><b>&#167;3. </b>Each inference-subject (or INFS) has a list of "property permissions",
each of which gives it permission to own a given property. Each INFS can
also inherit from a more general INFS, and it gets those permissions
automatically. So every individual door has permission to have the "open"
property automatically provided that the "door" kind's INFS has such a
permission. (This prevents our memory from filling up with unnecessary
permissions.)
</p>
<p class="inwebparagraph">In addition, it's efficient for each property also to have a list of the
permissions granted for it &mdash; in effect, a "who owns me" list.
</p>
<p class="inwebparagraph">That means that whenever a new property permission is created, it must be
entered into two lists &mdash; one for the property, one for the owner.
Fortunately, permissions are never revoked.
</p>
<p class="inwebparagraph">To return to the previous example, the "carrying capacity" property would
have a list of two permissions, P_1 and P_2. P_1 would also be found
in the list of permission for the INFS representing the kind "person",
and P_2 in the corresponding list for "container".
</p>
<p class="inwebparagraph">This doubled indexing is a tacit form of multiple-inheritance, even though
Inform 7 is officially a single-inheritance language from an objects-and-classes
point of view: "person" is not a kind of "container", nor vice versa,
but both effectively inherit the same behaviour to do with carrying capacity.
</p>
<p class="inwebparagraph"><a id="SP4"></a><b>&#167;4. </b>Complicating matters, plugins have the ability to attach data of their
own to a permission. For instance, the "parsing" plugin attaches the idea
of a property being visible &mdash; we might say that every thing has an
interior colour, but that it is invisible in the case of a dog and visible
in the case of a broken jar. Because of this, we need to make it possible
for the same property to have multiple permissions in the inheritance
hierarchy above a single point: the jar has a permission for "interior
colour" of its own, even though it inherits this permission from "thing"
in any case.
</p>
<p class="inwebparagraph"><a id="SP5"></a><b>&#167;5. </b>Anyway, here is a property permission:
</p>
<pre class="display">
<span class="reserved">typedef</span><span class="plain"> </span><span class="reserved">struct</span><span class="plain"> </span><span class="reserved">property_permission</span><span class="plain"> {</span>
<span class="reserved">struct</span><span class="plain"> </span><span class="reserved">inference_subject</span><span class="plain"> *</span><span class="identifier">property_owner</span><span class="plain">; </span> <span class="comment">to whom permission is granted</span>
<span class="reserved">struct</span><span class="plain"> </span><span class="reserved">property_permission</span><span class="plain"> *</span><span class="identifier">next_for_this_owner</span><span class="plain">; </span> <span class="comment">in list of permissions</span>
<span class="reserved">struct</span><span class="plain"> </span><span class="reserved">property</span><span class="plain"> *</span><span class="identifier">property_granted</span><span class="plain">; </span> <span class="comment">which property is permitted</span>
<span class="reserved">struct</span><span class="plain"> </span><span class="reserved">property_permission</span><span class="plain"> *</span><span class="identifier">next_for_this_property</span><span class="plain">; </span> <span class="comment">in list of permissions</span>
<span class="reserved">struct</span><span class="plain"> </span><span class="identifier">parse_node</span><span class="plain"> *</span><span class="identifier">where_granted</span><span class="plain">; </span> <span class="comment">sentence granting the permission</span>
<span class="reserved">struct</span><span class="plain"> </span><span class="identifier">general_pointer</span><span class="plain"> </span><span class="identifier">pp_storage_data</span><span class="plain">; </span> <span class="comment">how we'll compile this at run-time</span>
<span class="reserved">void</span><span class="plain"> *</span><span class="identifier">plugin_pp</span><span class="plain">[</span><span class="constant">MAX_PLUGINS</span><span class="plain">]; </span> <span class="comment">storage for plugins to attach, if they want to</span>
<span class="identifier">MEMORY_MANAGEMENT</span>
<span class="plain">} </span><span class="reserved">property_permission</span><span class="plain">;</span>
</pre>
<p class="inwebparagraph"></p>
<p class="endnote">The structure property_permission is accessed in 15/pr and here.</p>
<p class="inwebparagraph"><a id="SP6"></a><b>&#167;6. </b>These macros simply provide access to plugin data, exactly as for world
objects.
</p>
<pre class="definitions">
<span class="definitionkeyword">define</span> <span class="identifier">PLUGIN_PP</span><span class="plain">(</span><span class="identifier">id</span><span class="plain">, </span><span class="identifier">pp</span><span class="plain">)</span>
<span class="plain">((</span><span class="identifier">id</span><span class="plain">##</span><span class="identifier">_pp_data</span><span class="plain"> *) </span><span class="identifier">pp</span><span class="plain">-</span><span class="element">&gt;plugin_pp</span><span class="plain">[</span><span class="identifier">id</span><span class="plain">##</span><span class="identifier">_plugin</span><span class="plain">-&gt;</span><span class="identifier">allocation_id</span><span class="plain">])</span>
<span class="definitionkeyword">define</span> <span class="identifier">CREATE_PLUGIN_PP_DATA</span><span class="plain">(</span><span class="identifier">id</span><span class="plain">, </span><span class="identifier">pp</span><span class="plain">, </span><span class="identifier">creator</span><span class="plain">)</span>
<span class="plain">(</span><span class="identifier">pp</span><span class="plain">)-</span><span class="element">&gt;plugin_pp</span><span class="plain">[</span><span class="identifier">id</span><span class="plain">##</span><span class="identifier">_plugin</span><span class="plain">-&gt;</span><span class="identifier">allocation_id</span><span class="plain">] = (</span><span class="reserved">void</span><span class="plain"> *) (</span><span class="identifier">creator</span><span class="plain">(</span><span class="identifier">pp</span><span class="plain">));</span>
</pre>
<p class="inwebparagraph"><a id="SP7"></a><b>&#167;7. </b>This loop trawls through the two cross-lists:
</p>
<pre class="definitions">
<span class="definitionkeyword">define</span> <span class="identifier">LOOP_OVER_PERMISSIONS_FOR_PROPERTY</span><span class="plain">(</span><span class="identifier">pp</span><span class="plain">, </span><span class="identifier">prn</span><span class="plain">)</span>
<span class="reserved">for</span><span class="plain"> (</span><span class="identifier">pp</span><span class="plain"> = </span><span class="functiontext">Properties::permission_list</span><span class="plain">(</span><span class="identifier">prn</span><span class="plain">); </span><span class="identifier">pp</span><span class="plain">; </span><span class="identifier">pp</span><span class="plain"> = </span><span class="identifier">pp</span><span class="plain">-</span><span class="element">&gt;next_for_this_property</span><span class="plain">)</span>
<span class="definitionkeyword">define</span> <span class="identifier">LOOP_OVER_PERMISSIONS_FOR_INFS</span><span class="plain">(</span><span class="identifier">pp</span><span class="plain">, </span><span class="identifier">infs</span><span class="plain">)</span>
<span class="reserved">for</span><span class="plain"> (</span><span class="identifier">pp</span><span class="plain"> = *(</span><span class="functiontext">InferenceSubjects::get_permissions</span><span class="plain">(</span><span class="identifier">infs</span><span class="plain">)); </span><span class="identifier">pp</span><span class="plain">; </span><span class="identifier">pp</span><span class="plain"> = </span><span class="identifier">pp</span><span class="plain">-</span><span class="element">&gt;next_for_this_owner</span><span class="plain">)</span>
</pre>
<p class="inwebparagraph"><a id="SP8"></a><b>&#167;8. Searching for permission. </b>Note that an either/or property and its antonym (say, "open" and "closed")
are equivalent here: to find one is to find the other.
</p>
<p class="inwebparagraph">If these were long lists, or searched often, it would be faster to move each
found permission to the front, thus tending to move frequently-sought properties
to the start. But profiling shows that this would save no significant time,
whereas the unpredictable order might make the Index or SHOWME output harder
to verify with <code class="display"><span class="extract">intest</span></code>.
</p>
<pre class="display">
<span class="reserved">property_permission</span><span class="plain"> *</span><span class="functiontext">World::Permissions::find</span><span class="plain">(</span><span class="reserved">inference_subject</span><span class="plain"> *</span><span class="identifier">infs</span><span class="plain">,</span>
<span class="reserved">property</span><span class="plain"> *</span><span class="identifier">prn</span><span class="plain">, </span><span class="reserved">int</span><span class="plain"> </span><span class="identifier">allow_inheritance</span><span class="plain">) {</span>
<span class="reserved">property</span><span class="plain"> *</span><span class="identifier">prnbar</span><span class="plain"> = </span><span class="identifier">NULL</span><span class="plain">;</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="functiontext">Properties::is_either_or</span><span class="plain">(</span><span class="identifier">prn</span><span class="plain">)) </span><span class="identifier">prnbar</span><span class="plain"> = </span><span class="functiontext">Properties::EitherOr::get_negation</span><span class="plain">(</span><span class="identifier">prn</span><span class="plain">);</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">prn</span><span class="plain">)</span>
<span class="reserved">while</span><span class="plain"> (</span><span class="identifier">infs</span><span class="plain">) {</span>
<span class="reserved">property_permission</span><span class="plain"> *</span><span class="identifier">pp</span><span class="plain">;</span>
<span class="identifier">LOOP_OVER_PERMISSIONS_FOR_INFS</span><span class="plain">(</span><span class="identifier">pp</span><span class="plain">, </span><span class="identifier">infs</span><span class="plain">)</span>
<span class="reserved">if</span><span class="plain"> ((</span><span class="identifier">pp</span><span class="plain">-</span><span class="element">&gt;property_granted</span><span class="plain"> == </span><span class="identifier">prn</span><span class="plain">) || (</span><span class="identifier">pp</span><span class="plain">-</span><span class="element">&gt;property_granted</span><span class="plain"> == </span><span class="identifier">prnbar</span><span class="plain">))</span>
<span class="reserved">return</span><span class="plain"> </span><span class="identifier">pp</span><span class="plain">;</span>
<span class="identifier">infs</span><span class="plain"> = (</span><span class="identifier">allow_inheritance</span><span class="plain">)?(</span><span class="functiontext">InferenceSubjects::narrowest_broader_subject</span><span class="plain">(</span><span class="identifier">infs</span><span class="plain">)):</span><span class="identifier">NULL</span><span class="plain">;</span>
<span class="plain">}</span>
<span class="reserved">return</span><span class="plain"> </span><span class="identifier">NULL</span><span class="plain">;</span>
<span class="plain">}</span>
</pre>
<p class="inwebparagraph"></p>
<p class="endnote">The function World::Permissions::find is used in <a href="#SP9">&#167;9</a>, 9/imp (<a href="9-imp.html#SP7_1_1">&#167;7.1.1</a>), 14/ds2 (<a href="14-ds2.html#SP11_9_1_1_5_1_3">&#167;11.9.1.1.5.1.3</a>, <a href="14-ds2.html#SP11_9_1_2_3">&#167;11.9.1.2.3</a>), 15/ia (<a href="15-ia.html#SP2">&#167;2</a>), 15/tpr (<a href="15-tpr.html#SP7_2">&#167;7.2</a>), 16/in (<a href="16-in.html#SP16">&#167;16</a>, <a href="16-in.html#SP17">&#167;17</a>), 16/cmw (<a href="16-cmw.html#SP1_2_1">&#167;1.2.1</a>).</p>
<p class="inwebparagraph"><a id="SP9"></a><b>&#167;9. Granting permission. </b>This does nothing if permission already exists, simply returning the existing
permission structure; but note the use of <code class="display"><span class="extract">allow_inheritance</span></code>. If this is
set to <code class="display"><span class="extract">FALSE</span></code>, and we call for the "carrying capacity" property of the
player (say), then we may create a new permission even though the player's
kind ("person") already has one. This is intentional &mdash; it makes it possible
for a property to have different characteristics (say, visibility in the
parser) for some of its owners as compared with others.
</p>
<pre class="display">
<span class="reserved">property_permission</span><span class="plain"> *</span><span class="functiontext">World::Permissions::grant</span><span class="plain">(</span><span class="reserved">inference_subject</span><span class="plain"> *</span><span class="identifier">infs</span><span class="plain">, </span><span class="reserved">property</span><span class="plain"> *</span><span class="identifier">prn</span><span class="plain">,</span>
<span class="reserved">int</span><span class="plain"> </span><span class="identifier">allow_inheritance</span><span class="plain">) {</span>
<span class="reserved">property_permission</span><span class="plain"> *</span><span class="identifier">new_pp</span><span class="plain"> = </span><span class="functiontext">World::Permissions::find</span><span class="plain">(</span><span class="identifier">infs</span><span class="plain">, </span><span class="identifier">prn</span><span class="plain">, </span><span class="identifier">allow_inheritance</span><span class="plain">);</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">new_pp</span><span class="plain"> == </span><span class="identifier">NULL</span><span class="plain">) {</span>
<span class="identifier">LOGIF</span><span class="plain">(</span><span class="identifier">PROPERTY_PROVISION</span><span class="plain">, </span><span class="string">"Allowing $j to provide $Y\</span><span class="plain">n</span><span class="string">"</span><span class="plain">, </span><span class="identifier">infs</span><span class="plain">, </span><span class="identifier">prn</span><span class="plain">);</span>
&lt;<span class="cwebmacro">Create the new permission structure</span> <span class="cwebmacronumber">9.1</span>&gt;<span class="plain">;</span>
&lt;<span class="cwebmacro">Add the new permission to the owner's list</span> <span class="cwebmacronumber">9.2</span>&gt;<span class="character">;</span>
&lt;<span class="cwebmacro">Add the new permission to the property's list</span> <span class="cwebmacronumber">9.3</span>&gt;<span class="character">;</span>
&lt;<span class="cwebmacro">Notify plugins that a new permission has been issued</span> <span class="cwebmacronumber">9.4</span>&gt;<span class="plain">;</span>
<span class="plain">}</span>
<span class="reserved">return</span><span class="plain"> </span><span class="identifier">new_pp</span><span class="plain">;</span>
<span class="plain">}</span>
</pre>
<p class="inwebparagraph"></p>
<p class="endnote">The function World::Permissions::grant is used in 15/pr (<a href="15-pr.html#SP5_6">&#167;5.6</a>), 15/tpr (<a href="15-tpr.html#SP6">&#167;6</a>).</p>
<p class="inwebparagraph"><a id="SP9_1"></a><b>&#167;9.1. </b><code class="display">
&lt;<span class="cwebmacrodefn">Create the new permission structure</span> <span class="cwebmacronumber">9.1</span>&gt; =
</code></p>
<pre class="displaydefn">
<span class="identifier">new_pp</span><span class="plain"> = </span><span class="identifier">CREATE</span><span class="plain">(</span><span class="reserved">property_permission</span><span class="plain">);</span>
<span class="identifier">new_pp</span><span class="plain">-</span><span class="element">&gt;where_granted</span><span class="plain"> = </span><span class="identifier">current_sentence</span><span class="plain">;</span>
<span class="identifier">new_pp</span><span class="plain">-</span><span class="element">&gt;pp_storage_data</span><span class="plain"> = </span><span class="functiontext">InferenceSubjects::new_permission_granted</span><span class="plain">(</span><span class="identifier">infs</span><span class="plain">);</span>
</pre>
<p class="inwebparagraph"></p>
<p class="endnote">This code is used in <a href="#SP9">&#167;9</a>.</p>
<p class="inwebparagraph"><a id="SP9_2"></a><b>&#167;9.2. </b><code class="display">
&lt;<span class="cwebmacrodefn">Add the new permission to the owner's list</span> <span class="cwebmacronumber">9.2</span>&gt; =
</code></p>
<pre class="displaydefn">
<span class="identifier">new_pp</span><span class="plain">-</span><span class="element">&gt;property_owner</span><span class="plain"> = </span><span class="identifier">infs</span><span class="plain">;</span>
<span class="reserved">property_permission</span><span class="plain"> **</span><span class="identifier">ppl</span><span class="plain"> = </span><span class="functiontext">InferenceSubjects::get_permissions</span><span class="plain">(</span><span class="identifier">infs</span><span class="plain">);</span>
<span class="reserved">if</span><span class="plain"> (*</span><span class="identifier">ppl</span><span class="plain"> == </span><span class="identifier">NULL</span><span class="plain">) *</span><span class="identifier">ppl</span><span class="plain"> = </span><span class="identifier">new_pp</span><span class="plain">;</span>
<span class="reserved">else</span><span class="plain"> {</span>
<span class="reserved">property_permission</span><span class="plain"> *</span><span class="identifier">pp</span><span class="plain"> = *</span><span class="identifier">ppl</span><span class="plain">;</span>
<span class="reserved">while</span><span class="plain"> (</span><span class="identifier">pp</span><span class="plain">-</span><span class="element">&gt;next_for_this_owner</span><span class="plain">) </span><span class="identifier">pp</span><span class="plain"> = </span><span class="identifier">pp</span><span class="plain">-</span><span class="element">&gt;next_for_this_owner</span><span class="plain">;</span>
<span class="identifier">pp</span><span class="plain">-</span><span class="element">&gt;next_for_this_owner</span><span class="plain"> = </span><span class="identifier">new_pp</span><span class="plain">;</span>
<span class="plain">}</span>
<span class="identifier">new_pp</span><span class="plain">-</span><span class="element">&gt;next_for_this_owner</span><span class="plain"> = </span><span class="identifier">NULL</span><span class="plain">;</span>
</pre>
<p class="inwebparagraph"></p>
<p class="endnote">This code is used in <a href="#SP9">&#167;9</a>.</p>
<p class="inwebparagraph"><a id="SP9_3"></a><b>&#167;9.3. </b><code class="display">
&lt;<span class="cwebmacrodefn">Add the new permission to the property's list</span> <span class="cwebmacronumber">9.3</span>&gt; =
</code></p>
<pre class="displaydefn">
<span class="identifier">new_pp</span><span class="plain">-</span><span class="element">&gt;property_granted</span><span class="plain"> = </span><span class="identifier">prn</span><span class="plain">;</span>
<span class="reserved">property_permission</span><span class="plain"> *</span><span class="identifier">pp</span><span class="plain"> = </span><span class="functiontext">Properties::permission_list</span><span class="plain">(</span><span class="identifier">prn</span><span class="plain">);</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">pp</span><span class="plain"> == </span><span class="identifier">NULL</span><span class="plain">) {</span>
<span class="functiontext">Properties::set_permission_list</span><span class="plain">(</span><span class="identifier">prn</span><span class="plain">, </span><span class="identifier">new_pp</span><span class="plain">);</span>
<span class="plain">} </span><span class="reserved">else</span><span class="plain"> {</span>
<span class="reserved">while</span><span class="plain"> (</span><span class="identifier">pp</span><span class="plain">-</span><span class="element">&gt;next_for_this_property</span><span class="plain"> != </span><span class="identifier">NULL</span><span class="plain">) </span><span class="identifier">pp</span><span class="plain"> = </span><span class="identifier">pp</span><span class="plain">-</span><span class="element">&gt;next_for_this_property</span><span class="plain">;</span>
<span class="identifier">pp</span><span class="plain">-</span><span class="element">&gt;next_for_this_property</span><span class="plain"> = </span><span class="identifier">new_pp</span><span class="plain">;</span>
<span class="plain">}</span>
<span class="identifier">new_pp</span><span class="plain">-</span><span class="element">&gt;next_for_this_property</span><span class="plain"> = </span><span class="identifier">NULL</span><span class="plain">;</span>
</pre>
<p class="inwebparagraph"></p>
<p class="endnote">This code is used in <a href="#SP9">&#167;9</a>.</p>
<p class="inwebparagraph"><a id="SP9_4"></a><b>&#167;9.4. </b><code class="display">
&lt;<span class="cwebmacrodefn">Notify plugins that a new permission has been issued</span> <span class="cwebmacronumber">9.4</span>&gt; =
</code></p>
<pre class="displaydefn">
<span class="reserved">int</span><span class="plain"> </span><span class="identifier">i</span><span class="plain">;</span>
<span class="reserved">for</span><span class="plain"> (</span><span class="identifier">i</span><span class="plain">=0; </span><span class="identifier">i</span><span class="plain">&lt;</span><span class="constant">MAX_PLUGINS</span><span class="plain">; </span><span class="identifier">i</span><span class="plain">++) </span><span class="identifier">new_pp</span><span class="plain">-</span><span class="element">&gt;plugin_pp</span><span class="plain">[</span><span class="identifier">i</span><span class="plain">] = </span><span class="identifier">NULL</span><span class="plain">;</span>
<span class="functiontext">Plugins::Call::new_permission_notify</span><span class="plain">(</span><span class="identifier">new_pp</span><span class="plain">);</span>
</pre>
<p class="inwebparagraph"></p>
<p class="endnote">This code is used in <a href="#SP9">&#167;9</a>.</p>
<p class="inwebparagraph"><a id="SP10"></a><b>&#167;10. Miscellaneous. </b>With the two fundamental operations out of the way, there's not much left
to do except provide access to the details of the permission.
</p>
<pre class="display">
<span class="reserved">property</span><span class="plain"> *</span><span class="functiontext">World::Permissions::get_property</span><span class="plain">(</span><span class="reserved">property_permission</span><span class="plain"> *</span><span class="identifier">pp</span><span class="plain">) {</span>
<span class="reserved">return</span><span class="plain"> </span><span class="identifier">pp</span><span class="plain">-</span><span class="element">&gt;property_granted</span><span class="plain">;</span>
<span class="plain">}</span>
<span class="reserved">inference_subject</span><span class="plain"> *</span><span class="functiontext">World::Permissions::get_subject</span><span class="plain">(</span><span class="reserved">property_permission</span><span class="plain"> *</span><span class="identifier">pp</span><span class="plain">) {</span>
<span class="reserved">return</span><span class="plain"> </span><span class="identifier">pp</span><span class="plain">-</span><span class="element">&gt;property_owner</span><span class="plain">;</span>
<span class="plain">}</span>
<span class="identifier">general_pointer</span><span class="plain"> </span><span class="functiontext">World::Permissions::get_storage_data</span><span class="plain">(</span><span class="reserved">property_permission</span><span class="plain"> *</span><span class="identifier">pp</span><span class="plain">) {</span>
<span class="reserved">return</span><span class="plain"> </span><span class="identifier">pp</span><span class="plain">-</span><span class="element">&gt;pp_storage_data</span><span class="plain">;</span>
<span class="plain">}</span>
<span class="identifier">parse_node</span><span class="plain"> *</span><span class="functiontext">World::Permissions::where_granted</span><span class="plain">(</span><span class="reserved">property_permission</span><span class="plain"> *</span><span class="identifier">pp</span><span class="plain">) {</span>
<span class="reserved">return</span><span class="plain"> </span><span class="identifier">pp</span><span class="plain">-</span><span class="element">&gt;where_granted</span><span class="plain">;</span>
<span class="plain">}</span>
</pre>
<p class="inwebparagraph"></p>
<p class="endnote">The function World::Permissions::get_property is used in 15/pov (<a href="15-pov.html#SP4">&#167;4</a>), 15/epv (<a href="15-epv.html#SP1_1_4">&#167;1.1.4</a>).</p>
<p class="endnote">The function World::Permissions::get_subject is used in <a href="#SP11">&#167;11</a>, 5/ins (<a href="5-ins.html#SP11">&#167;11</a>), 15/epv (<a href="15-epv.html#SP3_1">&#167;3.1</a>).</p>
<p class="endnote">The function World::Permissions::get_storage_data is used in 15/pov (<a href="15-pov.html#SP3">&#167;3</a>).</p>
<p class="endnote">The function World::Permissions::where_granted is used in 15/pov (<a href="15-pov.html#SP4_1">&#167;4.1</a>).</p>
<p class="inwebparagraph"><a id="SP11"></a><b>&#167;11. </b>A case where it's convenient to run through permissions for a given
property &mdash; when indexing who can own it.
</p>
<pre class="display">
<span class="reserved">void</span><span class="plain"> </span><span class="functiontext">World::Permissions::index</span><span class="plain">(</span><span class="identifier">OUTPUT_STREAM</span><span class="plain">, </span><span class="reserved">property</span><span class="plain"> *</span><span class="identifier">prn</span><span class="plain">) {</span>
<span class="reserved">int</span><span class="plain"> </span><span class="identifier">ac</span><span class="plain"> = 0, </span><span class="identifier">s</span><span class="plain">;</span>
<span class="reserved">for</span><span class="plain"> (</span><span class="identifier">s</span><span class="plain"> = 1; </span><span class="identifier">s</span><span class="plain"> &lt;= 2; </span><span class="identifier">s</span><span class="plain">++) {</span>
<span class="reserved">property_permission</span><span class="plain"> *</span><span class="identifier">pp</span><span class="plain">;</span>
<span class="identifier">LOOP_OVER_PERMISSIONS_FOR_PROPERTY</span><span class="plain">(</span><span class="identifier">pp</span><span class="plain">, </span><span class="identifier">prn</span><span class="plain">) {</span>
<span class="identifier">wording</span><span class="plain"> </span><span class="identifier">W</span><span class="plain"> = </span><span class="functiontext">InferenceSubjects::get_name_text</span><span class="plain">(</span><span class="functiontext">World::Permissions::get_subject</span><span class="plain">(</span><span class="identifier">pp</span><span class="plain">));</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">Wordings::nonempty</span><span class="plain">(</span><span class="identifier">W</span><span class="plain">)) {</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">s</span><span class="plain"> == 1) </span><span class="identifier">ac</span><span class="plain">++;</span>
<span class="reserved">else</span><span class="plain"> {</span>
<span class="identifier">WRITE</span><span class="plain">(</span><span class="string">"&lt;/i&gt;%+W&lt;i&gt;"</span><span class="plain">, </span><span class="identifier">W</span><span class="plain">);</span>
<span class="identifier">ac</span><span class="plain">--;</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">ac</span><span class="plain"> == 1) </span><span class="identifier">WRITE</span><span class="plain">(</span><span class="string">" or "</span><span class="plain">);</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">ac</span><span class="plain"> &gt; 1) </span><span class="identifier">WRITE</span><span class="plain">(</span><span class="string">", "</span><span class="plain">);</span>
<span class="plain">}</span>
<span class="plain">}</span>
<span class="plain">}</span>
<span class="plain">}</span>
<span class="plain">}</span>
</pre>
<p class="inwebparagraph"></p>
<p class="endnote">The function World::Permissions::index is used in 5/ins (<a href="5-ins.html#SP37">&#167;37</a>), 15/ep (<a href="15-ep.html#SP17">&#167;17</a>).</p>
<hr class="tocbar">
<ul class="toc"><li><a href="16-is.html">Back to 'Inference Subjects'</a></li><li><a href="16-in.html">Continue with 'Inferences'</a></li></ul><hr class="tocbar">
<!--End of weave-->
</body>
</html>