mirror of
https://github.com/ganelson/inform.git
synced 2024-07-08 01:54:21 +03:00
303 lines
42 KiB
HTML
303 lines
42 KiB
HTML
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
|
|
<html>
|
|
<head>
|
|
<title>Plugin Manager</title>
|
|
<link href="../docs-assets/Breadcrumbs.css" rel="stylesheet" rev="stylesheet" type="text/css">
|
|
<meta name="viewport" content="width=device-width initial-scale=1">
|
|
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
|
|
<meta http-equiv="Content-Language" content="en-gb">
|
|
|
|
<link href="../docs-assets/Contents.css" rel="stylesheet" rev="stylesheet" type="text/css">
|
|
<link href="../docs-assets/Progress.css" rel="stylesheet" rev="stylesheet" type="text/css">
|
|
<link href="../docs-assets/Navigation.css" rel="stylesheet" rev="stylesheet" type="text/css">
|
|
<link href="../docs-assets/Fonts.css" rel="stylesheet" rev="stylesheet" type="text/css">
|
|
<link href="../docs-assets/Base.css" rel="stylesheet" rev="stylesheet" type="text/css">
|
|
<script>
|
|
function togglePopup(material_id) {
|
|
var popup = document.getElementById(material_id);
|
|
popup.classList.toggle("show");
|
|
}
|
|
</script>
|
|
|
|
<link href="../docs-assets/Popups.css" rel="stylesheet" rev="stylesheet" type="text/css">
|
|
<link href="../docs-assets/Colours.css" rel="stylesheet" rev="stylesheet" type="text/css">
|
|
<link href="../docs-assets/Preform-Colours.css" rel="stylesheet" rev="stylesheet" type="text/css">
|
|
|
|
</head>
|
|
<body class="commentary-font">
|
|
<nav role="navigation">
|
|
<h1><a href="../index.html">
|
|
<img src="../docs-assets/Inform.png" height=72">
|
|
</a></h1>
|
|
<ul><li><a href="../index.html">home</a></li>
|
|
</ul><h2>Compiler</h2><ul>
|
|
<li><a href="../structure.html">structure</a></li>
|
|
<li><a href="../inbuildn.html">inbuild</a></li>
|
|
<li><a href="../inform7n.html">inform7</a></li>
|
|
<li><a href="../intern.html">inter</a></li>
|
|
<li><a href="../services.html">services</a></li>
|
|
<li><a href="../secrets.html">secrets</a></li>
|
|
</ul><h2>Other Tools</h2><ul>
|
|
<li><a href="../inblorbn.html">inblorb</a></li>
|
|
<li><a href="../indocn.html">indoc</a></li>
|
|
<li><a href="../inform6.html">inform6</a></li>
|
|
<li><a href="../inpolicyn.html">inpolicy</a></li>
|
|
<li><a href="../inrtpsn.html">inrtps</a></li>
|
|
</ul><h2>Resources</h2><ul>
|
|
<li><a href="../extensions.html">extensions</a></li>
|
|
<li><a href="../kits.html">kits</a></li>
|
|
</ul><h2>Repository</h2><ul>
|
|
<li><a href="https://github.com/ganelson/inform"><img src="../docs-assets/github.png" height=18> github</a></li>
|
|
</ul><h2>Related Projects</h2><ul>
|
|
<li><a href="../../../inweb/index.html">inweb</a></li>
|
|
<li><a href="../../../intest/index.html">intest</a></li>
|
|
|
|
</ul>
|
|
</nav>
|
|
<main role="main">
|
|
<!--Weave of 'Plugin Manager' generated by Inweb-->
|
|
<div class="breadcrumbs">
|
|
<ul class="crumbs"><li><a href="../index.html">Home</a></li><li><a href="../inform7n.html">Inform7</a></li><li><a href="index.html">core</a></li><li><a href="index.html#3">Chapter 3: Plugins</a></li><li><b>Plugin Manager</b></li></ul></div>
|
|
<p class="purpose">Creating, activating or deactivating plugins.</p>
|
|
|
|
<p class="commentary firstcommentary"><a id="SP1" class="paragraph-anchor"></a><b>§1. </b>Plugins are optional extras for the Inform compiler: additions which can be
|
|
active or inactive on any given compilation run.
|
|
</p>
|
|
|
|
<p class="commentary">Except for one not-really-a-plugin called "core", each plugin is a piece of
|
|
functionality that can be "activated" or "deactivated". Plugins have an
|
|
ability to tweak or extend what the compiler does, giving it, for example,
|
|
an ability to reason about spatial relationships when the compiler is being
|
|
used for interactive fiction; or not, when it isn't.
|
|
</p>
|
|
|
|
<p class="commentary">There is no harm in this hard-wired maximum, since plugins are not things an
|
|
author can create in source text; we know exactly how many there are.
|
|
</p>
|
|
|
|
<pre class="definitions code-font"><span class="definition-keyword">define</span> <span class="constant-syntax">MAX_PLUGINS</span><span class="plain-syntax"> </span><span class="constant-syntax">32</span>
|
|
</pre>
|
|
<pre class="displayed-code all-displayed-code code-font">
|
|
<span class="reserved-syntax">typedef</span><span class="plain-syntax"> </span><span class="reserved-syntax">struct</span><span class="plain-syntax"> </span><span class="reserved-syntax">plugin</span><span class="plain-syntax"> {</span>
|
|
<span class="plain-syntax"> </span><span class="reserved-syntax">struct</span><span class="plain-syntax"> </span><span class="identifier-syntax">text_stream</span><span class="plain-syntax"> *</span><span class="identifier-syntax">textual_name</span><span class="plain-syntax">;</span>
|
|
<span class="plain-syntax"> </span><span class="reserved-syntax">struct</span><span class="plain-syntax"> </span><span class="identifier-syntax">wording</span><span class="plain-syntax"> </span><span class="identifier-syntax">wording_name</span><span class="plain-syntax">;</span>
|
|
<span class="plain-syntax"> </span><span class="reserved-syntax">struct</span><span class="plain-syntax"> </span><span class="reserved-syntax">plugin</span><span class="plain-syntax"> *</span><span class="identifier-syntax">parent_plugin</span><span class="plain-syntax">;</span>
|
|
<span class="plain-syntax"> </span><span class="reserved-syntax">void</span><span class="plain-syntax"> (*</span><span class="identifier-syntax">activation_function</span><span class="plain-syntax">)(</span><span class="reserved-syntax">void</span><span class="plain-syntax">);</span>
|
|
<span class="plain-syntax"> </span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">active</span><span class="plain-syntax">;</span>
|
|
<span class="plain-syntax"> </span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">permanently_active</span><span class="plain-syntax">;</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">CLASS_DEFINITION</span>
|
|
<span class="plain-syntax">} </span><span class="reserved-syntax">plugin</span><span class="plain-syntax">;</span>
|
|
|
|
<span class="reserved-syntax">plugin</span><span class="plain-syntax"> *</span><span class="function-syntax">PluginManager::new</span><button class="popup" onclick="togglePopup('usagePopup1')"><span class="comment-syntax">?</span><span class="popuptext" id="usagePopup1">Usage of <span class="code-font"><span class="function-syntax">PluginManager::new</span></span>:<br/>Core Module - <a href="1-cm.html#SP2">§2</a></span></button><span class="plain-syntax">(</span><span class="reserved-syntax">void</span><span class="plain-syntax"> (*</span><span class="identifier-syntax">starter</span><span class="plain-syntax">)(</span><span class="reserved-syntax">void</span><span class="plain-syntax">), </span><span class="identifier-syntax">text_stream</span><span class="plain-syntax"> *</span><span class="identifier-syntax">tname</span><span class="plain-syntax">, </span><span class="reserved-syntax">plugin</span><span class="plain-syntax"> *</span><span class="identifier-syntax">set</span><span class="plain-syntax">) {</span>
|
|
<span class="plain-syntax"> </span><span class="reserved-syntax">plugin</span><span class="plain-syntax"> *</span><span class="identifier-syntax">P</span><span class="plain-syntax"> = </span><span class="identifier-syntax">CREATE</span><span class="plain-syntax">(</span><span class="reserved-syntax">plugin</span><span class="plain-syntax">);</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">P</span><span class="plain-syntax">-></span><span class="element-syntax">textual_name</span><span class="plain-syntax"> = </span><span class="identifier-syntax">Str::duplicate</span><span class="plain-syntax">(</span><span class="identifier-syntax">tname</span><span class="plain-syntax">);</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">P</span><span class="plain-syntax">-></span><span class="element-syntax">wording_name</span><span class="plain-syntax"> = </span><span class="identifier-syntax">Feeds::feed_text</span><span class="plain-syntax">(</span><span class="identifier-syntax">tname</span><span class="plain-syntax">);</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">P</span><span class="plain-syntax">-></span><span class="element-syntax">activation_function</span><span class="plain-syntax"> = </span><span class="identifier-syntax">starter</span><span class="plain-syntax">;</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">P</span><span class="plain-syntax">-></span><span class="element-syntax">active</span><span class="plain-syntax"> = </span><span class="identifier-syntax">FALSE</span><span class="plain-syntax">;</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">P</span><span class="plain-syntax">-></span><span class="element-syntax">parent_plugin</span><span class="plain-syntax"> = </span><span class="identifier-syntax">set</span><span class="plain-syntax">;</span>
|
|
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">P</span><span class="plain-syntax">-></span><span class="identifier-syntax">allocation_id</span><span class="plain-syntax"> >= </span><span class="constant-syntax">MAX_PLUGINS</span><span class="plain-syntax">) </span><span class="identifier-syntax">internal_error</span><span class="plain-syntax">(</span><span class="string-syntax">"Too many plugins"</span><span class="plain-syntax">);</span>
|
|
<span class="plain-syntax"> </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><span class="identifier-syntax">P</span><span class="plain-syntax">;</span>
|
|
<span class="plain-syntax">}</span>
|
|
</pre>
|
|
<ul class="endnotetexts"><li>The structure plugin is private to this section.</li></ul>
|
|
<p class="commentary firstcommentary"><a id="SP2" class="paragraph-anchor"></a><b>§2. </b>An inactive plugin does nothing; it's as if that section of code were not in
|
|
the compiler at all.
|
|
</p>
|
|
|
|
<pre class="displayed-code all-displayed-code code-font">
|
|
<span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="function-syntax">PluginManager::active</span><span class="plain-syntax">(</span><span class="reserved-syntax">plugin</span><span class="plain-syntax"> *</span><span class="identifier-syntax">P</span><span class="plain-syntax">) {</span>
|
|
<span class="plain-syntax"> </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><span class="identifier-syntax">P</span><span class="plain-syntax">-></span><span class="element-syntax">active</span><span class="plain-syntax">;</span>
|
|
<span class="plain-syntax">}</span>
|
|
|
|
<span class="reserved-syntax">void</span><span class="plain-syntax"> </span><span class="function-syntax">PluginManager::list_plugins</span><span class="plain-syntax">(</span><span class="identifier-syntax">OUTPUT_STREAM</span><span class="plain-syntax">, </span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">state</span><span class="plain-syntax">) {</span>
|
|
<span class="plain-syntax"> </span><span class="reserved-syntax">plugin</span><span class="plain-syntax"> *</span><span class="identifier-syntax">P</span><span class="plain-syntax">;</span>
|
|
<span class="plain-syntax"> </span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">c</span><span class="plain-syntax"> = </span><span class="constant-syntax">0</span><span class="plain-syntax">;</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">LOOP_OVER</span><span class="plain-syntax">(</span><span class="identifier-syntax">P</span><span class="plain-syntax">, </span><span class="reserved-syntax">plugin</span><span class="plain-syntax">) </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">P</span><span class="plain-syntax">-></span><span class="element-syntax">active</span><span class="plain-syntax"> == </span><span class="identifier-syntax">state</span><span class="plain-syntax">) {</span>
|
|
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">c</span><span class="plain-syntax"> > </span><span class="constant-syntax">0</span><span class="plain-syntax">) </span><span class="identifier-syntax">WRITE</span><span class="plain-syntax">(</span><span class="string-syntax">", "</span><span class="plain-syntax">);</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">WRITE</span><span class="plain-syntax">(</span><span class="string-syntax">"%S"</span><span class="plain-syntax">, </span><span class="identifier-syntax">P</span><span class="plain-syntax">-></span><span class="element-syntax">textual_name</span><span class="plain-syntax">);</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">c</span><span class="plain-syntax">++;</span>
|
|
<span class="plain-syntax"> }</span>
|
|
<span class="plain-syntax">}</span>
|
|
</pre>
|
|
<p class="commentary firstcommentary"><a id="SP3" class="paragraph-anchor"></a><b>§3. </b>In the code above, plugins are set up as inactive by default — even "core",
|
|
which the compiler absolutely cannot live without. So <a href="../supervisor-module/5-ps2.html" class="internal">Project Services (in supervisor)</a>
|
|
calls the following before switching on optional things that it wants.
|
|
</p>
|
|
|
|
<pre class="displayed-code all-displayed-code code-font">
|
|
<span class="reserved-syntax">void</span><span class="plain-syntax"> </span><span class="function-syntax">PluginManager::activate_bare_minimum</span><span class="plain-syntax">(</span><span class="reserved-syntax">void</span><span class="plain-syntax">) {</span>
|
|
<span class="plain-syntax"> </span><span class="reserved-syntax">plugin</span><span class="plain-syntax"> *</span><span class="identifier-syntax">P</span><span class="plain-syntax">;</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">LOOP_OVER</span><span class="plain-syntax">(</span><span class="identifier-syntax">P</span><span class="plain-syntax">, </span><span class="reserved-syntax">plugin</span><span class="plain-syntax">)</span>
|
|
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> ((</span><span class="identifier-syntax">P</span><span class="plain-syntax">-></span><span class="element-syntax">permanently_active</span><span class="plain-syntax">) && (</span><span class="identifier-syntax">P</span><span class="plain-syntax">-></span><span class="element-syntax">active</span><span class="plain-syntax"> == </span><span class="identifier-syntax">FALSE</span><span class="plain-syntax">))</span>
|
|
<span class="plain-syntax"> </span><a href="3-pm.html#SP4" class="function-link"><span class="function-syntax">PluginManager::activate</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">P</span><span class="plain-syntax">);</span>
|
|
<span class="plain-syntax">}</span>
|
|
|
|
<span class="reserved-syntax">void</span><span class="plain-syntax"> </span><span class="function-syntax">PluginManager::make_permanently_active</span><button class="popup" onclick="togglePopup('usagePopup2')"><span class="comment-syntax">?</span><span class="popuptext" id="usagePopup2">Usage of <span class="code-font"><span class="function-syntax">PluginManager::make_permanently_active</span></span>:<br/>Core Module - <a href="1-cm.html#SP2">§2</a></span></button><span class="plain-syntax">(</span><span class="reserved-syntax">plugin</span><span class="plain-syntax"> *</span><span class="identifier-syntax">P</span><span class="plain-syntax">) {</span>
|
|
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">P</span><span class="plain-syntax"> == </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">) </span><span class="identifier-syntax">internal_error</span><span class="plain-syntax">(</span><span class="string-syntax">"no plugin"</span><span class="plain-syntax">);</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">P</span><span class="plain-syntax">-></span><span class="element-syntax">permanently_active</span><span class="plain-syntax"> = </span><span class="identifier-syntax">TRUE</span><span class="plain-syntax">;</span>
|
|
<span class="plain-syntax">}</span>
|
|
</pre>
|
|
<p class="commentary firstcommentary"><a id="SP4" class="paragraph-anchor"></a><b>§4. </b>Most plugins are subordinate to a parent plugin: for example, a dozen more
|
|
specific IF-related plugins are subordinate to the "interactive fiction" one.
|
|
Activating or deactivating a parent like that automatically activates
|
|
or deactivates its children.
|
|
</p>
|
|
|
|
<pre class="displayed-code all-displayed-code code-font">
|
|
<span class="reserved-syntax">void</span><span class="plain-syntax"> </span><span class="function-syntax">PluginManager::activate</span><button class="popup" onclick="togglePopup('usagePopup3')"><span class="comment-syntax">?</span><span class="popuptext" id="usagePopup3">Usage of <span class="code-font"><span class="function-syntax">PluginManager::activate</span></span>:<br/><a href="3-pm.html#SP3">§3</a></span></button><span class="plain-syntax">(</span><span class="reserved-syntax">plugin</span><span class="plain-syntax"> *</span><span class="identifier-syntax">P</span><span class="plain-syntax">) {</span>
|
|
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">P</span><span class="plain-syntax">) {</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">P</span><span class="plain-syntax">-></span><span class="identifier-syntax">active</span><span class="plain-syntax"> = </span><span class="identifier-syntax">TRUE</span><span class="plain-syntax">;</span>
|
|
<span class="plain-syntax"> </span><span class="reserved-syntax">plugin</span><span class="plain-syntax"> *</span><span class="identifier-syntax">Q</span><span class="plain-syntax">;</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">LOOP_OVER</span><span class="plain-syntax">(</span><span class="identifier-syntax">Q</span><span class="plain-syntax">, </span><span class="reserved-syntax">plugin</span><span class="plain-syntax">)</span>
|
|
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">Q</span><span class="plain-syntax">-></span><span class="element-syntax">parent_plugin</span><span class="plain-syntax"> == </span><span class="identifier-syntax">P</span><span class="plain-syntax">)</span>
|
|
<span class="plain-syntax"> </span><a href="3-pm.html#SP4" class="function-link"><span class="function-syntax">PluginManager::activate</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">Q</span><span class="plain-syntax">);</span>
|
|
<span class="plain-syntax"> }</span>
|
|
<span class="plain-syntax">}</span>
|
|
|
|
<span class="reserved-syntax">void</span><span class="plain-syntax"> </span><span class="function-syntax">PluginManager::deactivate</span><span class="plain-syntax">(</span><span class="reserved-syntax">plugin</span><span class="plain-syntax"> *</span><span class="identifier-syntax">P</span><span class="plain-syntax">) {</span>
|
|
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">P</span><span class="plain-syntax">) {</span>
|
|
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">P</span><span class="plain-syntax">-></span><span class="element-syntax">permanently_active</span><span class="plain-syntax">)</span>
|
|
<span class="plain-syntax"> </span><span class="named-paragraph-container code-font"><a href="3-pm.html#SP4_1" class="named-paragraph-link"><span class="named-paragraph">Issue problem for trying to remove the core</span><span class="named-paragraph-number">4.1</span></a></span>
|
|
<span class="plain-syntax"> </span><span class="reserved-syntax">else</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">P</span><span class="plain-syntax">-></span><span class="element-syntax">active</span><span class="plain-syntax"> = </span><span class="identifier-syntax">FALSE</span><span class="plain-syntax">;</span>
|
|
<span class="plain-syntax"> </span><span class="reserved-syntax">plugin</span><span class="plain-syntax"> *</span><span class="identifier-syntax">Q</span><span class="plain-syntax">;</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">LOOP_OVER</span><span class="plain-syntax">(</span><span class="identifier-syntax">Q</span><span class="plain-syntax">, </span><span class="reserved-syntax">plugin</span><span class="plain-syntax">)</span>
|
|
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">Q</span><span class="plain-syntax">-></span><span class="element-syntax">parent_plugin</span><span class="plain-syntax"> == </span><span class="identifier-syntax">P</span><span class="plain-syntax">)</span>
|
|
<span class="plain-syntax"> </span><a href="3-pm.html#SP4" class="function-link"><span class="function-syntax">PluginManager::deactivate</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">Q</span><span class="plain-syntax">);</span>
|
|
<span class="plain-syntax"> }</span>
|
|
<span class="plain-syntax">}</span>
|
|
</pre>
|
|
<p class="commentary firstcommentary"><a id="SP4_1" class="paragraph-anchor"></a><b>§4.1. </b><span class="named-paragraph-container code-font"><span class="named-paragraph-defn">Issue problem for trying to remove the core</span><span class="named-paragraph-number">4.1</span></span><span class="comment-syntax"> =</span>
|
|
</p>
|
|
|
|
<pre class="displayed-code all-displayed-code code-font">
|
|
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">problem_count</span><span class="plain-syntax"> == </span><span class="constant-syntax">0</span><span class="plain-syntax">)</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">StandardProblems::sentence_problem</span><span class="plain-syntax">(</span><a href="1-wtc.html#SP6" class="function-link"><span class="function-syntax">Task::syntax_tree</span></a><span class="plain-syntax">(), </span><span class="identifier-syntax">_p_</span><span class="plain-syntax">(</span><span class="identifier-syntax">Untestable</span><span class="plain-syntax">),</span>
|
|
<span class="plain-syntax"> </span><span class="string-syntax">"the core of the Inform language cannot be removed"</span><span class="plain-syntax">,</span>
|
|
<span class="plain-syntax"> </span><span class="string-syntax">"because then what should we do? What should we ever do?"</span><span class="plain-syntax">);</span>
|
|
<span class="plain-syntax"> </span><span class="reserved-syntax">return</span><span class="plain-syntax">;</span>
|
|
</pre>
|
|
<ul class="endnotetexts"><li>This code is used in <a href="3-pm.html#SP4">§4</a>.</li></ul>
|
|
<p class="commentary firstcommentary"><a id="SP5" class="paragraph-anchor"></a><b>§5. </b>Every active plugin gets to run its start function, if it provides one.
|
|
</p>
|
|
|
|
<p class="commentary">It's kind of incredible that C's grammar for round brackets is unambiguous.
|
|
</p>
|
|
|
|
<pre class="displayed-code all-displayed-code code-font">
|
|
<span class="reserved-syntax">void</span><span class="plain-syntax"> </span><span class="function-syntax">PluginManager::start_plugins</span><button class="popup" onclick="togglePopup('usagePopup4')"><span class="comment-syntax">?</span><span class="popuptext" id="usagePopup4">Usage of <span class="code-font"><span class="function-syntax">PluginManager::start_plugins</span></span>:<br/>What To Compile - <a href="1-wtc.html#SP3">§3</a></span></button><span class="plain-syntax">(</span><span class="reserved-syntax">void</span><span class="plain-syntax">) {</span>
|
|
<span class="plain-syntax"> </span><span class="reserved-syntax">plugin</span><span class="plain-syntax"> *</span><span class="identifier-syntax">P</span><span class="plain-syntax">;</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">LOOP_OVER</span><span class="plain-syntax">(</span><span class="identifier-syntax">P</span><span class="plain-syntax">, </span><span class="reserved-syntax">plugin</span><span class="plain-syntax">)</span>
|
|
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">P</span><span class="plain-syntax">-></span><span class="element-syntax">active</span><span class="plain-syntax">) {</span>
|
|
<span class="plain-syntax"> </span><span class="reserved-syntax">void</span><span class="plain-syntax"> (*</span><span class="identifier-syntax">start</span><span class="plain-syntax">)() = (</span><span class="reserved-syntax">void</span><span class="plain-syntax"> (*)()) </span><span class="identifier-syntax">P</span><span class="plain-syntax">-></span><span class="element-syntax">activation_function</span><span class="plain-syntax">;</span>
|
|
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">start</span><span class="plain-syntax">) (*</span><span class="identifier-syntax">start</span><span class="plain-syntax">)();</span>
|
|
<span class="plain-syntax"> }</span>
|
|
<span class="plain-syntax">}</span>
|
|
</pre>
|
|
<p class="commentary firstcommentary"><a id="SP6" class="paragraph-anchor"></a><b>§6. </b>The names of the great plugins are hard-wired into the compiler rather
|
|
than being stored in Preform grammar, and they therefore cannot be translated
|
|
out of English. But this is intentional, for now at least. Authors are not
|
|
intended to be aware of plugins; it is really kits of Inter code which choose
|
|
which plugins are active.
|
|
</p>
|
|
|
|
<p class="commentary">However, because it is possible to have headings in Inform source text which
|
|
restrict material according to whether a plugin is active, we do need a
|
|
Preform nonterminal to parse them, and here it is.
|
|
</p>
|
|
|
|
<pre class="Preform-displayed-code all-displayed-code code-font">
|
|
<span class="Preform-function-syntax"><language-element></span><span class="Preform-plain-syntax"> </span><span class="Preform-constant-syntax">internal</span><span class="Preform-plain-syntax"> </span><span class="Preform-constant-syntax">{</span>
|
|
<span class="Preform-plain-syntax"> </span><span class="Preform-reserved-syntax">plugin</span><span class="Preform-plain-syntax"> *</span><span class="Preform-identifier-syntax">P</span><span class="Preform-plain-syntax">;</span>
|
|
<span class="Preform-plain-syntax"> </span><span class="Preform-identifier-syntax">LOOP_OVER</span><span class="Preform-plain-syntax">(</span><span class="Preform-identifier-syntax">P</span><span class="Preform-plain-syntax">, </span><span class="Preform-reserved-syntax">plugin</span><span class="Preform-plain-syntax">)</span>
|
|
<span class="Preform-plain-syntax"> </span><span class="Preform-reserved-syntax">if</span><span class="Preform-plain-syntax"> (</span><span class="Preform-identifier-syntax">Wordings::match</span><span class="Preform-plain-syntax">(</span><span class="Preform-identifier-syntax">P</span><span class="Preform-plain-syntax">-></span><span class="Preform-element-syntax">wording_name</span><span class="Preform-plain-syntax">, </span><span class="Preform-identifier-syntax">W</span><span class="Preform-plain-syntax">)) {</span>
|
|
<span class="Preform-plain-syntax"> </span><span class="Preform-reserved-syntax">if</span><span class="Preform-plain-syntax"> (</span><span class="Preform-identifier-syntax">P</span><span class="Preform-plain-syntax">-></span><span class="Preform-element-syntax">active</span><span class="Preform-plain-syntax"> == </span><span class="Preform-identifier-syntax">FALSE</span><span class="Preform-plain-syntax">) {</span>
|
|
<span class="Preform-plain-syntax"> ==> { </span><span class="Preform-identifier-syntax">FALSE</span><span class="Preform-plain-syntax">, </span><span class="Preform-identifier-syntax">P</span><span class="Preform-plain-syntax"> };</span>
|
|
<span class="Preform-plain-syntax"> } </span><span class="Preform-reserved-syntax">else</span><span class="Preform-plain-syntax"> {</span>
|
|
<span class="Preform-plain-syntax"> ==> { </span><span class="Preform-identifier-syntax">TRUE</span><span class="Preform-plain-syntax">, </span><span class="Preform-identifier-syntax">P</span><span class="Preform-plain-syntax"> };</span>
|
|
<span class="Preform-plain-syntax"> }</span>
|
|
<span class="Preform-plain-syntax"> </span><span class="Preform-reserved-syntax">return</span><span class="Preform-plain-syntax"> </span><span class="Preform-identifier-syntax">TRUE</span><span class="Preform-plain-syntax">;</span>
|
|
<span class="Preform-plain-syntax"> }</span>
|
|
<span class="Preform-plain-syntax"> ==> { </span><span class="Preform-identifier-syntax">fail</span><span class="Preform-plain-syntax"> </span><span class="Preform-identifier-syntax">nonterminal</span><span class="Preform-plain-syntax"> };</span>
|
|
<span class="Preform-plain-syntax">}</span>
|
|
</pre>
|
|
<ul class="endnotetexts"><li>This is <a href="../words-module/4-ap.html" class="internal">Preform grammar</a>, not regular C code.</li></ul>
|
|
<p class="commentary firstcommentary"><a id="SP7" class="paragraph-anchor"></a><b>§7. </b>It's convenient also to provide:
|
|
</p>
|
|
|
|
<pre class="displayed-code all-displayed-code code-font">
|
|
<span class="reserved-syntax">plugin</span><span class="plain-syntax"> *</span><span class="function-syntax">PluginManager::parse</span><span class="plain-syntax">(</span><span class="identifier-syntax">text_stream</span><span class="plain-syntax"> *</span><span class="identifier-syntax">S</span><span class="plain-syntax">) {</span>
|
|
<span class="plain-syntax"> </span><span class="reserved-syntax">plugin</span><span class="plain-syntax"> *</span><span class="identifier-syntax">P</span><span class="plain-syntax">;</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">LOOP_OVER</span><span class="plain-syntax">(</span><span class="identifier-syntax">P</span><span class="plain-syntax">, </span><span class="reserved-syntax">plugin</span><span class="plain-syntax">)</span>
|
|
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">Str::eq_insensitive</span><span class="plain-syntax">(</span><span class="identifier-syntax">P</span><span class="plain-syntax">-></span><span class="element-syntax">textual_name</span><span class="plain-syntax">, </span><span class="identifier-syntax">S</span><span class="plain-syntax">))</span>
|
|
<span class="plain-syntax"> </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><span class="identifier-syntax">P</span><span class="plain-syntax">;</span>
|
|
<span class="plain-syntax"> </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">;</span>
|
|
<span class="plain-syntax">}</span>
|
|
</pre>
|
|
<p class="commentary firstcommentary"><a id="SP8" class="paragraph-anchor"></a><b>§8. </b>Plugins affect the running of the compiler by inserting functions called plugs
|
|
into the following "plugin rulebooks" — there's a mixed metaphor here, but
|
|
the idea is that they behave like Inform rulebooks. When a rulebook is called,
|
|
the compiler works through each plug until one of them returns something other
|
|
than <span class="extract"><span class="extract-syntax">FALSE</span></span>.
|
|
</p>
|
|
|
|
<p class="commentary">Plugins should add plugs in their activation functions, by calling
|
|
<a href="3-pm.html#SP8" class="internal">PluginManager::plug</a>, which has an interestingly vague type. The next
|
|
screenful of code looks like something of a workout for the C typechecker, but
|
|
it compiles under <span class="extract"><span class="extract-syntax">clang</span></span> without even the <span class="extract"><span class="extract-syntax">-Wpedantic</span></span> warning, and honestly
|
|
you're barely living as a C programmer if you never generate that one.
|
|
</p>
|
|
|
|
<pre class="displayed-code all-displayed-code code-font">
|
|
<span class="identifier-syntax">linked_list</span><span class="plain-syntax"> *</span><span class="identifier-syntax">plugin_rulebooks</span><span class="plain-syntax">[</span><span class="identifier-syntax">NO_DEFINED_PLUG_VALUES</span><span class="plain-syntax">+1]; </span><span class="comment-syntax"> of </span><span class="extract"><span class="extract-syntax">void</span></span><span class="comment-syntax">, reprehensibly</span>
|
|
|
|
<span class="reserved-syntax">void</span><span class="plain-syntax"> </span><span class="function-syntax">PluginManager::start</span><span class="plain-syntax">(</span><span class="reserved-syntax">void</span><span class="plain-syntax">) {</span>
|
|
<span class="plain-syntax"> </span><span class="reserved-syntax">for</span><span class="plain-syntax"> (</span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">i</span><span class="plain-syntax">=0; </span><span class="identifier-syntax">i</span><span class="plain-syntax"><=</span><span class="identifier-syntax">NO_DEFINED_PLUG_VALUES</span><span class="plain-syntax">; </span><span class="identifier-syntax">i</span><span class="plain-syntax">++)</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">plugin_rulebooks</span><span class="plain-syntax">[</span><span class="identifier-syntax">i</span><span class="plain-syntax">] = </span><span class="identifier-syntax">NEW_LINKED_LIST</span><span class="plain-syntax">(</span><span class="reserved-syntax">void</span><span class="plain-syntax">);</span>
|
|
<span class="plain-syntax">}</span>
|
|
|
|
<span class="reserved-syntax">void</span><span class="plain-syntax"> </span><span class="function-syntax">PluginManager::plug</span><span class="plain-syntax">(</span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">code</span><span class="plain-syntax">, </span><span class="reserved-syntax">int</span><span class="plain-syntax"> (*</span><span class="identifier-syntax">R</span><span class="plain-syntax">)()) {</span>
|
|
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">code</span><span class="plain-syntax"> > </span><span class="identifier-syntax">NO_DEFINED_PLUG_VALUES</span><span class="plain-syntax">) </span><span class="identifier-syntax">internal_error</span><span class="plain-syntax">(</span><span class="string-syntax">"not a plugin call"</span><span class="plain-syntax">);</span>
|
|
<span class="plain-syntax"> </span><span class="reserved-syntax">void</span><span class="plain-syntax"> *</span><span class="identifier-syntax">vR</span><span class="plain-syntax"> = (</span><span class="reserved-syntax">void</span><span class="plain-syntax"> *) </span><span class="identifier-syntax">R</span><span class="plain-syntax">;</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">ADD_TO_LINKED_LIST</span><span class="plain-syntax">(</span><span class="identifier-syntax">vR</span><span class="plain-syntax">, </span><span class="reserved-syntax">void</span><span class="plain-syntax">, </span><span class="identifier-syntax">plugin_rulebooks</span><span class="plain-syntax">[</span><span class="identifier-syntax">code</span><span class="plain-syntax">]);</span>
|
|
<span class="plain-syntax">}</span>
|
|
</pre>
|
|
<p class="commentary firstcommentary"><a id="SP9" class="paragraph-anchor"></a><b>§9. </b>The functions in <a href="3-pc.html" class="internal">Plugin Calls</a> then make use of these macros, which are
|
|
the easiest way to persuade the C typechecker to allow variable arguments to
|
|
be passed in a portable way. Similarly, there are two macros not one because
|
|
C does not allow a void variable argument list.
|
|
</p>
|
|
|
|
<p class="commentary">We must take care that the variables introduced in the macro body do not mask
|
|
existing variables used in the arguments; the only way to do this is to give
|
|
them implausible names.
|
|
</p>
|
|
|
|
<pre class="definitions code-font"><span class="definition-keyword">define</span> <span class="identifier-syntax">PLUGINS_CALL</span><span class="plain-syntax">(</span><span class="identifier-syntax">code</span><span class="plain-syntax">, </span><span class="identifier-syntax">args</span><span class="plain-syntax">...) {</span>
|
|
<span class="plain-syntax"> </span><span class="reserved-syntax">void</span><span class="plain-syntax"> *</span><span class="identifier-syntax">R_plugin_pointer_XYZZY</span><span class="plain-syntax">; </span><span class="comment-syntax"> no argument can have this name</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">LOOP_OVER_LINKED_LIST</span><span class="plain-syntax">(</span><span class="identifier-syntax">R_plugin_pointer_XYZZY</span><span class="plain-syntax">, </span><span class="reserved-syntax">void</span><span class="plain-syntax">, </span><span class="identifier-syntax">plugin_rulebooks</span><span class="plain-syntax">[</span><span class="identifier-syntax">code</span><span class="plain-syntax">]) {</span>
|
|
<span class="plain-syntax"> </span><span class="reserved-syntax">int</span><span class="plain-syntax"> (*</span><span class="identifier-syntax">R_plugin_rule_ZOOGE</span><span class="plain-syntax">)() = (</span><span class="reserved-syntax">int</span><span class="plain-syntax"> (*)()) </span><span class="identifier-syntax">R_plugin_pointer_XYZZY</span><span class="plain-syntax">; </span><span class="comment-syntax"> or this one</span>
|
|
<span class="plain-syntax"> </span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">Q_plugin_return_PLUGH</span><span class="plain-syntax"> = (*</span><span class="identifier-syntax">R_plugin_rule_ZOOGE</span><span class="plain-syntax">)(</span><span class="identifier-syntax">args</span><span class="plain-syntax">); </span><span class="comment-syntax"> or this</span>
|
|
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">Q_plugin_return_PLUGH</span><span class="plain-syntax">) </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><span class="identifier-syntax">Q_plugin_return_PLUGH</span><span class="plain-syntax">;</span>
|
|
<span class="plain-syntax"> }</span>
|
|
<span class="plain-syntax"> </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><span class="identifier-syntax">FALSE</span><span class="plain-syntax">;</span>
|
|
<span class="plain-syntax">}</span>
|
|
<span class="definition-keyword">define</span> <span class="identifier-syntax">PLUGINS_CALLV</span><span class="plain-syntax">(</span><span class="identifier-syntax">code</span><span class="plain-syntax">) {</span>
|
|
<span class="plain-syntax"> </span><span class="reserved-syntax">void</span><span class="plain-syntax"> *</span><span class="identifier-syntax">R_plugin_pointer_XYZZY</span><span class="plain-syntax">;</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">LOOP_OVER_LINKED_LIST</span><span class="plain-syntax">(</span><span class="identifier-syntax">R_plugin_pointer_XYZZY</span><span class="plain-syntax">, </span><span class="reserved-syntax">void</span><span class="plain-syntax">, </span><span class="identifier-syntax">plugin_rulebooks</span><span class="plain-syntax">[</span><span class="identifier-syntax">code</span><span class="plain-syntax">]) {</span>
|
|
<span class="plain-syntax"> </span><span class="reserved-syntax">int</span><span class="plain-syntax"> (*</span><span class="identifier-syntax">R_plugin_rule_ZOOGE</span><span class="plain-syntax">)() = (</span><span class="reserved-syntax">int</span><span class="plain-syntax"> (*)()) </span><span class="identifier-syntax">R_plugin_pointer_XYZZY</span><span class="plain-syntax">;</span>
|
|
<span class="plain-syntax"> </span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">Q_plugin_return_PLUGH</span><span class="plain-syntax"> = (*</span><span class="identifier-syntax">R_plugin_rule_ZOOGE</span><span class="plain-syntax">)();</span>
|
|
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">Q_plugin_return_PLUGH</span><span class="plain-syntax">) </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><span class="identifier-syntax">Q_plugin_return_PLUGH</span><span class="plain-syntax">;</span>
|
|
<span class="plain-syntax"> }</span>
|
|
<span class="plain-syntax"> </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><span class="identifier-syntax">FALSE</span><span class="plain-syntax">;</span>
|
|
<span class="plain-syntax">}</span>
|
|
</pre>
|
|
<nav role="progress"><div class="progresscontainer">
|
|
<ul class="progressbar"><li class="progressprev"><a href="2-kp.html">❮</a></li><li class="progresschapter"><a href="P-wtmd.html">P</a></li><li class="progresschapter"><a href="1-cm.html">1</a></li><li class="progresschapter"><a href="2-up.html">2</a></li><li class="progresscurrentchapter">3</li><li class="progresscurrent">pm</li><li class="progresssection"><a href="3-pc.html">pc</a></li><li class="progressnext"><a href="3-pc.html">❯</a></li></ul></div>
|
|
</nav><!--End of weave-->
|
|
|
|
</main>
|
|
</body>
|
|
</html>
|
|
|