<?xml version="1.0"?>
<feed xmlns="http://www.w3.org/2005/Atom" xml:lang="en">
	<id>https://wiki.spiretrading.com/api.php?action=feedcontributions&amp;feedformat=atom&amp;user=Kman</id>
	<title>Spire Trading Inc. - User contributions [en]</title>
	<link rel="self" type="application/atom+xml" href="https://wiki.spiretrading.com/api.php?action=feedcontributions&amp;feedformat=atom&amp;user=Kman"/>
	<link rel="alternate" type="text/html" href="https://wiki.spiretrading.com/index.php/Special:Contributions/Kman"/>
	<updated>2026-04-30T11:51:44Z</updated>
	<subtitle>User contributions</subtitle>
	<generator>MediaWiki 1.34.1</generator>
	<entry>
		<id>https://wiki.spiretrading.com/index.php?title=ASX_ITCH&amp;diff=148</id>
		<title>ASX ITCH</title>
		<link rel="alternate" type="text/html" href="https://wiki.spiretrading.com/index.php?title=ASX_ITCH&amp;diff=148"/>
		<updated>2020-07-28T23:00:34Z</updated>

		<summary type="html">&lt;p&gt;Kman: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Support for ASX Trade ITCH market data is provided by the AsxItchMarketDataFeedClient. This market data feed can be used by Spire to populate the security database for ASX listed securities, BBO quotes, time and sales, book quotes and order imbalances. In addition to real time market data, ASX Trade ITCH also provides a market data snapshot used for data recovery along with retransmission of dropped packets, both of which are fully supported.&lt;br /&gt;
&lt;br /&gt;
For more information about the ASX ITCH protocol and connectivity, refer to https://www.asxonline.com/public/documents/asx-trade-open-interface-manuals.html&lt;br /&gt;
&lt;br /&gt;
==Configuration==&lt;br /&gt;
&lt;br /&gt;
By default ASX ITCH is split into multiple feeds each handling a range of securities. Each feed is placed in its own directory and named &amp;lt;code&amp;gt;asxitch_partition[N]&amp;lt;/code&amp;gt; with &amp;lt;code&amp;gt;N = 1&amp;lt;/code&amp;gt; representing the first feed. Each feed also has its own configuration file structured as follows:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
---&lt;br /&gt;
service_locator:&lt;br /&gt;
&lt;br /&gt;
  # The Service Locator to authenticate with.&lt;br /&gt;
  address: 127.0.0.1:20000&lt;br /&gt;
&lt;br /&gt;
  # The market data feed's username.&lt;br /&gt;
  username: market_data_feed&lt;br /&gt;
&lt;br /&gt;
  # The market data feed's password.&lt;br /&gt;
  password: 1234&lt;br /&gt;
&lt;br /&gt;
# Whether to log all packets.&lt;br /&gt;
enable_logging: false&lt;br /&gt;
&lt;br /&gt;
# The market code (MIC) to publish.&lt;br /&gt;
market: ASX&lt;br /&gt;
&lt;br /&gt;
# Whether to synthetically publish time and sales&lt;br /&gt;
# based on matched orders.&lt;br /&gt;
is_time_and_sale: true&lt;br /&gt;
&lt;br /&gt;
# Specifies how frequently to publish updates to&lt;br /&gt;
# the market data server.&lt;br /&gt;
sampling: 100ms&lt;br /&gt;
&lt;br /&gt;
# The multicast group to join.&lt;br /&gt;
host: 233.0.0.0:12345&lt;br /&gt;
&lt;br /&gt;
# The network interface to use to join&lt;br /&gt;
# the multicast group.&lt;br /&gt;
interface: 192.168.0.1:30000&lt;br /&gt;
&lt;br /&gt;
# The GLIMPSE host to connect to for&lt;br /&gt;
# snapshot retrieval.&lt;br /&gt;
glimpse_host: 122.100.100.1:30000&lt;br /&gt;
&lt;br /&gt;
# How long to wait for a snapshot before&lt;br /&gt;
# timing out.&lt;br /&gt;
glimpse_timeout: 5s&lt;br /&gt;
&lt;br /&gt;
# The GLIMPSE username.&lt;br /&gt;
username: glimpse101&lt;br /&gt;
&lt;br /&gt;
# The GLIMPSE password.&lt;br /&gt;
password: 1234&lt;br /&gt;
...&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Operations==&lt;br /&gt;
&lt;br /&gt;
The AsxItchMarketDataFeedClient contains the standard suite of scripts used to manage each individual feed. &lt;br /&gt;
&lt;br /&gt;
The &amp;lt;code&amp;gt;start.sh&amp;lt;/code&amp;gt; script is used to start either a single feed by specifying the feed's unique identifier &amp;lt;code&amp;gt;partition[N]&amp;lt;/code&amp;gt; as a command line argument or used to start all feeds by passing &amp;lt;code&amp;gt;all&amp;lt;/code&amp;gt; as a command line argument. Similarly the &amp;lt;code&amp;gt;stop.sh&amp;lt;/code&amp;gt; script is used to stop a currently running feed. The &amp;lt;code&amp;gt;list_feeds.sh&amp;lt;/code&amp;gt; will output all currently running feeds and the &amp;lt;code&amp;gt;create_softlinks.sh&amp;lt;/code&amp;gt; script is used when first setting up the feeds, or when a new feed is added.&lt;br /&gt;
&lt;br /&gt;
On startup a log file is created with the name &amp;lt;code&amp;gt;srv_[YYYY][MM][DD]_[HH]_[MM]_[SS].log&amp;lt;/code&amp;gt; and is used to record dropped packets, any error messages or warnings, and if logging is enabled in the configuration file, a dump of every received message.&lt;/div&gt;</summary>
		<author><name>Kman</name></author>
		
	</entry>
	<entry>
		<id>https://wiki.spiretrading.com/index.php?title=ASX_ITCH&amp;diff=147</id>
		<title>ASX ITCH</title>
		<link rel="alternate" type="text/html" href="https://wiki.spiretrading.com/index.php?title=ASX_ITCH&amp;diff=147"/>
		<updated>2020-07-28T22:54:27Z</updated>

		<summary type="html">&lt;p&gt;Kman: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Support for ASX Trade ITCH market data is provided by the AsxItchMarketDataFeedClient. This market data feed can be used by Spire to populate the security database for ASX listed securities, BBO quotes, time and sales, book quotes and order imbalances. In addition to real time market data, ASX Trade ITCH also provides a market data snapshot used for data recovery along with retransmission of dropped packets, both of which are fully supported.&lt;br /&gt;
&lt;br /&gt;
==Configuration==&lt;br /&gt;
&lt;br /&gt;
By default ASX ITCH is split into multiple feeds each handling a range of securities. Each feed is placed in its own directory and named &amp;lt;code&amp;gt;asxitch_partition[N]&amp;lt;/code&amp;gt; with &amp;lt;code&amp;gt;N = 1&amp;lt;/code&amp;gt; representing the first feed. Each feed also has its own configuration file structured as follows:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
---&lt;br /&gt;
service_locator:&lt;br /&gt;
&lt;br /&gt;
  # The Service Locator to authenticate with.&lt;br /&gt;
  address: 127.0.0.1:20000&lt;br /&gt;
&lt;br /&gt;
  # The market data feed's username.&lt;br /&gt;
  username: market_data_feed&lt;br /&gt;
&lt;br /&gt;
  # The market data feed's password.&lt;br /&gt;
  password: 1234&lt;br /&gt;
&lt;br /&gt;
# Whether to log all packets.&lt;br /&gt;
enable_logging: false&lt;br /&gt;
&lt;br /&gt;
# The market code (MIC) to publish.&lt;br /&gt;
market: ASX&lt;br /&gt;
&lt;br /&gt;
# Whether to synthetically publish time and sales&lt;br /&gt;
# based on matched orders.&lt;br /&gt;
is_time_and_sale: true&lt;br /&gt;
&lt;br /&gt;
# Specifies how frequently to publish updates to&lt;br /&gt;
# the market data server.&lt;br /&gt;
sampling: 100ms&lt;br /&gt;
&lt;br /&gt;
# The multicast group to join.&lt;br /&gt;
host: 233.0.0.0:12345&lt;br /&gt;
&lt;br /&gt;
# The network interface to use to join&lt;br /&gt;
# the multicast group.&lt;br /&gt;
interface: 192.168.0.1:30000&lt;br /&gt;
&lt;br /&gt;
# The GLIMPSE host to connect to for&lt;br /&gt;
# snapshot retrieval.&lt;br /&gt;
glimpse_host: 122.100.100.1:30000&lt;br /&gt;
&lt;br /&gt;
# How long to wait for a snapshot before&lt;br /&gt;
# timing out.&lt;br /&gt;
glimpse_timeout: 5s&lt;br /&gt;
&lt;br /&gt;
# The GLIMPSE username.&lt;br /&gt;
username: glimpse101&lt;br /&gt;
&lt;br /&gt;
# The GLIMPSE password.&lt;br /&gt;
password: 1234&lt;br /&gt;
...&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Operations==&lt;br /&gt;
&lt;br /&gt;
The AsxItchMarketDataFeedClient contains the standard suite of scripts used to manage each individual feed. &lt;br /&gt;
&lt;br /&gt;
The &amp;lt;code&amp;gt;start.sh&amp;lt;/code&amp;gt; script is used to start either a single feed by specifying the feed's unique identifier &amp;lt;code&amp;gt;partition[N]&amp;lt;/code&amp;gt; as a command line argument or used to start all feeds by passing &amp;lt;code&amp;gt;all&amp;lt;/code&amp;gt; as a command line argument. Similarly the &amp;lt;code&amp;gt;stop.sh&amp;lt;/code&amp;gt; script is used to stop a currently running feed. The &amp;lt;code&amp;gt;list_feeds.sh&amp;lt;/code&amp;gt; will output all currently running feeds and the &amp;lt;code&amp;gt;create_softlinks.sh&amp;lt;/code&amp;gt; script is used when first setting up the feeds, or when a new feed is added.&lt;br /&gt;
&lt;br /&gt;
On startup a log file is created with the name &amp;lt;code&amp;gt;srv_[YYYY][MM][DD]_[HH]_[MM]_[SS].log&amp;lt;/code&amp;gt; and is used to record dropped packets, any error messages or warnings, and if logging is enabled in the configuration file, a dump of every received message.&lt;/div&gt;</summary>
		<author><name>Kman</name></author>
		
	</entry>
	<entry>
		<id>https://wiki.spiretrading.com/index.php?title=ASX_ITCH&amp;diff=146</id>
		<title>ASX ITCH</title>
		<link rel="alternate" type="text/html" href="https://wiki.spiretrading.com/index.php?title=ASX_ITCH&amp;diff=146"/>
		<updated>2020-07-28T18:04:02Z</updated>

		<summary type="html">&lt;p&gt;Kman: Created page with &amp;quot;Support for ASX Trade ITCH market data is provided by the AsxItchMarketDataFeedClient. This market data feed can be used by Spire to populate the security database for ASX lis...&amp;quot;&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Support for ASX Trade ITCH market data is provided by the AsxItchMarketDataFeedClient. This market data feed can be used by Spire to populate the security database for ASX listed securities, BBO quotes, time and sales, book quotes and order imbalances. In addition to real time market data, ASX Trade ITCH also provides a market data snapshot used for data recovery along with retransmission of dropped packets, both of which are fully supported.&lt;br /&gt;
&lt;br /&gt;
==Configuration==&lt;br /&gt;
&lt;br /&gt;
By default ASX ITCH is split into multiple feeds each handling a range of securities. Each feed is placed in its own directory and named &amp;lt;code&amp;gt;asxitch_partition[N]&amp;lt;/code&amp;gt; with &amp;lt;code&amp;gt;N = 1&amp;lt;/code&amp;gt; representing the first feed. Each feed also has its own configuration file structured as follows:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
---&lt;br /&gt;
service_locator:&lt;br /&gt;
&lt;br /&gt;
  # The Service Locator to authenticate with.&lt;br /&gt;
  address: 127.0.0.1:20000&lt;br /&gt;
&lt;br /&gt;
  # The market data feed's username.&lt;br /&gt;
  username: market_data_feed&lt;br /&gt;
&lt;br /&gt;
  # The market data feed's password.&lt;br /&gt;
  password: 1234&lt;br /&gt;
&lt;br /&gt;
# Whether to log all packets.&lt;br /&gt;
enable_logging: false&lt;br /&gt;
&lt;br /&gt;
# The market code (MIC) to publish.&lt;br /&gt;
market: ASX&lt;br /&gt;
&lt;br /&gt;
# Whether to synthetically publish time and sales&lt;br /&gt;
# based on matched orders.&lt;br /&gt;
is_time_and_sale: true&lt;br /&gt;
&lt;br /&gt;
# Specifies how frequently to publish updates to&lt;br /&gt;
# the market data server.&lt;br /&gt;
sampling: 100ms&lt;br /&gt;
&lt;br /&gt;
# The multicast group to join.&lt;br /&gt;
host: 233.71.185.40:21401&lt;br /&gt;
&lt;br /&gt;
# The network interface to use to join&lt;br /&gt;
# the multicast group.&lt;br /&gt;
interface: 192.168.0.99:21401&lt;br /&gt;
&lt;br /&gt;
# The GLIMPSE host to connect to for&lt;br /&gt;
# snapshot retrieval.&lt;br /&gt;
glimpse_host: 203.0.119.184:21801&lt;br /&gt;
&lt;br /&gt;
# How long to wait for a snapshot before&lt;br /&gt;
# timing out.&lt;br /&gt;
glimpse_timeout: 5s&lt;br /&gt;
&lt;br /&gt;
# The GLIMPSE username.&lt;br /&gt;
username: glimpse101&lt;br /&gt;
&lt;br /&gt;
# The GLIMPSE password.&lt;br /&gt;
password: 1234&lt;br /&gt;
...&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Operations==&lt;br /&gt;
&lt;br /&gt;
The AsxItchMarketDataFeedClient contains the standard suite of scripts used to manage each individual feed. &lt;br /&gt;
&lt;br /&gt;
The &amp;lt;code&amp;gt;start.sh&amp;lt;/code&amp;gt; script is used to start either a single feed by specifying the feed's unique identifier &amp;lt;code&amp;gt;partition[N]&amp;lt;/code&amp;gt; as a command line argument or used to start all feeds by passing &amp;lt;code&amp;gt;all&amp;lt;/code&amp;gt; as a command line argument. Similarly the &amp;lt;code&amp;gt;stop.sh&amp;lt;/code&amp;gt; script is used to stop a currently running feed. The &amp;lt;code&amp;gt;list_feeds.sh&amp;lt;/code&amp;gt; will output all currently running feeds and the &amp;lt;code&amp;gt;create_softlinks.sh&amp;lt;/code&amp;gt; script is used when first setting up the feeds, or when a new feed is added.&lt;br /&gt;
&lt;br /&gt;
On startup a log file is created with the name &amp;lt;code&amp;gt;srv_[YYYY][MM][DD]_[HH]_[MM]_[SS].log&amp;lt;/code&amp;gt; and is used to record dropped packets, any error messages or warnings, and if logging is enabled in the configuration file, a dump of every received message.&lt;/div&gt;</summary>
		<author><name>Kman</name></author>
		
	</entry>
	<entry>
		<id>https://wiki.spiretrading.com/index.php?title=UI_Kit&amp;diff=142</id>
		<title>UI Kit</title>
		<link rel="alternate" type="text/html" href="https://wiki.spiretrading.com/index.php?title=UI_Kit&amp;diff=142"/>
		<updated>2020-07-14T16:43:15Z</updated>

		<summary type="html">&lt;p&gt;Kman: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;User interfaces are specified by a set of documents describing a data model, user flow, layout, and styling. This article will go over each of these documents along with how they combine to describe the complete behavior from a small component such a button to larger components such as a login window. The example that will be used in each document is a user interface for a button component.&lt;br /&gt;
&lt;br /&gt;
==Model==&lt;br /&gt;
&lt;br /&gt;
Fundamentally, a UI is a visual representation of a set of data in a given state. The UI takes in that data upon initialization and transforms it based on external actions either provided by the user directly or some other external agent. In order for multiple UI components to work together, individual components signal when certain changes are made to that data or to the state of the component, which allows other UI components to respond and signal changes of their own. The complete description of the data a UI component operates on, the state of the component, as well as the signals it produces form the model and is typically documented in &amp;lt;code&amp;gt;model.txt&amp;lt;/code&amp;gt;. For a simple component such as a button we'd expect to see a label displayed by the button, whether the button is responding to user inputs, whether the mouse is interacting with the button, and finally a signal indicating when the user clicks on it. This would be documented as follows:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
Data:&lt;br /&gt;
  label: The text displayed in the button.&lt;br /&gt;
  enabled: Whether the button is responding to user actions.&lt;br /&gt;
&lt;br /&gt;
State:&lt;br /&gt;
  hovered: Whether the mouse position is within the button's visible region.&lt;br /&gt;
&lt;br /&gt;
Signals:&lt;br /&gt;
  clicked: Indicates the button was clicked by the user.&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
As a general matter, fields that go under &amp;lt;code&amp;gt;Data&amp;lt;/code&amp;gt; are inputs that are provided externally to the UI component, whereas fields that go under &amp;lt;code&amp;gt;State&amp;lt;/code&amp;gt; are internal to the component itself. Typically a button does not know what label it should display and does not manage changes to the label, some external component shall make use of a button and provide it with a label to display. Conversely the button can independently manage whether the mouse is hovered over it on its own by keeping track of the mouse position, it needs no external agent to inform it of this state.&lt;br /&gt;
&lt;br /&gt;
==User Flow==&lt;br /&gt;
&lt;br /&gt;
With the model defined, the user flow describes how the model is transformed based on external events. The user flow is broken down into a set of steps represented by colored shapes and are connected to one another by arrows. In order to follow a step, a list of criteria must be met depending on type of step represented. When a step is followed a function is performed at which point the step is said to be complete and then every arrow pointing away from the step must be evaluated to determine the next step to go to. If a step has no arrows pointing out of it, then that step is said to be a terminal step at which point no further changes to the UI are possible.&lt;br /&gt;
&lt;br /&gt;
In cases where a UI component is provided by the platform and already has an existing implementation, it may not be necessary to provide a user flow and instead the UI component can either reuse the existing user flow or defer the user flow to the platform. For example most platforms including HTML, macOS, Windows etc... already provide a text input field as well as a button, in those cases it is preferable to defer the user flow to the respective platform instead of redefining one. Only in cases where custom functionality or custom components are being created is a user flow required.&lt;br /&gt;
&lt;br /&gt;
Flow charts are documented using software available at https://diagrams.net&lt;br /&gt;
&lt;br /&gt;
===Start===&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
[[File:ui_kit_start.png|Start step]]&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
Every UI component begins at the start step, it appears as a dark green circle and is typically either the left-most step of the user flow or the top-most step. It can also be formally distinguished by the fact that it's the only step that may not have any arrows pointing into it, arrows may only point away from it. The start step does not perform any function and is only used as a visual indicator to quickly determine where the flow chart begins.&lt;br /&gt;
&lt;br /&gt;
If the UI performs any kind of initialization then the start step should have a single arrow pointing towards a step to handles such initialization. Refer to the login window for an example.&lt;br /&gt;
&lt;br /&gt;
===Actions===&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
[[File:ui_kit_action.png|Action step]]&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
Actions are steps that are taken unconditionally and perform a side-effect such as changing the state of the component or updating the model. Actions can be chained together by arrows to form a sequence of side-effects or multiple actions can be consolidated into a single step that performs the sequence. The choice of chaining versus consolidating is stylistic, if a step gets to be too large then it is preferable to break it into multiple steps that are chained together. If there are multiple small actions chained together then it is preferable to consolidate.&lt;br /&gt;
&lt;br /&gt;
Every side-effect specified by an action should be a single sentence that begins with a verb. For example if updating data XYZ in the model to the value 123, then the side-effect should be &amp;quot;Set XYZ to 123.&amp;quot; The function of an action step is execute each side-effect in order.&lt;br /&gt;
&lt;br /&gt;
A no-op can be used to indicate that no side-effect is to be performed. This can come in handy to describe an action state that does nothing but wait.&lt;br /&gt;
&lt;br /&gt;
===Events===&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
[[File:ui_kit_event.png|Event step]]&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
An event is step external to the UI that the UI has a chance to respond to. Events can be triggered by user input such as a keyboard press, mouse movement, or other input device as well as by signals produced by other UI components, such as a button indicating that it has been clicked or an input UI indicating an update to the model. An event step is followed if the event takes place after the completion of the current step's function. While multiple events may happen very close together in time, it is never possible for multiple events to occur simultaneously.&lt;br /&gt;
&lt;br /&gt;
===Conditions===&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
[[File:ui_kit_condition.png|Condition step]]&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
A condition is a step that is followed if at the completion of the current step's function some condition is satisfied. If a step leads to multiple conditions then it must either be the case that only one such condition can possibly be satisfied or each arrow pointing out of the step and into a condition must be labelled numerically starting from &amp;lt;code&amp;gt;0&amp;lt;/code&amp;gt; in which case each condition is tested in ascending order and the first condition that is satisfied is followed. For example consider the following user flow:&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
[[File:ui_kit_priority.png|Prioritizing conditions]]&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
If the current time is 6:30 PM then all three conditions are technically satisfied and so there is an ambiguity about which condition to follow. The numeric labels on the arrows are thus used to prioritize the conditions so that the conditional step &amp;lt;code&amp;gt;current time &amp;gt;= 6:00 PM&amp;lt;/code&amp;gt; is tested first and if satisfied then it's followed without considering the remaining conditions.&lt;br /&gt;
&lt;br /&gt;
===Tests===&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
[[File:ui_kit_test.png|Test step]]&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Similar to the condition step, the test step can also be used to conditionally follow an arrow. The test step itself is followed unconditionally and the function of the step is to perform a test. Once the function is completed a set of labelled arrows pointing away from the step are checked and the arrow whose label satisfies the test is followed.&lt;br /&gt;
&lt;br /&gt;
Both condition steps and test steps are technically interchangeable, the choice of one or the other is stylistic. One should prefer the test step in situations where a clear question can be asked and whose answer is a single value in which case the question is written in the body of the test step and each of the possible values or value ranges is a labelled arrow.&lt;br /&gt;
&lt;br /&gt;
===Signals===&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
[[File:ui_kit_signal.png|Signal step]]&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The function of a signal is to inform other UI components about a change in state so that those other components can respond to such changes in the form of events. That is, a signal produced by one UI component is treated as an event by another UI component. For example, a button UI contains a &amp;lt;code&amp;gt;clicked&amp;lt;/code&amp;gt; signal step indicating that the user clicked on it and in turn a form UI contains a corresponding &amp;lt;code&amp;gt;button clicked&amp;lt;/code&amp;gt; event step where said form may respond by updating its data model.&lt;br /&gt;
&lt;br /&gt;
Similar to an action step, signal steps are followed unconditionally.&lt;br /&gt;
&lt;br /&gt;
===Ambiguities===&lt;br /&gt;
&lt;br /&gt;
An ambiguity is a step that contains multiple arrows that are simultaneously satisfied. A flow chart that contains an ambiguity is ill-formed and must be resolved. For example if a step &amp;lt;code&amp;gt;Q&amp;lt;/code&amp;gt; has an arrow leading into an unconditional step (such as leading into an action or signal step), it must be the only arrow leading out of &amp;lt;code&amp;gt;Q&amp;lt;/code&amp;gt;, any other arrow would necessarily introduce an ambiguity. If a step has multiple arrows leading into conditional steps where more than one condition is satisfied then that too is an ambiguity. Resolving such ambiguity is done by giving each arrow a priority.&lt;br /&gt;
&lt;br /&gt;
===Example: Button===&lt;br /&gt;
&lt;br /&gt;
The following is an example of a simplified button user flow. The button only responds to user events when it's enabled. Furthermore whether the user presses the enter key, or the space bar, or uses the mouse to click, the button responds to all such events with the same &amp;lt;code&amp;gt;clicked&amp;lt;/code&amp;gt; signal. This allows more complex UIs to respond uniformly to a button without having to explicitly specify the manner in which a user interacted with it.&lt;br /&gt;
&lt;br /&gt;
Finally note that no consideration is made for a change in the label or a change in the hover state since both of those changes are strictly visual, they affect the appearance of the button but do not in anyway affect the behavior.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
[[File:user_flow_button.png|Button example]]&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Example: Login form===&lt;br /&gt;
&lt;br /&gt;
A login form's model consists of data representing a username and password that is input by the user, a state to store whether the user is in the process of logging in, and signals indicating whether the user has submitted their credentials or wishes to cancel a currently pending sign-in attempt. Its &amp;lt;code&amp;gt;model.txt&amp;lt;/code&amp;gt; is hence structured as follows:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
Data:&lt;br /&gt;
  username: The username input by the user.&lt;br /&gt;
  password: The user's password being input.&lt;br /&gt;
&lt;br /&gt;
State:&lt;br /&gt;
  status: The sign-in status of the UI, can be one of the following values:&lt;br /&gt;
            NONE - Default state.&lt;br /&gt;
            SIGNING-IN - The UI is in the process of signing in.&lt;br /&gt;
            REJECTED - The sign in was rejected, invalid username or password.&lt;br /&gt;
            UNAVAILABLE - The server is not available.&lt;br /&gt;
            SIGNED-IN - The sign in process succeeded.&lt;br /&gt;
&lt;br /&gt;
Signals:&lt;br /&gt;
  submit: Indicates the user has submitted their login credentials.&lt;br /&gt;
  cancel: The user wishes to cancel the sign-in process.&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The user flow for the login form is below:&lt;br /&gt;
&lt;br /&gt;
[[File:user_flow_login.png|Login example]]&lt;/div&gt;</summary>
		<author><name>Kman</name></author>
		
	</entry>
	<entry>
		<id>https://wiki.spiretrading.com/index.php?title=File:User_flow_login.png&amp;diff=141</id>
		<title>File:User flow login.png</title>
		<link rel="alternate" type="text/html" href="https://wiki.spiretrading.com/index.php?title=File:User_flow_login.png&amp;diff=141"/>
		<updated>2020-07-14T00:17:28Z</updated>

		<summary type="html">&lt;p&gt;Kman: Kman uploaded a new version of File:User flow login.png&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;/div&gt;</summary>
		<author><name>Kman</name></author>
		
	</entry>
	<entry>
		<id>https://wiki.spiretrading.com/index.php?title=UI_Kit&amp;diff=140</id>
		<title>UI Kit</title>
		<link rel="alternate" type="text/html" href="https://wiki.spiretrading.com/index.php?title=UI_Kit&amp;diff=140"/>
		<updated>2020-07-14T00:16:39Z</updated>

		<summary type="html">&lt;p&gt;Kman: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;User interfaces are specified by a set of documents describing a data model, user flow, layout, and styling. This article will go over each of these documents along with how they combine to describe the complete behavior from a small component such a button to larger components such as a login window. The example that will be used in each document is a user interface for a button component.&lt;br /&gt;
&lt;br /&gt;
==Model==&lt;br /&gt;
&lt;br /&gt;
Fundamentally, a UI is a visual representation of a set of data in a given state. The UI takes in that data upon initialization and transforms it based on external actions either provided by the user directly or some other external agent. In order for multiple UI components to work together, individual components signal when certain changes are made to that data or to the state of the component, which allows other UI components to respond and signal changes of their own. The complete description of the data a UI component operates on, the state of the component, as well as the signals it produces form the model and is typically documented in &amp;lt;code&amp;gt;model.txt&amp;lt;/code&amp;gt;. For a simple component such as a button we'd expect to see a label displayed by the button, whether the button is responding to user inputs, whether the mouse is interacting with the button, and finally a signal indicating when the user clicks on it. This would be documented as follows:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
Data:&lt;br /&gt;
  label: The text displayed in the button.&lt;br /&gt;
  enabled: Whether the button is responding to user actions.&lt;br /&gt;
&lt;br /&gt;
State:&lt;br /&gt;
  hovered: Whether the mouse position is within the button's visible region.&lt;br /&gt;
&lt;br /&gt;
Signals:&lt;br /&gt;
  clicked: Indicates the button was clicked by the user.&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
As a general matter, fields that go under &amp;lt;code&amp;gt;Data&amp;lt;/code&amp;gt; are inputs that are provided externally to the UI component, whereas fields that go under &amp;lt;code&amp;gt;State&amp;lt;/code&amp;gt; are internal to the component itself. Typically a button does not know what label it should display and does not manage changes to the label, some external component shall make use of a button and provide it with a label to display. Conversely the button can independently manage whether the mouse is hovered over it on its own by keeping track of the mouse position, it needs no external agent to inform it of this state.&lt;br /&gt;
&lt;br /&gt;
==User Flow==&lt;br /&gt;
&lt;br /&gt;
With the model defined, the user flow describes how the model is transformed based on external events. The user flow is broken down into a set of steps represented by colored shapes and are connected to one another by arrows. In order to follow a step, a list of criteria must be met depending on type of step represented. When a step is followed a function is performed at which point the step is said to be complete and then every arrow pointing away from the step must be evaluated to determine the next step to go to. If a step has no arrows pointing out of it, then that step is said to be a terminal step at which point no further changes to the UI are possible.&lt;br /&gt;
&lt;br /&gt;
Flow charts are documented using software available at https://diagrams.net&lt;br /&gt;
&lt;br /&gt;
===Start===&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
[[File:ui_kit_start.png|Start step]]&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
Every UI component begins at the start step, it appears as a dark green circle and is typically either the left-most step of the user flow or the top-most step. It can also be formally distinguished by the fact that it's the only step that may not have any arrows pointing into it, arrows may only point away from it. The start step does not perform any function and is only used as a visual indicator to quickly determine where the flow chart begins.&lt;br /&gt;
&lt;br /&gt;
If the UI performs any kind of initialization then the start step should have a single arrow pointing towards a step to handles such initialization. Refer to the login window for an example.&lt;br /&gt;
&lt;br /&gt;
===Actions===&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
[[File:ui_kit_action.png|Action step]]&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
Actions are steps that are taken unconditionally and perform a side-effect such as changing the state of the component or updating the model. Actions can be chained together by arrows to form a sequence of side-effects or multiple actions can be consolidated into a single step that performs the sequence. The choice of chaining versus consolidating is stylistic, if a step gets to be too large then it is preferable to break it into multiple steps that are chained together. If there are multiple small actions chained together then it is preferable to consolidate.&lt;br /&gt;
&lt;br /&gt;
Every side-effect specified by an action should be a single sentence that begins with a verb. For example if updating data XYZ in the model to the value 123, then the side-effect should be &amp;quot;Set XYZ to 123.&amp;quot; The function of an action step is execute each side-effect in order.&lt;br /&gt;
&lt;br /&gt;
A no-op can be used to indicate that no side-effect is to be performed. This can come in handy to describe an action state that does nothing but wait.&lt;br /&gt;
&lt;br /&gt;
===Events===&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
[[File:ui_kit_event.png|Event step]]&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
An event is step external to the UI that the UI has a chance to respond to. Events can be triggered by user input such as a keyboard press, mouse movement, or other input device as well as by signals produced by other UI components, such as a button indicating that it has been clicked or an input UI indicating an update to the model. An event step is followed if the event takes place after the completion of the current step's function. While multiple events may happen very close together in time, it is never possible for multiple events to occur simultaneously.&lt;br /&gt;
&lt;br /&gt;
===Conditions===&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
[[File:ui_kit_condition.png|Condition step]]&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
A condition is a step that is followed if at the completion of the current step's function some condition is satisfied. If a step leads to multiple conditions then it must either be the case that only one such condition can possibly be satisfied or each arrow pointing out of the step and into a condition must be labelled numerically starting from &amp;lt;code&amp;gt;0&amp;lt;/code&amp;gt; in which case each condition is tested in ascending order and the first condition that is satisfied is followed. For example consider the following user flow:&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
[[File:ui_kit_priority.png|Prioritizing conditions]]&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
If the current time is 6:30 PM then all three conditions are technically satisfied and so there is an ambiguity about which condition to follow. The numeric labels on the arrows are thus used to prioritize the conditions so that the conditional step &amp;lt;code&amp;gt;current time &amp;gt;= 6:00 PM&amp;lt;/code&amp;gt; is tested first and if satisfied then it's followed without considering the remaining conditions.&lt;br /&gt;
&lt;br /&gt;
===Tests===&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
[[File:ui_kit_test.png|Test step]]&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Similar to the condition step, the test step can also be used to conditionally follow an arrow. The test step itself is followed unconditionally and the function of the step is to perform a test. Once the function is completed a set of labelled arrows pointing away from the step are checked and the arrow whose label satisfies the test is followed.&lt;br /&gt;
&lt;br /&gt;
Both condition steps and test steps are technically interchangeable, the choice of one or the other is stylistic. One should prefer the test step in situations where a clear question can be asked and whose answer is a single value in which case the question is written in the body of the test step and each of the possible values or value ranges is a labelled arrow.&lt;br /&gt;
&lt;br /&gt;
===Signals===&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
[[File:ui_kit_signal.png|Signal step]]&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The function of a signal is to inform other UI components about a change in state so that those other components can respond to such changes in the form of events. That is, a signal produced by one UI component is treated as an event by another UI component. For example, a button UI contains a &amp;lt;code&amp;gt;clicked&amp;lt;/code&amp;gt; signal step indicating that the user clicked on it and in turn a form UI contains a corresponding &amp;lt;code&amp;gt;button clicked&amp;lt;/code&amp;gt; event step where said form may respond by updating its data model.&lt;br /&gt;
&lt;br /&gt;
Similar to an action step, signal steps are followed unconditionally.&lt;br /&gt;
&lt;br /&gt;
===Ambiguities===&lt;br /&gt;
&lt;br /&gt;
An ambiguity is a step that contains multiple arrows that are simultaneously satisfied. A flow chart that contains an ambiguity is ill-formed and must be resolved. For example if a step &amp;lt;code&amp;gt;Q&amp;lt;/code&amp;gt; has an arrow leading into an unconditional step (such as leading into an action or signal step), it must be the only arrow leading out of &amp;lt;code&amp;gt;Q&amp;lt;/code&amp;gt;, any other arrow would necessarily introduce an ambiguity. If a step has multiple arrows leading into conditional steps where more than one condition is satisfied then that too is an ambiguity. Resolving such ambiguity is done by giving each arrow a priority.&lt;br /&gt;
&lt;br /&gt;
===Example: Button===&lt;br /&gt;
&lt;br /&gt;
The following is an example of a simplified button user flow. The button only responds to user events when it's enabled. Furthermore whether the user presses the enter key, or the space bar, or uses the mouse to click, the button responds to all such events with the same &amp;lt;code&amp;gt;clicked&amp;lt;/code&amp;gt; signal. This allows more complex UIs to respond uniformly to a button without having to explicitly specify the manner in which a user interacted with it.&lt;br /&gt;
&lt;br /&gt;
Finally note that no consideration is made for a change in the label or a change in the hover state since both of those changes are strictly visual, they affect the appearance of the button but do not in anyway affect the behavior.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
[[File:user_flow_button.png|Button example]]&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Example: Login form===&lt;br /&gt;
&lt;br /&gt;
A login form's model consists of data representing a username and password that is input by the user, a state to store whether the user is in the process of logging in, and signals indicating whether the user has submitted their credentials or wishes to cancel a currently pending sign-in attempt. Its &amp;lt;code&amp;gt;model.txt&amp;lt;/code&amp;gt; is hence structured as follows:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
Data:&lt;br /&gt;
  username: The username input by the user.&lt;br /&gt;
  password: The user's password being input.&lt;br /&gt;
&lt;br /&gt;
State:&lt;br /&gt;
  status: The sign-in status of the UI, can be one of the following values:&lt;br /&gt;
            NONE - Default state.&lt;br /&gt;
            SIGNING-IN - The UI is in the process of signing in.&lt;br /&gt;
            REJECTED - The sign in was rejected, invalid username or password.&lt;br /&gt;
            UNAVAILABLE - The server is not available.&lt;br /&gt;
            SIGNED-IN - The sign in process succeeded.&lt;br /&gt;
&lt;br /&gt;
Signals:&lt;br /&gt;
  submit: Indicates the user has submitted their login credentials.&lt;br /&gt;
  cancel: The user wishes to cancel the sign-in process.&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The user flow for the login form is below:&lt;br /&gt;
&lt;br /&gt;
[[File:user_flow_login.png|Login example]]&lt;/div&gt;</summary>
		<author><name>Kman</name></author>
		
	</entry>
	<entry>
		<id>https://wiki.spiretrading.com/index.php?title=File:User_flow_login.png&amp;diff=139</id>
		<title>File:User flow login.png</title>
		<link rel="alternate" type="text/html" href="https://wiki.spiretrading.com/index.php?title=File:User_flow_login.png&amp;diff=139"/>
		<updated>2020-07-14T00:16:24Z</updated>

		<summary type="html">&lt;p&gt;Kman: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;/div&gt;</summary>
		<author><name>Kman</name></author>
		
	</entry>
	<entry>
		<id>https://wiki.spiretrading.com/index.php?title=UI_Kit&amp;diff=138</id>
		<title>UI Kit</title>
		<link rel="alternate" type="text/html" href="https://wiki.spiretrading.com/index.php?title=UI_Kit&amp;diff=138"/>
		<updated>2020-07-13T23:39:03Z</updated>

		<summary type="html">&lt;p&gt;Kman: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;User interfaces are specified by a set of documents describing a data model, user flow, layout, and styling. This article will go over each of these documents along with how they combine to describe the complete behavior from a small component such a button to larger components such as a login window. The example that will be used in each document is a user interface for a button component.&lt;br /&gt;
&lt;br /&gt;
==Model==&lt;br /&gt;
&lt;br /&gt;
Fundamentally, a UI is a visual representation of a set of data in a given state. The UI takes in that data upon initialization and transforms it based on external actions either provided by the user directly or some other external agent. In order for multiple UI components to work together, individual components signal when certain changes are made to that data or to the state of the component, which allows other UI components to respond and signal changes of their own. The complete description of the data a UI component operates on, the state of the component, as well as the signals it produces form the model and is typically documented in &amp;lt;code&amp;gt;model.txt&amp;lt;/code&amp;gt;. For a simple component such as a button we'd expect to see a label displayed by the button, whether the button is responding to user inputs, whether the mouse is interacting with the button, and finally a signal indicating when the user clicks on it. This would be documented as follows:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
Data:&lt;br /&gt;
  label: The text displayed in the button.&lt;br /&gt;
  enabled: Whether the button is responding to user actions.&lt;br /&gt;
&lt;br /&gt;
State:&lt;br /&gt;
  hovered: Whether the mouse position is within the button's visible region.&lt;br /&gt;
&lt;br /&gt;
Signals:&lt;br /&gt;
  clicked: Indicates the button was clicked by the user.&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
As a general matter, fields that go under &amp;lt;code&amp;gt;Data&amp;lt;/code&amp;gt; are inputs that are provided externally to the UI component, whereas fields that go under &amp;lt;code&amp;gt;State&amp;lt;/code&amp;gt; are internal to the component itself. Typically a button does not know what label it should display and does not manage changes to the label, some external component shall make use of a button and provide it with a label to display. Conversely the button can independently manage whether the mouse is hovered over it on its own by keeping track of the mouse position, it needs no external agent to inform it of this state.&lt;br /&gt;
&lt;br /&gt;
==User Flow==&lt;br /&gt;
&lt;br /&gt;
With the model defined, the user flow describes how the model is transformed based on external events. The user flow is broken down into a set of steps represented by colored shapes and are connected to one another by arrows. In order to follow a step, a list of criteria must be met depending on type of step represented. When a step is followed a function is performed at which point the step is said to be complete and then every arrow pointing away from the step must be evaluated to determine the next step to go to. If a step has no arrows pointing out of it, then that step is said to be a terminal step at which point no further changes to the UI are possible.&lt;br /&gt;
&lt;br /&gt;
Flow charts are documented using software available at https://diagrams.net&lt;br /&gt;
&lt;br /&gt;
===Start===&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
[[File:ui_kit_start.png|Start step]]&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
Every UI component begins at the start step, it appears as a dark green circle and is typically either the left-most step of the user flow or the top-most step. It can also be formally distinguished by the fact that it's the only step that may not have any arrows pointing into it, arrows may only point away from it. The start step does not perform any function and is only used as a visual indicator to quickly determine where the flow chart begins.&lt;br /&gt;
&lt;br /&gt;
If the UI performs any kind of initialization then the start step should have a single arrow pointing towards a step to handles such initialization. Refer to the login window for an example.&lt;br /&gt;
&lt;br /&gt;
===Actions===&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
[[File:ui_kit_action.png|Action step]]&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
Actions are steps that are taken unconditionally and perform a side-effect such as changing the state of the component or updating the model. Actions can be chained together by arrows to form a sequence of side-effects or multiple actions can be consolidated into a single step that performs the sequence. The choice of chaining versus consolidating is stylistic, if a step gets to be too large then it is preferable to break it into multiple steps that are chained together. If there are multiple small actions chained together then it is preferable to consolidate.&lt;br /&gt;
&lt;br /&gt;
Every side-effect specified by an action should be a single sentence that begins with a verb. For example if updating data XYZ in the model to the value 123, then the side-effect should be &amp;quot;Set XYZ to 123.&amp;quot; The function of an action step is execute each side-effect in order.&lt;br /&gt;
&lt;br /&gt;
A no-op can be used to indicate that no side-effect is to be performed. This can come in handy to describe an action state that does nothing but wait.&lt;br /&gt;
&lt;br /&gt;
===Events===&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
[[File:ui_kit_event.png|Event step]]&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
An event is step external to the UI that the UI has a chance to respond to. Events can be triggered by user input such as a keyboard press, mouse movement, or other input device as well as by signals produced by other UI components, such as a button indicating that it has been clicked or an input UI indicating an update to the model. An event step is followed if the event takes place after the completion of the current step's function. While multiple events may happen very close together in time, it is never possible for multiple events to occur simultaneously.&lt;br /&gt;
&lt;br /&gt;
===Conditions===&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
[[File:ui_kit_condition.png|Condition step]]&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
A condition is a step that is followed if at the completion of the current step's function some condition is satisfied. If a step leads to multiple conditions then it must either be the case that only one such condition can possibly be satisfied or each arrow pointing out of the step and into a condition must be labelled numerically starting from &amp;lt;code&amp;gt;0&amp;lt;/code&amp;gt; in which case each condition is tested in ascending order and the first condition that is satisfied is followed. For example consider the following user flow:&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
[[File:ui_kit_priority.png|Prioritizing conditions]]&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
If the current time is 6:30 PM then all three conditions are technically satisfied and so there is an ambiguity about which condition to follow. The numeric labels on the arrows are thus used to prioritize the conditions so that the conditional step &amp;lt;code&amp;gt;current time &amp;gt;= 6:00 PM&amp;lt;/code&amp;gt; is tested first and if satisfied then it's followed without considering the remaining conditions.&lt;br /&gt;
&lt;br /&gt;
===Tests===&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
[[File:ui_kit_test.png|Test step]]&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Similar to the condition step, the test step can also be used to conditionally follow an arrow. The test step itself is followed unconditionally and the function of the step is to perform a test. Once the function is completed a set of labelled arrows pointing away from the step are checked and the arrow whose label satisfies the test is followed.&lt;br /&gt;
&lt;br /&gt;
Both condition steps and test steps are technically interchangeable, the choice of one or the other is stylistic. One should prefer the test step in situations where a clear question can be asked and whose answer is a single value in which case the question is written in the body of the test step and each of the possible values or value ranges is a labelled arrow.&lt;br /&gt;
&lt;br /&gt;
===Signals===&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
[[File:ui_kit_signal.png|Signal step]]&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The function of a signal is to inform other UI components about a change in state so that those other components can respond to such changes in the form of events. That is, a signal produced by one UI component is treated as an event by another UI component. For example, a button UI contains a &amp;lt;code&amp;gt;clicked&amp;lt;/code&amp;gt; signal step indicating that the user clicked on it and in turn a form UI contains a corresponding &amp;lt;code&amp;gt;button clicked&amp;lt;/code&amp;gt; event step where said form may respond by updating its data model.&lt;br /&gt;
&lt;br /&gt;
Similar to an action step, signal steps are followed unconditionally.&lt;br /&gt;
&lt;br /&gt;
===Ambiguities===&lt;br /&gt;
&lt;br /&gt;
An ambiguity is a step that contains multiple arrows that are simultaneously satisfied. A flow chart that contains an ambiguity is ill-formed and must be resolved. For example if a step &amp;lt;code&amp;gt;Q&amp;lt;/code&amp;gt; has an arrow leading into an unconditional step (such as leading into an action or signal step), it must be the only arrow leading out of &amp;lt;code&amp;gt;Q&amp;lt;/code&amp;gt;, any other arrow would necessarily introduce an ambiguity. If a step has multiple arrows leading into conditional steps where more than one condition is satisfied then that too is an ambiguity. Resolving such ambiguity is done by giving each arrow a priority.&lt;br /&gt;
&lt;br /&gt;
===Example: Button===&lt;br /&gt;
&lt;br /&gt;
The following is an example of a simplified button user flow. The button only responds to user events when it's enabled. Furthermore whether the user presses the enter key, or the space bar, or uses the mouse to click, the button responds to all such events with the same &amp;lt;code&amp;gt;clicked&amp;lt;/code&amp;gt; signal. This allows more complex UIs to respond uniformly to a button without having to explicitly specify the manner in which a user interacted with it.&lt;br /&gt;
&lt;br /&gt;
Finally note that no consideration is made for a change in the label or a change in the hover state since both of those changes are strictly visual, they affect the appearance of the button but do not in anyway affect the behavior.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
[[File:user_flow_button.png|Button example]]&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;/div&gt;</summary>
		<author><name>Kman</name></author>
		
	</entry>
	<entry>
		<id>https://wiki.spiretrading.com/index.php?title=UI_Kit&amp;diff=137</id>
		<title>UI Kit</title>
		<link rel="alternate" type="text/html" href="https://wiki.spiretrading.com/index.php?title=UI_Kit&amp;diff=137"/>
		<updated>2020-07-13T23:38:44Z</updated>

		<summary type="html">&lt;p&gt;Kman: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;User interfaces are specified by a set of documents describing a data model, user flow, layout, and styling. This article will go over each of these documents along with how they combine to describe the complete behavior from a small component such a button to larger components such as a login window. The example that will be used in each document is a user interface for a button component.&lt;br /&gt;
&lt;br /&gt;
==Model==&lt;br /&gt;
&lt;br /&gt;
Fundamentally, a UI is a visual representation of a set of data in a given state. The UI takes in that data upon initialization and transforms it based on external actions either provided by the user directly or some other external agent. In order for multiple UI components to work together, individual components signal when certain changes are made to that data or to the state of the component, which allows other UI components to respond and signal changes of their own. The complete description of the data a UI component operates on, the state of the component, as well as the signals it produces form the model and is typically documented in &amp;lt;code&amp;gt;model.txt&amp;lt;/code&amp;gt;. For a simple component such as a button we'd expect to see a label displayed by the button, whether the button is responding to user inputs, whether the mouse is interacting with the button, and finally a signal indicating when the user clicks on it. This would be documented as follows:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
Data:&lt;br /&gt;
  label: The text displayed in the button.&lt;br /&gt;
  enabled: Whether the button is responding to user actions.&lt;br /&gt;
&lt;br /&gt;
State:&lt;br /&gt;
  hovered: Whether the mouse position is within the button's visible region.&lt;br /&gt;
&lt;br /&gt;
Signals:&lt;br /&gt;
  clicked: Indicates the button was clicked by the user.&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
As a general matter, fields that go under &amp;lt;code&amp;gt;Data&amp;lt;/code&amp;gt; are inputs that are provided externally to the UI component, whereas fields that go under &amp;lt;code&amp;gt;State&amp;lt;/code&amp;gt; are internal to the component itself. Typically a button does not know what label it should display and does not manage changes to the label, some external component shall make use of a button and provide it with a label to display. Conversely the button can independently manage whether the mouse is hovered over it on its own by keeping track of the mouse position, it needs no external agent to inform it of this state.&lt;br /&gt;
&lt;br /&gt;
==User Flow==&lt;br /&gt;
&lt;br /&gt;
With the model defined, the user flow describes how the model is transformed based on external events. The user flow is broken down into a set of steps represented by colored shapes and are connected to one another by arrows. In order to follow a step, a list of criteria must be met depending on type of step represented. When a step is followed a function is performed at which point the step is said to be complete and then every arrow pointing away from the step must be evaluated to determine the next step to go to. If a step has no arrows pointing out of it, then that step is said to be a terminal step at which point no further changes to the UI are possible.&lt;br /&gt;
&lt;br /&gt;
Flow charts are documented using software available at https://diagrams.net&lt;br /&gt;
&lt;br /&gt;
===Start===&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
[[File:ui_kit_start.png|Start step]]&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
Every UI component begins at the start step, it appears as a dark green circle and is typically either the left-most step of the user flow or the top-most step. It can also be formally distinguished by the fact that it's the only step that may not have any arrows pointing into it, arrows may only point away from it. The start step does not perform any function and is only used as a visual indicator to quickly determine where the flow chart begins.&lt;br /&gt;
&lt;br /&gt;
If the UI performs any kind of initialization then the start step should have a single arrow pointing towards a step to handles such initialization. Refer to the login window for an example.&lt;br /&gt;
&lt;br /&gt;
===Actions===&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
[[File:ui_kit_action.png|Action step]]&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
Actions are steps that are taken unconditionally and perform a side-effect such as changing the state of the component or updating the model. Actions can be chained together by arrows to form a sequence of side-effects or multiple actions can be consolidated into a single step that performs the sequence. The choice of chaining versus consolidating is stylistic, if a step gets to be too large then it is preferable to break it into multiple steps that are chained together. If there are multiple small actions chained together then it is preferable to consolidate.&lt;br /&gt;
&lt;br /&gt;
Every side-effect specified by an action should be a single sentence that begins with a verb. For example if updating data XYZ in the model to the value 123, then the side-effect should be &amp;quot;Set XYZ to 123.&amp;quot; The function of an action step is execute each side-effect in order.&lt;br /&gt;
&lt;br /&gt;
A no-op can be used to indicate that no side-effect is to be performed. This can come in handy to describe an action state that does nothing but wait.&lt;br /&gt;
&lt;br /&gt;
===Events===&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
[[File:ui_kit_event.png|Event step]]&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
An event is step external to the UI that the UI has a chance to respond to. Events can be triggered by user input such as a keyboard press, mouse movement, or other input device as well as by signals produced by other UI components, such as a button indicating that it has been clicked or an input UI indicating an update to the model. An event step is followed if the event takes place after the completion of the current step's function. While multiple events may happen very close together in time, it is never possible for multiple events to occur simultaneously.&lt;br /&gt;
&lt;br /&gt;
===Conditions===&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
[[File:ui_kit_condition.png|Condition step]]&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
A condition is a step that is followed if at the completion of the current step's function some condition is satisfied. If a step leads to multiple conditions then it must either be the case that only one such condition can possibly be satisfied or each arrow pointing out of the step and into a condition must be labelled numerically starting from &amp;lt;code&amp;gt;0&amp;lt;/code&amp;gt; in which case each condition is tested in ascending order and the first condition that is satisfied is followed. For example consider the following user flow:&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
[[File:ui_kit_priority.png|Prioritizing conditions]]&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
If the current time is 6:30 PM then all three conditions are technically satisfied and so there is an ambiguity about which condition to follow. The numeric labels on the arrows are thus used to prioritize the conditions so that the conditional step &amp;lt;code&amp;gt;current time &amp;gt;= 6:00 PM&amp;lt;/code&amp;gt; is tested first and if satisfied then it's followed without considering the remaining conditions.&lt;br /&gt;
&lt;br /&gt;
===Tests===&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
[[File:ui_kit_test.png|Test step]]&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Similar to the condition step, the test step can also be used to conditionally follow an arrow. The test step itself is followed unconditionally and the function of the step is to perform a test. Once the function is completed a set of labelled arrows pointing away from the step are checked and the arrow whose label satisfies the test is followed.&lt;br /&gt;
&lt;br /&gt;
Both condition steps and test steps are technically interchangeable, the choice of one or the other is stylistic. One should prefer the test step in situations where a clear question can be asked and whose answer is a single value in which case the question is written in the body of the test step and each of the possible values or value ranges is a labelled arrow.&lt;br /&gt;
&lt;br /&gt;
===Signals===&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
[[File:ui_kit_signal.png|Signal step]]&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The function of a signal is to inform other UI components about a change in state so that those other components can respond to such changes in the form of events. That is, a signal produced by one UI component is treated as an event by another UI component. For example, a button UI contains a &amp;lt;code&amp;gt;clicked&amp;lt;/code&amp;gt; signal step indicating that the user clicked on it and in turn a form UI contains a corresponding &amp;lt;code&amp;gt;button clicked&amp;lt;/code&amp;gt; event step where said form may respond by updating its data model.&lt;br /&gt;
&lt;br /&gt;
Similar to an action step, signal steps are followed unconditionally.&lt;br /&gt;
&lt;br /&gt;
===Ambiguities===&lt;br /&gt;
&lt;br /&gt;
An ambiguity is a step that contains multiple arrows that are simultaneously satisfied. A flow chart that contains an ambiguity is ill-formed and must be resolved. For example if a step &amp;lt;code&amp;gt;Q&amp;lt;/code&amp;gt; has an arrow leading into an unconditional step (such as leading into an action or signal step), it must be the only arrow leading out of &amp;lt;code&amp;gt;Q&amp;lt;/code&amp;gt;, any other arrow would necessarily introduce an ambiguity. If a step has multiple arrows leading into conditional steps where more than one condition is satisfied then that too is an ambiguity. Resolving such ambiguity is done by giving each arrow a priority.&lt;br /&gt;
&lt;br /&gt;
===Example: Button===&lt;br /&gt;
&lt;br /&gt;
The following is an example of a simplified button user flow. The button only responds to user events when it's enabled. Furthermore whether the user presses the enter key, or the space bar, or uses the mouse to click, the button responds to all such events with the same &amp;lt;code&amp;gt;clicked&amp;lt;/code&amp;gt; signal. This allows more complex UIs to respond uniformly to a button without having to explicitly specify the manner in which a user interacted with it.&lt;br /&gt;
&lt;br /&gt;
Finally note that no consideration is made for a change in the label or a change in the hover state since both of those changes are strictly visual, they affect the appearance of the button but do not in anyway affect the behavior.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
[[File:ui_kit_button.png|Button example]]&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;/div&gt;</summary>
		<author><name>Kman</name></author>
		
	</entry>
	<entry>
		<id>https://wiki.spiretrading.com/index.php?title=File:User_flow_button.png&amp;diff=136</id>
		<title>File:User flow button.png</title>
		<link rel="alternate" type="text/html" href="https://wiki.spiretrading.com/index.php?title=File:User_flow_button.png&amp;diff=136"/>
		<updated>2020-07-13T23:38:42Z</updated>

		<summary type="html">&lt;p&gt;Kman: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;/div&gt;</summary>
		<author><name>Kman</name></author>
		
	</entry>
	<entry>
		<id>https://wiki.spiretrading.com/index.php?title=UI_Kit&amp;diff=135</id>
		<title>UI Kit</title>
		<link rel="alternate" type="text/html" href="https://wiki.spiretrading.com/index.php?title=UI_Kit&amp;diff=135"/>
		<updated>2020-07-13T23:26:57Z</updated>

		<summary type="html">&lt;p&gt;Kman: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;User interfaces are specified by a set of documents describing a data model, user flow, layout, and styling. This article will go over each of these documents along with how they combine to describe the complete behavior from a small component such a button to larger components such as a login window. The example that will be used in each document is a user interface for a button component.&lt;br /&gt;
&lt;br /&gt;
==Model==&lt;br /&gt;
&lt;br /&gt;
Fundamentally, a UI is a visual representation of a set of data in a given state. The UI takes in that data upon initialization and transforms it based on external actions either provided by the user directly or some other external agent. In order for multiple UI components to work together, individual components signal when certain changes are made to that data or to the state of the component, which allows other UI components to respond and signal changes of their own. The complete description of the data a UI component operates on, the state of the component, as well as the signals it produces form the model and is typically documented in &amp;lt;code&amp;gt;model.txt&amp;lt;/code&amp;gt;. For a simple component such as a button we'd expect to see a label displayed by the button, whether the button is responding to user inputs, whether the mouse is interacting with the button, and finally a signal indicating when the user clicks on it. This would be documented as follows:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
Data:&lt;br /&gt;
  label: The text displayed in the button.&lt;br /&gt;
  enabled: Whether the button is responding to user actions.&lt;br /&gt;
&lt;br /&gt;
State:&lt;br /&gt;
  hovered: Whether the mouse position is within the button's visible region.&lt;br /&gt;
&lt;br /&gt;
Signals:&lt;br /&gt;
  clicked: Indicates the button was clicked by the user.&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
As a general matter, fields that go under &amp;lt;code&amp;gt;Data&amp;lt;/code&amp;gt; are inputs that are provided externally to the UI component, whereas fields that go under &amp;lt;code&amp;gt;State&amp;lt;/code&amp;gt; are internal to the component itself. Typically a button does not know what label it should display and does not manage changes to the label, some external component shall make use of a button and provide it with a label to display. Conversely the button can independently manage whether the mouse is hovered over it on its own by keeping track of the mouse position, it needs no external agent to inform it of this state.&lt;br /&gt;
&lt;br /&gt;
==User Flow==&lt;br /&gt;
&lt;br /&gt;
With the model defined, the user flow describes how the model is transformed based on external events. The user flow is broken down into a set of steps represented by colored shapes and are connected to one another by arrows. In order to follow a step, a list of criteria must be met depending on type of step represented. When a step is followed a function is performed at which point the step is said to be complete and then every arrow pointing away from the step must be evaluated to determine the next step to go to. If a step has no arrows pointing out of it, then that step is said to be a terminal step at which point no further changes to the UI are possible.&lt;br /&gt;
&lt;br /&gt;
Flow charts are documented using software available at https://diagrams.net&lt;br /&gt;
&lt;br /&gt;
===Start===&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
[[File:ui_kit_start.png|Start step]]&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
Every UI component begins at the start step, it appears as a dark green circle and is typically either the left-most step of the user flow or the top-most step. It can also be formally distinguished by the fact that it's the only step that may not have any arrows pointing into it, arrows may only point away from it. The start step does not perform any function and is only used as a visual indicator to quickly determine where the flow chart begins.&lt;br /&gt;
&lt;br /&gt;
If the UI performs any kind of initialization then the start step should have a single arrow pointing towards a step to handles such initialization. Refer to the login window for an example.&lt;br /&gt;
&lt;br /&gt;
===Actions===&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
[[File:ui_kit_action.png|Action step]]&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
Actions are steps that are taken unconditionally and perform a side-effect such as changing the state of the component or updating the model. Actions can be chained together by arrows to form a sequence of side-effects or multiple actions can be consolidated into a single step that performs the sequence. The choice of chaining versus consolidating is stylistic, if a step gets to be too large then it is preferable to break it into multiple steps that are chained together. If there are multiple small actions chained together then it is preferable to consolidate.&lt;br /&gt;
&lt;br /&gt;
Every side-effect specified by an action should be a single sentence that begins with a verb. For example if updating data XYZ in the model to the value 123, then the side-effect should be &amp;quot;Set XYZ to 123.&amp;quot; The function of an action step is execute each side-effect in order.&lt;br /&gt;
&lt;br /&gt;
A no-op can be used to indicate that no side-effect is to be performed. This can come in handy to describe an action state that does nothing but wait.&lt;br /&gt;
&lt;br /&gt;
===Events===&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
[[File:ui_kit_event.png|Event step]]&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
An event is step external to the UI that the UI has a chance to respond to. Events can be triggered by user input such as a keyboard press, mouse movement, or other input device as well as by signals produced by other UI components, such as a button indicating that it has been clicked or an input UI indicating an update to the model. An event step is followed if the event takes place after the completion of the current step's function. While multiple events may happen very close together in time, it is never possible for multiple events to occur simultaneously.&lt;br /&gt;
&lt;br /&gt;
===Conditions===&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
[[File:ui_kit_condition.png|Condition step]]&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
A condition is a step that is followed if at the completion of the current step's function some condition is satisfied. If a step leads to multiple conditions then it must either be the case that only one such condition can possibly be satisfied or each arrow pointing out of the step and into a condition must be labelled numerically starting from &amp;lt;code&amp;gt;0&amp;lt;/code&amp;gt; in which case each condition is tested in ascending order and the first condition that is satisfied is followed. For example consider the following user flow:&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
[[File:ui_kit_priority.png|Prioritizing conditions]]&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
If the current time is 6:30 PM then all three conditions are technically satisfied and so there is an ambiguity about which condition to follow. The numeric labels on the arrows are thus used to prioritize the conditions so that the conditional step &amp;lt;code&amp;gt;current time &amp;gt;= 6:00 PM&amp;lt;/code&amp;gt; is tested first and if satisfied then it's followed without considering the remaining conditions.&lt;br /&gt;
&lt;br /&gt;
===Tests===&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
[[File:ui_kit_test.png|Test step]]&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Similar to the condition step, the test step can also be used to conditionally follow an arrow. The test step itself is followed unconditionally and the function of the step is to perform a test. Once the function is completed a set of labelled arrows pointing away from the step are checked and the arrow whose label satisfies the test is followed.&lt;br /&gt;
&lt;br /&gt;
Both condition steps and test steps are technically interchangeable, the choice of one or the other is stylistic. One should prefer the test step in situations where a clear question can be asked and whose answer is a single value in which case the question is written in the body of the test step and each of the possible values or value ranges is a labelled arrow.&lt;br /&gt;
&lt;br /&gt;
===Signals===&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
[[File:ui_kit_signal.png|Signal step]]&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The function of a signal is to inform other UI components about a change in state so that those other components can respond to such changes in the form of events. That is, a signal produced by one UI component is treated as an event by another UI component. For example, a button UI contains a &amp;lt;code&amp;gt;clicked&amp;lt;/code&amp;gt; signal step indicating that the user clicked on it and in turn a form UI contains a corresponding &amp;lt;code&amp;gt;button clicked&amp;lt;/code&amp;gt; event step where said form may respond by updating its data model.&lt;br /&gt;
&lt;br /&gt;
Similar to an action step, signal steps are followed unconditionally.&lt;br /&gt;
&lt;br /&gt;
===Ambiguities===&lt;br /&gt;
&lt;br /&gt;
An ambiguity is a step that contains multiple arrows that are simultaneously satisfied. A flow chart that contains an ambiguity is ill-formed and must be resolved. For example if a step &amp;lt;code&amp;gt;Q&amp;lt;/code&amp;gt; has an arrow leading into an unconditional step (such as leading into an action or signal step), it must be the only arrow leading out of &amp;lt;code&amp;gt;Q&amp;lt;/code&amp;gt;, any other arrow would necessarily introduce an ambiguity. If a step has multiple arrows leading into conditional steps where more than one condition is satisfied then that too is an ambiguity. Resolving such ambiguity is done by giving each arrow a priority.&lt;/div&gt;</summary>
		<author><name>Kman</name></author>
		
	</entry>
	<entry>
		<id>https://wiki.spiretrading.com/index.php?title=UI_Kit&amp;diff=134</id>
		<title>UI Kit</title>
		<link rel="alternate" type="text/html" href="https://wiki.spiretrading.com/index.php?title=UI_Kit&amp;diff=134"/>
		<updated>2020-07-13T23:11:24Z</updated>

		<summary type="html">&lt;p&gt;Kman: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;User interfaces are specified by a set of documents describing a data model, user flow, layout, and styling. This article will go over each of these documents along with how they combine to describe the complete behavior from a small component such a button to larger components such as a login window. The example that will be used in each document is a user interface for a button component.&lt;br /&gt;
&lt;br /&gt;
==Model==&lt;br /&gt;
&lt;br /&gt;
Fundamentally, a UI is a visual representation of a set of data in a given state. The UI takes in that data upon initialization and transforms it based on external actions either provided by the user directly or some other external agent. In order for multiple UI components to work together, individual components signal when certain changes are made to that data or to the state of the component, which allows other UI components to respond and signal changes of their own. The complete description of the data a UI component operates on, the state of the component, as well as the signals it produces form the model and is typically documented in &amp;lt;code&amp;gt;model.txt&amp;lt;/code&amp;gt;. For a simple component such as a button we'd expect to see a label displayed by the button, whether the button is responding to user inputs, whether the mouse is interacting with the button, and finally a signal indicating when the user clicks on it. This would be documented as follows:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
Data:&lt;br /&gt;
  label: The text displayed in the button.&lt;br /&gt;
  enabled: Whether the button is responding to user actions.&lt;br /&gt;
&lt;br /&gt;
State:&lt;br /&gt;
  hovered: Whether the mouse position is within the button's visible region.&lt;br /&gt;
&lt;br /&gt;
Signals:&lt;br /&gt;
  clicked: Indicates the button was clicked by the user.&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
As a general matter, fields that go under &amp;lt;code&amp;gt;Data&amp;lt;/code&amp;gt; are inputs that are provided externally to the UI component, whereas fields that go under &amp;lt;code&amp;gt;State&amp;lt;/code&amp;gt; are internal to the component itself. Typically a button does not know what label it should display and does not manage changes to the label, some external component shall make use of a button and provide it with a label to display. Conversely the button can independently manage whether the mouse is hovered over it on its own by keeping track of the mouse position, it needs no external agent to inform it of this state.&lt;br /&gt;
&lt;br /&gt;
==User Flow==&lt;br /&gt;
&lt;br /&gt;
With the model defined, the user flow describes how the model is transformed based on external events. The user flow is broken down into a set of steps represented by colored shapes and are connected to one another by arrows. In order to follow a step, a list of criteria must be met depending on type of step represented. When a step is followed a function is performed at which point the step is said to be complete and then every arrow pointing away from the step must be evaluated to determine the next step to go to. If a step has no arrows pointing out of it, then that step is said to be a terminal step at which point no further changes to the UI are possible.&lt;br /&gt;
&lt;br /&gt;
Flow charts are documented using software available at https://diagrams.net&lt;br /&gt;
&lt;br /&gt;
===Start===&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
[[File:ui_kit_start.png|Start step]]&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
Every UI component begins at the start step, it appears as a dark green circle and is typically either the left-most step of the user flow or the top-most step. It can also be formally distinguished by the fact that it's the only step that may not have any arrows pointing into it, arrows may only point away from it. The start step does not perform any function and is only used as a visual indicator to quickly determine where the flow chart begins.&lt;br /&gt;
&lt;br /&gt;
If the UI performs any kind of initialization then the start step should have a single arrow pointing towards a step to handles such initialization. Refer to the login window for an example.&lt;br /&gt;
&lt;br /&gt;
===Actions===&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
[[File:ui_kit_action.png|Action step]]&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
Actions are steps that are taken unconditionally and perform a side-effect such as changing the state of the component or updating the model. Actions can be chained together by arrows to form a sequence of side-effects or multiple actions can be consolidated into a single step that performs the sequence. The choice of chaining versus consolidating is stylistic, if a step gets to be too large then it is preferable to break it into multiple steps that are chained together. If there are multiple small actions chained together then it is preferable to consolidate.&lt;br /&gt;
&lt;br /&gt;
Every side-effect specified by an action should be a single sentence that begins with a verb. For example if updating data XYZ in the model to the value 123, then the side-effect should be &amp;quot;Set XYZ to 123.&amp;quot; The function of an action step is execute each side-effect in order.&lt;br /&gt;
&lt;br /&gt;
A no-op can be used to indicate that no side-effect is to be performed. This can come in handy to describe an action state that does nothing but wait.&lt;br /&gt;
&lt;br /&gt;
===Events===&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
[[File:ui_kit_event.png|Event step]]&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
An event is step external to the UI that the UI has a chance to respond to. Events can be triggered by user input such as a keyboard press, mouse movement, or other input device as well as by signals produced by other UI components, such as a button indicating that it has been clicked or an input UI indicating an update to the model. An event step is followed if the event takes place after the completion of the current step's function. While multiple events may happen very close together in time, it is never possible for multiple events to occur simultaneously.&lt;br /&gt;
&lt;br /&gt;
===Conditions===&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
[[File:ui_kit_condition.png|Condition step]]&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
A condition is a step that is followed if at the completion of the current step's function some condition is satisfied. If a step leads to multiple conditions then it must either be the case that only one such condition can possibly be satisfied or each arrow pointing out of the step and into a condition must be labelled numerically starting from &amp;lt;code&amp;gt;0&amp;lt;/code&amp;gt; in which case each condition is tested in ascending order and the first condition that is satisfied is followed. For example consider the following user flow:&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
[[File:ui_kit_priority.png|Prioritizing conditions]]&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
If the current time is 6:30 PM then all three conditions are technically satisfied and so there is an ambiguity about which condition to follow. The numeric labels on the arrows are thus used to prioritize the conditions so that the conditional step &amp;lt;code&amp;gt;current time &amp;gt;= 6:00 PM&amp;lt;/code&amp;gt; is tested first and if satisfied then it's followed without considering the remaining conditions.&lt;br /&gt;
&lt;br /&gt;
===Tests===&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
[[File:ui_kit_test.png|Test step]]&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Similar to the condition step, the test step can also be used to conditionally follow an arrow. The test step itself is followed unconditionally and the function of the step is to perform a test. Once the function is completed a set of labelled arrows pointing away from the step are checked and the arrow whose label satisfies the test is followed.&lt;br /&gt;
&lt;br /&gt;
Both condition steps and test steps are technically interchangeable, the choice of one or the other is stylistic. One should prefer the test step in situations where a clear question can be asked and whose answer is a single value in which case the question is written in the body of the test step and each of the possible values or value ranges is a labelled arrow.&lt;br /&gt;
&lt;br /&gt;
===Signals===&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
[[File:ui_kit_signal.png|Signal step]]&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The function of a signal is to inform other UI components about a change in state so that those other components can respond to such changes in the form of events. That is, a signal produced by one UI component is treated as an event by another UI component. For example, a button UI contains a &amp;lt;code&amp;gt;clicked&amp;lt;/code&amp;gt; signal step indicating that the user clicked on it and in turn a form UI contains a corresponding &amp;lt;code&amp;gt;button clicked&amp;lt;/code&amp;gt; event step where said form may respond by updating its data model.&lt;br /&gt;
&lt;br /&gt;
Similar to an action step, signal steps are followed unconditionally.&lt;/div&gt;</summary>
		<author><name>Kman</name></author>
		
	</entry>
	<entry>
		<id>https://wiki.spiretrading.com/index.php?title=File:Ui_kit_signal.png&amp;diff=133</id>
		<title>File:Ui kit signal.png</title>
		<link rel="alternate" type="text/html" href="https://wiki.spiretrading.com/index.php?title=File:Ui_kit_signal.png&amp;diff=133"/>
		<updated>2020-07-13T23:09:57Z</updated>

		<summary type="html">&lt;p&gt;Kman: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;/div&gt;</summary>
		<author><name>Kman</name></author>
		
	</entry>
	<entry>
		<id>https://wiki.spiretrading.com/index.php?title=UI_Kit&amp;diff=132</id>
		<title>UI Kit</title>
		<link rel="alternate" type="text/html" href="https://wiki.spiretrading.com/index.php?title=UI_Kit&amp;diff=132"/>
		<updated>2020-07-13T23:01:44Z</updated>

		<summary type="html">&lt;p&gt;Kman: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;User interfaces are specified by a set of documents describing a data model, user flow, layout, and styling. This article will go over each of these documents along with how they combine to describe the complete behavior from a small component such a button to larger components such as a login window. The example that will be used in each document is a user interface for a button component.&lt;br /&gt;
&lt;br /&gt;
==Model==&lt;br /&gt;
&lt;br /&gt;
Fundamentally, a UI is a visual representation of a set of data in a given state. The UI takes in that data upon initialization and transforms it based on external actions either provided by the user directly or some other external agent. In order for multiple UI components to work together, individual components signal when certain changes are made to that data or to the state of the component, which allows other UI components to respond and signal changes of their own. The complete description of the data a UI component operates on, the state of the component, as well as the signals it produces form the model and is typically documented in &amp;lt;code&amp;gt;model.txt&amp;lt;/code&amp;gt;. For a simple component such as a button we'd expect to see a label displayed by the button, whether the button is responding to user inputs, whether the mouse is interacting with the button, and finally a signal indicating when the user clicks on it. This would be documented as follows:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
Data:&lt;br /&gt;
  label: The text displayed in the button.&lt;br /&gt;
  enabled: Whether the button is responding to user actions.&lt;br /&gt;
&lt;br /&gt;
State:&lt;br /&gt;
  hovered: Whether the mouse position is within the button's visible region.&lt;br /&gt;
&lt;br /&gt;
Signals:&lt;br /&gt;
  clicked: Indicates the button was clicked by the user.&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
As a general matter, fields that go under &amp;lt;code&amp;gt;Data&amp;lt;/code&amp;gt; are inputs that are provided externally to the UI component, whereas fields that go under &amp;lt;code&amp;gt;State&amp;lt;/code&amp;gt; are internal to the component itself. Typically a button does not know what label it should display and does not manage changes to the label, some external component shall make use of a button and provide it with a label to display. Conversely the button can independently manage whether the mouse is hovered over it on its own by keeping track of the mouse position, it needs no external agent to inform it of this state.&lt;br /&gt;
&lt;br /&gt;
==User Flow==&lt;br /&gt;
&lt;br /&gt;
With the model defined, the user flow describes how the model is transformed based on external events. The user flow is broken down into a set of steps represented by colored shapes and are connected to one another by arrows. In order to follow a step, a list of criteria must be met depending on type of step represented. When a step is followed a function is performed at which point the step is said to be complete and then every arrow pointing away from the step must be evaluated to determine the next step to go to. If a step has no arrows pointing out of it, then that step is said to be a terminal step at which point no further changes to the UI are possible.&lt;br /&gt;
&lt;br /&gt;
Flow charts are documented using software available at https://diagrams.net&lt;br /&gt;
&lt;br /&gt;
===Start===&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
[[File:ui_kit_start.png|Start step]]&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
Every UI component begins at the start step, it appears as a dark green circle and is typically either the left-most step of the user flow or the top-most step. It can also be formally distinguished by the fact that it's the only step that may not have any arrows pointing into it, arrows may only point away from it. The start step does not perform any function and is only used as a visual indicator to quickly determine where the flow chart begins.&lt;br /&gt;
&lt;br /&gt;
If the UI performs any kind of initialization then the start step should have a single arrow pointing towards a step to handles such initialization. Refer to the login window for an example.&lt;br /&gt;
&lt;br /&gt;
===Actions===&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
[[File:ui_kit_action.png|Action step]]&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
Actions are steps that are taken unconditionally and perform a side-effect such as changing the state of the component or updating the model. Actions can be chained together by arrows to form a sequence of side-effects or multiple actions can be consolidated into a single step that performs the sequence. The choice of chaining versus consolidating is stylistic, if a step gets to be too large then it is preferable to break it into multiple steps that are chained together. If there are multiple small actions chained together then it is preferable to consolidate.&lt;br /&gt;
&lt;br /&gt;
Every side-effect specified by an action should be a single sentence that begins with a verb. For example if updating data XYZ in the model to the value 123, then the side-effect should be &amp;quot;Set XYZ to 123.&amp;quot; The function of an action step is execute each side-effect in order.&lt;br /&gt;
&lt;br /&gt;
A no-op can be used to indicate that no side-effect is to be performed. This can come in handy to describe an action state that does nothing but wait.&lt;br /&gt;
&lt;br /&gt;
===Events===&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
[[File:ui_kit_event.png|Event step]]&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
An event is step external to the UI that the UI has a chance to respond to. Events can be triggered by user input such as a keyboard press, mouse movement, or other input device as well as by signals produced by other UI components, such as a button indicating that it has been clicked or an input UI indicating an update to the model. An event step is followed if the event takes place after the completion of the current step's function. While multiple events may happen very close together in time, it is never possible for multiple events to occur simultaneously.&lt;br /&gt;
&lt;br /&gt;
===Conditions===&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
[[File:ui_kit_condition.png|Condition step]]&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
A condition is a step that is followed if at the completion of the current step's function some condition is satisfied. If a step leads to multiple conditions then it must either be the case that only one such condition can possibly be satisfied or each arrow pointing out of the step and into a condition must be labelled numerically starting from &amp;lt;code&amp;gt;0&amp;lt;/code&amp;gt; in which case each condition is tested in ascending order and the first condition that is satisfied is followed. For example consider the following user flow:&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
[[File:ui_kit_priority.png|Prioritizing conditions]]&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
If the current time is 6:30 PM then all three conditions are technically satisfied and so there is an ambiguity about which condition to follow. The numeric labels on the arrows are thus used to prioritize the conditions so that the conditional step &amp;lt;code&amp;gt;current time &amp;gt;= 6:00 PM&amp;lt;/code&amp;gt; is tested first and if satisfied then it's followed without considering the remaining conditions.&lt;br /&gt;
&lt;br /&gt;
===Tests===&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
[[File:ui_kit_test.png|Test step]]&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Similar to the condition step, the test step can also be used to conditionally follow an arrow. The test step itself is followed unconditionally and the function of the step is to perform a test. Once the function is completed a set of labelled arrows pointing away from the step are checked and the arrow whose label satisfies the test is followed.&lt;br /&gt;
&lt;br /&gt;
Both condition steps and test steps are technically interchangeable, the choice of one or the other is stylistic. One should prefer the test step in situations where a clear question can be asked and whose answer is a single value in which case the question is written in the body of the test step and each of the possible values or value ranges is a labelled arrow.&lt;/div&gt;</summary>
		<author><name>Kman</name></author>
		
	</entry>
	<entry>
		<id>https://wiki.spiretrading.com/index.php?title=UI_Kit&amp;diff=131</id>
		<title>UI Kit</title>
		<link rel="alternate" type="text/html" href="https://wiki.spiretrading.com/index.php?title=UI_Kit&amp;diff=131"/>
		<updated>2020-07-13T23:00:42Z</updated>

		<summary type="html">&lt;p&gt;Kman: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;User interfaces are specified by a set of documents describing a data model, user flow, layout, and styling. This article will go over each of these documents along with how they combine to describe the complete behavior from a small component such a button to larger components such as a login window. The example that will be used in each document is a user interface for a button component.&lt;br /&gt;
&lt;br /&gt;
==Model==&lt;br /&gt;
&lt;br /&gt;
Fundamentally, a UI is a visual representation of a set of data in a given state. The UI takes in that data upon initialization and transforms it based on external actions either provided by the user directly or some other external agent. In order for multiple UI components to work together, individual components signal when certain changes are made to that data or to the state of the component, which allows other UI components to respond and signal changes of their own. The complete description of the data a UI component operates on, the state of the component, as well as the signals it produces form the model and is typically documented in &amp;lt;code&amp;gt;model.txt&amp;lt;/code&amp;gt;. For a simple component such as a button we'd expect to see a label displayed by the button, whether the button is responding to user inputs, whether the mouse is interacting with the button, and finally a signal indicating when the user clicks on it. This would be documented as follows:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
Data:&lt;br /&gt;
  label: The text displayed in the button.&lt;br /&gt;
  enabled: Whether the button is responding to user actions.&lt;br /&gt;
&lt;br /&gt;
State:&lt;br /&gt;
  hovered: Whether the mouse position is within the button's visible region.&lt;br /&gt;
&lt;br /&gt;
Signals:&lt;br /&gt;
  clicked: Indicates the button was clicked by the user.&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
As a general matter, fields that go under &amp;lt;code&amp;gt;Data&amp;lt;/code&amp;gt; are inputs that are provided externally to the UI component, whereas fields that go under &amp;lt;code&amp;gt;State&amp;lt;/code&amp;gt; are internal to the component itself. Typically a button does not know what label it should display and does not manage changes to the label, some external component shall make use of a button and provide it with a label to display. Conversely the button can independently manage whether the mouse is hovered over it on its own by keeping track of the mouse position, it needs no external agent to inform it of this state.&lt;br /&gt;
&lt;br /&gt;
==User Flow==&lt;br /&gt;
&lt;br /&gt;
With the model defined, the user flow describes how the model is transformed based on external events. The user flow is broken down into a set of steps represented by colored shapes and are connected to one another by arrows. In order to follow a step, a list of criteria must be met depending on type of step represented. When a step is followed a function is performed at which point the step is said to be complete and then every arrow pointing away from the step must be evaluated to determine the next step to go to. If a step has no arrows pointing out of it, then that step is said to be a terminal step at which point no further changes to the UI are possible.&lt;br /&gt;
&lt;br /&gt;
===Start===&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
[[File:ui_kit_start.png|Start step]]&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
Every UI component begins at the start step, it appears as a dark green circle and is typically either the left-most step of the user flow or the top-most step. It can also be formally distinguished by the fact that it's the only step that may not have any arrows pointing into it, arrows may only point away from it. The start step does not perform any function and is only used as a visual indicator to quickly determine where the flow chart begins.&lt;br /&gt;
&lt;br /&gt;
If the UI performs any kind of initialization then the start step should have a single arrow pointing towards a step to handles such initialization. Refer to the login window for an example.&lt;br /&gt;
&lt;br /&gt;
===Actions===&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
[[File:ui_kit_action.png|Action step]]&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
Actions are steps that are taken unconditionally and perform a side-effect such as changing the state of the component or updating the model. Actions can be chained together by arrows to form a sequence of side-effects or multiple actions can be consolidated into a single step that performs the sequence. The choice of chaining versus consolidating is stylistic, if a step gets to be too large then it is preferable to break it into multiple steps that are chained together. If there are multiple small actions chained together then it is preferable to consolidate.&lt;br /&gt;
&lt;br /&gt;
Every side-effect specified by an action should be a single sentence that begins with a verb. For example if updating data XYZ in the model to the value 123, then the side-effect should be &amp;quot;Set XYZ to 123.&amp;quot; The function of an action step is execute each side-effect in order.&lt;br /&gt;
&lt;br /&gt;
A no-op can be used to indicate that no side-effect is to be performed. This can come in handy to describe an action state that does nothing but wait.&lt;br /&gt;
&lt;br /&gt;
===Events===&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
[[File:ui_kit_event.png|Event step]]&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
An event is step external to the UI that the UI has a chance to respond to. Events can be triggered by user input such as a keyboard press, mouse movement, or other input device as well as by signals produced by other UI components, such as a button indicating that it has been clicked or an input UI indicating an update to the model. An event step is followed if the event takes place after the completion of the current step's function. While multiple events may happen very close together in time, it is never possible for multiple events to occur simultaneously.&lt;br /&gt;
&lt;br /&gt;
===Conditions===&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
[[File:ui_kit_condition.png|Condition step]]&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
A condition is a step that is followed if at the completion of the current step's function some condition is satisfied. If a step leads to multiple conditions then it must either be the case that only one such condition can possibly be satisfied or each arrow pointing out of the step and into a condition must be labelled numerically starting from &amp;lt;code&amp;gt;0&amp;lt;/code&amp;gt; in which case each condition is tested in ascending order and the first condition that is satisfied is followed. For example consider the following user flow:&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
[[File:ui_kit_priority.png|Prioritizing conditions]]&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
If the current time is 6:30 PM then all three conditions are technically satisfied and so there is an ambiguity about which condition to follow. The numeric labels on the arrows are thus used to prioritize the conditions so that the conditional step &amp;lt;code&amp;gt;current time &amp;gt;= 6:00 PM&amp;lt;/code&amp;gt; is tested first and if satisfied then it's followed without considering the remaining conditions.&lt;br /&gt;
&lt;br /&gt;
===Tests===&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
[[File:ui_kit_test.png|Test step]]&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Similar to the condition step, the test step can also be used to conditionally follow an arrow. The test step itself is followed unconditionally and the function of the step is to perform a test. Once the function is completed a set of labelled arrows pointing away from the step are checked and the arrow whose label satisfies the test is followed.&lt;br /&gt;
&lt;br /&gt;
Both condition steps and test steps are technically interchangeable, the choice of one or the other is stylistic. One should prefer the test step in situations where a clear question can be asked and whose answer is a single value in which case the question is written in the body of the test step and each of the possible values or value ranges is a labelled arrow.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Flow charts are documented using software available at https://diagrams.net&lt;/div&gt;</summary>
		<author><name>Kman</name></author>
		
	</entry>
	<entry>
		<id>https://wiki.spiretrading.com/index.php?title=UI_Kit&amp;diff=130</id>
		<title>UI Kit</title>
		<link rel="alternate" type="text/html" href="https://wiki.spiretrading.com/index.php?title=UI_Kit&amp;diff=130"/>
		<updated>2020-07-13T22:56:55Z</updated>

		<summary type="html">&lt;p&gt;Kman: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;User interfaces are specified by a set of documents describing a data model, user flow, layout, and styling. This article will go over each of these documents along with how they combine to describe the complete behavior from a small component such a button to larger components such as a login window. The example that will be used in each document is a user interface for a button component.&lt;br /&gt;
&lt;br /&gt;
==Model==&lt;br /&gt;
&lt;br /&gt;
Fundamentally, a UI is a visual representation of a set of data in a given state. The UI takes in that data upon initialization and transforms it based on external actions either provided by the user directly or some other external agent. In order for multiple UI components to work together, individual components signal when certain changes are made to that data or to the state of the component, which allows other UI components to respond and signal changes of their own. The complete description of the data a UI component operates on, the state of the component, as well as the signals it produces form the model and is typically documented in &amp;lt;code&amp;gt;model.txt&amp;lt;/code&amp;gt;. For a simple component such as a button we'd expect to see a label displayed by the button, whether the button is responding to user inputs, whether the mouse is interacting with the button, and finally a signal indicating when the user clicks on it. This would be documented as follows:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
Data:&lt;br /&gt;
  label: The text displayed in the button.&lt;br /&gt;
  enabled: Whether the button is responding to user actions.&lt;br /&gt;
&lt;br /&gt;
State:&lt;br /&gt;
  hovered: Whether the mouse position is within the button's visible region.&lt;br /&gt;
&lt;br /&gt;
Signals:&lt;br /&gt;
  clicked: Indicates the button was clicked by the user.&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
As a general matter, fields that go under &amp;lt;code&amp;gt;Data&amp;lt;/code&amp;gt; are inputs that are provided externally to the UI component, whereas fields that go under &amp;lt;code&amp;gt;State&amp;lt;/code&amp;gt; are internal to the component itself. Typically a button does not know what label it should display and does not manage changes to the label, some external component shall make use of a button and provide it with a label to display. Conversely the button can independently manage whether the mouse is hovered over it on its own by keeping track of the mouse position, it needs no external agent to inform it of this state.&lt;br /&gt;
&lt;br /&gt;
==User Flow==&lt;br /&gt;
&lt;br /&gt;
With the model defined, the user flow describes how the model is transformed based on external events. The user flow is broken down into a set of steps represented by colored shapes and are connected to one another by arrows. In order to follow a step, a list of criteria must be met depending on type of step represented. When a step is followed a function is performed at which point the step is said to be complete and then every arrow pointing away from the step must be evaluated to determine the next step to go to. If a step has no arrows pointing out of it, then that step is said to be a terminal step at which point no further changes to the UI are possible.&lt;br /&gt;
&lt;br /&gt;
===Start===&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
[[File:ui_kit_start.png|Start step]]&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
Every UI component begins at the start step, it appears as a dark green circle and is typically either the left-most step of the user flow or the top-most step. It can also be formally distinguished by the fact that it's the only step that may not have any arrows pointing into it, arrows may only point away from it. The start step does not perform any function and is only used as a visual indicator to quickly determine where the flow chart begins.&lt;br /&gt;
&lt;br /&gt;
If the UI performs any kind of initialization then the start step should have a single arrow pointing towards a step to handles such initialization. Refer to the login window for an example.&lt;br /&gt;
&lt;br /&gt;
===Actions===&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
[[File:ui_kit_action.png|Action step]]&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
Actions are steps that are taken unconditionally and perform a side-effect such as changing the state of the component or updating the model. Actions can be chained together by arrows to form a sequence of side-effects or multiple actions can be consolidated into a single step that performs the sequence. The choice of chaining versus consolidating is stylistic, if a step gets to be too large then it is preferable to break it into multiple steps that are chained together. If there are multiple small actions chained together then it is preferable to consolidate.&lt;br /&gt;
&lt;br /&gt;
Every side-effect specified by an action should be a single sentence that begins with a verb. For example if updating data XYZ in the model to the value 123, then the side-effect should be &amp;quot;Set XYZ to 123.&amp;quot; The function of an action step is execute each side-effect in order.&lt;br /&gt;
&lt;br /&gt;
A no-op can be used to indicate that no side-effect is to be performed. This can come in handy to describe an action state that does nothing but wait.&lt;br /&gt;
&lt;br /&gt;
===Events===&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
[[File:ui_kit_event.png|Event step]]&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
An event is step external to the UI that the UI has a chance to respond to. Events can be triggered by user input such as a keyboard press, mouse movement, or other input device as well as by signals produced by other UI components, such as a button indicating that it has been clicked or an input UI indicating an update to the model. An event step is followed if the event takes place after the completion of the current step's function. While multiple events may happen very close together in time, it is never possible for multiple events to occur simultaneously.&lt;br /&gt;
&lt;br /&gt;
===Conditions===&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
[[File:ui_kit_condition.png|Condition step]]&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
A condition is a step that is followed if at the completion of the current step's function some condition is satisfied. If a step leads to multiple conditions then it must either be the case that only one such condition can possibly be satisfied or each arrow pointing out of the step and into a condition must be labelled numerically starting from &amp;lt;code&amp;gt;0&amp;lt;/code&amp;gt; in which case each condition is tested in ascending order and the first condition that is satisfied is followed. For example consider the following user flow:&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
[[File:ui_kit_priority.png|Prioritizing conditions]]&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
If the current time is 6:30 PM then all three conditions are technically satisfied and so there is an ambiguity about which condition to follow. The numeric labels on the arrows are thus used to prioritize the conditions so that the conditional step &amp;lt;code&amp;gt;current time &amp;gt;= 6:00 PM&amp;lt;/code&amp;gt; is tested first and if satisfied then it's followed without considering the remaining conditions.&lt;br /&gt;
&lt;br /&gt;
===Tests===&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
[[File:ui_kit_test.png|Test step]]&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Similar to the condition step, the test step can also be used to conditionally follow an arrow. The test step itself is followed unconditionally and the function of the step is to perform a test. Once the function is completed a set of labelled arrows pointing away from the step are checked and the arrow whose label satisfies the test is followed.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Flow charts are documented using software available at https://diagrams.net&lt;/div&gt;</summary>
		<author><name>Kman</name></author>
		
	</entry>
	<entry>
		<id>https://wiki.spiretrading.com/index.php?title=File:Ui_kit_test.png&amp;diff=129</id>
		<title>File:Ui kit test.png</title>
		<link rel="alternate" type="text/html" href="https://wiki.spiretrading.com/index.php?title=File:Ui_kit_test.png&amp;diff=129"/>
		<updated>2020-07-13T22:56:35Z</updated>

		<summary type="html">&lt;p&gt;Kman: Kman uploaded a new version of File:Ui kit test.png&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;/div&gt;</summary>
		<author><name>Kman</name></author>
		
	</entry>
	<entry>
		<id>https://wiki.spiretrading.com/index.php?title=File:Ui_kit_test.png&amp;diff=128</id>
		<title>File:Ui kit test.png</title>
		<link rel="alternate" type="text/html" href="https://wiki.spiretrading.com/index.php?title=File:Ui_kit_test.png&amp;diff=128"/>
		<updated>2020-07-13T22:55:39Z</updated>

		<summary type="html">&lt;p&gt;Kman: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;/div&gt;</summary>
		<author><name>Kman</name></author>
		
	</entry>
	<entry>
		<id>https://wiki.spiretrading.com/index.php?title=UI_Kit&amp;diff=127</id>
		<title>UI Kit</title>
		<link rel="alternate" type="text/html" href="https://wiki.spiretrading.com/index.php?title=UI_Kit&amp;diff=127"/>
		<updated>2020-07-13T22:47:17Z</updated>

		<summary type="html">&lt;p&gt;Kman: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;User interfaces are specified by a set of documents describing a data model, user flow, layout, and styling. This article will go over each of these documents along with how they combine to describe the complete behavior from a small component such a button to larger components such as a login window. The example that will be used in each document is a user interface for a button component.&lt;br /&gt;
&lt;br /&gt;
==Model==&lt;br /&gt;
&lt;br /&gt;
Fundamentally, a UI is a visual representation of a set of data in a given state. The UI takes in that data upon initialization and transforms it based on external actions either provided by the user directly or some other external agent. In order for multiple UI components to work together, individual components signal when certain changes are made to that data or to the state of the component, which allows other UI components to respond and signal changes of their own. The complete description of the data a UI component operates on, the state of the component, as well as the signals it produces form the model and is typically documented in &amp;lt;code&amp;gt;model.txt&amp;lt;/code&amp;gt;. For a simple component such as a button we'd expect to see a label displayed by the button, whether the button is responding to user inputs, whether the mouse is interacting with the button, and finally a signal indicating when the user clicks on it. This would be documented as follows:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
Data:&lt;br /&gt;
  label: The text displayed in the button.&lt;br /&gt;
  enabled: Whether the button is responding to user actions.&lt;br /&gt;
&lt;br /&gt;
State:&lt;br /&gt;
  hovered: Whether the mouse position is within the button's visible region.&lt;br /&gt;
&lt;br /&gt;
Signals:&lt;br /&gt;
  clicked: Indicates the button was clicked by the user.&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
As a general matter, fields that go under &amp;lt;code&amp;gt;Data&amp;lt;/code&amp;gt; are inputs that are provided externally to the UI component, whereas fields that go under &amp;lt;code&amp;gt;State&amp;lt;/code&amp;gt; are internal to the component itself. Typically a button does not know what label it should display and does not manage changes to the label, some external component shall make use of a button and provide it with a label to display. Conversely the button can independently manage whether the mouse is hovered over it on its own by keeping track of the mouse position, it needs no external agent to inform it of this state.&lt;br /&gt;
&lt;br /&gt;
==User Flow==&lt;br /&gt;
&lt;br /&gt;
With the model defined, the user flow describes how the model is transformed based on external events. The user flow is broken down into a set of steps represented by colored shapes and are connected to one another by arrows. In order to follow a step, a list of criteria must be met depending on type of step represented. When a step is followed a function is performed at which point the step is said to be complete and then every arrow pointing away from the step must be evaluated to determine the next step to go to. If a step has no arrows pointing out of it, then that step is said to be a terminal step at which point no further changes to the UI are possible.&lt;br /&gt;
&lt;br /&gt;
===Start===&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
[[File:ui_kit_start.png|Start step]]&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
Every UI component begins at the start step, it appears as a dark green circle and is typically either the left-most step of the user flow or the top-most step. It can also be formally distinguished by the fact that it's the only step that may not have any arrows pointing into it, arrows may only point away from it. The start step does not perform any function and is only used as a visual indicator to quickly determine where the flow chart begins.&lt;br /&gt;
&lt;br /&gt;
If the UI performs any kind of initialization then the start step should have a single arrow pointing towards a step to handles such initialization. Refer to the login window for an example.&lt;br /&gt;
&lt;br /&gt;
===Actions===&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
[[File:ui_kit_action.png|Action step]]&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
Actions are steps that are taken unconditionally and perform a side-effect such as changing the state of the component or updating the model. Actions can be chained together by arrows to form a sequence of side-effects or multiple actions can be consolidated into a single step that performs the sequence. The choice of chaining versus consolidating is stylistic, if a step gets to be too large then it is preferable to break it into multiple steps that are chained together. If there are multiple small actions chained together then it is preferable to consolidate.&lt;br /&gt;
&lt;br /&gt;
Every side-effect specified by an action should be a single sentence that begins with a verb. For example if updating data XYZ in the model to the value 123, then the side-effect should be &amp;quot;Set XYZ to 123.&amp;quot; The function of an action step is execute each side-effect in order.&lt;br /&gt;
&lt;br /&gt;
A no-op can be used to indicate that no side-effect is to be performed. This can come in handy to describe an action state that does nothing but wait.&lt;br /&gt;
&lt;br /&gt;
===Events===&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
[[File:ui_kit_event.png|Event step]]&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
An event is step external to the UI that the UI has a chance to respond to. Events can be triggered by user input such as a keyboard press, mouse movement, or other input device as well as by signals produced by other UI components, such as a button indicating that it has been clicked or an input UI indicating an update to the model. An event step is followed if the event takes place after the completion of the current step's function. While multiple events may happen very close together in time, it is never possible for multiple events to occur simultaneously.&lt;br /&gt;
&lt;br /&gt;
===Conditions===&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
[[File:ui_kit_condition.png|Start state]]&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
A condition is a step that is followed if at the completion of the current step's function some condition is satisfied. If a step leads to multiple conditions then it must either be the case that only one such condition can possibly be satisfied or each arrow pointing out of the step and into a condition must be labelled numerically starting from &amp;lt;code&amp;gt;0&amp;lt;/code&amp;gt; in which case each condition is tested in ascending order and the first condition that is satisfied is followed. For example consider the following user flow:&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
[[File:ui_kit_priority.png|Prioritizing conditions]]&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
If the current time is 6:30 PM then all three conditions are technically satisfied and so there is an ambiguity about which condition to follow. The numeric labels on the arrows are thus used to prioritize the conditions so that &amp;lt;code&amp;gt;current time &amp;gt;= 6:00 PM&amp;lt;/code&amp;gt; is tested first and if satisfied then it's followed without considering the remaining conditions.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Flow charts are documented using software available at https://diagrams.net&lt;/div&gt;</summary>
		<author><name>Kman</name></author>
		
	</entry>
	<entry>
		<id>https://wiki.spiretrading.com/index.php?title=File:Ui_kit_priority.png&amp;diff=126</id>
		<title>File:Ui kit priority.png</title>
		<link rel="alternate" type="text/html" href="https://wiki.spiretrading.com/index.php?title=File:Ui_kit_priority.png&amp;diff=126"/>
		<updated>2020-07-13T22:43:55Z</updated>

		<summary type="html">&lt;p&gt;Kman: Kman uploaded a new version of File:Ui kit priority.png&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Summary ==&lt;br /&gt;
Condition state of a user flow diagram.&lt;/div&gt;</summary>
		<author><name>Kman</name></author>
		
	</entry>
	<entry>
		<id>https://wiki.spiretrading.com/index.php?title=File:Ui_kit_priority.png&amp;diff=125</id>
		<title>File:Ui kit priority.png</title>
		<link rel="alternate" type="text/html" href="https://wiki.spiretrading.com/index.php?title=File:Ui_kit_priority.png&amp;diff=125"/>
		<updated>2020-07-13T22:43:15Z</updated>

		<summary type="html">&lt;p&gt;Kman: Condition state of a user flow diagram.&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Summary ==&lt;br /&gt;
Condition state of a user flow diagram.&lt;/div&gt;</summary>
		<author><name>Kman</name></author>
		
	</entry>
	<entry>
		<id>https://wiki.spiretrading.com/index.php?title=UI_Kit&amp;diff=124</id>
		<title>UI Kit</title>
		<link rel="alternate" type="text/html" href="https://wiki.spiretrading.com/index.php?title=UI_Kit&amp;diff=124"/>
		<updated>2020-07-13T22:38:46Z</updated>

		<summary type="html">&lt;p&gt;Kman: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;User interfaces are specified by a set of documents describing a data model, user flow, layout, and styling. This article will go over each of these documents along with how they combine to describe the complete behavior from a small component such a button to larger components such as a login window. The example that will be used in each document is a user interface for a button component.&lt;br /&gt;
&lt;br /&gt;
==Model==&lt;br /&gt;
&lt;br /&gt;
Fundamentally, a UI is a visual representation of a set of data in a given state. The UI takes in that data upon initialization and transforms it based on external actions either provided by the user directly or some other external agent. In order for multiple UI components to work together, individual components signal when certain changes are made to that data or to the state of the component, which allows other UI components to respond and signal changes of their own. The complete description of the data a UI component operates on, the state of the component, as well as the signals it produces form the model and is typically documented in &amp;lt;code&amp;gt;model.txt&amp;lt;/code&amp;gt;. For a simple component such as a button we'd expect to see a label displayed by the button, whether the button is responding to user inputs, whether the mouse is interacting with the button, and finally a signal indicating when the user clicks on it. This would be documented as follows:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
Data:&lt;br /&gt;
  label: The text displayed in the button.&lt;br /&gt;
  enabled: Whether the button is responding to user actions.&lt;br /&gt;
&lt;br /&gt;
State:&lt;br /&gt;
  hovered: Whether the mouse position is within the button's visible region.&lt;br /&gt;
&lt;br /&gt;
Signals:&lt;br /&gt;
  clicked: Indicates the button was clicked by the user.&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
As a general matter, fields that go under &amp;lt;code&amp;gt;Data&amp;lt;/code&amp;gt; are inputs that are provided externally to the UI component, whereas fields that go under &amp;lt;code&amp;gt;State&amp;lt;/code&amp;gt; are internal to the component itself. Typically a button does not know what label it should display and does not manage changes to the label, some external component shall make use of a button and provide it with a label to display. Conversely the button can independently manage whether the mouse is hovered over it on its own by keeping track of the mouse position, it needs no external agent to inform it of this state.&lt;br /&gt;
&lt;br /&gt;
==User Flow==&lt;br /&gt;
&lt;br /&gt;
With the model defined, the user flow describes how the model is transformed based on external events. The user flow is broken down into a set of steps represented by colored shapes and are connected to one another by arrows. In order to follow a step, a list of criteria must be met depending on type of step represented. When a step is followed a function is performed at which point the step is said to be complete and then every arrow pointing away from the step must be evaluated to determine the next step to go to. If a step has no arrows pointing out of it, then that step is said to be a terminal step at which point no further changes to the UI are possible.&lt;br /&gt;
&lt;br /&gt;
===Start===&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
[[File:ui_kit_start.png|Start step]]&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
Every UI component begins at the start step, it appears as a dark green circle and is typically either the left-most step of the user flow or the top-most step. It can also be formally distinguished by the fact that it's the only step that may not have any arrows pointing into it, arrows may only point away from it. The start step does not perform any function and is only used as a visual indicator to quickly determine where the flow chart begins.&lt;br /&gt;
&lt;br /&gt;
If the UI performs any kind of initialization then the start step should have a single arrow pointing towards a step to handles such initialization. Refer to the login window for an example.&lt;br /&gt;
&lt;br /&gt;
===Actions===&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
[[File:ui_kit_action.png|Action step]]&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
Actions are steps that are taken unconditionally and perform a side-effect such as changing the state of the component or updating the model. Actions can be chained together by arrows to form a sequence of side-effects or multiple actions can be consolidated into a single step that performs the sequence. The choice of chaining versus consolidating is stylistic, if a step gets to be too large then it is preferable to break it into multiple steps that are chained together. If there are multiple small actions chained together then it is preferable to consolidate.&lt;br /&gt;
&lt;br /&gt;
Every side-effect specified by an action should be a single sentence that begins with a verb. For example if updating data XYZ in the model to the value 123, then the side-effect should be &amp;quot;Set XYZ to 123.&amp;quot; The function of an action step is execute each side-effect in order.&lt;br /&gt;
&lt;br /&gt;
A no-op can be used to indicate that no side-effect is to be performed. This can come in handy to describe an action state that does nothing but wait.&lt;br /&gt;
&lt;br /&gt;
===Events===&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
[[File:ui_kit_event.png|Event step]]&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
An event is step external to the UI that the UI has a chance to respond to. Events can be triggered by user input such as a keyboard press, mouse movement, or other input device as well as by signals produced by other UI components, such as a button indicating that it has been clicked or an input UI indicating an update to the model. An event step is followed if the event takes place after the completion of the current step's function. While multiple events may happen very close together in time, it is never possible for multiple events to occur simultaneously.&lt;br /&gt;
&lt;br /&gt;
===Conditions===&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
[[File:ui_kit_condition.png|Start state]]&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
A condition is a step that is followed if at the completion of the current step's function some condition is satisfied. If a step leads to multiple conditions then it must either be the case that only one such condition can possibly be satisfied or each arrow pointing out of the step and into a condition must be labelled numerically starting from &amp;lt;code&amp;gt;0&amp;lt;/code&amp;gt; in which case each condition is tested in ascending order and the first condition that is satisfied is followed.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Flow charts are documented using software available at https://diagrams.net&lt;/div&gt;</summary>
		<author><name>Kman</name></author>
		
	</entry>
	<entry>
		<id>https://wiki.spiretrading.com/index.php?title=File:Ui_kit_event.png&amp;diff=123</id>
		<title>File:Ui kit event.png</title>
		<link rel="alternate" type="text/html" href="https://wiki.spiretrading.com/index.php?title=File:Ui_kit_event.png&amp;diff=123"/>
		<updated>2020-07-13T22:32:24Z</updated>

		<summary type="html">&lt;p&gt;Kman: Condition state of a user flow diagram.&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Summary ==&lt;br /&gt;
Condition state of a user flow diagram.&lt;/div&gt;</summary>
		<author><name>Kman</name></author>
		
	</entry>
	<entry>
		<id>https://wiki.spiretrading.com/index.php?title=UI_Kit&amp;diff=122</id>
		<title>UI Kit</title>
		<link rel="alternate" type="text/html" href="https://wiki.spiretrading.com/index.php?title=UI_Kit&amp;diff=122"/>
		<updated>2020-07-13T22:22:32Z</updated>

		<summary type="html">&lt;p&gt;Kman: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;User interfaces are specified by a set of documents describing a data model, user flow, layout, and styling. This article will go over each of these documents along with how they combine to describe the complete behavior from a small component such a button to larger components such as a login window. The example that will be used in each document is a user interface for a button component.&lt;br /&gt;
&lt;br /&gt;
==Model==&lt;br /&gt;
&lt;br /&gt;
Fundamentally, a UI is a visual representation of a set of data in a given state. The UI takes in that data upon initialization and transforms it based on external actions either provided by the user directly or some other external agent. In order for multiple UI components to work together, individual components signal when certain changes are made to that data or to the state of the component, which allows other UI components to respond and signal changes of their own. The complete description of the data a UI component operates on, the state of the component, as well as the signals it produces form the model and is typically documented in &amp;lt;code&amp;gt;model.txt&amp;lt;/code&amp;gt;. For a simple component such as a button we'd expect to see a label displayed by the button, whether the button is responding to user inputs, whether the mouse is interacting with the button, and finally a signal indicating when the user clicks on it. This would be documented as follows:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
Data:&lt;br /&gt;
  label: The text displayed in the button.&lt;br /&gt;
  enabled: Whether the button is responding to user actions.&lt;br /&gt;
&lt;br /&gt;
State:&lt;br /&gt;
  hovered: Whether the mouse position is within the button's visible region.&lt;br /&gt;
&lt;br /&gt;
Signals:&lt;br /&gt;
  clicked: Indicates the button was clicked by the user.&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
As a general matter, fields that go under &amp;lt;code&amp;gt;Data&amp;lt;/code&amp;gt; are inputs that are provided externally to the UI component, whereas fields that go under &amp;lt;code&amp;gt;State&amp;lt;/code&amp;gt; are internal to the component itself. Typically a button does not know what label it should display and does not manage changes to the label, some external component shall make use of a button and provide it with a label to display. Conversely the button can independently manage whether the mouse is hovered over it on its own by keeping track of the mouse position, it needs no external agent to inform it of this state.&lt;br /&gt;
&lt;br /&gt;
==User Flow==&lt;br /&gt;
&lt;br /&gt;
With the model defined, the user flow describes how the model is transformed based on external events. The user flow is broken down into a set of steps represented by colored shapes and are connected to one another by arrows. In order to follow a step, a list of criteria must be met depending on type of step represented. When a step is followed a function is performed at which point the step is said to be complete and then every arrow pointing away from the step must be evaluated to determine the next step to go to. If a step has no arrows pointing out of it, then that step is said to be a terminal step at which point no further changes to the UI are possible.&lt;br /&gt;
&lt;br /&gt;
===Start===&lt;br /&gt;
&lt;br /&gt;
[[File:ui_kit_start.png|Start step]]&lt;br /&gt;
&lt;br /&gt;
Every UI component begins at the start step, it appears as a dark green circle and is typically either the left-most step of the user flow or the top-most step. It can also be formally distinguished by the fact that it's the only step that may not have any arrows pointing into it, arrows may only point away from it. The start step does not perform any function and is only used as a visual indicator to quickly determine where the flow chart begins.&lt;br /&gt;
&lt;br /&gt;
If the UI performs any kind of initialization then the start step should have a single arrow pointing towards a step to handles such initialization. Refer to the login window for an example.&lt;br /&gt;
&lt;br /&gt;
===Actions===&lt;br /&gt;
&lt;br /&gt;
[[File:ui_kit_action.png|Start state]]&lt;br /&gt;
&lt;br /&gt;
Actions are steps that are taken unconditionally and perform a side-effect such as changing the state of the component or updating the model. Actions can be chained together by arrows to form a sequence of side-effects or multiple actions can be consolidated into a single step that performs the sequence. The choice of chaining versus consolidating is stylistic, if a step gets to be too large then it is preferable to break it into multiple steps that are chained together. If there are multiple small actions chained together then it is preferable to consolidate.&lt;br /&gt;
&lt;br /&gt;
Every side-effect specified by an action should be a single sentence that begins with a verb. For example if updating data XYZ in the model to the value 123, then the side-effect should be &amp;quot;Set XYZ to 123.&amp;quot; The function of an action step is execute each side-effect in order.&lt;br /&gt;
&lt;br /&gt;
A no-op can be used to indicate that no side-effect is to be performed. This can come in handy to describe an action state that does nothing but wait.&lt;br /&gt;
&lt;br /&gt;
===Conditions===&lt;br /&gt;
&lt;br /&gt;
[[File:ui_kit_condition.png|Start state]]&lt;br /&gt;
&lt;br /&gt;
A condition is a step that is followed if at the completion of the current step's function some condition is true.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Flow charts are documented using software available at https://diagrams.net&lt;/div&gt;</summary>
		<author><name>Kman</name></author>
		
	</entry>
	<entry>
		<id>https://wiki.spiretrading.com/index.php?title=File:Ui_kit_condition.png&amp;diff=121</id>
		<title>File:Ui kit condition.png</title>
		<link rel="alternate" type="text/html" href="https://wiki.spiretrading.com/index.php?title=File:Ui_kit_condition.png&amp;diff=121"/>
		<updated>2020-07-13T22:11:49Z</updated>

		<summary type="html">&lt;p&gt;Kman: Condition state of a user flow diagram.&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Summary ==&lt;br /&gt;
Condition state of a user flow diagram.&lt;/div&gt;</summary>
		<author><name>Kman</name></author>
		
	</entry>
	<entry>
		<id>https://wiki.spiretrading.com/index.php?title=File:Ui_kit_action.png&amp;diff=120</id>
		<title>File:Ui kit action.png</title>
		<link rel="alternate" type="text/html" href="https://wiki.spiretrading.com/index.php?title=File:Ui_kit_action.png&amp;diff=120"/>
		<updated>2020-07-13T21:57:47Z</updated>

		<summary type="html">&lt;p&gt;Kman: A user flow action state.&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Summary ==&lt;br /&gt;
A user flow action state.&lt;/div&gt;</summary>
		<author><name>Kman</name></author>
		
	</entry>
	<entry>
		<id>https://wiki.spiretrading.com/index.php?title=File:Ui_kit_start.png&amp;diff=119</id>
		<title>File:Ui kit start.png</title>
		<link rel="alternate" type="text/html" href="https://wiki.spiretrading.com/index.php?title=File:Ui_kit_start.png&amp;diff=119"/>
		<updated>2020-07-13T21:53:59Z</updated>

		<summary type="html">&lt;p&gt;Kman: Start state of a user flow diagram.&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Summary ==&lt;br /&gt;
Start state of a user flow diagram.&lt;/div&gt;</summary>
		<author><name>Kman</name></author>
		
	</entry>
	<entry>
		<id>https://wiki.spiretrading.com/index.php?title=UI_Kit&amp;diff=118</id>
		<title>UI Kit</title>
		<link rel="alternate" type="text/html" href="https://wiki.spiretrading.com/index.php?title=UI_Kit&amp;diff=118"/>
		<updated>2020-07-13T21:36:01Z</updated>

		<summary type="html">&lt;p&gt;Kman: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;User interfaces are specified by a set of documents describing a data model, user flow, layout, and styling. This article will go over each of these documents along with how they combine to describe the complete behavior from a small component such a button to larger components such as a login window. The example that will be used in each document is a user interface for a button component.&lt;br /&gt;
&lt;br /&gt;
==Model==&lt;br /&gt;
&lt;br /&gt;
Fundamentally, a UI is a visual representation of a set of data in a given state. The UI takes in that data upon initialization and transforms it based on external actions either provided by the user directly or some other external agent. In order for multiple UI components to work together, individual components signal when certain changes are made to that data or to the state of the component, which allows other UI components to respond and signal changes of their own. The complete description of the data a UI component operates on, the state of the component, as well as the signals it produces form the model and is typically documented in &amp;lt;code&amp;gt;model.txt&amp;lt;/code&amp;gt;. For a simple component such as a button we'd expect to see a label displayed by the button, whether the button is responding to user inputs, whether the mouse is interacting with the button, and finally a signal indicating when the user clicks on it. This would be documented as follows:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
Data:&lt;br /&gt;
  label: The text displayed in the button.&lt;br /&gt;
  enabled: Whether the button is responding to user actions.&lt;br /&gt;
&lt;br /&gt;
State:&lt;br /&gt;
  hovered: Whether the mouse position is within the button's visible region.&lt;br /&gt;
&lt;br /&gt;
Signals:&lt;br /&gt;
  clicked: Indicates the button was clicked by the user.&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
As a general matter, fields that go under &amp;lt;code&amp;gt;Data&amp;lt;/code&amp;gt; are inputs that are provided externally to the UI component, whereas fields that go under &amp;lt;code&amp;gt;State&amp;lt;/code&amp;gt; are internal to the component itself. Typically a button does not know what label it should display and does not manage changes to the label, some external component shall make use of a button and provide it with a label to display. Conversely the button can independently manage whether the mouse is hovered over it on its own by keeping track of the mouse position, it needs no external agent to inform it of this state.&lt;br /&gt;
&lt;br /&gt;
==User Flow==&lt;br /&gt;
&lt;br /&gt;
With the model defined, the user flow describes how the model is transformed based on external events. The flow chart is documented using software available at https://diagrams.net and consists of the following components:&lt;br /&gt;
&lt;br /&gt;
===The start state===&lt;br /&gt;
&lt;br /&gt;
Every UI component begins in the start state, it appears as a dark green circle and is typically either the left-most element of the user flow or the top-most element. It can also be formally distinguished by the fact that it's the only state that may not have any arrows pointing into it, arrows may only point away from it.&lt;br /&gt;
&lt;br /&gt;
If the UI performs any kind of initialization then the start state should have a single arrow pointing towards a state that handles such initialization. Refer to the login window for an example.&lt;/div&gt;</summary>
		<author><name>Kman</name></author>
		
	</entry>
	<entry>
		<id>https://wiki.spiretrading.com/index.php?title=UI_Kit&amp;diff=117</id>
		<title>UI Kit</title>
		<link rel="alternate" type="text/html" href="https://wiki.spiretrading.com/index.php?title=UI_Kit&amp;diff=117"/>
		<updated>2020-07-13T21:28:23Z</updated>

		<summary type="html">&lt;p&gt;Kman: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;User interfaces are specified by a set of documents describing a data model, user flow, layout, and styling. This article will go over each of these documents along with how they combine to describe the complete behavior from a small component such a button to larger components such as a login window. The example that will be used in each document is a user interface for a button component.&lt;br /&gt;
&lt;br /&gt;
==Model==&lt;br /&gt;
&lt;br /&gt;
Fundamentally, a UI is a visual representation of a set of data in a given state. The UI takes in that data upon initialization and transforms it based on external actions either provided by the user directly or some other external agent. In order for multiple UI components to work together, individual components signal when certain changes are made to that data or to the state of the component, which allows other UI components to respond and signal changes of their own. The complete description of the data a UI component operates on, the state of the component, as well as the signals it produces form the model and is typically documented in &amp;lt;code&amp;gt;model.txt&amp;lt;/code&amp;gt;. For a simple component such as a button we'd expect to see a label displayed by the button, whether the button is responding to user inputs, whether the mouse is interacting with the button, and finally a signal indicating when the user clicks on it. This would be documented as follows:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
Data:&lt;br /&gt;
  label: The text displayed in the button.&lt;br /&gt;
  enabled: Whether the button is responding to user actions.&lt;br /&gt;
&lt;br /&gt;
State:&lt;br /&gt;
  hovered: Whether the mouse position is within the button's visible region.&lt;br /&gt;
&lt;br /&gt;
Signals:&lt;br /&gt;
  clicked: Indicates the button was clicked by the user.&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
As a general matter, fields that go under &amp;lt;code&amp;gt;Data&amp;lt;/code&amp;gt; are inputs that are provided externally to the UI component, whereas fields that go under &amp;lt;code&amp;gt;State&amp;lt;/code&amp;gt; are internal to the component itself. Typically a button does not know what label it should display and does not manage changes to the label, some external component shall make use of a button and provide it with a label to display. Conversely the button can independently manage whether the mouse is hovered over it on its own by keeping track of the mouse position, it needs no external agent to inform it of this state.&lt;br /&gt;
&lt;br /&gt;
==User Flow==&lt;br /&gt;
&lt;br /&gt;
With the model defined, the user flow describes how the model is transformed based on external events. The flow chart is documented using software available at https://diagrams.net and consists of the following components:&lt;br /&gt;
&lt;br /&gt;
===The start state===&lt;/div&gt;</summary>
		<author><name>Kman</name></author>
		
	</entry>
	<entry>
		<id>https://wiki.spiretrading.com/index.php?title=UI_Kit&amp;diff=116</id>
		<title>UI Kit</title>
		<link rel="alternate" type="text/html" href="https://wiki.spiretrading.com/index.php?title=UI_Kit&amp;diff=116"/>
		<updated>2020-07-13T21:28:06Z</updated>

		<summary type="html">&lt;p&gt;Kman: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;User interfaces are specified by a set of documents describing a data model, user flow, layout, and styling. This article will go over each of these documents along with how they combine to describe the complete behavior from a small component such a button to larger components such as a login window. The example that will be used in each document is a user interface for a button component.&lt;br /&gt;
&lt;br /&gt;
==Model==&lt;br /&gt;
&lt;br /&gt;
Fundamentally, a UI is a visual representation of a set of data in a given state. The UI takes in that data upon initialization and transforms it based on external actions either provided by the user directly or some other external agent. In order for multiple UI components to work together, individual components signal when certain changes are made to that data or to the state of the component, which allows other UI components to respond and signal changes of their own. The complete description of the data a UI component operates on, the state of the component, as well as the signals it produces form the model and is typically documented in &amp;lt;code&amp;gt;model.txt&amp;lt;/code&amp;gt;. For a simple component such as a button we'd expect to see a label displayed by the button, whether the button is responding to user inputs, whether the mouse is interacting with the button, and finally a signal indicating when the user clicks on it. This would be documented as follows:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
Data:&lt;br /&gt;
  label: The text displayed in the button.&lt;br /&gt;
  enabled: Whether the button is responding to user actions.&lt;br /&gt;
&lt;br /&gt;
State:&lt;br /&gt;
  hovered: Whether the mouse position is within the button's visible region.&lt;br /&gt;
&lt;br /&gt;
Signals:&lt;br /&gt;
  clicked: Indicates the button was clicked by the user.&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
As a general matter, fields that go under &amp;lt;code&amp;gt;Data&amp;lt;/code&amp;gt; are inputs that are provided externally to the UI component, whereas fields that go under &amp;lt;code&amp;gt;State&amp;lt;/code&amp;gt; are internal to the component itself. Typically a button does not know what label it should display and does not manage changes to the label, some external component shall make use of a button and provide it with a label to display. Conversely the button can independently manage whether the mouse is hovered over it on its own by keeping track of the mouse position, it needs no external agent to inform it of this state.&lt;br /&gt;
&lt;br /&gt;
==User Flow==&lt;br /&gt;
&lt;br /&gt;
With the model defined, the user flow describes how the model is transformed based on external events. The flow chart is documented using software available at https://diagrams.net and consists of the following components:&lt;br /&gt;
&lt;br /&gt;
====The start state====&lt;/div&gt;</summary>
		<author><name>Kman</name></author>
		
	</entry>
	<entry>
		<id>https://wiki.spiretrading.com/index.php?title=UI_Kit&amp;diff=115</id>
		<title>UI Kit</title>
		<link rel="alternate" type="text/html" href="https://wiki.spiretrading.com/index.php?title=UI_Kit&amp;diff=115"/>
		<updated>2020-07-13T21:07:50Z</updated>

		<summary type="html">&lt;p&gt;Kman: Created page with &amp;quot;User interfaces are specified by a set of documents describing a data model, user flow, layout, and styling. This article will go over each of these documents along with how t...&amp;quot;&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;User interfaces are specified by a set of documents describing a data model, user flow, layout, and styling. This article will go over each of these documents along with how they combine to describe the complete behavior from a small component such a button to larger components such as a login window. The example that will be used in each document is a user interface for a button component.&lt;br /&gt;
&lt;br /&gt;
==Data Model==&lt;br /&gt;
&lt;br /&gt;
Fundamentally, a UI is a visual representation of a set of data in a given state. The UI takes in that data upon initialization and transforms it based on external actions either provided by the user directly or some other external agent. In order for multiple UI components to work together, individual components signal when certain changes are made to that data or to the state of the component, which allows other UI components to respond and signal changes of their own. The complete description of both the data a UI component operates on as well as the signals it produces form the data model and is typically documented in &amp;lt;code&amp;gt;model.txt&amp;lt;/code&amp;gt;. Using the button as an example the document appears as follows:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
Data:&lt;br /&gt;
  label: The text that's displayed in the button.&lt;br /&gt;
&lt;br /&gt;
Signals:&lt;br /&gt;
  clicked: Indicates that the button was clicked by the user.&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;/div&gt;</summary>
		<author><name>Kman</name></author>
		
	</entry>
	<entry>
		<id>https://wiki.spiretrading.com/index.php?title=TypeScript_Style_Guide&amp;diff=102</id>
		<title>TypeScript Style Guide</title>
		<link rel="alternate" type="text/html" href="https://wiki.spiretrading.com/index.php?title=TypeScript_Style_Guide&amp;diff=102"/>
		<updated>2020-04-07T15:49:49Z</updated>

		<summary type="html">&lt;p&gt;Kman: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;This article specifies the most general guidelines used for all Spire projects written using TypeScript as the primary programming language. Each individual project may extend or override the guidelines specified herein. The overall aim of this guideline is to provide consistency across the numerous projects developed by Spire in order to promote and benefit from modern web development practices as well as tailor them to our specific requirements.&lt;br /&gt;
&lt;br /&gt;
In general, the guidelines are very specific and opinionated. This is done intentionally to ensure that every detail has been given proper consideration and that every line of code is written with care and diligence. It is taken as a prerequisite that writing robust, clean and maintainable code requires paying close attention to even the smallest of details. As such, when there are two or more ways to write or express any given statement or expression, be it using spaces or tabs, number of characters per line, purple or violet, the guideline will often require that one particular approach be used to the exclusion of others.&lt;br /&gt;
&lt;br /&gt;
Finally, this document is constantly evolving and as such older projects may not be up-to-date with the guidelines found here. In those circumstances one must use their best judgment about how to integrate these guidelines into older codebases. As a general principle, consistency should favor the local over the global, that is it is more important to be consistent with a function definition than within a file, and more important to be consistent within a file than within a directory, project, etc...&lt;br /&gt;
&lt;br /&gt;
=Development Environment=&lt;br /&gt;
&lt;br /&gt;
The primary operating systems supported by Spire projects are Ubuntu 18.02 LTS, Windows 10, and macOS. On all systems, nodejs is used as the build system and webpack is used as the bundler.&lt;br /&gt;
&lt;br /&gt;
For source control, git is used and projects are to be hosted on [https://github.com/spiretrading Spire Trading's Github page].&lt;br /&gt;
&lt;br /&gt;
Each developer is welcome to use an editor of their choice, however [https://code.visualstudio.com/ Visual Studio Code] is recommended.&lt;br /&gt;
&lt;br /&gt;
=File Names=&lt;br /&gt;
&lt;br /&gt;
Use [https://en.wikipedia.org/wiki/Snake_case snake case] using all lower case letters for files and directories. The name of a file should correspond to the primary class that it exports.&lt;br /&gt;
&lt;br /&gt;
The default extension for TypeScript files is ''ts''&lt;br /&gt;
&lt;br /&gt;
The extension used for TypeScript files containing JSX is ''tsx''&lt;br /&gt;
&lt;br /&gt;
All files end with a single new line character.&lt;br /&gt;
&lt;br /&gt;
=Directory Structure=&lt;br /&gt;
&lt;br /&gt;
A project is broken down into a library component, a test component, and one or more application components. These components are referred to as ''artifacts''. The applications go into their own ''applications'' directory and the libraries into the ''library'' directory. Within each artifact is a ''build'' directory containing the build scripts needed to build that artifact. Scripts for POSIX systems are found in the ''posix'' sub-directory and Windows build files are within the ''windows'' sub-directory. The build scripts specified are ''setup'' to download and install any dependencies needed to produce the artifact and the ''build'' script which produces the artifact. Typically the ''setup'' script is run only once or when a new dependency is introduced to the project, and the ''build'' script is run anytime a new build is needed.&lt;br /&gt;
&lt;br /&gt;
Finally there is a top-level ''build'' directory for the project as a whole which produces all artifacts by recursively calling each artifact's individual build scripts. Additionally the top-level build directory also includes a ''setup'' script which downloads all third party dependencies. Some projects may also opt to include an ''install'' script which sets up a suitable development environment, and other scripts for continuous builds, deployment and testing.&lt;br /&gt;
&lt;br /&gt;
Assuming a project named sudoku the following directory structure should be used:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
sudoku                             # Root level directory.&lt;br /&gt;
  build.sh                         # Script used to build all projects on POSIX.&lt;br /&gt;
  build.bat                        # Script used to build all projects on Windows.&lt;br /&gt;
  configure.sh                     # Script used to configure all projects on POSIX.&lt;br /&gt;
  configure.bat                    # Script used to configure all projects on Windows.&lt;br /&gt;
  setup.sh                         # Script used to install all dependencies on POSIX.&lt;br /&gt;
  setup.bat                        # Script used to install all dependencies on Windows.&lt;br /&gt;
  \application                     # Contains source specific for the sudoku web app.&lt;br /&gt;
    build.sh                       # Script used to build the web app on POSIX.&lt;br /&gt;
    build.bat                      # Script used to build the web app on Windows.&lt;br /&gt;
    configure.sh                   # Script used to configure the web app on POSIX.&lt;br /&gt;
    configure.bat                  # Script used to configure the web app on Windows.&lt;br /&gt;
    package.json                   # The Node JS package description.&lt;br /&gt;
    tsconfig.json                  # The TypeScript compiler configuration.&lt;br /&gt;
    setup.sh                       # Script used the web app dependencies on POSIX.&lt;br /&gt;
    setup.bat                      # Script used the web app dependencies on Windows.&lt;br /&gt;
    webpack.config.js              # The Webpack configuration.&lt;br /&gt;
    \source                        # Contains the web application source files.&lt;br /&gt;
      \index.html                  # The HTML file that loads the JavaScript application.&lt;br /&gt;
      \index.tsx                   # The TypeScript/JSX file containing the application.&lt;br /&gt;
  \library                         # Contains the common library code.&lt;br /&gt;
    build.sh                       # Script used to build the library on POSIX.&lt;br /&gt;
    build.bat                      # Script used to build the library on Windows.&lt;br /&gt;
    configure.sh                   # Script used to configure the library on POSIX.&lt;br /&gt;
    configure.bat                  # Script used to configure the library on Windows.&lt;br /&gt;
    package.json                   # The Node JS package description.&lt;br /&gt;
    setup.sh                       # Script used the library on POSIX.&lt;br /&gt;
    setup.bat                      # Script used the library on Windows.&lt;br /&gt;
    tsconfig.json                  # The TypeScript compiler configuration.&lt;br /&gt;
    \source                        # Contains the library source files.&lt;br /&gt;
      index.ts                     # Exports all definitions contained in this directory.&lt;br /&gt;
      \pages                       # Contains the source code for individual web pages.&lt;br /&gt;
        index.ts                   # Exports all definitions for every web page defined&lt;br /&gt;
                                   # in this directory.&lt;br /&gt;
        \landing_page              # Contains the source code for the landing page.&lt;br /&gt;
          index.ts                 # Exports the landing page.&lt;br /&gt;
          landing_page.tsx         # The TypeScript/JSX source code for the landing page.&lt;br /&gt;
        \page_2                    # Contains the source for for another web page.&lt;br /&gt;
          ...                      # Structured in a similar manner as the landing page.&lt;br /&gt;
  \resources                       # Contains images, fonts, CSS files and all other web&lt;br /&gt;
                                   # assets.&lt;br /&gt;
    \index.css                     # Contains the main CSS file, typically this is the&lt;br /&gt;
                                   # only CSS file used.&lt;br /&gt;
    \fonts                         # A directory of fonts used.&lt;br /&gt;
  \tests                           # This directory contains tests for every page of the&lt;br /&gt;
                                   # web app.&lt;br /&gt;
    build.sh                       # Script used to build all tests on POSIX.&lt;br /&gt;
    build.bat                      # Script used to build all tests on Windows.&lt;br /&gt;
    configure.sh                   # Script used to configure all tests on POSIX.&lt;br /&gt;
    configure.bat                  # Script used to configure all tests on Windows.&lt;br /&gt;
    setup.sh                       # Script used to install all test dependencies on POSIX.&lt;br /&gt;
    setup.bat                      # Script used to install all test dependencies on&lt;br /&gt;
                                   # Windows.&lt;br /&gt;
    \scratch                       # Directory containing a test/demo for a single page.&lt;br /&gt;
      build.sh                     # Script used to build the test on POSIX.&lt;br /&gt;
      build.bat                    # Script used to build the test on Windows.&lt;br /&gt;
      configure.sh                 # Script used to configure the test on POSIX.&lt;br /&gt;
      configure.bat                # Script used to configure the test on Windows.&lt;br /&gt;
      package.json                 # The Node JS package description.&lt;br /&gt;
      tsconfig.json                # The TypeScript compiler configuration.&lt;br /&gt;
      setup.sh                     # Script used the test dependencies on POSIX.&lt;br /&gt;
      setup.bat                    # Script used the test dependencies on Windows.&lt;br /&gt;
      webpack.config.js            # The Webpack configuration.&lt;br /&gt;
      \source                      # Contains the test source files.&lt;br /&gt;
        \index.html                # The HTML file that loads the JavaScript application.&lt;br /&gt;
        \index.tsx                 # The TypeScript/JSX file containing the application.&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
An example of the above directory structure containing a basic skeletal implementation of all files can be found here: https://github.com/spiretrading/sudoku&lt;br /&gt;
&lt;br /&gt;
=Component Names=&lt;br /&gt;
&lt;br /&gt;
Naming components can be difficult. Names are usually prefixed with the context or domain. Most components will fall under one of the following categories.&lt;br /&gt;
&lt;br /&gt;
==Field==&lt;br /&gt;
The primary function of a field is to display data. The data can be edited. It can have a readonly property. It contains a onChange callback.&lt;br /&gt;
&lt;br /&gt;
Examples: DurationField, NumberField&lt;br /&gt;
&lt;br /&gt;
===Selection Field===&lt;br /&gt;
A specialized field. It requires a list of potential values to choose from.&lt;br /&gt;
&lt;br /&gt;
Example: CountrySelectionField&lt;br /&gt;
&lt;br /&gt;
==Input==&lt;br /&gt;
The primary function of a input is to get user input. Inputs usually do not have a initial value unlike fields. Inputs can have a readonly mode, but it is only to be used when the input should not accept input.&lt;br /&gt;
&lt;br /&gt;
Example: SecurityInput&lt;br /&gt;
&lt;br /&gt;
===Button===&lt;br /&gt;
Buttons are a specialized form of input. Only has a onClick callback.&lt;br /&gt;
&lt;br /&gt;
Examples: Button, BurgerButton&lt;br /&gt;
&lt;br /&gt;
==Box==&lt;br /&gt;
A component that displays data that cannot be directly edited.&lt;br /&gt;
&lt;br /&gt;
=Syntax=&lt;br /&gt;
&lt;br /&gt;
==Indentation==&lt;br /&gt;
Code is indented using 2 spaces per level, tabs are not permitted.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=typescript line=line&amp;gt;&lt;br /&gt;
function factorial(n: number): number {&lt;br /&gt;
  if(n == 0) {&lt;br /&gt;
    return 1;&lt;br /&gt;
  }&lt;br /&gt;
  return n * factorial(n - 1);&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Line Structure==&lt;br /&gt;
&lt;br /&gt;
Statements must end with a semi-colon ';' or a closing brace '}', even in cases where TypeScript allows them to be optional.&lt;br /&gt;
&lt;br /&gt;
Lines are limited to 80 characters. Exceptions to this rule are long imports and long string literals where breaking up the literal into multiple lines is not possible. In order to break up long statements into multiple lines the following rules are used:&lt;br /&gt;
&lt;br /&gt;
* Break the line at a comma, operator or opening bracket.&lt;br /&gt;
&amp;lt;syntaxhighlight lang=typescript line=line&amp;gt;&lt;br /&gt;
&lt;br /&gt;
// Correct, line break at comma.&lt;br /&gt;
f(a, ..., b,&lt;br /&gt;
  c, ..., d);&lt;br /&gt;
&lt;br /&gt;
// Incorrect, line break after expression.&lt;br /&gt;
f(a, ..., b&lt;br /&gt;
  , c, ..., d);&lt;br /&gt;
&lt;br /&gt;
// Correct, line break after operator.&lt;br /&gt;
a + ... + b +&lt;br /&gt;
  c + ... + d;&lt;br /&gt;
&lt;br /&gt;
// Incorrect, line break after expression.&lt;br /&gt;
a + ... + b&lt;br /&gt;
  + c + ... + d;&lt;br /&gt;
&lt;br /&gt;
// Correct, line break after opening bracket.&lt;br /&gt;
f(&lt;br /&gt;
  a, ..., b, c, ..., d);&lt;br /&gt;
&lt;br /&gt;
// Incorrect, line break after function name.&lt;br /&gt;
f&lt;br /&gt;
  (a, ..., b, c, ..., d);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* For statements that begin new blocks of code (such as if/while/class...), in order to avoid confusing the line continuation with the code block, the line continuation is indented two extra levels. For example consider the following snippet of code:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=typescript line=line&amp;gt;&lt;br /&gt;
// Incorrect.&lt;br /&gt;
if(condition_a &amp;amp;&amp;amp; condition_b &amp;amp;&amp;amp; ... &amp;amp;&amp;amp;&lt;br /&gt;
  condition_c) {&lt;br /&gt;
  console.log('meow');&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The line continuation on line 2 clashes with the code block on line 3. To avoid this clash the above code is indented as follows:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=typescript line=line&amp;gt;&lt;br /&gt;
// Correct.&lt;br /&gt;
if(condition_a &amp;amp;&amp;amp; condition_b &amp;amp;&amp;amp; ... &amp;amp;&amp;amp;&lt;br /&gt;
    condition_c) {&lt;br /&gt;
  console.log('meow');&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The extra level of indentation in the line continuation makes it clear where the condition ends and the code block begins.&lt;br /&gt;
&lt;br /&gt;
==Braces==&lt;br /&gt;
&lt;br /&gt;
Braces are placed using a variant of the [http://wiki.c2.com/?OneTrueBraceStyle OTBS style]. The opening brace is placed on the same line as the declaring statement with one single space preceding it, and the closing brace is placed on a line of its own at the same level of indentation as the declaring statement. For if statements, the else/else if is placed on the same line as the closing brace. For do/while loops, the while is placed on the same line as the closing brace.&lt;br /&gt;
&lt;br /&gt;
Examples:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=typescript line=line&amp;gt;&lt;br /&gt;
// Correct.&lt;br /&gt;
if(&amp;lt;cond&amp;gt;) {&lt;br /&gt;
  &amp;lt;body&amp;gt;&lt;br /&gt;
} else {&lt;br /&gt;
  &amp;lt;default&amp;gt;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
// Correct.&lt;br /&gt;
do {&lt;br /&gt;
  &amp;lt;body&amp;gt;&lt;br /&gt;
} while(&amp;lt;cond&amp;gt;);&lt;br /&gt;
&lt;br /&gt;
// Incorrect.&lt;br /&gt;
if(&amp;lt;cond&amp;gt;)&lt;br /&gt;
{&lt;br /&gt;
  &amp;lt;body&amp;gt;&lt;br /&gt;
}&lt;br /&gt;
else&lt;br /&gt;
{&lt;br /&gt;
  &amp;lt;default&amp;gt;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
// Incorrect.&lt;br /&gt;
do&lt;br /&gt;
{&lt;br /&gt;
  &amp;lt;body&amp;gt;&lt;br /&gt;
}&lt;br /&gt;
while(&amp;lt;cond&amp;gt;);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Spacing==&lt;br /&gt;
&lt;br /&gt;
The following are correct use cases for white spaces:&lt;br /&gt;
&lt;br /&gt;
* Used for indentation.&lt;br /&gt;
* Used to surround binary operations.&lt;br /&gt;
&amp;lt;syntaxhighlight lang=typescript line=line&amp;gt;&lt;br /&gt;
// Correct.&lt;br /&gt;
const x = a + b;&lt;br /&gt;
const y = 5;&lt;br /&gt;
&lt;br /&gt;
//! Incorrect&lt;br /&gt;
const x = a+b;&lt;br /&gt;
const y=5;&lt;br /&gt;
const z= 5;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* One space is placed after a comma.&lt;br /&gt;
&amp;lt;syntaxhighlight lang=typescript line=line&amp;gt;&lt;br /&gt;
// Correct.&lt;br /&gt;
f(1, 2);&lt;br /&gt;
function g(a: number, b: number): number;&lt;br /&gt;
&lt;br /&gt;
//! Incorrect&lt;br /&gt;
f(1,2);&lt;br /&gt;
function g(a:number,b:number);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Naming==&lt;br /&gt;
&lt;br /&gt;
[https://en.wikipedia.org/wiki/Camel_case Camel case] is used for naming whereas variables and functions use mixedCase and namespaces, modules, and types use CapWords. Names should be descriptive but should avoid being verbose.&lt;br /&gt;
&lt;br /&gt;
Classes and variables should be given the name of a noun and functions the name of a verb. Functions that return a boolean or boolean variables should be named in the form of a question starting with isX or hasX.&lt;br /&gt;
&lt;br /&gt;
==Imports==&lt;br /&gt;
Imports are listed in order of most global to local. Where dependencies have the same locality, then they are ordered alphabetically. For example, the first group of dependencies to be imported are third party packages which are listed in alphabetical order based on the package name. In the above snippet the third party dependencies are jquery, react and react-router-dom which are imported in alphabetical order. Then local dependencies are imported where directories further up the hierarchy are imported first. That is, the directory '../../..' which is three levels up is imported before the directory '..' which is only one level up.&lt;br /&gt;
&lt;br /&gt;
When multiple names are imported from a package, they must be listed in alphabetical order.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=typescript line=line&amp;gt;&lt;br /&gt;
import * as $ from 'jquery';&lt;br /&gt;
import * as React from 'react';&lt;br /&gt;
import * as Router from 'react-router-dom';&lt;br /&gt;
import {HBoxLayout, Padding, VBoxLayout} from '../../..';&lt;br /&gt;
import {Model} from '..';&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Declarations==&lt;br /&gt;
&lt;br /&gt;
Any declaration (such as a function or class) that is intended to be imported by another file must be documented using [http://usejsdoc.org/ JSDoc style]. If the definition is local then that documentation should be omitted entirely.&lt;br /&gt;
&lt;br /&gt;
Any documentation should be preceded by a blank line. In the code snippet, Properties is part of the public API so it is documented along with all of its fields, but the State is internal to the file so no aspect of it is documented.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=typescript line=line&amp;gt;&lt;br /&gt;
&lt;br /&gt;
/** Stores the React properties used to render a Page. */&lt;br /&gt;
export interface Properties {&lt;br /&gt;
&lt;br /&gt;
  /** The model used to display the page. */&lt;br /&gt;
  model: Model;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
export interface State {&lt;br /&gt;
  redirect: string;&lt;br /&gt;
  isLoading: boolean;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Variable Declarations==&lt;br /&gt;
&lt;br /&gt;
Variables are declared so that only one variable is declared per line, prefer declaring variables using ''const'' when possible, and deferring to ''let'' otherwise, variables should always be initialized at the point of their declaration.&lt;br /&gt;
&lt;br /&gt;
For complex initialization of values, use an [https://en.wikipedia.org/wiki/Immediately-invoked_function_expression immediately invoked lambda expression] as follows:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=typescript line=line&amp;gt;&lt;br /&gt;
const value = (() =&amp;gt; {&lt;br /&gt;
  if(condition) {&lt;br /&gt;
    return 123;&lt;br /&gt;
  }&lt;br /&gt;
  return 321;&lt;br /&gt;
})();&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=Example=&lt;br /&gt;
&lt;br /&gt;
Below is a full example combining numerous elements of the style guide to define a typical React component. It should be used as a general reference for how code is laid out, structured, and properly spaced.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=typescript line=line&amp;gt;&lt;br /&gt;
import * as $ from 'jquery';&lt;br /&gt;
import * as React from 'react';&lt;br /&gt;
import * as Router from 'react-router-dom';&lt;br /&gt;
import {HBoxLayout, Padding, VBoxLayout} from '..';&lt;br /&gt;
import {Model} from '.';&lt;br /&gt;
&lt;br /&gt;
/** Stores the React properties used to render a Page. */&lt;br /&gt;
export interface Properties {&lt;br /&gt;
&lt;br /&gt;
  /** The model used to display the page. */&lt;br /&gt;
  model: Model;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
export interface State {&lt;br /&gt;
  redirect: string;&lt;br /&gt;
  isLoading: boolean;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/** Displays an HTML page. */&lt;br /&gt;
export class Page extends React.Component&amp;lt;Properties, State&amp;gt; {&lt;br /&gt;
  constructor(props: Properties) {&lt;br /&gt;
    super(props);&lt;br /&gt;
    this.state = {&lt;br /&gt;
      redirect: '',&lt;br /&gt;
      isLoading: true&lt;br /&gt;
    };&lt;br /&gt;
  }&lt;br /&gt;
&lt;br /&gt;
  public componentWillMount(): void {&lt;br /&gt;
    this.props.model.load().then(&lt;br /&gt;
      () =&amp;gt; {&lt;br /&gt;
        this.setState({&lt;br /&gt;
          isLoading: false&lt;br /&gt;
        });&lt;br /&gt;
      });&lt;br /&gt;
  }&lt;br /&gt;
&lt;br /&gt;
  public render(): JSX.Element {&lt;br /&gt;
    if(this.state.redirect) {&lt;br /&gt;
      return &amp;lt;Router.Redirect push to={this.state.redirect}/&amp;gt;;&lt;br /&gt;
    } else if(this.state.isLoading) {&lt;br /&gt;
      return &amp;lt;LoadingPage/&amp;gt;;&lt;br /&gt;
    }&lt;br /&gt;
    const style = {&lt;br /&gt;
      backgroundColor: '#FFFFFF',&lt;br /&gt;
      font: 'Roboto 14px'&lt;br /&gt;
    };&lt;br /&gt;
    return (&lt;br /&gt;
      &amp;lt;div style={style}&amp;gt;&lt;br /&gt;
        &amp;lt;h1&amp;gt;Hello world!&amp;lt;/h1&amp;gt;&lt;br /&gt;
        &amp;lt;img src='cat.jpg'/&amp;gt;&lt;br /&gt;
      &amp;lt;/div&amp;gt;);&lt;br /&gt;
  }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=Additional References=&lt;br /&gt;
&lt;br /&gt;
The bulk of this style guide focuses on syntax rather than good programming practices. The following list are reference materials for best practices on writing portable, efficient, and clean TypeScript:&lt;br /&gt;
&lt;br /&gt;
* [https://www.typescriptlang.org/docs/handbook/basic-types.html TypeScript Hand Book]&lt;/div&gt;</summary>
		<author><name>Kman</name></author>
		
	</entry>
	<entry>
		<id>https://wiki.spiretrading.com/index.php?title=Tasks&amp;diff=62</id>
		<title>Tasks</title>
		<link rel="alternate" type="text/html" href="https://wiki.spiretrading.com/index.php?title=Tasks&amp;diff=62"/>
		<updated>2019-01-03T20:59:22Z</updated>

		<summary type="html">&lt;p&gt;Kman: /* First Attempt */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Tasks provide a way of encapsulating and managing asynchronous actions in a composable manner. They are primarily used to perform some sort of I/O operation and/or manage a series of sub-tasks. Beam provides several classes to define your own tasks as well as classes that connect tasks to one another.&lt;br /&gt;
&lt;br /&gt;
The task API in Beam is defined by two base classes, the class Beam::Tasks::Task which represents a task, and the class Beam::Tasks::TaskFactory which constructs tasks. In this article we will explore how we can use these two classes in ways that allow us to start, stop, modify and resume asynchronous actions.&lt;br /&gt;
&lt;br /&gt;
=Interface=&lt;br /&gt;
==Task==&lt;br /&gt;
&lt;br /&gt;
The Task class defines two methods, an Execute() method to start the task and a Cancel() method to request that the task stop. Both operations are asynchronous, meaning that they return immediately and the actual operation of the task takes place in a separate thread of execution. In order to keep track of the progress of a task one must monitor its state which can be any of the following:&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! scope=&amp;quot;col&amp;quot;| State&lt;br /&gt;
! scope=&amp;quot;col&amp;quot;| Description&lt;br /&gt;
|-&lt;br /&gt;
| scope=&amp;quot;row&amp;quot;| NONE&lt;br /&gt;
| The task has not yet been executed.&lt;br /&gt;
|-&lt;br /&gt;
| scope=&amp;quot;row&amp;quot;| INITIALIZING&lt;br /&gt;
| The task is performing some initialization, during this state no sub-tasks may be executed.&lt;br /&gt;
|-&lt;br /&gt;
| scope=&amp;quot;row&amp;quot;| ACTIVE&lt;br /&gt;
| The task is running, during this state sub-tasks may be executed.&lt;br /&gt;
|-&lt;br /&gt;
| scope=&amp;quot;row&amp;quot;| PENDING_CANCEL&lt;br /&gt;
| A request to cancel the task has been made, no new sub-tasks may be executed.&lt;br /&gt;
|-&lt;br /&gt;
| scope=&amp;quot;row&amp;quot;| CANCELED&lt;br /&gt;
| The task was canceled.&lt;br /&gt;
|-&lt;br /&gt;
| scope=&amp;quot;row&amp;quot;| FAILED&lt;br /&gt;
| The task could not complete due to an error.&lt;br /&gt;
|-&lt;br /&gt;
| scope=&amp;quot;row&amp;quot;| EXPIRED&lt;br /&gt;
| The task could not complete due to a time constraint.&lt;br /&gt;
|-&lt;br /&gt;
| scope=&amp;quot;row&amp;quot;| COMPLETE&lt;br /&gt;
| The task completed successfully.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
The states CANCELED, FAILED, EXPIRED and COMPLETE all represent terminal states. Before a task can transition to a terminal state, all of its sub tasks must be in a terminal state. Furthermore once a task is in a terminal state the task is not permitted to perform any additional action or transition to a different state.&lt;br /&gt;
&lt;br /&gt;
The current state of the task along with all of its transitions is accessed through its Publisher by calling the GetPublisher() method. The publisher will emit objects of type Beam::Tasks::Task::StateEntry which contains two fields as follows:&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! scope=&amp;quot;col&amp;quot;| Name&lt;br /&gt;
! scope=&amp;quot;col&amp;quot;| Type&lt;br /&gt;
! scope=&amp;quot;col&amp;quot;| Description&lt;br /&gt;
|-&lt;br /&gt;
| scope=&amp;quot;row&amp;quot;| m_state&lt;br /&gt;
| Beam::Tasks::Task::State&lt;br /&gt;
| The state of the task.&lt;br /&gt;
|-&lt;br /&gt;
| scope=&amp;quot;row&amp;quot;| m_message&lt;br /&gt;
| std::string&lt;br /&gt;
| A message describing the reason for the transition.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
In effect a task begins in the NONE state, is then started via the Execute() method, transitions into the INITIALIZATION state where it performs any setup needed, then proceeds to the ACTIVE state where it performs its operation including executing any required sub-tasks, and then finally terminates all of its sub-tasks and performs any final clean-up before ending in a terminal state. During any point after the INITIALIZATION state it may encounter a cancel request (via the Cancel() method) or an error, either of which should result in cleaning-up and terminating its sub-tasks before transitioning to the FAILED or CANCELED state.&lt;br /&gt;
&lt;br /&gt;
==Task Factory==&lt;br /&gt;
&lt;br /&gt;
The task factory is responsible for creating new tasks by invoking its Create() method. In addition to this a task factory also keeps track of the parameters and state needed to create tasks. Setting a task's parameter is done by calling the factory's Set(name, value) method and retrieving a parameter is done via the Get(name) method.&lt;br /&gt;
&lt;br /&gt;
===Continuations===&lt;br /&gt;
&lt;br /&gt;
One additional operation that task factories perform is constructing what is called a continuation task. Continuations are a mechanism that allow us to resume a task that previously terminated, but more than that they also allow us to modify the parameters of that task. In a sense, a continuation lets us take a terminated task, modify it, and then continue running it with those modifications.&lt;br /&gt;
&lt;br /&gt;
To do this, task factories have a method PrepareContinuation(task). To use it you pass into it a task that has terminated, then you modify its properties using the Set(name, value) method, and then finally you invoke the Create() method to get a newly constructed task that represents the continuation of the old task.&lt;br /&gt;
&lt;br /&gt;
Not all tasks support continuations, those that do not will throw a Beam::NotSupportedException.&lt;br /&gt;
&lt;br /&gt;
==BasicTask==&lt;br /&gt;
&lt;br /&gt;
As a great deal of care must be taken to ensure that tasks properly transition from State to State, including managing sub-tasks, handling cancel requests etc... Beam provides the Beam::Tasks::BasicTask as a base class which can be inherited from to take care of much of the work needed to write a proper task. For example it ensures that upon a cancel request that the task transitions into the PENDING_CANCEL state and terminates all managed sub-tasks.&lt;br /&gt;
&lt;br /&gt;
To make use of a the BasicTask you need only implement the OnExecute() method to start your task, and the OnCancel() method to handle cancelling your class.&lt;br /&gt;
&lt;br /&gt;
=Example=&lt;br /&gt;
&lt;br /&gt;
To showcase a simple example, let's build a task that prints &amp;quot;hello&amp;quot; every second a given number of times. We will write a HelloTask class which inherits from BasicTask, and a HelloTaskFactory.&lt;br /&gt;
&lt;br /&gt;
==First Attempt==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=python line=line&amp;gt;&lt;br /&gt;
import datetime&lt;br /&gt;
import time&lt;br /&gt;
&lt;br /&gt;
import beam&lt;br /&gt;
&lt;br /&gt;
class HelloTask(beam.tasks.BasicTask):&lt;br /&gt;
  '''Prints hello a specified number of times.'''&lt;br /&gt;
&lt;br /&gt;
  def __init__(self, timer, iterations):&lt;br /&gt;
    ''' Constructs this task.&lt;br /&gt;
    :param timer: The Timer used to wait between successive prints.&lt;br /&gt;
    :param iterations: The number of times to print.&lt;br /&gt;
    '''&lt;br /&gt;
&lt;br /&gt;
    # We must make sure to initialize the base class.&lt;br /&gt;
    beam.tasks.BasicTask.__init__(self)&lt;br /&gt;
    self.timer = timer&lt;br /&gt;
    self.iterations = iterations&lt;br /&gt;
&lt;br /&gt;
    # The number of times we've printed so far.&lt;br /&gt;
    self.counter = 0&lt;br /&gt;
&lt;br /&gt;
    # Used to handle timer callbacks.&lt;br /&gt;
    self.tasks = beam.RoutineTaskQueue()&lt;br /&gt;
&lt;br /&gt;
  # This overrides BasicTask.on_execute.&lt;br /&gt;
  # When called we can assume that our Task is in the INITIALIZATION state.&lt;br /&gt;
  def on_execute(self):&lt;br /&gt;
&lt;br /&gt;
    # To initialize our task we will monitor our timer and then start the timer.&lt;br /&gt;
    self.timer.get_publisher().monitor(self.tasks.get_slot(self.on_timer))&lt;br /&gt;
    self.timer.start()&lt;br /&gt;
&lt;br /&gt;
    # Once the initialization is complete we transition to the ACTIVE state.&lt;br /&gt;
    self.set_active()&lt;br /&gt;
&lt;br /&gt;
  # This overrides BasicTask.on_cancel.&lt;br /&gt;
  # When called we can assume that our Task is in the PENDING_CANCEL state.&lt;br /&gt;
  # No new sub-tasks may be executed.&lt;br /&gt;
  def on_cancel(self):&lt;br /&gt;
&lt;br /&gt;
    # In order to synchronize handling the cancel operation with the timer,&lt;br /&gt;
    # we will push a helper function onto our RoutineTaskQueue.&lt;br /&gt;
    # This ensures no race-conditions take place between the timer and&lt;br /&gt;
    # the cancel request.&lt;br /&gt;
    self.tasks.push(self._on_cancel)&lt;br /&gt;
&lt;br /&gt;
  # This handles the timer expiry.&lt;br /&gt;
  def on_timer(self, result):&lt;br /&gt;
    if result == beam.threading.Timer.Result.EXPIRED:&lt;br /&gt;
&lt;br /&gt;
      # This branch implies that our timer expired normally.&lt;br /&gt;
      print('hello')&lt;br /&gt;
      self.counter += 1&lt;br /&gt;
      if self.counter &amp;gt;= self.iterations:&lt;br /&gt;
&lt;br /&gt;
        # There is nothing more to print, so transition to&lt;br /&gt;
        # a terminal state, which by default is the COMPLETE state.&lt;br /&gt;
        self.set_terminal()&lt;br /&gt;
      else:&lt;br /&gt;
&lt;br /&gt;
        # There are still further iterations, restart the timer.&lt;br /&gt;
        self.timer.start()&lt;br /&gt;
    else:&lt;br /&gt;
&lt;br /&gt;
        # This branch implies that we canceled the timer in response&lt;br /&gt;
        # to a cancel request.&lt;br /&gt;
        # In this case we set our state to CANCELED.&lt;br /&gt;
        self.set_terminal(beam.tasks.Task.State.CANCELED)&lt;br /&gt;
&lt;br /&gt;
  def _on_cancel(self):&lt;br /&gt;
    if self.counter &amp;lt; self.iterations:&lt;br /&gt;
&lt;br /&gt;
      # Only cancel the timer if there are iterations remaining.&lt;br /&gt;
      self.timer.cancel()&lt;br /&gt;
&lt;br /&gt;
class HelloTaskFactory(beam.tasks.TaskFactory):&lt;br /&gt;
  '''Builds HelloTasks.'''&lt;br /&gt;
&lt;br /&gt;
  # Typically the parameters that get passed into the Task are&lt;br /&gt;
  # defined as static constant strings in the TaskFactory.&lt;br /&gt;
  # This makes it easier to identify the properties of a task&lt;br /&gt;
  # as well as reference them (avoiding potential typos).&lt;br /&gt;
  ITERATIONS = 'iterations'&lt;br /&gt;
&lt;br /&gt;
  def __init__(self, timer_factory):&lt;br /&gt;
    '''Constructs a HelloTaskFactory.&lt;br /&gt;
    :param timer_factory: Used to construct Timers.&lt;br /&gt;
    '''&lt;br /&gt;
&lt;br /&gt;
    # Factories will typically inherit from TaskFactory as a base class.&lt;br /&gt;
    beam.tasks.TaskFactory.__init__(self)&lt;br /&gt;
    self.timer_factory = timer_factory&lt;br /&gt;
&lt;br /&gt;
    # The constructor should define all the properties and default&lt;br /&gt;
    # values for those properties.&lt;br /&gt;
    self.define_property(HelloTaskFactory.ITERATIONS, 10)&lt;br /&gt;
&lt;br /&gt;
    # This variable keeps track of continuations.&lt;br /&gt;
    self.continuation_task = None&lt;br /&gt;
&lt;br /&gt;
  # This overrides the TaskFactory create method.&lt;br /&gt;
  def create(self):&lt;br /&gt;
&lt;br /&gt;
    if self.continuation_task is None:&lt;br /&gt;
&lt;br /&gt;
      # We are not creating a continuation task, so all we need to do is&lt;br /&gt;
      # construct a HelloTask using the ITERATIONS property defined above.&lt;br /&gt;
      return HelloTask(self.timer_factory(datetime.timedelta(seconds = 1)),&lt;br /&gt;
        self.get(HelloTaskFactory.ITERATIONS))&lt;br /&gt;
    else:&lt;br /&gt;
&lt;br /&gt;
      # We are creating a continuation task.  The continuation of a HelloTask of&lt;br /&gt;
      # N iterations that has already printed C times is basically a HelloTask&lt;br /&gt;
      # that prints N - C times.&lt;br /&gt;
      continuation = HelloTask(&lt;br /&gt;
        self.timer_factory(datetime.timedelta(seconds = 1)),&lt;br /&gt;
        self.get(HelloTaskFactory.ITERATIONS) - self.continuation_task.counter)&lt;br /&gt;
      self.continuation_task = None&lt;br /&gt;
      return continuation&lt;br /&gt;
&lt;br /&gt;
  # This overrides the TaskFactory prepare_continuation method.&lt;br /&gt;
  def prepare_continuation(self, task):&lt;br /&gt;
&lt;br /&gt;
    # We store the task to continue.&lt;br /&gt;
    self.continuation_task = task&lt;br /&gt;
&lt;br /&gt;
def main():&lt;br /&gt;
&lt;br /&gt;
  # Construct the HelloTaskFactory using the LiveTimer for 5 iterations.&lt;br /&gt;
  factory = HelloTaskFactory(beam.threading.LiveTimer)&lt;br /&gt;
  factory.set(HelloTaskFactory.ITERATIONS, 5)&lt;br /&gt;
  task = factory.create()&lt;br /&gt;
  task.execute()&lt;br /&gt;
&lt;br /&gt;
  # Let's sleep for 2 seconds before canceling the task.&lt;br /&gt;
  # It should print hello twice.&lt;br /&gt;
  time.sleep(2)&lt;br /&gt;
  task.cancel()&lt;br /&gt;
&lt;br /&gt;
  # Wait for the task to enter the CANCELED state.&lt;br /&gt;
  beam.tasks.wait(task)&lt;br /&gt;
&lt;br /&gt;
  # Build the continuation task and execute it.  To do this we first&lt;br /&gt;
  # call prepare_continuation, then we make our modifications using the set&lt;br /&gt;
  # method, then we create the task and execute it.&lt;br /&gt;
  factory.prepare_continuation(task)&lt;br /&gt;
  factory.set(HelloTaskFactory.ITERATIONS, 7)&lt;br /&gt;
  task = factory.create()&lt;br /&gt;
&lt;br /&gt;
  # We expect it to print hello three times before coming to an end.&lt;br /&gt;
  task.execute()&lt;br /&gt;
  beam.tasks.wait(task)&lt;br /&gt;
&lt;br /&gt;
if __name__ == '__main__':&lt;br /&gt;
  main()&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Decomposition==&lt;br /&gt;
&lt;br /&gt;
The above example works, but upon reflection we should notice that this Task is responsible for two distinct things. One is the responsibility of printing, and the other is the responsibility of repeating. Given that the purpose of tasks is to be able to compose asynchronous operations we should separate these two responsibilities from one another. To do that we will change our HelloTask so that all it does is print hello after a specified time period, followed by a RepetitionTask which repeats a task a specified number of times. The benefit of this is that our RepetitionTask can be reused to repeat any task whatsoever down the road.&lt;br /&gt;
&lt;br /&gt;
We will define it as follows:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=python line=line&amp;gt;&lt;br /&gt;
import copy&lt;br /&gt;
import datetime&lt;br /&gt;
import time&lt;br /&gt;
&lt;br /&gt;
import beam&lt;br /&gt;
&lt;br /&gt;
class RepetitionTask(beam.tasks.BasicTask):&lt;br /&gt;
  '''Repeats a Task a specified number of times.'''&lt;br /&gt;
&lt;br /&gt;
  def __init__(self, task_factory, iterations):&lt;br /&gt;
    '''Constructs the Task.&lt;br /&gt;
    :param task_factory: Builds the Task to repeat.&lt;br /&gt;
    :param iterations: The number of times to repeat the Task.&lt;br /&gt;
    '''&lt;br /&gt;
    beam.tasks.BasicTask.__init__(self)&lt;br /&gt;
&lt;br /&gt;
    # We should always make a deep copy of factories in order to&lt;br /&gt;
    # avoid modifying a factory belonging to another task or having&lt;br /&gt;
    # another task modify our factory.&lt;br /&gt;
    self.task_factory = copy.deepcopy(task_factory)&lt;br /&gt;
    self.iterations = iterations&lt;br /&gt;
    self.counter = 0&lt;br /&gt;
&lt;br /&gt;
    # This stores the task currently being executed.&lt;br /&gt;
    self.task = None&lt;br /&gt;
&lt;br /&gt;
    # This is used to handle callbacks from our tasks.&lt;br /&gt;
    self.tasks = beam.RoutineTaskQueue()&lt;br /&gt;
&lt;br /&gt;
  def on_execute(self):&lt;br /&gt;
&lt;br /&gt;
    # Defer to a helper function.&lt;br /&gt;
    self.execute_task()&lt;br /&gt;
&lt;br /&gt;
  def on_cancel(self):&lt;br /&gt;
&lt;br /&gt;
    # As before, to avoid race conditions between cancels and&lt;br /&gt;
    # our task we will push a callback onto a RoutineTaskQueue&lt;br /&gt;
    # to handle cancellations.&lt;br /&gt;
    self.tasks.push(self._on_cancel)&lt;br /&gt;
&lt;br /&gt;
  def on_state(self, state_entry):&lt;br /&gt;
&lt;br /&gt;
    # This method handles transitions of the task we're repeating.&lt;br /&gt;
    if state_entry.state == beam.tasks.Task.State.CANCELED:&lt;br /&gt;
&lt;br /&gt;
      # This branch indicates that we canceled our task which&lt;br /&gt;
      # means that we're handling a cancel request.&lt;br /&gt;
      self.set_terminal(beam.tasks.Task.State.CANCELED)&lt;br /&gt;
    elif beam.tasks.is_terminal(state_entry.state):&lt;br /&gt;
&lt;br /&gt;
      # This branch indicates that our task terminated and&lt;br /&gt;
      # hence we should repeat.&lt;br /&gt;
      self.execute_task()&lt;br /&gt;
&lt;br /&gt;
  def _on_cancel(self):&lt;br /&gt;
    if self.counter &amp;lt; self.iterations:&lt;br /&gt;
&lt;br /&gt;
      # Similar to before, only cancel if we still have&lt;br /&gt;
      # repetitions to process.&lt;br /&gt;
      self.task.cancel()&lt;br /&gt;
&lt;br /&gt;
  def execute_task(self):&lt;br /&gt;
    if self.counter &amp;gt;= self.iterations:&lt;br /&gt;
&lt;br /&gt;
      # This branch indicates there are no more iterations left.&lt;br /&gt;
      self.set_terminal()&lt;br /&gt;
    else:&lt;br /&gt;
&lt;br /&gt;
      # This branch indicates that we need to repeat the task&lt;br /&gt;
      # by constructing a new one and executing it.&lt;br /&gt;
      self.counter += 1&lt;br /&gt;
      self.task = self.task_factory.create()&lt;br /&gt;
      self.task.get_publisher().monitor(self.tasks.get_slot(self.on_state))&lt;br /&gt;
      self.task.execute()&lt;br /&gt;
&lt;br /&gt;
# This class is very similar to the HelloTaskFactory.&lt;br /&gt;
class RepetitionTaskFactory(beam.tasks.TaskFactory):&lt;br /&gt;
  ITERATIONS = 'iterations'&lt;br /&gt;
&lt;br /&gt;
  def __init__(self, task_factory):&lt;br /&gt;
    beam.tasks.TaskFactory.__init__(self)&lt;br /&gt;
    self.task_factory = copy.deepcopy(task_factory)&lt;br /&gt;
    self.define_property(RepetitionTaskFactory.ITERATIONS, 10)&lt;br /&gt;
    self.continuation_task = None&lt;br /&gt;
&lt;br /&gt;
  def create(self):&lt;br /&gt;
    if self.continuation_task is None:&lt;br /&gt;
      return RepetitionTask(self.task_factory,&lt;br /&gt;
        self.get(RepetitionTaskFactory.ITERATIONS))&lt;br /&gt;
    else:&lt;br /&gt;
      continuation = RepetitionTask(self.task_factory,&lt;br /&gt;
        self.get(RepetitionTaskFactory.ITERATIONS) -&lt;br /&gt;
        self.continuation_task.counter)&lt;br /&gt;
      self.continuation_task = None&lt;br /&gt;
      return continuation&lt;br /&gt;
&lt;br /&gt;
  def prepare_continuation(self, task):&lt;br /&gt;
    self.continuation_task = task&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
# Now that we have factored out the job of repeating tasks we can rewrite our&lt;br /&gt;
# HelloTask as follows:&lt;br /&gt;
&lt;br /&gt;
class HelloTask(beam.tasks.BasicTask):&lt;br /&gt;
  def __init__(self, timer):&lt;br /&gt;
    beam.tasks.BasicTask.__init__(self)&lt;br /&gt;
    self.timer = timer&lt;br /&gt;
    self.tasks = beam.RoutineTaskQueue()&lt;br /&gt;
&lt;br /&gt;
  def on_execute(self):&lt;br /&gt;
    self.timer.get_publisher().monitor(self.tasks.get_slot(self.on_timer))&lt;br /&gt;
    self.timer.start()&lt;br /&gt;
    self.set_active()&lt;br /&gt;
&lt;br /&gt;
  def on_cancel(self):&lt;br /&gt;
    self.tasks.push(self._on_cancel)&lt;br /&gt;
&lt;br /&gt;
  def on_timer(self, result):&lt;br /&gt;
    print('hello')&lt;br /&gt;
    if result == beam.threading.Timer.Result.EXPIRED:&lt;br /&gt;
      self.set_terminal()&lt;br /&gt;
    else:&lt;br /&gt;
      self.set_terminal(beam.tasks.Task.State.CANCELED)&lt;br /&gt;
&lt;br /&gt;
  def _on_cancel(self):&lt;br /&gt;
    self.timer.cancel()&lt;br /&gt;
&lt;br /&gt;
class HelloTaskFactory(beam.tasks.TaskFactory):&lt;br /&gt;
  def __init__(self, timer_factory):&lt;br /&gt;
    beam.tasks.TaskFactory.__init__(self)&lt;br /&gt;
    self.timer_factory = timer_factory&lt;br /&gt;
&lt;br /&gt;
  def create(self):&lt;br /&gt;
    return HelloTask(self.timer_factory(datetime.timedelta(seconds = 1)))&lt;br /&gt;
&lt;br /&gt;
# Finally once these two pieces are in place we can combine them as follows:&lt;br /&gt;
&lt;br /&gt;
def main():&lt;br /&gt;
&lt;br /&gt;
  # First build the HelloTaskFactory&lt;br /&gt;
  hello_factory = HelloTaskFactory(beam.threading.LiveTimer)&lt;br /&gt;
&lt;br /&gt;
  # Pass the above factory into the RepetitionTaskFactory.&lt;br /&gt;
  # The result is a factory that composes a RepetitionTask with&lt;br /&gt;
  # a HelloTask.&lt;br /&gt;
  factory = RepetitionTaskFactory(hello_factory)&lt;br /&gt;
  factory.set(RepetitionTaskFactory.ITERATIONS, 5)&lt;br /&gt;
&lt;br /&gt;
  # Now we can use the factory similarly to how we used it before.&lt;br /&gt;
  task = factory.create()&lt;br /&gt;
  task.execute()&lt;br /&gt;
  time.sleep(2)&lt;br /&gt;
  task.cancel()&lt;br /&gt;
  beam.tasks.wait(task)&lt;br /&gt;
  factory.prepare_continuation(task)&lt;br /&gt;
  factory.set(RepetitionTaskFactory.ITERATIONS, 7)&lt;br /&gt;
  task = factory.create()&lt;br /&gt;
  task.execute()&lt;br /&gt;
  beam.tasks.wait(task)&lt;br /&gt;
&lt;br /&gt;
if __name__ == '__main__':&lt;br /&gt;
  main()&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
In actuality, we can take this decomposition one step further by factoring out from the HelloTask the responsibility of printing 'hello' with the responsibility of running a task after a specified period of time. If we so desired we would write a TimerTask/TimerTaskFactory and then our final composition would be along the lines of a RepetitionTaskFactory(TimerTaskFactory(HelloTaskFactory(), beam.threading.LiveTimer)).&lt;/div&gt;</summary>
		<author><name>Kman</name></author>
		
	</entry>
	<entry>
		<id>https://wiki.spiretrading.com/index.php?title=Tasks&amp;diff=61</id>
		<title>Tasks</title>
		<link rel="alternate" type="text/html" href="https://wiki.spiretrading.com/index.php?title=Tasks&amp;diff=61"/>
		<updated>2019-01-03T20:59:10Z</updated>

		<summary type="html">&lt;p&gt;Kman: /* Decomposition */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Tasks provide a way of encapsulating and managing asynchronous actions in a composable manner. They are primarily used to perform some sort of I/O operation and/or manage a series of sub-tasks. Beam provides several classes to define your own tasks as well as classes that connect tasks to one another.&lt;br /&gt;
&lt;br /&gt;
The task API in Beam is defined by two base classes, the class Beam::Tasks::Task which represents a task, and the class Beam::Tasks::TaskFactory which constructs tasks. In this article we will explore how we can use these two classes in ways that allow us to start, stop, modify and resume asynchronous actions.&lt;br /&gt;
&lt;br /&gt;
=Interface=&lt;br /&gt;
==Task==&lt;br /&gt;
&lt;br /&gt;
The Task class defines two methods, an Execute() method to start the task and a Cancel() method to request that the task stop. Both operations are asynchronous, meaning that they return immediately and the actual operation of the task takes place in a separate thread of execution. In order to keep track of the progress of a task one must monitor its state which can be any of the following:&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! scope=&amp;quot;col&amp;quot;| State&lt;br /&gt;
! scope=&amp;quot;col&amp;quot;| Description&lt;br /&gt;
|-&lt;br /&gt;
| scope=&amp;quot;row&amp;quot;| NONE&lt;br /&gt;
| The task has not yet been executed.&lt;br /&gt;
|-&lt;br /&gt;
| scope=&amp;quot;row&amp;quot;| INITIALIZING&lt;br /&gt;
| The task is performing some initialization, during this state no sub-tasks may be executed.&lt;br /&gt;
|-&lt;br /&gt;
| scope=&amp;quot;row&amp;quot;| ACTIVE&lt;br /&gt;
| The task is running, during this state sub-tasks may be executed.&lt;br /&gt;
|-&lt;br /&gt;
| scope=&amp;quot;row&amp;quot;| PENDING_CANCEL&lt;br /&gt;
| A request to cancel the task has been made, no new sub-tasks may be executed.&lt;br /&gt;
|-&lt;br /&gt;
| scope=&amp;quot;row&amp;quot;| CANCELED&lt;br /&gt;
| The task was canceled.&lt;br /&gt;
|-&lt;br /&gt;
| scope=&amp;quot;row&amp;quot;| FAILED&lt;br /&gt;
| The task could not complete due to an error.&lt;br /&gt;
|-&lt;br /&gt;
| scope=&amp;quot;row&amp;quot;| EXPIRED&lt;br /&gt;
| The task could not complete due to a time constraint.&lt;br /&gt;
|-&lt;br /&gt;
| scope=&amp;quot;row&amp;quot;| COMPLETE&lt;br /&gt;
| The task completed successfully.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
The states CANCELED, FAILED, EXPIRED and COMPLETE all represent terminal states. Before a task can transition to a terminal state, all of its sub tasks must be in a terminal state. Furthermore once a task is in a terminal state the task is not permitted to perform any additional action or transition to a different state.&lt;br /&gt;
&lt;br /&gt;
The current state of the task along with all of its transitions is accessed through its Publisher by calling the GetPublisher() method. The publisher will emit objects of type Beam::Tasks::Task::StateEntry which contains two fields as follows:&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! scope=&amp;quot;col&amp;quot;| Name&lt;br /&gt;
! scope=&amp;quot;col&amp;quot;| Type&lt;br /&gt;
! scope=&amp;quot;col&amp;quot;| Description&lt;br /&gt;
|-&lt;br /&gt;
| scope=&amp;quot;row&amp;quot;| m_state&lt;br /&gt;
| Beam::Tasks::Task::State&lt;br /&gt;
| The state of the task.&lt;br /&gt;
|-&lt;br /&gt;
| scope=&amp;quot;row&amp;quot;| m_message&lt;br /&gt;
| std::string&lt;br /&gt;
| A message describing the reason for the transition.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
In effect a task begins in the NONE state, is then started via the Execute() method, transitions into the INITIALIZATION state where it performs any setup needed, then proceeds to the ACTIVE state where it performs its operation including executing any required sub-tasks, and then finally terminates all of its sub-tasks and performs any final clean-up before ending in a terminal state. During any point after the INITIALIZATION state it may encounter a cancel request (via the Cancel() method) or an error, either of which should result in cleaning-up and terminating its sub-tasks before transitioning to the FAILED or CANCELED state.&lt;br /&gt;
&lt;br /&gt;
==Task Factory==&lt;br /&gt;
&lt;br /&gt;
The task factory is responsible for creating new tasks by invoking its Create() method. In addition to this a task factory also keeps track of the parameters and state needed to create tasks. Setting a task's parameter is done by calling the factory's Set(name, value) method and retrieving a parameter is done via the Get(name) method.&lt;br /&gt;
&lt;br /&gt;
===Continuations===&lt;br /&gt;
&lt;br /&gt;
One additional operation that task factories perform is constructing what is called a continuation task. Continuations are a mechanism that allow us to resume a task that previously terminated, but more than that they also allow us to modify the parameters of that task. In a sense, a continuation lets us take a terminated task, modify it, and then continue running it with those modifications.&lt;br /&gt;
&lt;br /&gt;
To do this, task factories have a method PrepareContinuation(task). To use it you pass into it a task that has terminated, then you modify its properties using the Set(name, value) method, and then finally you invoke the Create() method to get a newly constructed task that represents the continuation of the old task.&lt;br /&gt;
&lt;br /&gt;
Not all tasks support continuations, those that do not will throw a Beam::NotSupportedException.&lt;br /&gt;
&lt;br /&gt;
==BasicTask==&lt;br /&gt;
&lt;br /&gt;
As a great deal of care must be taken to ensure that tasks properly transition from State to State, including managing sub-tasks, handling cancel requests etc... Beam provides the Beam::Tasks::BasicTask as a base class which can be inherited from to take care of much of the work needed to write a proper task. For example it ensures that upon a cancel request that the task transitions into the PENDING_CANCEL state and terminates all managed sub-tasks.&lt;br /&gt;
&lt;br /&gt;
To make use of a the BasicTask you need only implement the OnExecute() method to start your task, and the OnCancel() method to handle cancelling your class.&lt;br /&gt;
&lt;br /&gt;
=Example=&lt;br /&gt;
&lt;br /&gt;
To showcase a simple example, let's build a task that prints &amp;quot;hello&amp;quot; every second a given number of times. We will write a HelloTask class which inherits from BasicTask, and a HelloTaskFactory.&lt;br /&gt;
&lt;br /&gt;
==First Attempt==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=python line=line&amp;gt;&lt;br /&gt;
import beam&lt;br /&gt;
import datetime&lt;br /&gt;
import time&lt;br /&gt;
&lt;br /&gt;
class HelloTask(beam.tasks.BasicTask):&lt;br /&gt;
  '''Prints hello a specified number of times.'''&lt;br /&gt;
&lt;br /&gt;
  def __init__(self, timer, iterations):&lt;br /&gt;
    ''' Constructs this task.&lt;br /&gt;
    :param timer: The Timer used to wait between successive prints.&lt;br /&gt;
    :param iterations: The number of times to print.&lt;br /&gt;
    '''&lt;br /&gt;
&lt;br /&gt;
    # We must make sure to initialize the base class.&lt;br /&gt;
    beam.tasks.BasicTask.__init__(self)&lt;br /&gt;
    self.timer = timer&lt;br /&gt;
    self.iterations = iterations&lt;br /&gt;
&lt;br /&gt;
    # The number of times we've printed so far.&lt;br /&gt;
    self.counter = 0&lt;br /&gt;
&lt;br /&gt;
    # Used to handle timer callbacks.&lt;br /&gt;
    self.tasks = beam.RoutineTaskQueue()&lt;br /&gt;
&lt;br /&gt;
  # This overrides BasicTask.on_execute.&lt;br /&gt;
  # When called we can assume that our Task is in the INITIALIZATION state.&lt;br /&gt;
  def on_execute(self):&lt;br /&gt;
&lt;br /&gt;
    # To initialize our task we will monitor our timer and then start the timer.&lt;br /&gt;
    self.timer.get_publisher().monitor(self.tasks.get_slot(self.on_timer))&lt;br /&gt;
    self.timer.start()&lt;br /&gt;
&lt;br /&gt;
    # Once the initialization is complete we transition to the ACTIVE state.&lt;br /&gt;
    self.set_active()&lt;br /&gt;
&lt;br /&gt;
  # This overrides BasicTask.on_cancel.&lt;br /&gt;
  # When called we can assume that our Task is in the PENDING_CANCEL state.&lt;br /&gt;
  # No new sub-tasks may be executed.&lt;br /&gt;
  def on_cancel(self):&lt;br /&gt;
&lt;br /&gt;
    # In order to synchronize handling the cancel operation with the timer,&lt;br /&gt;
    # we will push a helper function onto our RoutineTaskQueue.&lt;br /&gt;
    # This ensures no race-conditions take place between the timer and&lt;br /&gt;
    # the cancel request.&lt;br /&gt;
    self.tasks.push(self._on_cancel)&lt;br /&gt;
&lt;br /&gt;
  # This handles the timer expiry.&lt;br /&gt;
  def on_timer(self, result):&lt;br /&gt;
    if result == beam.threading.Timer.Result.EXPIRED:&lt;br /&gt;
&lt;br /&gt;
      # This branch implies that our timer expired normally.&lt;br /&gt;
      print('hello')&lt;br /&gt;
      self.counter += 1&lt;br /&gt;
      if self.counter &amp;gt;= self.iterations:&lt;br /&gt;
&lt;br /&gt;
        # There is nothing more to print, so transition to&lt;br /&gt;
        # a terminal state, which by default is the COMPLETE state.&lt;br /&gt;
        self.set_terminal()&lt;br /&gt;
      else:&lt;br /&gt;
&lt;br /&gt;
        # There are still further iterations, restart the timer.&lt;br /&gt;
        self.timer.start()&lt;br /&gt;
    else:&lt;br /&gt;
&lt;br /&gt;
        # This branch implies that we canceled the timer in response&lt;br /&gt;
        # to a cancel request.&lt;br /&gt;
        # In this case we set our state to CANCELED.&lt;br /&gt;
        self.set_terminal(beam.tasks.Task.State.CANCELED)&lt;br /&gt;
&lt;br /&gt;
  def _on_cancel(self):&lt;br /&gt;
    if self.counter &amp;lt; self.iterations:&lt;br /&gt;
&lt;br /&gt;
      # Only cancel the timer if there are iterations remaining.&lt;br /&gt;
      self.timer.cancel()&lt;br /&gt;
&lt;br /&gt;
class HelloTaskFactory(beam.tasks.TaskFactory):&lt;br /&gt;
  '''Builds HelloTasks.'''&lt;br /&gt;
&lt;br /&gt;
  # Typically the parameters that get passed into the Task are&lt;br /&gt;
  # defined as static constant strings in the TaskFactory.&lt;br /&gt;
  # This makes it easier to identify the properties of a task&lt;br /&gt;
  # as well as reference them (avoiding potential typos).&lt;br /&gt;
  ITERATIONS = 'iterations'&lt;br /&gt;
&lt;br /&gt;
  def __init__(self, timer_factory):&lt;br /&gt;
    '''Constructs a HelloTaskFactory.&lt;br /&gt;
    :param timer_factory: Used to construct Timers.&lt;br /&gt;
    '''&lt;br /&gt;
&lt;br /&gt;
    # Factories will typically inherit from TaskFactory as a base class.&lt;br /&gt;
    beam.tasks.TaskFactory.__init__(self)&lt;br /&gt;
    self.timer_factory = timer_factory&lt;br /&gt;
&lt;br /&gt;
    # The constructor should define all the properties and default&lt;br /&gt;
    # values for those properties.&lt;br /&gt;
    self.define_property(HelloTaskFactory.ITERATIONS, 10)&lt;br /&gt;
&lt;br /&gt;
    # This variable keeps track of continuations.&lt;br /&gt;
    self.continuation_task = None&lt;br /&gt;
&lt;br /&gt;
  # This overrides the TaskFactory create method.&lt;br /&gt;
  def create(self):&lt;br /&gt;
&lt;br /&gt;
    if self.continuation_task is None:&lt;br /&gt;
&lt;br /&gt;
      # We are not creating a continuation task, so all we need to do is&lt;br /&gt;
      # construct a HelloTask using the ITERATIONS property defined above.&lt;br /&gt;
      return HelloTask(self.timer_factory(datetime.timedelta(seconds = 1)),&lt;br /&gt;
        self.get(HelloTaskFactory.ITERATIONS))&lt;br /&gt;
    else:&lt;br /&gt;
&lt;br /&gt;
      # We are creating a continuation task.  The continuation of a HelloTask of&lt;br /&gt;
      # N iterations that has already printed C times is basically a HelloTask&lt;br /&gt;
      # that prints N - C times.&lt;br /&gt;
      continuation = HelloTask(&lt;br /&gt;
        self.timer_factory(datetime.timedelta(seconds = 1)),&lt;br /&gt;
        self.get(HelloTaskFactory.ITERATIONS) - self.continuation_task.counter)&lt;br /&gt;
      self.continuation_task = None&lt;br /&gt;
      return continuation&lt;br /&gt;
&lt;br /&gt;
  # This overrides the TaskFactory prepare_continuation method.&lt;br /&gt;
  def prepare_continuation(self, task):&lt;br /&gt;
&lt;br /&gt;
    # We store the task to continue.&lt;br /&gt;
    self.continuation_task = task&lt;br /&gt;
&lt;br /&gt;
def main():&lt;br /&gt;
&lt;br /&gt;
  # Construct the HelloTaskFactory using the LiveTimer for 5 iterations.&lt;br /&gt;
  factory = HelloTaskFactory(beam.threading.LiveTimer)&lt;br /&gt;
  factory.set(HelloTaskFactory.ITERATIONS, 5)&lt;br /&gt;
  task = factory.create()&lt;br /&gt;
  task.execute()&lt;br /&gt;
&lt;br /&gt;
  # Let's sleep for 2 seconds before canceling the task.&lt;br /&gt;
  # It should print hello twice.&lt;br /&gt;
  time.sleep(2)&lt;br /&gt;
  task.cancel()&lt;br /&gt;
&lt;br /&gt;
  # Wait for the task to enter the CANCELED state.&lt;br /&gt;
  beam.tasks.wait(task)&lt;br /&gt;
&lt;br /&gt;
  # Build the continuation task and execute it.  To do this we first&lt;br /&gt;
  # call prepare_continuation, then we make our modifications using the set&lt;br /&gt;
  # method, then we create the task and execute it.&lt;br /&gt;
  factory.prepare_continuation(task)&lt;br /&gt;
  factory.set(HelloTaskFactory.ITERATIONS, 7)&lt;br /&gt;
  task = factory.create()&lt;br /&gt;
&lt;br /&gt;
  # We expect it to print hello three times before coming to an end.&lt;br /&gt;
  task.execute()&lt;br /&gt;
  beam.tasks.wait(task)&lt;br /&gt;
&lt;br /&gt;
if __name__ == '__main__':&lt;br /&gt;
  main()&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Decomposition==&lt;br /&gt;
&lt;br /&gt;
The above example works, but upon reflection we should notice that this Task is responsible for two distinct things. One is the responsibility of printing, and the other is the responsibility of repeating. Given that the purpose of tasks is to be able to compose asynchronous operations we should separate these two responsibilities from one another. To do that we will change our HelloTask so that all it does is print hello after a specified time period, followed by a RepetitionTask which repeats a task a specified number of times. The benefit of this is that our RepetitionTask can be reused to repeat any task whatsoever down the road.&lt;br /&gt;
&lt;br /&gt;
We will define it as follows:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=python line=line&amp;gt;&lt;br /&gt;
import copy&lt;br /&gt;
import datetime&lt;br /&gt;
import time&lt;br /&gt;
&lt;br /&gt;
import beam&lt;br /&gt;
&lt;br /&gt;
class RepetitionTask(beam.tasks.BasicTask):&lt;br /&gt;
  '''Repeats a Task a specified number of times.'''&lt;br /&gt;
&lt;br /&gt;
  def __init__(self, task_factory, iterations):&lt;br /&gt;
    '''Constructs the Task.&lt;br /&gt;
    :param task_factory: Builds the Task to repeat.&lt;br /&gt;
    :param iterations: The number of times to repeat the Task.&lt;br /&gt;
    '''&lt;br /&gt;
    beam.tasks.BasicTask.__init__(self)&lt;br /&gt;
&lt;br /&gt;
    # We should always make a deep copy of factories in order to&lt;br /&gt;
    # avoid modifying a factory belonging to another task or having&lt;br /&gt;
    # another task modify our factory.&lt;br /&gt;
    self.task_factory = copy.deepcopy(task_factory)&lt;br /&gt;
    self.iterations = iterations&lt;br /&gt;
    self.counter = 0&lt;br /&gt;
&lt;br /&gt;
    # This stores the task currently being executed.&lt;br /&gt;
    self.task = None&lt;br /&gt;
&lt;br /&gt;
    # This is used to handle callbacks from our tasks.&lt;br /&gt;
    self.tasks = beam.RoutineTaskQueue()&lt;br /&gt;
&lt;br /&gt;
  def on_execute(self):&lt;br /&gt;
&lt;br /&gt;
    # Defer to a helper function.&lt;br /&gt;
    self.execute_task()&lt;br /&gt;
&lt;br /&gt;
  def on_cancel(self):&lt;br /&gt;
&lt;br /&gt;
    # As before, to avoid race conditions between cancels and&lt;br /&gt;
    # our task we will push a callback onto a RoutineTaskQueue&lt;br /&gt;
    # to handle cancellations.&lt;br /&gt;
    self.tasks.push(self._on_cancel)&lt;br /&gt;
&lt;br /&gt;
  def on_state(self, state_entry):&lt;br /&gt;
&lt;br /&gt;
    # This method handles transitions of the task we're repeating.&lt;br /&gt;
    if state_entry.state == beam.tasks.Task.State.CANCELED:&lt;br /&gt;
&lt;br /&gt;
      # This branch indicates that we canceled our task which&lt;br /&gt;
      # means that we're handling a cancel request.&lt;br /&gt;
      self.set_terminal(beam.tasks.Task.State.CANCELED)&lt;br /&gt;
    elif beam.tasks.is_terminal(state_entry.state):&lt;br /&gt;
&lt;br /&gt;
      # This branch indicates that our task terminated and&lt;br /&gt;
      # hence we should repeat.&lt;br /&gt;
      self.execute_task()&lt;br /&gt;
&lt;br /&gt;
  def _on_cancel(self):&lt;br /&gt;
    if self.counter &amp;lt; self.iterations:&lt;br /&gt;
&lt;br /&gt;
      # Similar to before, only cancel if we still have&lt;br /&gt;
      # repetitions to process.&lt;br /&gt;
      self.task.cancel()&lt;br /&gt;
&lt;br /&gt;
  def execute_task(self):&lt;br /&gt;
    if self.counter &amp;gt;= self.iterations:&lt;br /&gt;
&lt;br /&gt;
      # This branch indicates there are no more iterations left.&lt;br /&gt;
      self.set_terminal()&lt;br /&gt;
    else:&lt;br /&gt;
&lt;br /&gt;
      # This branch indicates that we need to repeat the task&lt;br /&gt;
      # by constructing a new one and executing it.&lt;br /&gt;
      self.counter += 1&lt;br /&gt;
      self.task = self.task_factory.create()&lt;br /&gt;
      self.task.get_publisher().monitor(self.tasks.get_slot(self.on_state))&lt;br /&gt;
      self.task.execute()&lt;br /&gt;
&lt;br /&gt;
# This class is very similar to the HelloTaskFactory.&lt;br /&gt;
class RepetitionTaskFactory(beam.tasks.TaskFactory):&lt;br /&gt;
  ITERATIONS = 'iterations'&lt;br /&gt;
&lt;br /&gt;
  def __init__(self, task_factory):&lt;br /&gt;
    beam.tasks.TaskFactory.__init__(self)&lt;br /&gt;
    self.task_factory = copy.deepcopy(task_factory)&lt;br /&gt;
    self.define_property(RepetitionTaskFactory.ITERATIONS, 10)&lt;br /&gt;
    self.continuation_task = None&lt;br /&gt;
&lt;br /&gt;
  def create(self):&lt;br /&gt;
    if self.continuation_task is None:&lt;br /&gt;
      return RepetitionTask(self.task_factory,&lt;br /&gt;
        self.get(RepetitionTaskFactory.ITERATIONS))&lt;br /&gt;
    else:&lt;br /&gt;
      continuation = RepetitionTask(self.task_factory,&lt;br /&gt;
        self.get(RepetitionTaskFactory.ITERATIONS) -&lt;br /&gt;
        self.continuation_task.counter)&lt;br /&gt;
      self.continuation_task = None&lt;br /&gt;
      return continuation&lt;br /&gt;
&lt;br /&gt;
  def prepare_continuation(self, task):&lt;br /&gt;
    self.continuation_task = task&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
# Now that we have factored out the job of repeating tasks we can rewrite our&lt;br /&gt;
# HelloTask as follows:&lt;br /&gt;
&lt;br /&gt;
class HelloTask(beam.tasks.BasicTask):&lt;br /&gt;
  def __init__(self, timer):&lt;br /&gt;
    beam.tasks.BasicTask.__init__(self)&lt;br /&gt;
    self.timer = timer&lt;br /&gt;
    self.tasks = beam.RoutineTaskQueue()&lt;br /&gt;
&lt;br /&gt;
  def on_execute(self):&lt;br /&gt;
    self.timer.get_publisher().monitor(self.tasks.get_slot(self.on_timer))&lt;br /&gt;
    self.timer.start()&lt;br /&gt;
    self.set_active()&lt;br /&gt;
&lt;br /&gt;
  def on_cancel(self):&lt;br /&gt;
    self.tasks.push(self._on_cancel)&lt;br /&gt;
&lt;br /&gt;
  def on_timer(self, result):&lt;br /&gt;
    print('hello')&lt;br /&gt;
    if result == beam.threading.Timer.Result.EXPIRED:&lt;br /&gt;
      self.set_terminal()&lt;br /&gt;
    else:&lt;br /&gt;
      self.set_terminal(beam.tasks.Task.State.CANCELED)&lt;br /&gt;
&lt;br /&gt;
  def _on_cancel(self):&lt;br /&gt;
    self.timer.cancel()&lt;br /&gt;
&lt;br /&gt;
class HelloTaskFactory(beam.tasks.TaskFactory):&lt;br /&gt;
  def __init__(self, timer_factory):&lt;br /&gt;
    beam.tasks.TaskFactory.__init__(self)&lt;br /&gt;
    self.timer_factory = timer_factory&lt;br /&gt;
&lt;br /&gt;
  def create(self):&lt;br /&gt;
    return HelloTask(self.timer_factory(datetime.timedelta(seconds = 1)))&lt;br /&gt;
&lt;br /&gt;
# Finally once these two pieces are in place we can combine them as follows:&lt;br /&gt;
&lt;br /&gt;
def main():&lt;br /&gt;
&lt;br /&gt;
  # First build the HelloTaskFactory&lt;br /&gt;
  hello_factory = HelloTaskFactory(beam.threading.LiveTimer)&lt;br /&gt;
&lt;br /&gt;
  # Pass the above factory into the RepetitionTaskFactory.&lt;br /&gt;
  # The result is a factory that composes a RepetitionTask with&lt;br /&gt;
  # a HelloTask.&lt;br /&gt;
  factory = RepetitionTaskFactory(hello_factory)&lt;br /&gt;
  factory.set(RepetitionTaskFactory.ITERATIONS, 5)&lt;br /&gt;
&lt;br /&gt;
  # Now we can use the factory similarly to how we used it before.&lt;br /&gt;
  task = factory.create()&lt;br /&gt;
  task.execute()&lt;br /&gt;
  time.sleep(2)&lt;br /&gt;
  task.cancel()&lt;br /&gt;
  beam.tasks.wait(task)&lt;br /&gt;
  factory.prepare_continuation(task)&lt;br /&gt;
  factory.set(RepetitionTaskFactory.ITERATIONS, 7)&lt;br /&gt;
  task = factory.create()&lt;br /&gt;
  task.execute()&lt;br /&gt;
  beam.tasks.wait(task)&lt;br /&gt;
&lt;br /&gt;
if __name__ == '__main__':&lt;br /&gt;
  main()&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
In actuality, we can take this decomposition one step further by factoring out from the HelloTask the responsibility of printing 'hello' with the responsibility of running a task after a specified period of time. If we so desired we would write a TimerTask/TimerTaskFactory and then our final composition would be along the lines of a RepetitionTaskFactory(TimerTaskFactory(HelloTaskFactory(), beam.threading.LiveTimer)).&lt;/div&gt;</summary>
		<author><name>Kman</name></author>
		
	</entry>
	<entry>
		<id>https://wiki.spiretrading.com/index.php?title=Tasks&amp;diff=60</id>
		<title>Tasks</title>
		<link rel="alternate" type="text/html" href="https://wiki.spiretrading.com/index.php?title=Tasks&amp;diff=60"/>
		<updated>2019-01-03T20:56:14Z</updated>

		<summary type="html">&lt;p&gt;Kman: /* First Attempt */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Tasks provide a way of encapsulating and managing asynchronous actions in a composable manner. They are primarily used to perform some sort of I/O operation and/or manage a series of sub-tasks. Beam provides several classes to define your own tasks as well as classes that connect tasks to one another.&lt;br /&gt;
&lt;br /&gt;
The task API in Beam is defined by two base classes, the class Beam::Tasks::Task which represents a task, and the class Beam::Tasks::TaskFactory which constructs tasks. In this article we will explore how we can use these two classes in ways that allow us to start, stop, modify and resume asynchronous actions.&lt;br /&gt;
&lt;br /&gt;
=Interface=&lt;br /&gt;
==Task==&lt;br /&gt;
&lt;br /&gt;
The Task class defines two methods, an Execute() method to start the task and a Cancel() method to request that the task stop. Both operations are asynchronous, meaning that they return immediately and the actual operation of the task takes place in a separate thread of execution. In order to keep track of the progress of a task one must monitor its state which can be any of the following:&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! scope=&amp;quot;col&amp;quot;| State&lt;br /&gt;
! scope=&amp;quot;col&amp;quot;| Description&lt;br /&gt;
|-&lt;br /&gt;
| scope=&amp;quot;row&amp;quot;| NONE&lt;br /&gt;
| The task has not yet been executed.&lt;br /&gt;
|-&lt;br /&gt;
| scope=&amp;quot;row&amp;quot;| INITIALIZING&lt;br /&gt;
| The task is performing some initialization, during this state no sub-tasks may be executed.&lt;br /&gt;
|-&lt;br /&gt;
| scope=&amp;quot;row&amp;quot;| ACTIVE&lt;br /&gt;
| The task is running, during this state sub-tasks may be executed.&lt;br /&gt;
|-&lt;br /&gt;
| scope=&amp;quot;row&amp;quot;| PENDING_CANCEL&lt;br /&gt;
| A request to cancel the task has been made, no new sub-tasks may be executed.&lt;br /&gt;
|-&lt;br /&gt;
| scope=&amp;quot;row&amp;quot;| CANCELED&lt;br /&gt;
| The task was canceled.&lt;br /&gt;
|-&lt;br /&gt;
| scope=&amp;quot;row&amp;quot;| FAILED&lt;br /&gt;
| The task could not complete due to an error.&lt;br /&gt;
|-&lt;br /&gt;
| scope=&amp;quot;row&amp;quot;| EXPIRED&lt;br /&gt;
| The task could not complete due to a time constraint.&lt;br /&gt;
|-&lt;br /&gt;
| scope=&amp;quot;row&amp;quot;| COMPLETE&lt;br /&gt;
| The task completed successfully.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
The states CANCELED, FAILED, EXPIRED and COMPLETE all represent terminal states. Before a task can transition to a terminal state, all of its sub tasks must be in a terminal state. Furthermore once a task is in a terminal state the task is not permitted to perform any additional action or transition to a different state.&lt;br /&gt;
&lt;br /&gt;
The current state of the task along with all of its transitions is accessed through its Publisher by calling the GetPublisher() method. The publisher will emit objects of type Beam::Tasks::Task::StateEntry which contains two fields as follows:&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! scope=&amp;quot;col&amp;quot;| Name&lt;br /&gt;
! scope=&amp;quot;col&amp;quot;| Type&lt;br /&gt;
! scope=&amp;quot;col&amp;quot;| Description&lt;br /&gt;
|-&lt;br /&gt;
| scope=&amp;quot;row&amp;quot;| m_state&lt;br /&gt;
| Beam::Tasks::Task::State&lt;br /&gt;
| The state of the task.&lt;br /&gt;
|-&lt;br /&gt;
| scope=&amp;quot;row&amp;quot;| m_message&lt;br /&gt;
| std::string&lt;br /&gt;
| A message describing the reason for the transition.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
In effect a task begins in the NONE state, is then started via the Execute() method, transitions into the INITIALIZATION state where it performs any setup needed, then proceeds to the ACTIVE state where it performs its operation including executing any required sub-tasks, and then finally terminates all of its sub-tasks and performs any final clean-up before ending in a terminal state. During any point after the INITIALIZATION state it may encounter a cancel request (via the Cancel() method) or an error, either of which should result in cleaning-up and terminating its sub-tasks before transitioning to the FAILED or CANCELED state.&lt;br /&gt;
&lt;br /&gt;
==Task Factory==&lt;br /&gt;
&lt;br /&gt;
The task factory is responsible for creating new tasks by invoking its Create() method. In addition to this a task factory also keeps track of the parameters and state needed to create tasks. Setting a task's parameter is done by calling the factory's Set(name, value) method and retrieving a parameter is done via the Get(name) method.&lt;br /&gt;
&lt;br /&gt;
===Continuations===&lt;br /&gt;
&lt;br /&gt;
One additional operation that task factories perform is constructing what is called a continuation task. Continuations are a mechanism that allow us to resume a task that previously terminated, but more than that they also allow us to modify the parameters of that task. In a sense, a continuation lets us take a terminated task, modify it, and then continue running it with those modifications.&lt;br /&gt;
&lt;br /&gt;
To do this, task factories have a method PrepareContinuation(task). To use it you pass into it a task that has terminated, then you modify its properties using the Set(name, value) method, and then finally you invoke the Create() method to get a newly constructed task that represents the continuation of the old task.&lt;br /&gt;
&lt;br /&gt;
Not all tasks support continuations, those that do not will throw a Beam::NotSupportedException.&lt;br /&gt;
&lt;br /&gt;
==BasicTask==&lt;br /&gt;
&lt;br /&gt;
As a great deal of care must be taken to ensure that tasks properly transition from State to State, including managing sub-tasks, handling cancel requests etc... Beam provides the Beam::Tasks::BasicTask as a base class which can be inherited from to take care of much of the work needed to write a proper task. For example it ensures that upon a cancel request that the task transitions into the PENDING_CANCEL state and terminates all managed sub-tasks.&lt;br /&gt;
&lt;br /&gt;
To make use of a the BasicTask you need only implement the OnExecute() method to start your task, and the OnCancel() method to handle cancelling your class.&lt;br /&gt;
&lt;br /&gt;
=Example=&lt;br /&gt;
&lt;br /&gt;
To showcase a simple example, let's build a task that prints &amp;quot;hello&amp;quot; every second a given number of times. We will write a HelloTask class which inherits from BasicTask, and a HelloTaskFactory.&lt;br /&gt;
&lt;br /&gt;
==First Attempt==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=python line=line&amp;gt;&lt;br /&gt;
import beam&lt;br /&gt;
import datetime&lt;br /&gt;
import time&lt;br /&gt;
&lt;br /&gt;
class HelloTask(beam.tasks.BasicTask):&lt;br /&gt;
  '''Prints hello a specified number of times.'''&lt;br /&gt;
&lt;br /&gt;
  def __init__(self, timer, iterations):&lt;br /&gt;
    ''' Constructs this task.&lt;br /&gt;
    :param timer: The Timer used to wait between successive prints.&lt;br /&gt;
    :param iterations: The number of times to print.&lt;br /&gt;
    '''&lt;br /&gt;
&lt;br /&gt;
    # We must make sure to initialize the base class.&lt;br /&gt;
    beam.tasks.BasicTask.__init__(self)&lt;br /&gt;
    self.timer = timer&lt;br /&gt;
    self.iterations = iterations&lt;br /&gt;
&lt;br /&gt;
    # The number of times we've printed so far.&lt;br /&gt;
    self.counter = 0&lt;br /&gt;
&lt;br /&gt;
    # Used to handle timer callbacks.&lt;br /&gt;
    self.tasks = beam.RoutineTaskQueue()&lt;br /&gt;
&lt;br /&gt;
  # This overrides BasicTask.on_execute.&lt;br /&gt;
  # When called we can assume that our Task is in the INITIALIZATION state.&lt;br /&gt;
  def on_execute(self):&lt;br /&gt;
&lt;br /&gt;
    # To initialize our task we will monitor our timer and then start the timer.&lt;br /&gt;
    self.timer.get_publisher().monitor(self.tasks.get_slot(self.on_timer))&lt;br /&gt;
    self.timer.start()&lt;br /&gt;
&lt;br /&gt;
    # Once the initialization is complete we transition to the ACTIVE state.&lt;br /&gt;
    self.set_active()&lt;br /&gt;
&lt;br /&gt;
  # This overrides BasicTask.on_cancel.&lt;br /&gt;
  # When called we can assume that our Task is in the PENDING_CANCEL state.&lt;br /&gt;
  # No new sub-tasks may be executed.&lt;br /&gt;
  def on_cancel(self):&lt;br /&gt;
&lt;br /&gt;
    # In order to synchronize handling the cancel operation with the timer,&lt;br /&gt;
    # we will push a helper function onto our RoutineTaskQueue.&lt;br /&gt;
    # This ensures no race-conditions take place between the timer and&lt;br /&gt;
    # the cancel request.&lt;br /&gt;
    self.tasks.push(self._on_cancel)&lt;br /&gt;
&lt;br /&gt;
  # This handles the timer expiry.&lt;br /&gt;
  def on_timer(self, result):&lt;br /&gt;
    if result == beam.threading.Timer.Result.EXPIRED:&lt;br /&gt;
&lt;br /&gt;
      # This branch implies that our timer expired normally.&lt;br /&gt;
      print('hello')&lt;br /&gt;
      self.counter += 1&lt;br /&gt;
      if self.counter &amp;gt;= self.iterations:&lt;br /&gt;
&lt;br /&gt;
        # There is nothing more to print, so transition to&lt;br /&gt;
        # a terminal state, which by default is the COMPLETE state.&lt;br /&gt;
        self.set_terminal()&lt;br /&gt;
      else:&lt;br /&gt;
&lt;br /&gt;
        # There are still further iterations, restart the timer.&lt;br /&gt;
        self.timer.start()&lt;br /&gt;
    else:&lt;br /&gt;
&lt;br /&gt;
        # This branch implies that we canceled the timer in response&lt;br /&gt;
        # to a cancel request.&lt;br /&gt;
        # In this case we set our state to CANCELED.&lt;br /&gt;
        self.set_terminal(beam.tasks.Task.State.CANCELED)&lt;br /&gt;
&lt;br /&gt;
  def _on_cancel(self):&lt;br /&gt;
    if self.counter &amp;lt; self.iterations:&lt;br /&gt;
&lt;br /&gt;
      # Only cancel the timer if there are iterations remaining.&lt;br /&gt;
      self.timer.cancel()&lt;br /&gt;
&lt;br /&gt;
class HelloTaskFactory(beam.tasks.TaskFactory):&lt;br /&gt;
  '''Builds HelloTasks.'''&lt;br /&gt;
&lt;br /&gt;
  # Typically the parameters that get passed into the Task are&lt;br /&gt;
  # defined as static constant strings in the TaskFactory.&lt;br /&gt;
  # This makes it easier to identify the properties of a task&lt;br /&gt;
  # as well as reference them (avoiding potential typos).&lt;br /&gt;
  ITERATIONS = 'iterations'&lt;br /&gt;
&lt;br /&gt;
  def __init__(self, timer_factory):&lt;br /&gt;
    '''Constructs a HelloTaskFactory.&lt;br /&gt;
    :param timer_factory: Used to construct Timers.&lt;br /&gt;
    '''&lt;br /&gt;
&lt;br /&gt;
    # Factories will typically inherit from TaskFactory as a base class.&lt;br /&gt;
    beam.tasks.TaskFactory.__init__(self)&lt;br /&gt;
    self.timer_factory = timer_factory&lt;br /&gt;
&lt;br /&gt;
    # The constructor should define all the properties and default&lt;br /&gt;
    # values for those properties.&lt;br /&gt;
    self.define_property(HelloTaskFactory.ITERATIONS, 10)&lt;br /&gt;
&lt;br /&gt;
    # This variable keeps track of continuations.&lt;br /&gt;
    self.continuation_task = None&lt;br /&gt;
&lt;br /&gt;
  # This overrides the TaskFactory create method.&lt;br /&gt;
  def create(self):&lt;br /&gt;
&lt;br /&gt;
    if self.continuation_task is None:&lt;br /&gt;
&lt;br /&gt;
      # We are not creating a continuation task, so all we need to do is&lt;br /&gt;
      # construct a HelloTask using the ITERATIONS property defined above.&lt;br /&gt;
      return HelloTask(self.timer_factory(datetime.timedelta(seconds = 1)),&lt;br /&gt;
        self.get(HelloTaskFactory.ITERATIONS))&lt;br /&gt;
    else:&lt;br /&gt;
&lt;br /&gt;
      # We are creating a continuation task.  The continuation of a HelloTask of&lt;br /&gt;
      # N iterations that has already printed C times is basically a HelloTask&lt;br /&gt;
      # that prints N - C times.&lt;br /&gt;
      continuation = HelloTask(&lt;br /&gt;
        self.timer_factory(datetime.timedelta(seconds = 1)),&lt;br /&gt;
        self.get(HelloTaskFactory.ITERATIONS) - self.continuation_task.counter)&lt;br /&gt;
      self.continuation_task = None&lt;br /&gt;
      return continuation&lt;br /&gt;
&lt;br /&gt;
  # This overrides the TaskFactory prepare_continuation method.&lt;br /&gt;
  def prepare_continuation(self, task):&lt;br /&gt;
&lt;br /&gt;
    # We store the task to continue.&lt;br /&gt;
    self.continuation_task = task&lt;br /&gt;
&lt;br /&gt;
def main():&lt;br /&gt;
&lt;br /&gt;
  # Construct the HelloTaskFactory using the LiveTimer for 5 iterations.&lt;br /&gt;
  factory = HelloTaskFactory(beam.threading.LiveTimer)&lt;br /&gt;
  factory.set(HelloTaskFactory.ITERATIONS, 5)&lt;br /&gt;
  task = factory.create()&lt;br /&gt;
  task.execute()&lt;br /&gt;
&lt;br /&gt;
  # Let's sleep for 2 seconds before canceling the task.&lt;br /&gt;
  # It should print hello twice.&lt;br /&gt;
  time.sleep(2)&lt;br /&gt;
  task.cancel()&lt;br /&gt;
&lt;br /&gt;
  # Wait for the task to enter the CANCELED state.&lt;br /&gt;
  beam.tasks.wait(task)&lt;br /&gt;
&lt;br /&gt;
  # Build the continuation task and execute it.  To do this we first&lt;br /&gt;
  # call prepare_continuation, then we make our modifications using the set&lt;br /&gt;
  # method, then we create the task and execute it.&lt;br /&gt;
  factory.prepare_continuation(task)&lt;br /&gt;
  factory.set(HelloTaskFactory.ITERATIONS, 7)&lt;br /&gt;
  task = factory.create()&lt;br /&gt;
&lt;br /&gt;
  # We expect it to print hello three times before coming to an end.&lt;br /&gt;
  task.execute()&lt;br /&gt;
  beam.tasks.wait(task)&lt;br /&gt;
&lt;br /&gt;
if __name__ == '__main__':&lt;br /&gt;
  main()&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Decomposition==&lt;br /&gt;
&lt;br /&gt;
The above example works, but upon reflection we should notice that this Task is responsible for two distinct things. One is the responsibility of printing, and the other is the responsibility of repeating. Given that the purpose of tasks is to be able to compose asynchronous operations we should separate these two responsibilities from one another. To do that we will change our HelloTask so that all it does is print hello after a specified time period, followed by a RepetitionTask which repeats a task a specified number of times. The benefit of this is that our RepetitionTask can be reused to repeat any task whatsoever down the road.&lt;br /&gt;
&lt;br /&gt;
We will define it as follows:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=python line=line&amp;gt;&lt;br /&gt;
class RepetitionTask(beam.tasks.BasicTask):&lt;br /&gt;
  '''Repeats a Task a specified number of times.'''&lt;br /&gt;
&lt;br /&gt;
  def __init__(self, task_factory, iterations):&lt;br /&gt;
    '''Constructs the Task.&lt;br /&gt;
    :param task_factory: Builds the Task to repeat.&lt;br /&gt;
    :param iterations: The number of times to repeat the Task.&lt;br /&gt;
    '''&lt;br /&gt;
    beam.tasks.BasicTask.__init__(self)&lt;br /&gt;
&lt;br /&gt;
    # We should always make a deep copy of factories in order to&lt;br /&gt;
    # avoid modifying a factory belonging to another task or having&lt;br /&gt;
    # another task modify our factory.&lt;br /&gt;
    self.task_factory = copy.deepcopy(task_factory)&lt;br /&gt;
    self.iterations = iterations&lt;br /&gt;
    self.counter = 0&lt;br /&gt;
&lt;br /&gt;
    # This stores the task currently being executed.&lt;br /&gt;
    self.task = None&lt;br /&gt;
&lt;br /&gt;
    # This is used to handle callbacks from our tasks.&lt;br /&gt;
    self.tasks = beam.RoutineTaskQueue()&lt;br /&gt;
&lt;br /&gt;
  def on_execute(self):&lt;br /&gt;
&lt;br /&gt;
    # Defer to a helper function.&lt;br /&gt;
    self.execute_task()&lt;br /&gt;
&lt;br /&gt;
  def on_cancel(self):&lt;br /&gt;
&lt;br /&gt;
    # As before, to avoid race conditions between cancels and&lt;br /&gt;
    # our task we will push a callback onto a RoutineTaskQueue&lt;br /&gt;
    # to handle cancellations.&lt;br /&gt;
    self.tasks.push(self._on_cancel)&lt;br /&gt;
&lt;br /&gt;
  def on_state(self, state_entry):&lt;br /&gt;
&lt;br /&gt;
    # This method handles transitions of the task we're repeating.&lt;br /&gt;
    if state_entry.state == beam.tasks.Task.State.CANCELED:&lt;br /&gt;
&lt;br /&gt;
      # This branch indicates that we canceled our task which&lt;br /&gt;
      # means that we're handling a cancel request.&lt;br /&gt;
      self.set_terminal(beam.tasks.Task.State.CANCELED)&lt;br /&gt;
    elif beam.tasks.is_terminal(state_entry.state):&lt;br /&gt;
&lt;br /&gt;
      # This branch indicates that our task terminated and&lt;br /&gt;
      # hence we should repeat.&lt;br /&gt;
      self.execute_task()&lt;br /&gt;
&lt;br /&gt;
  def _on_cancel(self):&lt;br /&gt;
    if self.counter &amp;lt; self.iterations:&lt;br /&gt;
&lt;br /&gt;
      # Similar to before, only cancel if we still have&lt;br /&gt;
      # repetitions to process.&lt;br /&gt;
      self.task.cancel()&lt;br /&gt;
&lt;br /&gt;
  def execute_task(self):&lt;br /&gt;
    if self.counter &amp;gt;= self.iterations:&lt;br /&gt;
&lt;br /&gt;
      # This branch indicates there are no more iterations left.&lt;br /&gt;
      self.set_terminal()&lt;br /&gt;
    else:&lt;br /&gt;
&lt;br /&gt;
      # This branch indicates that we need to repeat the task&lt;br /&gt;
      # by constructing a new one and executing it.&lt;br /&gt;
      self.counter += 1&lt;br /&gt;
      self.task = self.task_factory.create()&lt;br /&gt;
      self.task.get_publisher().monitor(self.tasks.get_slot(self.on_state))&lt;br /&gt;
      self.task.execute()&lt;br /&gt;
&lt;br /&gt;
# This class is very similar to the HelloTaskFactory.&lt;br /&gt;
class RepetitionTaskFactory(beam.tasks.TaskFactory):&lt;br /&gt;
  ITERATIONS = 'iterations'&lt;br /&gt;
&lt;br /&gt;
  def __init__(self, task_factory):&lt;br /&gt;
    beam.tasks.TaskFactory.__init__(self)&lt;br /&gt;
    self.task_factory = copy.deepcopy(task_factory)&lt;br /&gt;
    self.define_property(RepetitionTaskFactory.ITERATIONS, 10)&lt;br /&gt;
    self.continuation_task = None&lt;br /&gt;
&lt;br /&gt;
  def create(self):&lt;br /&gt;
    if self.continuation_task is None:&lt;br /&gt;
      return RepetitionTask(self.task_factory,&lt;br /&gt;
        self.get(RepetitionTaskFactory.ITERATIONS))&lt;br /&gt;
    else:&lt;br /&gt;
      continuation = RepetitionTask(self.task_factory,&lt;br /&gt;
        self.get(RepetitionTaskFactory.ITERATIONS) -&lt;br /&gt;
        self.continuation_task.counter)&lt;br /&gt;
      self.continuation_task = None&lt;br /&gt;
      return continuation&lt;br /&gt;
&lt;br /&gt;
  def prepare_continuation(self, task):&lt;br /&gt;
    self.continuation_task = task&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Now that we have factored out the job of repeating tasks we can rewrite our HelloTask as follows:&lt;br /&gt;
&lt;br /&gt;
class HelloTask(beam.tasks.BasicTask):&lt;br /&gt;
  def __init__(self, timer):&lt;br /&gt;
    beam.tasks.BasicTask.__init__(self)&lt;br /&gt;
    self.timer = timer&lt;br /&gt;
    self.tasks = beam.RoutineTaskQueue()&lt;br /&gt;
&lt;br /&gt;
  def on_execute(self):&lt;br /&gt;
    self.timer.get_publisher().monitor(self.tasks.get_slot(self.on_timer))&lt;br /&gt;
    self.timer.start()&lt;br /&gt;
    self.set_active()&lt;br /&gt;
&lt;br /&gt;
  def on_cancel(self):&lt;br /&gt;
    self.tasks.push(self._on_cancel)&lt;br /&gt;
&lt;br /&gt;
  def on_timer(self, result):&lt;br /&gt;
    print 'hello'&lt;br /&gt;
    if result == beam.threading.Timer.Result.EXPIRED:&lt;br /&gt;
      self.set_terminal()&lt;br /&gt;
    else:&lt;br /&gt;
      self.set_terminal(beam.tasks.Task.State.CANCELED)&lt;br /&gt;
&lt;br /&gt;
  def _on_cancel(self):&lt;br /&gt;
    self.timer.cancel()&lt;br /&gt;
&lt;br /&gt;
class HelloTaskFactory(beam.tasks.TaskFactory):&lt;br /&gt;
  def __init__(self, timer_factory):&lt;br /&gt;
    beam.tasks.TaskFactory.__init__(self)&lt;br /&gt;
    self.timer_factory = timer_factory&lt;br /&gt;
&lt;br /&gt;
  def create(self):&lt;br /&gt;
    return HelloTask(self.timer_factory(datetime.timedelta(seconds = 1)))&lt;br /&gt;
&lt;br /&gt;
Finally once these two pieces are in place we can combine them as follows:&lt;br /&gt;
&lt;br /&gt;
def main():&lt;br /&gt;
&lt;br /&gt;
  # First build the HelloTaskFactory&lt;br /&gt;
  hello_factory = HelloTaskFactory(beam.threading.LiveTimer)&lt;br /&gt;
&lt;br /&gt;
  # Pass the above factory into the RepetitionTaskFactory.&lt;br /&gt;
  # The result is a factory that composes a RepetitionTask with&lt;br /&gt;
  # a HelloTask.&lt;br /&gt;
  factory = RepetitionTaskFactory(hello_factory)&lt;br /&gt;
  factory.set(RepetitionTaskFactory.ITERATIONS, 5)&lt;br /&gt;
&lt;br /&gt;
  # Now we can use the factory similarly to how we used it before.&lt;br /&gt;
  task = factory.create()&lt;br /&gt;
  task.execute()&lt;br /&gt;
  time.sleep(2)&lt;br /&gt;
  task.cancel()&lt;br /&gt;
  beam.tasks.wait(task)&lt;br /&gt;
  factory.prepare_continuation(task)&lt;br /&gt;
  factory.set(RepetitionTaskFactory.ITERATIONS, 7)&lt;br /&gt;
  task = factory.create()&lt;br /&gt;
  task.execute()&lt;br /&gt;
  beam.tasks.wait(task)&lt;br /&gt;
&lt;br /&gt;
if __name__ == '__main__':&lt;br /&gt;
  main()&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
In actuality, we can take this decomposition one step further by factoring out from the HelloTask the responsibility of printing 'hello' with the responsibility of running a task after a specified period of time. If we so desired we would write a TimerTask/TimerTaskFactory and then our final composition would be along the lines of a RepetitionTaskFactory(TimerTaskFactory(HelloTaskFactory(), beam.threading.LiveTimer)).&lt;/div&gt;</summary>
		<author><name>Kman</name></author>
		
	</entry>
	<entry>
		<id>https://wiki.spiretrading.com/index.php?title=Query&amp;diff=59</id>
		<title>Query</title>
		<link rel="alternate" type="text/html" href="https://wiki.spiretrading.com/index.php?title=Query&amp;diff=59"/>
		<updated>2018-12-19T18:01:04Z</updated>

		<summary type="html">&lt;p&gt;Kman: /* Example */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Beam provides a series of classes to query historical and real time streaming data along a wide range of search criteria. It is one of the core APIs provided by Beam and used extensively in Spire to search through and disseminate market data and order executions.&lt;br /&gt;
&lt;br /&gt;
==Structure==&lt;br /&gt;
Much of the data stored by Spire is in the form of a time series. The data is grouped together based on an index, for example time and sales data is indexed by its ticker symbol, order's are indexed by the account the order belongs to etc... For every item there is both a timestamp and a sequence number associated with it (to identify which data was published first in the event that two items have the same timestamp).&lt;br /&gt;
&lt;br /&gt;
The most common type of query used in Spire to search through a time series is defined by the Beam::Queries::BasicQuery class. It consists of five components that are used to fully specify the type of data that is to be retrieved. Those five components are described in detail as follows:&lt;br /&gt;
&lt;br /&gt;
===Index===&lt;br /&gt;
Every data item to query over must be associated with a single index. Specifying the value of the index to query over is defined by the class Beam::Queries::IndexedQuery.&lt;br /&gt;
&lt;br /&gt;
===Range===&lt;br /&gt;
This component is defined by the class Beam::Queries::RangedIndex and it specifies the time range to search through as well as whether the query is strictly for historical data, real time data, or both. The class Beam::Queries::Range defines the semantics of a range and consists of a start value and an end value, both of which can be either a timestamp or a sequence number. Sequence numbers are defined by the class Beam::Queries::Sequence and it contains two special values which control the behavior of a query: LAST and PRESENT.&lt;br /&gt;
&lt;br /&gt;
If the end of a range is specified to be PRESENT then the query will return all matching values that are currently stored in the database. If the end of a range is specified to be LAST or +infinity then in addition to returning all currently matching values, the query will also return matching values published in real time as they arrive.&lt;br /&gt;
&lt;br /&gt;
Any other value used to mark the end of a range results in a strictly historical data query, even if the value denotes some point in the future.&lt;br /&gt;
&lt;br /&gt;
===Snapshot limit===&lt;br /&gt;
This specifies the maximusm number of historical data items to retrieve. This is typically used to prevent a query from returning too much data. The class Beam::Queries::SnapshotLimit contains two values, the size of the limit and the type of the limit. The size controls the maximum number of historical data items are returned by a query (with the special value of UNLIMITED if every value should be returned), as well as the type of snapshot. The type dictates whether items should be returned from the beginning of the series or the end of the series (the HEAD and TAIL respectively).&lt;br /&gt;
&lt;br /&gt;
For example to query for the very last item currently stored in a time series, one can use a range of [FIRST, PRESENT] and a snapshot limit whose type is TAIL and whose size is 1. Alternatively to query for the first 10 values in a time series one would use a range of [FIRST, PRESENT] and a snapshot limit with type HEAD and size 10.&lt;br /&gt;
&lt;br /&gt;
The class Beam::Queries::SnapshotLimitedQuery is the component used to indicate what the snapshot limit of a query should be. By default, this class specifies that no values are to be returned (its size is 0). This is because one is expected to be explicit about how much data is desired. The special value Beam::Queries::SnapshotLimit::Unlimited() can be used to explicitly indicate that there is no limit on how much data should be returned, however, it should be noted that the database engine handling the request may impose limits of its own regarding the maximum size of a snapshot.&lt;br /&gt;
&lt;br /&gt;
===Interruption policy===&lt;br /&gt;
When querying for real time data it is possible for the query to get interrupted, usually due to a disconnection. This component, defined by Beam::Queries::InterruptableQuery, specifies what action should be taken in the event of such an interruption. The possible recovery options are defined by the enumerator Beam::Queries::InterruptionPolicy as follows:&lt;br /&gt;
&lt;br /&gt;
RECOVER_DATA, the query should attempt to re-establish a connection to the database and recover any data that was published during the time that the query was interrupted.&lt;br /&gt;
IGNORE_CONTINUE, the query should attempt to re-establish a connection to the database but ignore any data that was published during the time that the query was interrupted. This is usually desirable when only live, real time data is desired as this option will omit any stale data published during the interruption.&lt;br /&gt;
BREAK_QUERY, the query should abort, indicating an exception. This is the default interruption policy.&lt;br /&gt;
&lt;br /&gt;
===Filter===&lt;br /&gt;
&lt;br /&gt;
==Example==&lt;br /&gt;
An example of a query for historical data might be to retrieve the first 1000 time and sales for MSFT.NSDQ from December 11th, 2018 to December 12th, 2018.&lt;br /&gt;
&lt;br /&gt;
===C++===&lt;br /&gt;
&amp;lt;syntaxhighlight lang=c++ line=line&amp;gt;&lt;br /&gt;
#include &amp;lt;iostream&amp;gt;&lt;br /&gt;
#include &amp;quot;Nexus/MarketDataService/SecurityMarketDataQuery.hpp&amp;quot;&lt;br /&gt;
#include &amp;quot;Nexus/ServiceClients/ApplicationServiceClients.hpp&amp;quot;&lt;br /&gt;
&lt;br /&gt;
int main() {&lt;br /&gt;
  auto socketThreadPool = Beam::Network::SocketThreadPool();&lt;br /&gt;
  auto timerThreadPool = Beam::Threading::TimerThreadPool();&lt;br /&gt;
&lt;br /&gt;
  // Connect to the service.&lt;br /&gt;
  auto serviceClients = Nexus::ApplicationServiceClients(&lt;br /&gt;
    Beam::Network::IpAddress(&amp;quot;127.0.0.1&amp;quot;, 20000), &amp;quot;username&amp;quot;,&lt;br /&gt;
    &amp;quot;password&amp;quot;, Beam::Ref(socketThreadPool), Beam::Ref(timerThreadPool));&lt;br /&gt;
  serviceClients.Open();&lt;br /&gt;
  auto&amp;amp; marketDataClient = serviceClients.GetMarketDataClient();&lt;br /&gt;
&lt;br /&gt;
  // Build the query.&lt;br /&gt;
  auto query = Nexus::MarketDataService::SecurityMarketDataQuery();&lt;br /&gt;
  query.SetIndex(Nexus::ParseSecurity(&amp;quot;MSFT.NSDQ&amp;quot;));&lt;br /&gt;
  query.SetRange(Beam::TimeService::ToUtcTime(&lt;br /&gt;
    boost::posix_time::ptime(boost::gregorian::date(2018, 12, 11))),&lt;br /&gt;
    Beam::TimeService::ToUtcTime(&lt;br /&gt;
    boost::posix_time::ptime(boost::gregorian::date(2018, 12, 12))));&lt;br /&gt;
  query.SetSnapshotLimit(Beam::Queries::SnapshotLimit::Type::HEAD, 1000);&lt;br /&gt;
&lt;br /&gt;
  // Build the Queue to store the results.&lt;br /&gt;
  auto queue = std::make_shared&amp;lt;Beam::Queue&amp;lt;Nexus::TimeAndSale&amp;gt;&amp;gt;();&lt;br /&gt;
&lt;br /&gt;
  // Submit the query to the market data service.&lt;br /&gt;
  marketDataClient.QueryTimeAndSales(query, queue);&lt;br /&gt;
&lt;br /&gt;
  // Print the results&lt;br /&gt;
  try {&lt;br /&gt;
    while(true) {&lt;br /&gt;
      std::cout &amp;lt;&amp;lt; queue-&amp;gt;Top().m_price &amp;lt;&amp;lt; std::endl;&lt;br /&gt;
      queue-&amp;gt;Pop();&lt;br /&gt;
    }&lt;br /&gt;
  } catch(const Beam::PipeBrokenException&amp;amp;) {}&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Python===&lt;br /&gt;
&amp;lt;syntaxhighlight lang=python line=line&amp;gt;&lt;br /&gt;
import beam&lt;br /&gt;
import nexus&lt;br /&gt;
import datetime&lt;br /&gt;
&lt;br /&gt;
# Connect to the service.&lt;br /&gt;
service_clients = nexus.ApplicationServiceClients(&lt;br /&gt;
  beam.network.IpAddress('127.0.0.1', 20000),&lt;br /&gt;
  'username', 'password')&lt;br /&gt;
&lt;br /&gt;
service_clients.open()&lt;br /&gt;
market_data_client = service_clients.get_market_data_client()&lt;br /&gt;
&lt;br /&gt;
# Build the query.&lt;br /&gt;
query = beam.queries.Query()&lt;br /&gt;
query.index = nexus.parse_security('MSFT.NSDQ')&lt;br /&gt;
query.range = beam.queries.Range(beam.time_service.to_utc_time(&lt;br /&gt;
  datetime.datetime(2018, 12, 11)), beam.time_service.to_utc_time(&lt;br /&gt;
  datetime.datetime(2018, 12, 12)))&lt;br /&gt;
query.snapshot_limit = beam.queries.SnapshotLimit(&lt;br /&gt;
  beam.queries.SnapshotLimit.Type.HEAD, 1000)&lt;br /&gt;
&lt;br /&gt;
# Build the Queue to store the results.&lt;br /&gt;
queue = beam.Queue()&lt;br /&gt;
&lt;br /&gt;
# Submit the query to the market data service.&lt;br /&gt;
market_data_client.query_time_and_sales(query, queue)&lt;br /&gt;
&lt;br /&gt;
# Print the results&lt;br /&gt;
try:&lt;br /&gt;
  while True:&lt;br /&gt;
    print(queue.top().price)&lt;br /&gt;
    queue.pop()&lt;br /&gt;
except:&lt;br /&gt;
  pass&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;/div&gt;</summary>
		<author><name>Kman</name></author>
		
	</entry>
	<entry>
		<id>https://wiki.spiretrading.com/index.php?title=Query&amp;diff=58</id>
		<title>Query</title>
		<link rel="alternate" type="text/html" href="https://wiki.spiretrading.com/index.php?title=Query&amp;diff=58"/>
		<updated>2018-12-19T17:59:56Z</updated>

		<summary type="html">&lt;p&gt;Kman: /* C++ */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Beam provides a series of classes to query historical and real time streaming data along a wide range of search criteria. It is one of the core APIs provided by Beam and used extensively in Spire to search through and disseminate market data and order executions.&lt;br /&gt;
&lt;br /&gt;
==Structure==&lt;br /&gt;
Much of the data stored by Spire is in the form of a time series. The data is grouped together based on an index, for example time and sales data is indexed by its ticker symbol, order's are indexed by the account the order belongs to etc... For every item there is both a timestamp and a sequence number associated with it (to identify which data was published first in the event that two items have the same timestamp).&lt;br /&gt;
&lt;br /&gt;
The most common type of query used in Spire to search through a time series is defined by the Beam::Queries::BasicQuery class. It consists of five components that are used to fully specify the type of data that is to be retrieved. Those five components are described in detail as follows:&lt;br /&gt;
&lt;br /&gt;
===Index===&lt;br /&gt;
Every data item to query over must be associated with a single index. Specifying the value of the index to query over is defined by the class Beam::Queries::IndexedQuery.&lt;br /&gt;
&lt;br /&gt;
===Range===&lt;br /&gt;
This component is defined by the class Beam::Queries::RangedIndex and it specifies the time range to search through as well as whether the query is strictly for historical data, real time data, or both. The class Beam::Queries::Range defines the semantics of a range and consists of a start value and an end value, both of which can be either a timestamp or a sequence number. Sequence numbers are defined by the class Beam::Queries::Sequence and it contains two special values which control the behavior of a query: LAST and PRESENT.&lt;br /&gt;
&lt;br /&gt;
If the end of a range is specified to be PRESENT then the query will return all matching values that are currently stored in the database. If the end of a range is specified to be LAST or +infinity then in addition to returning all currently matching values, the query will also return matching values published in real time as they arrive.&lt;br /&gt;
&lt;br /&gt;
Any other value used to mark the end of a range results in a strictly historical data query, even if the value denotes some point in the future.&lt;br /&gt;
&lt;br /&gt;
===Snapshot limit===&lt;br /&gt;
This specifies the maximusm number of historical data items to retrieve. This is typically used to prevent a query from returning too much data. The class Beam::Queries::SnapshotLimit contains two values, the size of the limit and the type of the limit. The size controls the maximum number of historical data items are returned by a query (with the special value of UNLIMITED if every value should be returned), as well as the type of snapshot. The type dictates whether items should be returned from the beginning of the series or the end of the series (the HEAD and TAIL respectively).&lt;br /&gt;
&lt;br /&gt;
For example to query for the very last item currently stored in a time series, one can use a range of [FIRST, PRESENT] and a snapshot limit whose type is TAIL and whose size is 1. Alternatively to query for the first 10 values in a time series one would use a range of [FIRST, PRESENT] and a snapshot limit with type HEAD and size 10.&lt;br /&gt;
&lt;br /&gt;
The class Beam::Queries::SnapshotLimitedQuery is the component used to indicate what the snapshot limit of a query should be. By default, this class specifies that no values are to be returned (its size is 0). This is because one is expected to be explicit about how much data is desired. The special value Beam::Queries::SnapshotLimit::Unlimited() can be used to explicitly indicate that there is no limit on how much data should be returned, however, it should be noted that the database engine handling the request may impose limits of its own regarding the maximum size of a snapshot.&lt;br /&gt;
&lt;br /&gt;
===Interruption policy===&lt;br /&gt;
When querying for real time data it is possible for the query to get interrupted, usually due to a disconnection. This component, defined by Beam::Queries::InterruptableQuery, specifies what action should be taken in the event of such an interruption. The possible recovery options are defined by the enumerator Beam::Queries::InterruptionPolicy as follows:&lt;br /&gt;
&lt;br /&gt;
RECOVER_DATA, the query should attempt to re-establish a connection to the database and recover any data that was published during the time that the query was interrupted.&lt;br /&gt;
IGNORE_CONTINUE, the query should attempt to re-establish a connection to the database but ignore any data that was published during the time that the query was interrupted. This is usually desirable when only live, real time data is desired as this option will omit any stale data published during the interruption.&lt;br /&gt;
BREAK_QUERY, the query should abort, indicating an exception. This is the default interruption policy.&lt;br /&gt;
&lt;br /&gt;
===Filter===&lt;br /&gt;
&lt;br /&gt;
==Example==&lt;br /&gt;
An example of a query for historical data might be to retrieve the first 1000 time and sales for MSFT.NSDQ from August 11th, 2016 to August 12th, 2016.&lt;br /&gt;
&lt;br /&gt;
===C++===&lt;br /&gt;
&amp;lt;syntaxhighlight lang=c++ line=line&amp;gt;&lt;br /&gt;
#include &amp;lt;iostream&amp;gt;&lt;br /&gt;
#include &amp;quot;Nexus/MarketDataService/SecurityMarketDataQuery.hpp&amp;quot;&lt;br /&gt;
#include &amp;quot;Nexus/ServiceClients/ApplicationServiceClients.hpp&amp;quot;&lt;br /&gt;
&lt;br /&gt;
int main() {&lt;br /&gt;
  auto socketThreadPool = Beam::Network::SocketThreadPool();&lt;br /&gt;
  auto timerThreadPool = Beam::Threading::TimerThreadPool();&lt;br /&gt;
&lt;br /&gt;
  // Connect to the service.&lt;br /&gt;
  auto serviceClients = Nexus::ApplicationServiceClients(&lt;br /&gt;
    Beam::Network::IpAddress(&amp;quot;127.0.0.1&amp;quot;, 20000), &amp;quot;username&amp;quot;,&lt;br /&gt;
    &amp;quot;password&amp;quot;, Beam::Ref(socketThreadPool), Beam::Ref(timerThreadPool));&lt;br /&gt;
  serviceClients.Open();&lt;br /&gt;
  auto&amp;amp; marketDataClient = serviceClients.GetMarketDataClient();&lt;br /&gt;
&lt;br /&gt;
  // Build the query.&lt;br /&gt;
  auto query = Nexus::MarketDataService::SecurityMarketDataQuery();&lt;br /&gt;
  query.SetIndex(Nexus::ParseSecurity(&amp;quot;MSFT.NSDQ&amp;quot;));&lt;br /&gt;
  query.SetRange(Beam::TimeService::ToUtcTime(&lt;br /&gt;
    boost::posix_time::ptime(boost::gregorian::date(2018, 12, 11))),&lt;br /&gt;
    Beam::TimeService::ToUtcTime(&lt;br /&gt;
    boost::posix_time::ptime(boost::gregorian::date(2018, 12, 12))));&lt;br /&gt;
  query.SetSnapshotLimit(Beam::Queries::SnapshotLimit::Type::HEAD, 1000);&lt;br /&gt;
&lt;br /&gt;
  // Build the Queue to store the results.&lt;br /&gt;
  auto queue = std::make_shared&amp;lt;Beam::Queue&amp;lt;Nexus::TimeAndSale&amp;gt;&amp;gt;();&lt;br /&gt;
&lt;br /&gt;
  // Submit the query to the market data service.&lt;br /&gt;
  marketDataClient.QueryTimeAndSales(query, queue);&lt;br /&gt;
&lt;br /&gt;
  // Print the results&lt;br /&gt;
  try {&lt;br /&gt;
    while(true) {&lt;br /&gt;
      std::cout &amp;lt;&amp;lt; queue-&amp;gt;Top().m_price &amp;lt;&amp;lt; std::endl;&lt;br /&gt;
      queue-&amp;gt;Pop();&lt;br /&gt;
    }&lt;br /&gt;
  } catch(const Beam::PipeBrokenException&amp;amp;) {}&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Python===&lt;br /&gt;
&amp;lt;syntaxhighlight lang=python line=line&amp;gt;&lt;br /&gt;
import beam&lt;br /&gt;
import nexus&lt;br /&gt;
import datetime&lt;br /&gt;
&lt;br /&gt;
# Connect to the service.&lt;br /&gt;
service_clients = nexus.ApplicationServiceClients(&lt;br /&gt;
  beam.network.IpAddress('127.0.0.1', 20000),&lt;br /&gt;
  'username', 'password')&lt;br /&gt;
&lt;br /&gt;
service_clients.open()&lt;br /&gt;
market_data_client = service_clients.get_market_data_client()&lt;br /&gt;
&lt;br /&gt;
# Build the query.&lt;br /&gt;
query = beam.queries.Query()&lt;br /&gt;
query.index = nexus.parse_security('MSFT.NSDQ')&lt;br /&gt;
query.range = beam.queries.Range(beam.time_service.to_utc_time(&lt;br /&gt;
  datetime.datetime(2018, 12, 11)), beam.time_service.to_utc_time(&lt;br /&gt;
  datetime.datetime(2018, 12, 12)))&lt;br /&gt;
query.snapshot_limit = beam.queries.SnapshotLimit(&lt;br /&gt;
  beam.queries.SnapshotLimit.Type.HEAD, 1000)&lt;br /&gt;
&lt;br /&gt;
# Build the Queue to store the results.&lt;br /&gt;
queue = beam.Queue()&lt;br /&gt;
&lt;br /&gt;
# Submit the query to the market data service.&lt;br /&gt;
market_data_client.query_time_and_sales(query, queue)&lt;br /&gt;
&lt;br /&gt;
# Print the results&lt;br /&gt;
try:&lt;br /&gt;
  while True:&lt;br /&gt;
    print(queue.top().price)&lt;br /&gt;
    queue.pop()&lt;br /&gt;
except:&lt;br /&gt;
  pass&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;/div&gt;</summary>
		<author><name>Kman</name></author>
		
	</entry>
	<entry>
		<id>https://wiki.spiretrading.com/index.php?title=Query&amp;diff=57</id>
		<title>Query</title>
		<link rel="alternate" type="text/html" href="https://wiki.spiretrading.com/index.php?title=Query&amp;diff=57"/>
		<updated>2018-12-19T16:53:08Z</updated>

		<summary type="html">&lt;p&gt;Kman: /* Python */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Beam provides a series of classes to query historical and real time streaming data along a wide range of search criteria. It is one of the core APIs provided by Beam and used extensively in Spire to search through and disseminate market data and order executions.&lt;br /&gt;
&lt;br /&gt;
==Structure==&lt;br /&gt;
Much of the data stored by Spire is in the form of a time series. The data is grouped together based on an index, for example time and sales data is indexed by its ticker symbol, order's are indexed by the account the order belongs to etc... For every item there is both a timestamp and a sequence number associated with it (to identify which data was published first in the event that two items have the same timestamp).&lt;br /&gt;
&lt;br /&gt;
The most common type of query used in Spire to search through a time series is defined by the Beam::Queries::BasicQuery class. It consists of five components that are used to fully specify the type of data that is to be retrieved. Those five components are described in detail as follows:&lt;br /&gt;
&lt;br /&gt;
===Index===&lt;br /&gt;
Every data item to query over must be associated with a single index. Specifying the value of the index to query over is defined by the class Beam::Queries::IndexedQuery.&lt;br /&gt;
&lt;br /&gt;
===Range===&lt;br /&gt;
This component is defined by the class Beam::Queries::RangedIndex and it specifies the time range to search through as well as whether the query is strictly for historical data, real time data, or both. The class Beam::Queries::Range defines the semantics of a range and consists of a start value and an end value, both of which can be either a timestamp or a sequence number. Sequence numbers are defined by the class Beam::Queries::Sequence and it contains two special values which control the behavior of a query: LAST and PRESENT.&lt;br /&gt;
&lt;br /&gt;
If the end of a range is specified to be PRESENT then the query will return all matching values that are currently stored in the database. If the end of a range is specified to be LAST or +infinity then in addition to returning all currently matching values, the query will also return matching values published in real time as they arrive.&lt;br /&gt;
&lt;br /&gt;
Any other value used to mark the end of a range results in a strictly historical data query, even if the value denotes some point in the future.&lt;br /&gt;
&lt;br /&gt;
===Snapshot limit===&lt;br /&gt;
This specifies the maximusm number of historical data items to retrieve. This is typically used to prevent a query from returning too much data. The class Beam::Queries::SnapshotLimit contains two values, the size of the limit and the type of the limit. The size controls the maximum number of historical data items are returned by a query (with the special value of UNLIMITED if every value should be returned), as well as the type of snapshot. The type dictates whether items should be returned from the beginning of the series or the end of the series (the HEAD and TAIL respectively).&lt;br /&gt;
&lt;br /&gt;
For example to query for the very last item currently stored in a time series, one can use a range of [FIRST, PRESENT] and a snapshot limit whose type is TAIL and whose size is 1. Alternatively to query for the first 10 values in a time series one would use a range of [FIRST, PRESENT] and a snapshot limit with type HEAD and size 10.&lt;br /&gt;
&lt;br /&gt;
The class Beam::Queries::SnapshotLimitedQuery is the component used to indicate what the snapshot limit of a query should be. By default, this class specifies that no values are to be returned (its size is 0). This is because one is expected to be explicit about how much data is desired. The special value Beam::Queries::SnapshotLimit::Unlimited() can be used to explicitly indicate that there is no limit on how much data should be returned, however, it should be noted that the database engine handling the request may impose limits of its own regarding the maximum size of a snapshot.&lt;br /&gt;
&lt;br /&gt;
===Interruption policy===&lt;br /&gt;
When querying for real time data it is possible for the query to get interrupted, usually due to a disconnection. This component, defined by Beam::Queries::InterruptableQuery, specifies what action should be taken in the event of such an interruption. The possible recovery options are defined by the enumerator Beam::Queries::InterruptionPolicy as follows:&lt;br /&gt;
&lt;br /&gt;
RECOVER_DATA, the query should attempt to re-establish a connection to the database and recover any data that was published during the time that the query was interrupted.&lt;br /&gt;
IGNORE_CONTINUE, the query should attempt to re-establish a connection to the database but ignore any data that was published during the time that the query was interrupted. This is usually desirable when only live, real time data is desired as this option will omit any stale data published during the interruption.&lt;br /&gt;
BREAK_QUERY, the query should abort, indicating an exception. This is the default interruption policy.&lt;br /&gt;
&lt;br /&gt;
===Filter===&lt;br /&gt;
&lt;br /&gt;
==Example==&lt;br /&gt;
An example of a query for historical data might be to retrieve the first 1000 time and sales for MSFT.NSDQ from August 11th, 2016 to August 12th, 2016.&lt;br /&gt;
&lt;br /&gt;
===C++===&lt;br /&gt;
&amp;lt;syntaxhighlight lang=c++ line=line&amp;gt;&lt;br /&gt;
#include &amp;lt;iostream&amp;gt;&lt;br /&gt;
#include &amp;quot;Nexus/MarketDataService/SecurityMarketDataQuery.hpp&amp;quot;&lt;br /&gt;
#include &amp;quot;Nexus/ServiceClients/ApplicationServiceClients.hpp&amp;quot;&lt;br /&gt;
&lt;br /&gt;
int main() {&lt;br /&gt;
  Beam::Network::SocketThreadPool socketThreadPool;&lt;br /&gt;
  Beam::Threading::TimerThreadPool timerThreadPool;&lt;br /&gt;
&lt;br /&gt;
  // Connect to the service.&lt;br /&gt;
  Nexus::ApplicationServiceClients serviceClients{&lt;br /&gt;
    Beam::Network::IpAddress{&amp;quot;127.0.0.1&amp;quot;, 20000}, &amp;quot;username&amp;quot;,&lt;br /&gt;
    &amp;quot;password&amp;quot;, Beam::Ref(socketThreadPool), Beam::Ref(timerThreadPool)};&lt;br /&gt;
  serviceClients.Open();&lt;br /&gt;
  auto&amp;amp; marketDataClient = serviceClients.GetMarketDataClient();&lt;br /&gt;
&lt;br /&gt;
  // Build the query.&lt;br /&gt;
  auto query = Nexus::MarketDataService::SecurityMarketDataQuery();&lt;br /&gt;
  query.SetIndex(Nexus::ParseSecurity(&amp;quot;MSFT.NSDQ&amp;quot;));&lt;br /&gt;
  query.SetRange(Beam::TimeService::ToUtcTime(&lt;br /&gt;
    boost::posix_time::ptime{boost::gregorian::date{2016 , 8, 11}}),&lt;br /&gt;
    Beam::TimeService::ToUtcTime(&lt;br /&gt;
    boost::posix_time::ptime{boost::gregorian::date{2016, 8, 12}}));&lt;br /&gt;
  query.SetSnapshotLimit(Beam::Queries::SnapshotLimit::Type::HEAD, 1000);&lt;br /&gt;
&lt;br /&gt;
  // Build the Queue to store the results.&lt;br /&gt;
  auto queue = std::make_shared&amp;lt;Beam::Queue&amp;lt;Nexus::TimeAndSale&amp;gt;&amp;gt;();&lt;br /&gt;
&lt;br /&gt;
  // Submit the query to the market data service.&lt;br /&gt;
  marketDataClient.QueryTimeAndSales(query, queue);&lt;br /&gt;
&lt;br /&gt;
  // Print the results&lt;br /&gt;
  try {&lt;br /&gt;
    while(true) {&lt;br /&gt;
      std::cout &amp;lt;&amp;lt; queue-&amp;gt;Top().m_price &amp;lt;&amp;lt; std::endl;&lt;br /&gt;
      queue-&amp;gt;Pop();&lt;br /&gt;
    }&lt;br /&gt;
  } catch(const Beam::PipeBrokenException&amp;amp;) {}&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Python===&lt;br /&gt;
&amp;lt;syntaxhighlight lang=python line=line&amp;gt;&lt;br /&gt;
import beam&lt;br /&gt;
import nexus&lt;br /&gt;
import datetime&lt;br /&gt;
&lt;br /&gt;
# Connect to the service.&lt;br /&gt;
service_clients = nexus.ApplicationServiceClients(&lt;br /&gt;
  beam.network.IpAddress('127.0.0.1', 20000),&lt;br /&gt;
  'username', 'password')&lt;br /&gt;
&lt;br /&gt;
service_clients.open()&lt;br /&gt;
market_data_client = service_clients.get_market_data_client()&lt;br /&gt;
&lt;br /&gt;
# Build the query.&lt;br /&gt;
query = beam.queries.Query()&lt;br /&gt;
query.index = nexus.parse_security('MSFT.NSDQ')&lt;br /&gt;
query.range = beam.queries.Range(beam.time_service.to_utc_time(&lt;br /&gt;
  datetime.datetime(2018, 12, 11)), beam.time_service.to_utc_time(&lt;br /&gt;
  datetime.datetime(2018, 12, 12)))&lt;br /&gt;
query.snapshot_limit = beam.queries.SnapshotLimit(&lt;br /&gt;
  beam.queries.SnapshotLimit.Type.HEAD, 1000)&lt;br /&gt;
&lt;br /&gt;
# Build the Queue to store the results.&lt;br /&gt;
queue = beam.Queue()&lt;br /&gt;
&lt;br /&gt;
# Submit the query to the market data service.&lt;br /&gt;
market_data_client.query_time_and_sales(query, queue)&lt;br /&gt;
&lt;br /&gt;
# Print the results&lt;br /&gt;
try:&lt;br /&gt;
  while True:&lt;br /&gt;
    print(queue.top().price)&lt;br /&gt;
    queue.pop()&lt;br /&gt;
except:&lt;br /&gt;
  pass&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;/div&gt;</summary>
		<author><name>Kman</name></author>
		
	</entry>
	<entry>
		<id>https://wiki.spiretrading.com/index.php?title=Query&amp;diff=56</id>
		<title>Query</title>
		<link rel="alternate" type="text/html" href="https://wiki.spiretrading.com/index.php?title=Query&amp;diff=56"/>
		<updated>2018-12-19T16:52:25Z</updated>

		<summary type="html">&lt;p&gt;Kman: /* Python */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Beam provides a series of classes to query historical and real time streaming data along a wide range of search criteria. It is one of the core APIs provided by Beam and used extensively in Spire to search through and disseminate market data and order executions.&lt;br /&gt;
&lt;br /&gt;
==Structure==&lt;br /&gt;
Much of the data stored by Spire is in the form of a time series. The data is grouped together based on an index, for example time and sales data is indexed by its ticker symbol, order's are indexed by the account the order belongs to etc... For every item there is both a timestamp and a sequence number associated with it (to identify which data was published first in the event that two items have the same timestamp).&lt;br /&gt;
&lt;br /&gt;
The most common type of query used in Spire to search through a time series is defined by the Beam::Queries::BasicQuery class. It consists of five components that are used to fully specify the type of data that is to be retrieved. Those five components are described in detail as follows:&lt;br /&gt;
&lt;br /&gt;
===Index===&lt;br /&gt;
Every data item to query over must be associated with a single index. Specifying the value of the index to query over is defined by the class Beam::Queries::IndexedQuery.&lt;br /&gt;
&lt;br /&gt;
===Range===&lt;br /&gt;
This component is defined by the class Beam::Queries::RangedIndex and it specifies the time range to search through as well as whether the query is strictly for historical data, real time data, or both. The class Beam::Queries::Range defines the semantics of a range and consists of a start value and an end value, both of which can be either a timestamp or a sequence number. Sequence numbers are defined by the class Beam::Queries::Sequence and it contains two special values which control the behavior of a query: LAST and PRESENT.&lt;br /&gt;
&lt;br /&gt;
If the end of a range is specified to be PRESENT then the query will return all matching values that are currently stored in the database. If the end of a range is specified to be LAST or +infinity then in addition to returning all currently matching values, the query will also return matching values published in real time as they arrive.&lt;br /&gt;
&lt;br /&gt;
Any other value used to mark the end of a range results in a strictly historical data query, even if the value denotes some point in the future.&lt;br /&gt;
&lt;br /&gt;
===Snapshot limit===&lt;br /&gt;
This specifies the maximusm number of historical data items to retrieve. This is typically used to prevent a query from returning too much data. The class Beam::Queries::SnapshotLimit contains two values, the size of the limit and the type of the limit. The size controls the maximum number of historical data items are returned by a query (with the special value of UNLIMITED if every value should be returned), as well as the type of snapshot. The type dictates whether items should be returned from the beginning of the series or the end of the series (the HEAD and TAIL respectively).&lt;br /&gt;
&lt;br /&gt;
For example to query for the very last item currently stored in a time series, one can use a range of [FIRST, PRESENT] and a snapshot limit whose type is TAIL and whose size is 1. Alternatively to query for the first 10 values in a time series one would use a range of [FIRST, PRESENT] and a snapshot limit with type HEAD and size 10.&lt;br /&gt;
&lt;br /&gt;
The class Beam::Queries::SnapshotLimitedQuery is the component used to indicate what the snapshot limit of a query should be. By default, this class specifies that no values are to be returned (its size is 0). This is because one is expected to be explicit about how much data is desired. The special value Beam::Queries::SnapshotLimit::Unlimited() can be used to explicitly indicate that there is no limit on how much data should be returned, however, it should be noted that the database engine handling the request may impose limits of its own regarding the maximum size of a snapshot.&lt;br /&gt;
&lt;br /&gt;
===Interruption policy===&lt;br /&gt;
When querying for real time data it is possible for the query to get interrupted, usually due to a disconnection. This component, defined by Beam::Queries::InterruptableQuery, specifies what action should be taken in the event of such an interruption. The possible recovery options are defined by the enumerator Beam::Queries::InterruptionPolicy as follows:&lt;br /&gt;
&lt;br /&gt;
RECOVER_DATA, the query should attempt to re-establish a connection to the database and recover any data that was published during the time that the query was interrupted.&lt;br /&gt;
IGNORE_CONTINUE, the query should attempt to re-establish a connection to the database but ignore any data that was published during the time that the query was interrupted. This is usually desirable when only live, real time data is desired as this option will omit any stale data published during the interruption.&lt;br /&gt;
BREAK_QUERY, the query should abort, indicating an exception. This is the default interruption policy.&lt;br /&gt;
&lt;br /&gt;
===Filter===&lt;br /&gt;
&lt;br /&gt;
==Example==&lt;br /&gt;
An example of a query for historical data might be to retrieve the first 1000 time and sales for MSFT.NSDQ from August 11th, 2016 to August 12th, 2016.&lt;br /&gt;
&lt;br /&gt;
===C++===&lt;br /&gt;
&amp;lt;syntaxhighlight lang=c++ line=line&amp;gt;&lt;br /&gt;
#include &amp;lt;iostream&amp;gt;&lt;br /&gt;
#include &amp;quot;Nexus/MarketDataService/SecurityMarketDataQuery.hpp&amp;quot;&lt;br /&gt;
#include &amp;quot;Nexus/ServiceClients/ApplicationServiceClients.hpp&amp;quot;&lt;br /&gt;
&lt;br /&gt;
int main() {&lt;br /&gt;
  Beam::Network::SocketThreadPool socketThreadPool;&lt;br /&gt;
  Beam::Threading::TimerThreadPool timerThreadPool;&lt;br /&gt;
&lt;br /&gt;
  // Connect to the service.&lt;br /&gt;
  Nexus::ApplicationServiceClients serviceClients{&lt;br /&gt;
    Beam::Network::IpAddress{&amp;quot;127.0.0.1&amp;quot;, 20000}, &amp;quot;username&amp;quot;,&lt;br /&gt;
    &amp;quot;password&amp;quot;, Beam::Ref(socketThreadPool), Beam::Ref(timerThreadPool)};&lt;br /&gt;
  serviceClients.Open();&lt;br /&gt;
  auto&amp;amp; marketDataClient = serviceClients.GetMarketDataClient();&lt;br /&gt;
&lt;br /&gt;
  // Build the query.&lt;br /&gt;
  auto query = Nexus::MarketDataService::SecurityMarketDataQuery();&lt;br /&gt;
  query.SetIndex(Nexus::ParseSecurity(&amp;quot;MSFT.NSDQ&amp;quot;));&lt;br /&gt;
  query.SetRange(Beam::TimeService::ToUtcTime(&lt;br /&gt;
    boost::posix_time::ptime{boost::gregorian::date{2016 , 8, 11}}),&lt;br /&gt;
    Beam::TimeService::ToUtcTime(&lt;br /&gt;
    boost::posix_time::ptime{boost::gregorian::date{2016, 8, 12}}));&lt;br /&gt;
  query.SetSnapshotLimit(Beam::Queries::SnapshotLimit::Type::HEAD, 1000);&lt;br /&gt;
&lt;br /&gt;
  // Build the Queue to store the results.&lt;br /&gt;
  auto queue = std::make_shared&amp;lt;Beam::Queue&amp;lt;Nexus::TimeAndSale&amp;gt;&amp;gt;();&lt;br /&gt;
&lt;br /&gt;
  // Submit the query to the market data service.&lt;br /&gt;
  marketDataClient.QueryTimeAndSales(query, queue);&lt;br /&gt;
&lt;br /&gt;
  // Print the results&lt;br /&gt;
  try {&lt;br /&gt;
    while(true) {&lt;br /&gt;
      std::cout &amp;lt;&amp;lt; queue-&amp;gt;Top().m_price &amp;lt;&amp;lt; std::endl;&lt;br /&gt;
      queue-&amp;gt;Pop();&lt;br /&gt;
    }&lt;br /&gt;
  } catch(const Beam::PipeBrokenException&amp;amp;) {}&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Python===&lt;br /&gt;
&amp;lt;syntaxhighlight lang=python line=line&amp;gt;&lt;br /&gt;
import beam&lt;br /&gt;
import nexus&lt;br /&gt;
import datetime&lt;br /&gt;
&lt;br /&gt;
# Connect to the service.&lt;br /&gt;
service_clients = nexus.ApplicationServiceClients(&lt;br /&gt;
  beam.network.IpAddress('127.0.0.1', 20000),&lt;br /&gt;
  'username', 'password')&lt;br /&gt;
&lt;br /&gt;
service_clients.open()&lt;br /&gt;
market_data_client = service_clients.get_market_data_client()&lt;br /&gt;
&lt;br /&gt;
# Build the query.&lt;br /&gt;
query = beam.queries.Query()&lt;br /&gt;
query.index = nexus.parse_security('MSFT.NSDQ')&lt;br /&gt;
query.range = beam.queries.Range(beam.time_service.to_utc_time(&lt;br /&gt;
  datetime.datetime(2018, 12, 11)), beam.time_service.to_utc_time(&lt;br /&gt;
  datetime.datetime(2018, 12, 12)))&lt;br /&gt;
query.snapshot_limit = beam.queries.SnapshotLimit(&lt;br /&gt;
  beam.queries.SnapshotLimit.Type.HEAD, 1000)&lt;br /&gt;
&lt;br /&gt;
# Build the Queue to store the results.&lt;br /&gt;
queue = beam.Queue()&lt;br /&gt;
&lt;br /&gt;
# Submit the query to the market data service.&lt;br /&gt;
market_data_client.query_time_and_sales(query, queue)&lt;br /&gt;
&lt;br /&gt;
# Print the results&lt;br /&gt;
try:&lt;br /&gt;
  while True:&lt;br /&gt;
    print queue.top().price&lt;br /&gt;
    queue.pop()&lt;br /&gt;
except:&lt;br /&gt;
  pass&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;/div&gt;</summary>
		<author><name>Kman</name></author>
		
	</entry>
	<entry>
		<id>https://wiki.spiretrading.com/index.php?title=Tasks&amp;diff=55</id>
		<title>Tasks</title>
		<link rel="alternate" type="text/html" href="https://wiki.spiretrading.com/index.php?title=Tasks&amp;diff=55"/>
		<updated>2018-09-11T21:03:32Z</updated>

		<summary type="html">&lt;p&gt;Kman: /* Decomposition */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Tasks provide a way of encapsulating and managing asynchronous actions in a composable manner. They are primarily used to perform some sort of I/O operation and/or manage a series of sub-tasks. Beam provides several classes to define your own tasks as well as classes that connect tasks to one another.&lt;br /&gt;
&lt;br /&gt;
The task API in Beam is defined by two base classes, the class Beam::Tasks::Task which represents a task, and the class Beam::Tasks::TaskFactory which constructs tasks. In this article we will explore how we can use these two classes in ways that allow us to start, stop, modify and resume asynchronous actions.&lt;br /&gt;
&lt;br /&gt;
=Interface=&lt;br /&gt;
==Task==&lt;br /&gt;
&lt;br /&gt;
The Task class defines two methods, an Execute() method to start the task and a Cancel() method to request that the task stop. Both operations are asynchronous, meaning that they return immediately and the actual operation of the task takes place in a separate thread of execution. In order to keep track of the progress of a task one must monitor its state which can be any of the following:&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! scope=&amp;quot;col&amp;quot;| State&lt;br /&gt;
! scope=&amp;quot;col&amp;quot;| Description&lt;br /&gt;
|-&lt;br /&gt;
| scope=&amp;quot;row&amp;quot;| NONE&lt;br /&gt;
| The task has not yet been executed.&lt;br /&gt;
|-&lt;br /&gt;
| scope=&amp;quot;row&amp;quot;| INITIALIZING&lt;br /&gt;
| The task is performing some initialization, during this state no sub-tasks may be executed.&lt;br /&gt;
|-&lt;br /&gt;
| scope=&amp;quot;row&amp;quot;| ACTIVE&lt;br /&gt;
| The task is running, during this state sub-tasks may be executed.&lt;br /&gt;
|-&lt;br /&gt;
| scope=&amp;quot;row&amp;quot;| PENDING_CANCEL&lt;br /&gt;
| A request to cancel the task has been made, no new sub-tasks may be executed.&lt;br /&gt;
|-&lt;br /&gt;
| scope=&amp;quot;row&amp;quot;| CANCELED&lt;br /&gt;
| The task was canceled.&lt;br /&gt;
|-&lt;br /&gt;
| scope=&amp;quot;row&amp;quot;| FAILED&lt;br /&gt;
| The task could not complete due to an error.&lt;br /&gt;
|-&lt;br /&gt;
| scope=&amp;quot;row&amp;quot;| EXPIRED&lt;br /&gt;
| The task could not complete due to a time constraint.&lt;br /&gt;
|-&lt;br /&gt;
| scope=&amp;quot;row&amp;quot;| COMPLETE&lt;br /&gt;
| The task completed successfully.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
The states CANCELED, FAILED, EXPIRED and COMPLETE all represent terminal states. Before a task can transition to a terminal state, all of its sub tasks must be in a terminal state. Furthermore once a task is in a terminal state the task is not permitted to perform any additional action or transition to a different state.&lt;br /&gt;
&lt;br /&gt;
The current state of the task along with all of its transitions is accessed through its Publisher by calling the GetPublisher() method. The publisher will emit objects of type Beam::Tasks::Task::StateEntry which contains two fields as follows:&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! scope=&amp;quot;col&amp;quot;| Name&lt;br /&gt;
! scope=&amp;quot;col&amp;quot;| Type&lt;br /&gt;
! scope=&amp;quot;col&amp;quot;| Description&lt;br /&gt;
|-&lt;br /&gt;
| scope=&amp;quot;row&amp;quot;| m_state&lt;br /&gt;
| Beam::Tasks::Task::State&lt;br /&gt;
| The state of the task.&lt;br /&gt;
|-&lt;br /&gt;
| scope=&amp;quot;row&amp;quot;| m_message&lt;br /&gt;
| std::string&lt;br /&gt;
| A message describing the reason for the transition.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
In effect a task begins in the NONE state, is then started via the Execute() method, transitions into the INITIALIZATION state where it performs any setup needed, then proceeds to the ACTIVE state where it performs its operation including executing any required sub-tasks, and then finally terminates all of its sub-tasks and performs any final clean-up before ending in a terminal state. During any point after the INITIALIZATION state it may encounter a cancel request (via the Cancel() method) or an error, either of which should result in cleaning-up and terminating its sub-tasks before transitioning to the FAILED or CANCELED state.&lt;br /&gt;
&lt;br /&gt;
==Task Factory==&lt;br /&gt;
&lt;br /&gt;
The task factory is responsible for creating new tasks by invoking its Create() method. In addition to this a task factory also keeps track of the parameters and state needed to create tasks. Setting a task's parameter is done by calling the factory's Set(name, value) method and retrieving a parameter is done via the Get(name) method.&lt;br /&gt;
&lt;br /&gt;
===Continuations===&lt;br /&gt;
&lt;br /&gt;
One additional operation that task factories perform is constructing what is called a continuation task. Continuations are a mechanism that allow us to resume a task that previously terminated, but more than that they also allow us to modify the parameters of that task. In a sense, a continuation lets us take a terminated task, modify it, and then continue running it with those modifications.&lt;br /&gt;
&lt;br /&gt;
To do this, task factories have a method PrepareContinuation(task). To use it you pass into it a task that has terminated, then you modify its properties using the Set(name, value) method, and then finally you invoke the Create() method to get a newly constructed task that represents the continuation of the old task.&lt;br /&gt;
&lt;br /&gt;
Not all tasks support continuations, those that do not will throw a Beam::NotSupportedException.&lt;br /&gt;
&lt;br /&gt;
==BasicTask==&lt;br /&gt;
&lt;br /&gt;
As a great deal of care must be taken to ensure that tasks properly transition from State to State, including managing sub-tasks, handling cancel requests etc... Beam provides the Beam::Tasks::BasicTask as a base class which can be inherited from to take care of much of the work needed to write a proper task. For example it ensures that upon a cancel request that the task transitions into the PENDING_CANCEL state and terminates all managed sub-tasks.&lt;br /&gt;
&lt;br /&gt;
To make use of a the BasicTask you need only implement the OnExecute() method to start your task, and the OnCancel() method to handle cancelling your class.&lt;br /&gt;
&lt;br /&gt;
=Example=&lt;br /&gt;
&lt;br /&gt;
To showcase a simple example, let's build a task that prints &amp;quot;hello&amp;quot; every second a given number of times. We will write a HelloTask class which inherits from BasicTask, and a HelloTaskFactory.&lt;br /&gt;
&lt;br /&gt;
==First Attempt==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=python line=line&amp;gt;&lt;br /&gt;
import beam&lt;br /&gt;
import datetime&lt;br /&gt;
import time&lt;br /&gt;
&lt;br /&gt;
class HelloTask(beam.tasks.BasicTask):&lt;br /&gt;
  '''Prints hello a specified number of times.'''&lt;br /&gt;
&lt;br /&gt;
  def __init__(self, timer, iterations):&lt;br /&gt;
    ''' Constructs this task.&lt;br /&gt;
    :param timer: The Timer used to wait between successive prints.&lt;br /&gt;
    :param iterations: The number of times to print.&lt;br /&gt;
    '''&lt;br /&gt;
&lt;br /&gt;
    # We must make sure to initialize the base class.&lt;br /&gt;
    beam.tasks.BasicTask.__init__(self)&lt;br /&gt;
    self.timer = timer&lt;br /&gt;
    self.iterations = iterations&lt;br /&gt;
&lt;br /&gt;
    # The number of times we've printed so far.&lt;br /&gt;
    self.counter = 0&lt;br /&gt;
&lt;br /&gt;
    # Used to handle timer callbacks.&lt;br /&gt;
    self.tasks = beam.RoutineTaskQueue()&lt;br /&gt;
&lt;br /&gt;
  # This overrides BasicTask.on_execute.&lt;br /&gt;
  # When called we can assume that our Task is in the INITIALIZATION state.&lt;br /&gt;
  def on_execute(self):&lt;br /&gt;
&lt;br /&gt;
    # To initialize our task we will monitor our timer and then start the timer.&lt;br /&gt;
    self.timer.get_publisher().monitor(self.tasks.get_slot(self.on_timer))&lt;br /&gt;
    self.timer.start()&lt;br /&gt;
&lt;br /&gt;
    # Once the initialization is complete we transition to the ACTIVE state.&lt;br /&gt;
    self.set_active()&lt;br /&gt;
&lt;br /&gt;
  # This overrides BasicTask.on_cancel.&lt;br /&gt;
  # When called we can assume that our Task is in the PENDING_CANCEL state.&lt;br /&gt;
  # No new sub-tasks may be executed.&lt;br /&gt;
  def on_cancel(self):&lt;br /&gt;
&lt;br /&gt;
    # In order to synchronize handling the cancel operation with the timer,&lt;br /&gt;
    # we will push a helper function onto our RoutineTaskQueue.&lt;br /&gt;
    # This ensures no race-conditions take place between the timer and&lt;br /&gt;
    # the cancel request.&lt;br /&gt;
    self.tasks.push(self._on_cancel)&lt;br /&gt;
&lt;br /&gt;
  # This handles the timer expiry.&lt;br /&gt;
  def on_timer(self, result):&lt;br /&gt;
    if result == beam.threading.Timer.Result.EXPIRED:&lt;br /&gt;
&lt;br /&gt;
      # This branch implies that our timer expired normally.&lt;br /&gt;
      print 'hello'&lt;br /&gt;
      self.counter += 1&lt;br /&gt;
      if self.counter &amp;gt;= self.iterations:&lt;br /&gt;
&lt;br /&gt;
        # There is nothing more to print, so transition to&lt;br /&gt;
        # a terminal state, which by default is the COMPLETE state.&lt;br /&gt;
        self.set_terminal()&lt;br /&gt;
      else:&lt;br /&gt;
&lt;br /&gt;
        # There are still further iterations, restart the timer.&lt;br /&gt;
        self.timer.start()&lt;br /&gt;
    else:&lt;br /&gt;
&lt;br /&gt;
        # This branch implies that we canceled the timer in response&lt;br /&gt;
        # to a cancel request.&lt;br /&gt;
        # In this case we set our state to CANCELED.&lt;br /&gt;
        self.set_terminal(beam.tasks.Task.State.CANCELED)&lt;br /&gt;
&lt;br /&gt;
  def _on_cancel(self):&lt;br /&gt;
    if self.counter &amp;lt; self.iterations:&lt;br /&gt;
&lt;br /&gt;
      # Only cancel the timer if there are iterations remaining.&lt;br /&gt;
      self.timer.cancel()&lt;br /&gt;
&lt;br /&gt;
class HelloTaskFactory(beam.tasks.TaskFactory):&lt;br /&gt;
  '''Builds HelloTasks.'''&lt;br /&gt;
&lt;br /&gt;
  # Typically the parameters that get passed into the Task are&lt;br /&gt;
  # defined as static constant strings in the TaskFactory.&lt;br /&gt;
  # This makes it easier to identify the properties of a task&lt;br /&gt;
  # as well as reference them (avoiding potential typos).&lt;br /&gt;
  ITERATIONS = 'iterations'&lt;br /&gt;
&lt;br /&gt;
  def __init__(self, timer_factory):&lt;br /&gt;
    '''Constructs a HelloTaskFactory.&lt;br /&gt;
    :param timer_factory: Used to construct Timers.&lt;br /&gt;
    '''&lt;br /&gt;
&lt;br /&gt;
    # Factories will typically inherit from TaskFactory as a base class.&lt;br /&gt;
    beam.tasks.TaskFactory.__init__(self)&lt;br /&gt;
    self.timer_factory = timer_factory&lt;br /&gt;
&lt;br /&gt;
    # The constructor should define all the properties and default&lt;br /&gt;
    # values for those properties.&lt;br /&gt;
    self.define_property(HelloTaskFactory.ITERATIONS, 10)&lt;br /&gt;
&lt;br /&gt;
    # This variable keeps track of continuations.&lt;br /&gt;
    self.continuation_task = None&lt;br /&gt;
&lt;br /&gt;
  # This overrides the TaskFactory create method.&lt;br /&gt;
  def create(self):&lt;br /&gt;
&lt;br /&gt;
    if self.continuation_task is None:&lt;br /&gt;
&lt;br /&gt;
      # We are not creating a continuation task, so all we need to do is&lt;br /&gt;
      # construct a HelloTask using the ITERATIONS property defined above.&lt;br /&gt;
      return HelloTask(self.timer_factory(datetime.timedelta(seconds = 1)),&lt;br /&gt;
        self.get(HelloTaskFactory.ITERATIONS))&lt;br /&gt;
    else:&lt;br /&gt;
&lt;br /&gt;
      # We are creating a continuation task.  The continuation of a HelloTask of&lt;br /&gt;
      # N iterations that has already printed C times is basically a HelloTask&lt;br /&gt;
      # that prints N - C times.&lt;br /&gt;
      continuation = HelloTask(&lt;br /&gt;
        self.timer_factory(datetime.timedelta(seconds = 1)),&lt;br /&gt;
        self.get(HelloTaskFactory.ITERATIONS) - self.continuation_task.counter)&lt;br /&gt;
      self.continuation_task = None&lt;br /&gt;
      return continuation&lt;br /&gt;
&lt;br /&gt;
  # This overrides the TaskFactory prepare_continuation method.&lt;br /&gt;
  def prepare_continuation(self, task):&lt;br /&gt;
&lt;br /&gt;
    # We store the task to continue.&lt;br /&gt;
    self.continuation_task = task&lt;br /&gt;
&lt;br /&gt;
def main():&lt;br /&gt;
&lt;br /&gt;
  # Construct the HelloTaskFactory using the LiveTimer for 5 iterations.&lt;br /&gt;
  factory = HelloTaskFactory(beam.threading.LiveTimer)&lt;br /&gt;
  factory.set(HelloTaskFactory.ITERATIONS, 5)&lt;br /&gt;
  task = factory.create()&lt;br /&gt;
  task.execute()&lt;br /&gt;
&lt;br /&gt;
  # Let's sleep for 2 seconds before canceling the task.&lt;br /&gt;
  # It should print hello twice.&lt;br /&gt;
  time.sleep(2)&lt;br /&gt;
  task.cancel()&lt;br /&gt;
&lt;br /&gt;
  # Wait for the task to enter the CANCELED state.&lt;br /&gt;
  beam.tasks.wait(task)&lt;br /&gt;
&lt;br /&gt;
  # Build the continuation task and execute it.  To do this we first&lt;br /&gt;
  # call prepare_continuation, then we make our modifications using the set&lt;br /&gt;
  # method, then we create the task and execute it.&lt;br /&gt;
  factory.prepare_continuation(task)&lt;br /&gt;
  factory.set(HelloTaskFactory.ITERATIONS, 7)&lt;br /&gt;
  task = factory.create()&lt;br /&gt;
&lt;br /&gt;
  # We expect it to print hello three times before coming to an end.&lt;br /&gt;
  task.execute()&lt;br /&gt;
  beam.tasks.wait(task)&lt;br /&gt;
&lt;br /&gt;
if __name__ == '__main__':&lt;br /&gt;
  main()&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Decomposition==&lt;br /&gt;
&lt;br /&gt;
The above example works, but upon reflection we should notice that this Task is responsible for two distinct things. One is the responsibility of printing, and the other is the responsibility of repeating. Given that the purpose of tasks is to be able to compose asynchronous operations we should separate these two responsibilities from one another. To do that we will change our HelloTask so that all it does is print hello after a specified time period, followed by a RepetitionTask which repeats a task a specified number of times. The benefit of this is that our RepetitionTask can be reused to repeat any task whatsoever down the road.&lt;br /&gt;
&lt;br /&gt;
We will define it as follows:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=python line=line&amp;gt;&lt;br /&gt;
class RepetitionTask(beam.tasks.BasicTask):&lt;br /&gt;
  '''Repeats a Task a specified number of times.'''&lt;br /&gt;
&lt;br /&gt;
  def __init__(self, task_factory, iterations):&lt;br /&gt;
    '''Constructs the Task.&lt;br /&gt;
    :param task_factory: Builds the Task to repeat.&lt;br /&gt;
    :param iterations: The number of times to repeat the Task.&lt;br /&gt;
    '''&lt;br /&gt;
    beam.tasks.BasicTask.__init__(self)&lt;br /&gt;
&lt;br /&gt;
    # We should always make a deep copy of factories in order to&lt;br /&gt;
    # avoid modifying a factory belonging to another task or having&lt;br /&gt;
    # another task modify our factory.&lt;br /&gt;
    self.task_factory = copy.deepcopy(task_factory)&lt;br /&gt;
    self.iterations = iterations&lt;br /&gt;
    self.counter = 0&lt;br /&gt;
&lt;br /&gt;
    # This stores the task currently being executed.&lt;br /&gt;
    self.task = None&lt;br /&gt;
&lt;br /&gt;
    # This is used to handle callbacks from our tasks.&lt;br /&gt;
    self.tasks = beam.RoutineTaskQueue()&lt;br /&gt;
&lt;br /&gt;
  def on_execute(self):&lt;br /&gt;
&lt;br /&gt;
    # Defer to a helper function.&lt;br /&gt;
    self.execute_task()&lt;br /&gt;
&lt;br /&gt;
  def on_cancel(self):&lt;br /&gt;
&lt;br /&gt;
    # As before, to avoid race conditions between cancels and&lt;br /&gt;
    # our task we will push a callback onto a RoutineTaskQueue&lt;br /&gt;
    # to handle cancellations.&lt;br /&gt;
    self.tasks.push(self._on_cancel)&lt;br /&gt;
&lt;br /&gt;
  def on_state(self, state_entry):&lt;br /&gt;
&lt;br /&gt;
    # This method handles transitions of the task we're repeating.&lt;br /&gt;
    if state_entry.state == beam.tasks.Task.State.CANCELED:&lt;br /&gt;
&lt;br /&gt;
      # This branch indicates that we canceled our task which&lt;br /&gt;
      # means that we're handling a cancel request.&lt;br /&gt;
      self.set_terminal(beam.tasks.Task.State.CANCELED)&lt;br /&gt;
    elif beam.tasks.is_terminal(state_entry.state):&lt;br /&gt;
&lt;br /&gt;
      # This branch indicates that our task terminated and&lt;br /&gt;
      # hence we should repeat.&lt;br /&gt;
      self.execute_task()&lt;br /&gt;
&lt;br /&gt;
  def _on_cancel(self):&lt;br /&gt;
    if self.counter &amp;lt; self.iterations:&lt;br /&gt;
&lt;br /&gt;
      # Similar to before, only cancel if we still have&lt;br /&gt;
      # repetitions to process.&lt;br /&gt;
      self.task.cancel()&lt;br /&gt;
&lt;br /&gt;
  def execute_task(self):&lt;br /&gt;
    if self.counter &amp;gt;= self.iterations:&lt;br /&gt;
&lt;br /&gt;
      # This branch indicates there are no more iterations left.&lt;br /&gt;
      self.set_terminal()&lt;br /&gt;
    else:&lt;br /&gt;
&lt;br /&gt;
      # This branch indicates that we need to repeat the task&lt;br /&gt;
      # by constructing a new one and executing it.&lt;br /&gt;
      self.counter += 1&lt;br /&gt;
      self.task = self.task_factory.create()&lt;br /&gt;
      self.task.get_publisher().monitor(self.tasks.get_slot(self.on_state))&lt;br /&gt;
      self.task.execute()&lt;br /&gt;
&lt;br /&gt;
# This class is very similar to the HelloTaskFactory.&lt;br /&gt;
class RepetitionTaskFactory(beam.tasks.TaskFactory):&lt;br /&gt;
  ITERATIONS = 'iterations'&lt;br /&gt;
&lt;br /&gt;
  def __init__(self, task_factory):&lt;br /&gt;
    beam.tasks.TaskFactory.__init__(self)&lt;br /&gt;
    self.task_factory = copy.deepcopy(task_factory)&lt;br /&gt;
    self.define_property(RepetitionTaskFactory.ITERATIONS, 10)&lt;br /&gt;
    self.continuation_task = None&lt;br /&gt;
&lt;br /&gt;
  def create(self):&lt;br /&gt;
    if self.continuation_task is None:&lt;br /&gt;
      return RepetitionTask(self.task_factory,&lt;br /&gt;
        self.get(RepetitionTaskFactory.ITERATIONS))&lt;br /&gt;
    else:&lt;br /&gt;
      continuation = RepetitionTask(self.task_factory,&lt;br /&gt;
        self.get(RepetitionTaskFactory.ITERATIONS) -&lt;br /&gt;
        self.continuation_task.counter)&lt;br /&gt;
      self.continuation_task = None&lt;br /&gt;
      return continuation&lt;br /&gt;
&lt;br /&gt;
  def prepare_continuation(self, task):&lt;br /&gt;
    self.continuation_task = task&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Now that we have factored out the job of repeating tasks we can rewrite our HelloTask as follows:&lt;br /&gt;
&lt;br /&gt;
class HelloTask(beam.tasks.BasicTask):&lt;br /&gt;
  def __init__(self, timer):&lt;br /&gt;
    beam.tasks.BasicTask.__init__(self)&lt;br /&gt;
    self.timer = timer&lt;br /&gt;
    self.tasks = beam.RoutineTaskQueue()&lt;br /&gt;
&lt;br /&gt;
  def on_execute(self):&lt;br /&gt;
    self.timer.get_publisher().monitor(self.tasks.get_slot(self.on_timer))&lt;br /&gt;
    self.timer.start()&lt;br /&gt;
    self.set_active()&lt;br /&gt;
&lt;br /&gt;
  def on_cancel(self):&lt;br /&gt;
    self.tasks.push(self._on_cancel)&lt;br /&gt;
&lt;br /&gt;
  def on_timer(self, result):&lt;br /&gt;
    print 'hello'&lt;br /&gt;
    if result == beam.threading.Timer.Result.EXPIRED:&lt;br /&gt;
      self.set_terminal()&lt;br /&gt;
    else:&lt;br /&gt;
      self.set_terminal(beam.tasks.Task.State.CANCELED)&lt;br /&gt;
&lt;br /&gt;
  def _on_cancel(self):&lt;br /&gt;
    self.timer.cancel()&lt;br /&gt;
&lt;br /&gt;
class HelloTaskFactory(beam.tasks.TaskFactory):&lt;br /&gt;
  def __init__(self, timer_factory):&lt;br /&gt;
    beam.tasks.TaskFactory.__init__(self)&lt;br /&gt;
    self.timer_factory = timer_factory&lt;br /&gt;
&lt;br /&gt;
  def create(self):&lt;br /&gt;
    return HelloTask(self.timer_factory(datetime.timedelta(seconds = 1)))&lt;br /&gt;
&lt;br /&gt;
Finally once these two pieces are in place we can combine them as follows:&lt;br /&gt;
&lt;br /&gt;
def main():&lt;br /&gt;
&lt;br /&gt;
  # First build the HelloTaskFactory&lt;br /&gt;
  hello_factory = HelloTaskFactory(beam.threading.LiveTimer)&lt;br /&gt;
&lt;br /&gt;
  # Pass the above factory into the RepetitionTaskFactory.&lt;br /&gt;
  # The result is a factory that composes a RepetitionTask with&lt;br /&gt;
  # a HelloTask.&lt;br /&gt;
  factory = RepetitionTaskFactory(hello_factory)&lt;br /&gt;
  factory.set(RepetitionTaskFactory.ITERATIONS, 5)&lt;br /&gt;
&lt;br /&gt;
  # Now we can use the factory similarly to how we used it before.&lt;br /&gt;
  task = factory.create()&lt;br /&gt;
  task.execute()&lt;br /&gt;
  time.sleep(2)&lt;br /&gt;
  task.cancel()&lt;br /&gt;
  beam.tasks.wait(task)&lt;br /&gt;
  factory.prepare_continuation(task)&lt;br /&gt;
  factory.set(RepetitionTaskFactory.ITERATIONS, 7)&lt;br /&gt;
  task = factory.create()&lt;br /&gt;
  task.execute()&lt;br /&gt;
  beam.tasks.wait(task)&lt;br /&gt;
&lt;br /&gt;
if __name__ == '__main__':&lt;br /&gt;
  main()&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
In actuality, we can take this decomposition one step further by factoring out from the HelloTask the responsibility of printing 'hello' with the responsibility of running a task after a specified period of time. If we so desired we would write a TimerTask/TimerTaskFactory and then our final composition would be along the lines of a RepetitionTaskFactory(TimerTaskFactory(HelloTaskFactory(), beam.threading.LiveTimer)).&lt;/div&gt;</summary>
		<author><name>Kman</name></author>
		
	</entry>
	<entry>
		<id>https://wiki.spiretrading.com/index.php?title=Tasks&amp;diff=54</id>
		<title>Tasks</title>
		<link rel="alternate" type="text/html" href="https://wiki.spiretrading.com/index.php?title=Tasks&amp;diff=54"/>
		<updated>2018-09-11T21:02:50Z</updated>

		<summary type="html">&lt;p&gt;Kman: /* First Attempt */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Tasks provide a way of encapsulating and managing asynchronous actions in a composable manner. They are primarily used to perform some sort of I/O operation and/or manage a series of sub-tasks. Beam provides several classes to define your own tasks as well as classes that connect tasks to one another.&lt;br /&gt;
&lt;br /&gt;
The task API in Beam is defined by two base classes, the class Beam::Tasks::Task which represents a task, and the class Beam::Tasks::TaskFactory which constructs tasks. In this article we will explore how we can use these two classes in ways that allow us to start, stop, modify and resume asynchronous actions.&lt;br /&gt;
&lt;br /&gt;
=Interface=&lt;br /&gt;
==Task==&lt;br /&gt;
&lt;br /&gt;
The Task class defines two methods, an Execute() method to start the task and a Cancel() method to request that the task stop. Both operations are asynchronous, meaning that they return immediately and the actual operation of the task takes place in a separate thread of execution. In order to keep track of the progress of a task one must monitor its state which can be any of the following:&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! scope=&amp;quot;col&amp;quot;| State&lt;br /&gt;
! scope=&amp;quot;col&amp;quot;| Description&lt;br /&gt;
|-&lt;br /&gt;
| scope=&amp;quot;row&amp;quot;| NONE&lt;br /&gt;
| The task has not yet been executed.&lt;br /&gt;
|-&lt;br /&gt;
| scope=&amp;quot;row&amp;quot;| INITIALIZING&lt;br /&gt;
| The task is performing some initialization, during this state no sub-tasks may be executed.&lt;br /&gt;
|-&lt;br /&gt;
| scope=&amp;quot;row&amp;quot;| ACTIVE&lt;br /&gt;
| The task is running, during this state sub-tasks may be executed.&lt;br /&gt;
|-&lt;br /&gt;
| scope=&amp;quot;row&amp;quot;| PENDING_CANCEL&lt;br /&gt;
| A request to cancel the task has been made, no new sub-tasks may be executed.&lt;br /&gt;
|-&lt;br /&gt;
| scope=&amp;quot;row&amp;quot;| CANCELED&lt;br /&gt;
| The task was canceled.&lt;br /&gt;
|-&lt;br /&gt;
| scope=&amp;quot;row&amp;quot;| FAILED&lt;br /&gt;
| The task could not complete due to an error.&lt;br /&gt;
|-&lt;br /&gt;
| scope=&amp;quot;row&amp;quot;| EXPIRED&lt;br /&gt;
| The task could not complete due to a time constraint.&lt;br /&gt;
|-&lt;br /&gt;
| scope=&amp;quot;row&amp;quot;| COMPLETE&lt;br /&gt;
| The task completed successfully.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
The states CANCELED, FAILED, EXPIRED and COMPLETE all represent terminal states. Before a task can transition to a terminal state, all of its sub tasks must be in a terminal state. Furthermore once a task is in a terminal state the task is not permitted to perform any additional action or transition to a different state.&lt;br /&gt;
&lt;br /&gt;
The current state of the task along with all of its transitions is accessed through its Publisher by calling the GetPublisher() method. The publisher will emit objects of type Beam::Tasks::Task::StateEntry which contains two fields as follows:&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! scope=&amp;quot;col&amp;quot;| Name&lt;br /&gt;
! scope=&amp;quot;col&amp;quot;| Type&lt;br /&gt;
! scope=&amp;quot;col&amp;quot;| Description&lt;br /&gt;
|-&lt;br /&gt;
| scope=&amp;quot;row&amp;quot;| m_state&lt;br /&gt;
| Beam::Tasks::Task::State&lt;br /&gt;
| The state of the task.&lt;br /&gt;
|-&lt;br /&gt;
| scope=&amp;quot;row&amp;quot;| m_message&lt;br /&gt;
| std::string&lt;br /&gt;
| A message describing the reason for the transition.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
In effect a task begins in the NONE state, is then started via the Execute() method, transitions into the INITIALIZATION state where it performs any setup needed, then proceeds to the ACTIVE state where it performs its operation including executing any required sub-tasks, and then finally terminates all of its sub-tasks and performs any final clean-up before ending in a terminal state. During any point after the INITIALIZATION state it may encounter a cancel request (via the Cancel() method) or an error, either of which should result in cleaning-up and terminating its sub-tasks before transitioning to the FAILED or CANCELED state.&lt;br /&gt;
&lt;br /&gt;
==Task Factory==&lt;br /&gt;
&lt;br /&gt;
The task factory is responsible for creating new tasks by invoking its Create() method. In addition to this a task factory also keeps track of the parameters and state needed to create tasks. Setting a task's parameter is done by calling the factory's Set(name, value) method and retrieving a parameter is done via the Get(name) method.&lt;br /&gt;
&lt;br /&gt;
===Continuations===&lt;br /&gt;
&lt;br /&gt;
One additional operation that task factories perform is constructing what is called a continuation task. Continuations are a mechanism that allow us to resume a task that previously terminated, but more than that they also allow us to modify the parameters of that task. In a sense, a continuation lets us take a terminated task, modify it, and then continue running it with those modifications.&lt;br /&gt;
&lt;br /&gt;
To do this, task factories have a method PrepareContinuation(task). To use it you pass into it a task that has terminated, then you modify its properties using the Set(name, value) method, and then finally you invoke the Create() method to get a newly constructed task that represents the continuation of the old task.&lt;br /&gt;
&lt;br /&gt;
Not all tasks support continuations, those that do not will throw a Beam::NotSupportedException.&lt;br /&gt;
&lt;br /&gt;
==BasicTask==&lt;br /&gt;
&lt;br /&gt;
As a great deal of care must be taken to ensure that tasks properly transition from State to State, including managing sub-tasks, handling cancel requests etc... Beam provides the Beam::Tasks::BasicTask as a base class which can be inherited from to take care of much of the work needed to write a proper task. For example it ensures that upon a cancel request that the task transitions into the PENDING_CANCEL state and terminates all managed sub-tasks.&lt;br /&gt;
&lt;br /&gt;
To make use of a the BasicTask you need only implement the OnExecute() method to start your task, and the OnCancel() method to handle cancelling your class.&lt;br /&gt;
&lt;br /&gt;
=Example=&lt;br /&gt;
&lt;br /&gt;
To showcase a simple example, let's build a task that prints &amp;quot;hello&amp;quot; every second a given number of times. We will write a HelloTask class which inherits from BasicTask, and a HelloTaskFactory.&lt;br /&gt;
&lt;br /&gt;
==First Attempt==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=python line=line&amp;gt;&lt;br /&gt;
import beam&lt;br /&gt;
import datetime&lt;br /&gt;
import time&lt;br /&gt;
&lt;br /&gt;
class HelloTask(beam.tasks.BasicTask):&lt;br /&gt;
  '''Prints hello a specified number of times.'''&lt;br /&gt;
&lt;br /&gt;
  def __init__(self, timer, iterations):&lt;br /&gt;
    ''' Constructs this task.&lt;br /&gt;
    :param timer: The Timer used to wait between successive prints.&lt;br /&gt;
    :param iterations: The number of times to print.&lt;br /&gt;
    '''&lt;br /&gt;
&lt;br /&gt;
    # We must make sure to initialize the base class.&lt;br /&gt;
    beam.tasks.BasicTask.__init__(self)&lt;br /&gt;
    self.timer = timer&lt;br /&gt;
    self.iterations = iterations&lt;br /&gt;
&lt;br /&gt;
    # The number of times we've printed so far.&lt;br /&gt;
    self.counter = 0&lt;br /&gt;
&lt;br /&gt;
    # Used to handle timer callbacks.&lt;br /&gt;
    self.tasks = beam.RoutineTaskQueue()&lt;br /&gt;
&lt;br /&gt;
  # This overrides BasicTask.on_execute.&lt;br /&gt;
  # When called we can assume that our Task is in the INITIALIZATION state.&lt;br /&gt;
  def on_execute(self):&lt;br /&gt;
&lt;br /&gt;
    # To initialize our task we will monitor our timer and then start the timer.&lt;br /&gt;
    self.timer.get_publisher().monitor(self.tasks.get_slot(self.on_timer))&lt;br /&gt;
    self.timer.start()&lt;br /&gt;
&lt;br /&gt;
    # Once the initialization is complete we transition to the ACTIVE state.&lt;br /&gt;
    self.set_active()&lt;br /&gt;
&lt;br /&gt;
  # This overrides BasicTask.on_cancel.&lt;br /&gt;
  # When called we can assume that our Task is in the PENDING_CANCEL state.&lt;br /&gt;
  # No new sub-tasks may be executed.&lt;br /&gt;
  def on_cancel(self):&lt;br /&gt;
&lt;br /&gt;
    # In order to synchronize handling the cancel operation with the timer,&lt;br /&gt;
    # we will push a helper function onto our RoutineTaskQueue.&lt;br /&gt;
    # This ensures no race-conditions take place between the timer and&lt;br /&gt;
    # the cancel request.&lt;br /&gt;
    self.tasks.push(self._on_cancel)&lt;br /&gt;
&lt;br /&gt;
  # This handles the timer expiry.&lt;br /&gt;
  def on_timer(self, result):&lt;br /&gt;
    if result == beam.threading.Timer.Result.EXPIRED:&lt;br /&gt;
&lt;br /&gt;
      # This branch implies that our timer expired normally.&lt;br /&gt;
      print 'hello'&lt;br /&gt;
      self.counter += 1&lt;br /&gt;
      if self.counter &amp;gt;= self.iterations:&lt;br /&gt;
&lt;br /&gt;
        # There is nothing more to print, so transition to&lt;br /&gt;
        # a terminal state, which by default is the COMPLETE state.&lt;br /&gt;
        self.set_terminal()&lt;br /&gt;
      else:&lt;br /&gt;
&lt;br /&gt;
        # There are still further iterations, restart the timer.&lt;br /&gt;
        self.timer.start()&lt;br /&gt;
    else:&lt;br /&gt;
&lt;br /&gt;
        # This branch implies that we canceled the timer in response&lt;br /&gt;
        # to a cancel request.&lt;br /&gt;
        # In this case we set our state to CANCELED.&lt;br /&gt;
        self.set_terminal(beam.tasks.Task.State.CANCELED)&lt;br /&gt;
&lt;br /&gt;
  def _on_cancel(self):&lt;br /&gt;
    if self.counter &amp;lt; self.iterations:&lt;br /&gt;
&lt;br /&gt;
      # Only cancel the timer if there are iterations remaining.&lt;br /&gt;
      self.timer.cancel()&lt;br /&gt;
&lt;br /&gt;
class HelloTaskFactory(beam.tasks.TaskFactory):&lt;br /&gt;
  '''Builds HelloTasks.'''&lt;br /&gt;
&lt;br /&gt;
  # Typically the parameters that get passed into the Task are&lt;br /&gt;
  # defined as static constant strings in the TaskFactory.&lt;br /&gt;
  # This makes it easier to identify the properties of a task&lt;br /&gt;
  # as well as reference them (avoiding potential typos).&lt;br /&gt;
  ITERATIONS = 'iterations'&lt;br /&gt;
&lt;br /&gt;
  def __init__(self, timer_factory):&lt;br /&gt;
    '''Constructs a HelloTaskFactory.&lt;br /&gt;
    :param timer_factory: Used to construct Timers.&lt;br /&gt;
    '''&lt;br /&gt;
&lt;br /&gt;
    # Factories will typically inherit from TaskFactory as a base class.&lt;br /&gt;
    beam.tasks.TaskFactory.__init__(self)&lt;br /&gt;
    self.timer_factory = timer_factory&lt;br /&gt;
&lt;br /&gt;
    # The constructor should define all the properties and default&lt;br /&gt;
    # values for those properties.&lt;br /&gt;
    self.define_property(HelloTaskFactory.ITERATIONS, 10)&lt;br /&gt;
&lt;br /&gt;
    # This variable keeps track of continuations.&lt;br /&gt;
    self.continuation_task = None&lt;br /&gt;
&lt;br /&gt;
  # This overrides the TaskFactory create method.&lt;br /&gt;
  def create(self):&lt;br /&gt;
&lt;br /&gt;
    if self.continuation_task is None:&lt;br /&gt;
&lt;br /&gt;
      # We are not creating a continuation task, so all we need to do is&lt;br /&gt;
      # construct a HelloTask using the ITERATIONS property defined above.&lt;br /&gt;
      return HelloTask(self.timer_factory(datetime.timedelta(seconds = 1)),&lt;br /&gt;
        self.get(HelloTaskFactory.ITERATIONS))&lt;br /&gt;
    else:&lt;br /&gt;
&lt;br /&gt;
      # We are creating a continuation task.  The continuation of a HelloTask of&lt;br /&gt;
      # N iterations that has already printed C times is basically a HelloTask&lt;br /&gt;
      # that prints N - C times.&lt;br /&gt;
      continuation = HelloTask(&lt;br /&gt;
        self.timer_factory(datetime.timedelta(seconds = 1)),&lt;br /&gt;
        self.get(HelloTaskFactory.ITERATIONS) - self.continuation_task.counter)&lt;br /&gt;
      self.continuation_task = None&lt;br /&gt;
      return continuation&lt;br /&gt;
&lt;br /&gt;
  # This overrides the TaskFactory prepare_continuation method.&lt;br /&gt;
  def prepare_continuation(self, task):&lt;br /&gt;
&lt;br /&gt;
    # We store the task to continue.&lt;br /&gt;
    self.continuation_task = task&lt;br /&gt;
&lt;br /&gt;
def main():&lt;br /&gt;
&lt;br /&gt;
  # Construct the HelloTaskFactory using the LiveTimer for 5 iterations.&lt;br /&gt;
  factory = HelloTaskFactory(beam.threading.LiveTimer)&lt;br /&gt;
  factory.set(HelloTaskFactory.ITERATIONS, 5)&lt;br /&gt;
  task = factory.create()&lt;br /&gt;
  task.execute()&lt;br /&gt;
&lt;br /&gt;
  # Let's sleep for 2 seconds before canceling the task.&lt;br /&gt;
  # It should print hello twice.&lt;br /&gt;
  time.sleep(2)&lt;br /&gt;
  task.cancel()&lt;br /&gt;
&lt;br /&gt;
  # Wait for the task to enter the CANCELED state.&lt;br /&gt;
  beam.tasks.wait(task)&lt;br /&gt;
&lt;br /&gt;
  # Build the continuation task and execute it.  To do this we first&lt;br /&gt;
  # call prepare_continuation, then we make our modifications using the set&lt;br /&gt;
  # method, then we create the task and execute it.&lt;br /&gt;
  factory.prepare_continuation(task)&lt;br /&gt;
  factory.set(HelloTaskFactory.ITERATIONS, 7)&lt;br /&gt;
  task = factory.create()&lt;br /&gt;
&lt;br /&gt;
  # We expect it to print hello three times before coming to an end.&lt;br /&gt;
  task.execute()&lt;br /&gt;
  beam.tasks.wait(task)&lt;br /&gt;
&lt;br /&gt;
if __name__ == '__main__':&lt;br /&gt;
  main()&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Decomposition==&lt;br /&gt;
&lt;br /&gt;
The above example works, but upon reflection we should notice that this Task is responsible for two distinct things. One is the responsibility of printing, and the other is the responsibility of repeating. Given that the purpose of tasks is to be able to compose asynchronous operations we should separate these two responsibilities from one another. To do that we will change our HelloTask so that all it does is print hello after a specified time period, followed by a RepetitionTask which repeats a task a specified number of times. The benefit of this is that our RepetitionTask can be reused to repeat any task whatsoever down the road.&lt;br /&gt;
&lt;br /&gt;
We will define it as follows:&lt;br /&gt;
&lt;br /&gt;
class RepetitionTask(beam.tasks.BasicTask):&lt;br /&gt;
  '''Repeats a Task a specified number of times.'''&lt;br /&gt;
&lt;br /&gt;
  def __init__(self, task_factory, iterations):&lt;br /&gt;
    '''Constructs the Task.&lt;br /&gt;
    :param task_factory: Builds the Task to repeat.&lt;br /&gt;
    :param iterations: The number of times to repeat the Task.&lt;br /&gt;
    '''&lt;br /&gt;
    beam.tasks.BasicTask.__init__(self)&lt;br /&gt;
&lt;br /&gt;
    # We should always make a deep copy of factories in order to&lt;br /&gt;
    # avoid modifying a factory belonging to another task or having&lt;br /&gt;
    # another task modify our factory.&lt;br /&gt;
    self.task_factory = copy.deepcopy(task_factory)&lt;br /&gt;
    self.iterations = iterations&lt;br /&gt;
    self.counter = 0&lt;br /&gt;
&lt;br /&gt;
    # This stores the task currently being executed.&lt;br /&gt;
    self.task = None&lt;br /&gt;
&lt;br /&gt;
    # This is used to handle callbacks from our tasks.&lt;br /&gt;
    self.tasks = beam.RoutineTaskQueue()&lt;br /&gt;
&lt;br /&gt;
  def on_execute(self):&lt;br /&gt;
&lt;br /&gt;
    # Defer to a helper function.&lt;br /&gt;
    self.execute_task()&lt;br /&gt;
&lt;br /&gt;
  def on_cancel(self):&lt;br /&gt;
&lt;br /&gt;
    # As before, to avoid race conditions between cancels and&lt;br /&gt;
    # our task we will push a callback onto a RoutineTaskQueue&lt;br /&gt;
    # to handle cancellations.&lt;br /&gt;
    self.tasks.push(self._on_cancel)&lt;br /&gt;
&lt;br /&gt;
  def on_state(self, state_entry):&lt;br /&gt;
&lt;br /&gt;
    # This method handles transitions of the task we're repeating.&lt;br /&gt;
    if state_entry.state == beam.tasks.Task.State.CANCELED:&lt;br /&gt;
&lt;br /&gt;
      # This branch indicates that we canceled our task which&lt;br /&gt;
      # means that we're handling a cancel request.&lt;br /&gt;
      self.set_terminal(beam.tasks.Task.State.CANCELED)&lt;br /&gt;
    elif beam.tasks.is_terminal(state_entry.state):&lt;br /&gt;
&lt;br /&gt;
      # This branch indicates that our task terminated and&lt;br /&gt;
      # hence we should repeat.&lt;br /&gt;
      self.execute_task()&lt;br /&gt;
&lt;br /&gt;
  def _on_cancel(self):&lt;br /&gt;
    if self.counter &amp;lt; self.iterations:&lt;br /&gt;
&lt;br /&gt;
      # Similar to before, only cancel if we still have&lt;br /&gt;
      # repetitions to process.&lt;br /&gt;
      self.task.cancel()&lt;br /&gt;
&lt;br /&gt;
  def execute_task(self):&lt;br /&gt;
    if self.counter &amp;gt;= self.iterations:&lt;br /&gt;
&lt;br /&gt;
      # This branch indicates there are no more iterations left.&lt;br /&gt;
      self.set_terminal()&lt;br /&gt;
    else:&lt;br /&gt;
&lt;br /&gt;
      # This branch indicates that we need to repeat the task&lt;br /&gt;
      # by constructing a new one and executing it.&lt;br /&gt;
      self.counter += 1&lt;br /&gt;
      self.task = self.task_factory.create()&lt;br /&gt;
      self.task.get_publisher().monitor(self.tasks.get_slot(self.on_state))&lt;br /&gt;
      self.task.execute()&lt;br /&gt;
&lt;br /&gt;
# This class is very similar to the HelloTaskFactory.&lt;br /&gt;
class RepetitionTaskFactory(beam.tasks.TaskFactory):&lt;br /&gt;
  ITERATIONS = 'iterations'&lt;br /&gt;
&lt;br /&gt;
  def __init__(self, task_factory):&lt;br /&gt;
    beam.tasks.TaskFactory.__init__(self)&lt;br /&gt;
    self.task_factory = copy.deepcopy(task_factory)&lt;br /&gt;
    self.define_property(RepetitionTaskFactory.ITERATIONS, 10)&lt;br /&gt;
    self.continuation_task = None&lt;br /&gt;
&lt;br /&gt;
  def create(self):&lt;br /&gt;
    if self.continuation_task is None:&lt;br /&gt;
      return RepetitionTask(self.task_factory,&lt;br /&gt;
        self.get(RepetitionTaskFactory.ITERATIONS))&lt;br /&gt;
    else:&lt;br /&gt;
      continuation = RepetitionTask(self.task_factory,&lt;br /&gt;
        self.get(RepetitionTaskFactory.ITERATIONS) -&lt;br /&gt;
        self.continuation_task.counter)&lt;br /&gt;
      self.continuation_task = None&lt;br /&gt;
      return continuation&lt;br /&gt;
&lt;br /&gt;
  def prepare_continuation(self, task):&lt;br /&gt;
    self.continuation_task = task&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Now that we have factored out the job of repeating tasks we can rewrite our HelloTask as follows:&lt;br /&gt;
&lt;br /&gt;
class HelloTask(beam.tasks.BasicTask):&lt;br /&gt;
  def __init__(self, timer):&lt;br /&gt;
    beam.tasks.BasicTask.__init__(self)&lt;br /&gt;
    self.timer = timer&lt;br /&gt;
    self.tasks = beam.RoutineTaskQueue()&lt;br /&gt;
&lt;br /&gt;
  def on_execute(self):&lt;br /&gt;
    self.timer.get_publisher().monitor(self.tasks.get_slot(self.on_timer))&lt;br /&gt;
    self.timer.start()&lt;br /&gt;
    self.set_active()&lt;br /&gt;
&lt;br /&gt;
  def on_cancel(self):&lt;br /&gt;
    self.tasks.push(self._on_cancel)&lt;br /&gt;
&lt;br /&gt;
  def on_timer(self, result):&lt;br /&gt;
    print 'hello'&lt;br /&gt;
    if result == beam.threading.Timer.Result.EXPIRED:&lt;br /&gt;
      self.set_terminal()&lt;br /&gt;
    else:&lt;br /&gt;
      self.set_terminal(beam.tasks.Task.State.CANCELED)&lt;br /&gt;
&lt;br /&gt;
  def _on_cancel(self):&lt;br /&gt;
    self.timer.cancel()&lt;br /&gt;
&lt;br /&gt;
class HelloTaskFactory(beam.tasks.TaskFactory):&lt;br /&gt;
  def __init__(self, timer_factory):&lt;br /&gt;
    beam.tasks.TaskFactory.__init__(self)&lt;br /&gt;
    self.timer_factory = timer_factory&lt;br /&gt;
&lt;br /&gt;
  def create(self):&lt;br /&gt;
    return HelloTask(self.timer_factory(datetime.timedelta(seconds = 1)))&lt;br /&gt;
&lt;br /&gt;
Finally once these two pieces are in place we can combine them as follows:&lt;br /&gt;
&lt;br /&gt;
def main():&lt;br /&gt;
&lt;br /&gt;
  # First build the HelloTaskFactory&lt;br /&gt;
  hello_factory = HelloTaskFactory(beam.threading.LiveTimer)&lt;br /&gt;
&lt;br /&gt;
  # Pass the above factory into the RepetitionTaskFactory.&lt;br /&gt;
  # The result is a factory that composes a RepetitionTask with&lt;br /&gt;
  # a HelloTask.&lt;br /&gt;
  factory = RepetitionTaskFactory(hello_factory)&lt;br /&gt;
  factory.set(RepetitionTaskFactory.ITERATIONS, 5)&lt;br /&gt;
&lt;br /&gt;
  # Now we can use the factory similarly to how we used it before.&lt;br /&gt;
  task = factory.create()&lt;br /&gt;
  task.execute()&lt;br /&gt;
  time.sleep(2)&lt;br /&gt;
  task.cancel()&lt;br /&gt;
  beam.tasks.wait(task)&lt;br /&gt;
  factory.prepare_continuation(task)&lt;br /&gt;
  factory.set(RepetitionTaskFactory.ITERATIONS, 7)&lt;br /&gt;
  task = factory.create()&lt;br /&gt;
  task.execute()&lt;br /&gt;
  beam.tasks.wait(task)&lt;br /&gt;
&lt;br /&gt;
if __name__ == '__main__':&lt;br /&gt;
  main()&lt;br /&gt;
&lt;br /&gt;
In actuality, we can take this decomposition one step further by factoring out from the HelloTask the responsibility of printing 'hello' with the responsibility of running a task after a specified period of time. If we so desired we would write a TimerTask/TimerTaskFactory and then our final composition would be along the lines of a RepetitionTaskFactory(TimerTaskFactory(HelloTaskFactory(), beam.threading.LiveTimer)).&lt;/div&gt;</summary>
		<author><name>Kman</name></author>
		
	</entry>
	<entry>
		<id>https://wiki.spiretrading.com/index.php?title=Tasks&amp;diff=53</id>
		<title>Tasks</title>
		<link rel="alternate" type="text/html" href="https://wiki.spiretrading.com/index.php?title=Tasks&amp;diff=53"/>
		<updated>2018-09-11T20:57:52Z</updated>

		<summary type="html">&lt;p&gt;Kman: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Tasks provide a way of encapsulating and managing asynchronous actions in a composable manner. They are primarily used to perform some sort of I/O operation and/or manage a series of sub-tasks. Beam provides several classes to define your own tasks as well as classes that connect tasks to one another.&lt;br /&gt;
&lt;br /&gt;
The task API in Beam is defined by two base classes, the class Beam::Tasks::Task which represents a task, and the class Beam::Tasks::TaskFactory which constructs tasks. In this article we will explore how we can use these two classes in ways that allow us to start, stop, modify and resume asynchronous actions.&lt;br /&gt;
&lt;br /&gt;
=Interface=&lt;br /&gt;
==Task==&lt;br /&gt;
&lt;br /&gt;
The Task class defines two methods, an Execute() method to start the task and a Cancel() method to request that the task stop. Both operations are asynchronous, meaning that they return immediately and the actual operation of the task takes place in a separate thread of execution. In order to keep track of the progress of a task one must monitor its state which can be any of the following:&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! scope=&amp;quot;col&amp;quot;| State&lt;br /&gt;
! scope=&amp;quot;col&amp;quot;| Description&lt;br /&gt;
|-&lt;br /&gt;
| scope=&amp;quot;row&amp;quot;| NONE&lt;br /&gt;
| The task has not yet been executed.&lt;br /&gt;
|-&lt;br /&gt;
| scope=&amp;quot;row&amp;quot;| INITIALIZING&lt;br /&gt;
| The task is performing some initialization, during this state no sub-tasks may be executed.&lt;br /&gt;
|-&lt;br /&gt;
| scope=&amp;quot;row&amp;quot;| ACTIVE&lt;br /&gt;
| The task is running, during this state sub-tasks may be executed.&lt;br /&gt;
|-&lt;br /&gt;
| scope=&amp;quot;row&amp;quot;| PENDING_CANCEL&lt;br /&gt;
| A request to cancel the task has been made, no new sub-tasks may be executed.&lt;br /&gt;
|-&lt;br /&gt;
| scope=&amp;quot;row&amp;quot;| CANCELED&lt;br /&gt;
| The task was canceled.&lt;br /&gt;
|-&lt;br /&gt;
| scope=&amp;quot;row&amp;quot;| FAILED&lt;br /&gt;
| The task could not complete due to an error.&lt;br /&gt;
|-&lt;br /&gt;
| scope=&amp;quot;row&amp;quot;| EXPIRED&lt;br /&gt;
| The task could not complete due to a time constraint.&lt;br /&gt;
|-&lt;br /&gt;
| scope=&amp;quot;row&amp;quot;| COMPLETE&lt;br /&gt;
| The task completed successfully.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
The states CANCELED, FAILED, EXPIRED and COMPLETE all represent terminal states. Before a task can transition to a terminal state, all of its sub tasks must be in a terminal state. Furthermore once a task is in a terminal state the task is not permitted to perform any additional action or transition to a different state.&lt;br /&gt;
&lt;br /&gt;
The current state of the task along with all of its transitions is accessed through its Publisher by calling the GetPublisher() method. The publisher will emit objects of type Beam::Tasks::Task::StateEntry which contains two fields as follows:&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! scope=&amp;quot;col&amp;quot;| Name&lt;br /&gt;
! scope=&amp;quot;col&amp;quot;| Type&lt;br /&gt;
! scope=&amp;quot;col&amp;quot;| Description&lt;br /&gt;
|-&lt;br /&gt;
| scope=&amp;quot;row&amp;quot;| m_state&lt;br /&gt;
| Beam::Tasks::Task::State&lt;br /&gt;
| The state of the task.&lt;br /&gt;
|-&lt;br /&gt;
| scope=&amp;quot;row&amp;quot;| m_message&lt;br /&gt;
| std::string&lt;br /&gt;
| A message describing the reason for the transition.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
In effect a task begins in the NONE state, is then started via the Execute() method, transitions into the INITIALIZATION state where it performs any setup needed, then proceeds to the ACTIVE state where it performs its operation including executing any required sub-tasks, and then finally terminates all of its sub-tasks and performs any final clean-up before ending in a terminal state. During any point after the INITIALIZATION state it may encounter a cancel request (via the Cancel() method) or an error, either of which should result in cleaning-up and terminating its sub-tasks before transitioning to the FAILED or CANCELED state.&lt;br /&gt;
&lt;br /&gt;
==Task Factory==&lt;br /&gt;
&lt;br /&gt;
The task factory is responsible for creating new tasks by invoking its Create() method. In addition to this a task factory also keeps track of the parameters and state needed to create tasks. Setting a task's parameter is done by calling the factory's Set(name, value) method and retrieving a parameter is done via the Get(name) method.&lt;br /&gt;
&lt;br /&gt;
===Continuations===&lt;br /&gt;
&lt;br /&gt;
One additional operation that task factories perform is constructing what is called a continuation task. Continuations are a mechanism that allow us to resume a task that previously terminated, but more than that they also allow us to modify the parameters of that task. In a sense, a continuation lets us take a terminated task, modify it, and then continue running it with those modifications.&lt;br /&gt;
&lt;br /&gt;
To do this, task factories have a method PrepareContinuation(task). To use it you pass into it a task that has terminated, then you modify its properties using the Set(name, value) method, and then finally you invoke the Create() method to get a newly constructed task that represents the continuation of the old task.&lt;br /&gt;
&lt;br /&gt;
Not all tasks support continuations, those that do not will throw a Beam::NotSupportedException.&lt;br /&gt;
&lt;br /&gt;
==BasicTask==&lt;br /&gt;
&lt;br /&gt;
As a great deal of care must be taken to ensure that tasks properly transition from State to State, including managing sub-tasks, handling cancel requests etc... Beam provides the Beam::Tasks::BasicTask as a base class which can be inherited from to take care of much of the work needed to write a proper task. For example it ensures that upon a cancel request that the task transitions into the PENDING_CANCEL state and terminates all managed sub-tasks.&lt;br /&gt;
&lt;br /&gt;
To make use of a the BasicTask you need only implement the OnExecute() method to start your task, and the OnCancel() method to handle cancelling your class.&lt;br /&gt;
&lt;br /&gt;
=Example=&lt;br /&gt;
&lt;br /&gt;
To showcase a simple example, let's build a task that prints &amp;quot;hello&amp;quot; every second a given number of times. We will write a HelloTask class which inherits from BasicTask, and a HelloTaskFactory.&lt;br /&gt;
&lt;br /&gt;
==First Attempt==&lt;br /&gt;
&lt;br /&gt;
import beam&lt;br /&gt;
import datetime&lt;br /&gt;
import time&lt;br /&gt;
&lt;br /&gt;
class HelloTask(beam.tasks.BasicTask):&lt;br /&gt;
  '''Prints hello a specified number of times.'''&lt;br /&gt;
&lt;br /&gt;
  def __init__(self, timer, iterations):&lt;br /&gt;
    ''' Constructs this task.&lt;br /&gt;
    :param timer: The Timer used to wait between successive prints.&lt;br /&gt;
    :param iterations: The number of times to print.&lt;br /&gt;
    '''&lt;br /&gt;
&lt;br /&gt;
    # We must make sure to initialize the base class.&lt;br /&gt;
    beam.tasks.BasicTask.__init__(self)&lt;br /&gt;
    self.timer = timer&lt;br /&gt;
    self.iterations = iterations&lt;br /&gt;
&lt;br /&gt;
    # The number of times we've printed so far.&lt;br /&gt;
    self.counter = 0&lt;br /&gt;
&lt;br /&gt;
    # Used to handle timer callbacks.&lt;br /&gt;
    self.tasks = beam.RoutineTaskQueue()&lt;br /&gt;
&lt;br /&gt;
  # This overrides BasicTask.on_execute.&lt;br /&gt;
  # When called we can assume that our Task is in the INITIALIZATION state.&lt;br /&gt;
  def on_execute(self):&lt;br /&gt;
&lt;br /&gt;
    # To initialize our task we will monitor our timer and then start the timer.&lt;br /&gt;
    self.timer.get_publisher().monitor(self.tasks.get_slot(self.on_timer))&lt;br /&gt;
    self.timer.start()&lt;br /&gt;
&lt;br /&gt;
    # Once the initialization is complete we transition to the ACTIVE state.&lt;br /&gt;
    self.set_active()&lt;br /&gt;
&lt;br /&gt;
  # This overrides BasicTask.on_cancel.&lt;br /&gt;
  # When called we can assume that our Task is in the PENDING_CANCEL state.&lt;br /&gt;
  # No new sub-tasks may be executed.&lt;br /&gt;
  def on_cancel(self):&lt;br /&gt;
&lt;br /&gt;
    # In order to synchronize handling the cancel operation with the timer,&lt;br /&gt;
    # we will push a helper function onto our RoutineTaskQueue.&lt;br /&gt;
    # This ensures no race-conditions take place between the timer and&lt;br /&gt;
    # the cancel request.&lt;br /&gt;
    self.tasks.push(self._on_cancel)&lt;br /&gt;
&lt;br /&gt;
  # This handles the timer expiry.&lt;br /&gt;
  def on_timer(self, result):&lt;br /&gt;
    if result == beam.threading.Timer.Result.EXPIRED:&lt;br /&gt;
&lt;br /&gt;
      # This branch implies that our timer expired normally.&lt;br /&gt;
      print 'hello'&lt;br /&gt;
      self.counter += 1&lt;br /&gt;
      if self.counter &amp;gt;= self.iterations:&lt;br /&gt;
&lt;br /&gt;
        # There is nothing more to print, so transition to&lt;br /&gt;
        # a terminal state, which by default is the COMPLETE state.&lt;br /&gt;
        self.set_terminal()&lt;br /&gt;
      else:&lt;br /&gt;
&lt;br /&gt;
        # There are still further iterations, restart the timer.&lt;br /&gt;
        self.timer.start()&lt;br /&gt;
    else:&lt;br /&gt;
&lt;br /&gt;
        # This branch implies that we canceled the timer in response&lt;br /&gt;
        # to a cancel request.&lt;br /&gt;
        # In this case we set our state to CANCELED.&lt;br /&gt;
        self.set_terminal(beam.tasks.Task.State.CANCELED)&lt;br /&gt;
&lt;br /&gt;
  def _on_cancel(self):&lt;br /&gt;
    if self.counter &amp;lt; self.iterations:&lt;br /&gt;
&lt;br /&gt;
      # Only cancel the timer if there are iterations remaining.&lt;br /&gt;
      self.timer.cancel()&lt;br /&gt;
&lt;br /&gt;
class HelloTaskFactory(beam.tasks.TaskFactory):&lt;br /&gt;
  '''Builds HelloTasks.'''&lt;br /&gt;
&lt;br /&gt;
  # Typically the parameters that get passed into the Task are&lt;br /&gt;
  # defined as static constant strings in the TaskFactory.&lt;br /&gt;
  # This makes it easier to identify the properties of a task&lt;br /&gt;
  # as well as reference them (avoiding potential typos).&lt;br /&gt;
  ITERATIONS = 'iterations'&lt;br /&gt;
&lt;br /&gt;
  def __init__(self, timer_factory):&lt;br /&gt;
    '''Constructs a HelloTaskFactory.&lt;br /&gt;
    :param timer_factory: Used to construct Timers.&lt;br /&gt;
    '''&lt;br /&gt;
&lt;br /&gt;
    # Factories will typically inherit from TaskFactory as a base class.&lt;br /&gt;
    beam.tasks.TaskFactory.__init__(self)&lt;br /&gt;
    self.timer_factory = timer_factory&lt;br /&gt;
&lt;br /&gt;
    # The constructor should define all the properties and default&lt;br /&gt;
    # values for those properties.&lt;br /&gt;
    self.define_property(HelloTaskFactory.ITERATIONS, 10)&lt;br /&gt;
&lt;br /&gt;
    # This variable keeps track of continuations.&lt;br /&gt;
    self.continuation_task = None&lt;br /&gt;
&lt;br /&gt;
  # This overrides the TaskFactory create method.&lt;br /&gt;
  def create(self):&lt;br /&gt;
&lt;br /&gt;
    if self.continuation_task is None:&lt;br /&gt;
&lt;br /&gt;
      # We are not creating a continuation task, so all we need to do is&lt;br /&gt;
      # construct a HelloTask using the ITERATIONS property defined above.&lt;br /&gt;
      return HelloTask(self.timer_factory(datetime.timedelta(seconds = 1)),&lt;br /&gt;
        self.get(HelloTaskFactory.ITERATIONS))&lt;br /&gt;
    else:&lt;br /&gt;
&lt;br /&gt;
      # We are creating a continuation task.  The continuation of a HelloTask of&lt;br /&gt;
      # N iterations that has already printed C times is basically a HelloTask&lt;br /&gt;
      # that prints N - C times.&lt;br /&gt;
      continuation = HelloTask(&lt;br /&gt;
        self.timer_factory(datetime.timedelta(seconds = 1)),&lt;br /&gt;
        self.get(HelloTaskFactory.ITERATIONS) - self.continuation_task.counter)&lt;br /&gt;
      self.continuation_task = None&lt;br /&gt;
      return continuation&lt;br /&gt;
&lt;br /&gt;
  # This overrides the TaskFactory prepare_continuation method.&lt;br /&gt;
  def prepare_continuation(self, task):&lt;br /&gt;
&lt;br /&gt;
    # We store the task to continue.&lt;br /&gt;
    self.continuation_task = task&lt;br /&gt;
&lt;br /&gt;
def main():&lt;br /&gt;
&lt;br /&gt;
  # Construct the HelloTaskFactory using the LiveTimer for 5 iterations.&lt;br /&gt;
  factory = HelloTaskFactory(beam.threading.LiveTimer)&lt;br /&gt;
  factory.set(HelloTaskFactory.ITERATIONS, 5)&lt;br /&gt;
  task = factory.create()&lt;br /&gt;
  task.execute()&lt;br /&gt;
&lt;br /&gt;
  # Let's sleep for 2 seconds before canceling the task.&lt;br /&gt;
  # It should print hello twice.&lt;br /&gt;
  time.sleep(2)&lt;br /&gt;
  task.cancel()&lt;br /&gt;
&lt;br /&gt;
  # Wait for the task to enter the CANCELED state.&lt;br /&gt;
  beam.tasks.wait(task)&lt;br /&gt;
&lt;br /&gt;
  # Build the continuation task and execute it.  To do this we first&lt;br /&gt;
  # call prepare_continuation, then we make our modifications using the set&lt;br /&gt;
  # method, then we create the task and execute it.&lt;br /&gt;
  factory.prepare_continuation(task)&lt;br /&gt;
  factory.set(HelloTaskFactory.ITERATIONS, 7)&lt;br /&gt;
  task = factory.create()&lt;br /&gt;
&lt;br /&gt;
  # We expect it to print hello three times before coming to an end.&lt;br /&gt;
  task.execute()&lt;br /&gt;
  beam.tasks.wait(task)&lt;br /&gt;
&lt;br /&gt;
if __name__ == '__main__':&lt;br /&gt;
  main()&lt;br /&gt;
&lt;br /&gt;
==Decomposition==&lt;br /&gt;
&lt;br /&gt;
The above example works, but upon reflection we should notice that this Task is responsible for two distinct things. One is the responsibility of printing, and the other is the responsibility of repeating. Given that the purpose of tasks is to be able to compose asynchronous operations we should separate these two responsibilities from one another. To do that we will change our HelloTask so that all it does is print hello after a specified time period, followed by a RepetitionTask which repeats a task a specified number of times. The benefit of this is that our RepetitionTask can be reused to repeat any task whatsoever down the road.&lt;br /&gt;
&lt;br /&gt;
We will define it as follows:&lt;br /&gt;
&lt;br /&gt;
class RepetitionTask(beam.tasks.BasicTask):&lt;br /&gt;
  '''Repeats a Task a specified number of times.'''&lt;br /&gt;
&lt;br /&gt;
  def __init__(self, task_factory, iterations):&lt;br /&gt;
    '''Constructs the Task.&lt;br /&gt;
    :param task_factory: Builds the Task to repeat.&lt;br /&gt;
    :param iterations: The number of times to repeat the Task.&lt;br /&gt;
    '''&lt;br /&gt;
    beam.tasks.BasicTask.__init__(self)&lt;br /&gt;
&lt;br /&gt;
    # We should always make a deep copy of factories in order to&lt;br /&gt;
    # avoid modifying a factory belonging to another task or having&lt;br /&gt;
    # another task modify our factory.&lt;br /&gt;
    self.task_factory = copy.deepcopy(task_factory)&lt;br /&gt;
    self.iterations = iterations&lt;br /&gt;
    self.counter = 0&lt;br /&gt;
&lt;br /&gt;
    # This stores the task currently being executed.&lt;br /&gt;
    self.task = None&lt;br /&gt;
&lt;br /&gt;
    # This is used to handle callbacks from our tasks.&lt;br /&gt;
    self.tasks = beam.RoutineTaskQueue()&lt;br /&gt;
&lt;br /&gt;
  def on_execute(self):&lt;br /&gt;
&lt;br /&gt;
    # Defer to a helper function.&lt;br /&gt;
    self.execute_task()&lt;br /&gt;
&lt;br /&gt;
  def on_cancel(self):&lt;br /&gt;
&lt;br /&gt;
    # As before, to avoid race conditions between cancels and&lt;br /&gt;
    # our task we will push a callback onto a RoutineTaskQueue&lt;br /&gt;
    # to handle cancellations.&lt;br /&gt;
    self.tasks.push(self._on_cancel)&lt;br /&gt;
&lt;br /&gt;
  def on_state(self, state_entry):&lt;br /&gt;
&lt;br /&gt;
    # This method handles transitions of the task we're repeating.&lt;br /&gt;
    if state_entry.state == beam.tasks.Task.State.CANCELED:&lt;br /&gt;
&lt;br /&gt;
      # This branch indicates that we canceled our task which&lt;br /&gt;
      # means that we're handling a cancel request.&lt;br /&gt;
      self.set_terminal(beam.tasks.Task.State.CANCELED)&lt;br /&gt;
    elif beam.tasks.is_terminal(state_entry.state):&lt;br /&gt;
&lt;br /&gt;
      # This branch indicates that our task terminated and&lt;br /&gt;
      # hence we should repeat.&lt;br /&gt;
      self.execute_task()&lt;br /&gt;
&lt;br /&gt;
  def _on_cancel(self):&lt;br /&gt;
    if self.counter &amp;lt; self.iterations:&lt;br /&gt;
&lt;br /&gt;
      # Similar to before, only cancel if we still have&lt;br /&gt;
      # repetitions to process.&lt;br /&gt;
      self.task.cancel()&lt;br /&gt;
&lt;br /&gt;
  def execute_task(self):&lt;br /&gt;
    if self.counter &amp;gt;= self.iterations:&lt;br /&gt;
&lt;br /&gt;
      # This branch indicates there are no more iterations left.&lt;br /&gt;
      self.set_terminal()&lt;br /&gt;
    else:&lt;br /&gt;
&lt;br /&gt;
      # This branch indicates that we need to repeat the task&lt;br /&gt;
      # by constructing a new one and executing it.&lt;br /&gt;
      self.counter += 1&lt;br /&gt;
      self.task = self.task_factory.create()&lt;br /&gt;
      self.task.get_publisher().monitor(self.tasks.get_slot(self.on_state))&lt;br /&gt;
      self.task.execute()&lt;br /&gt;
&lt;br /&gt;
# This class is very similar to the HelloTaskFactory.&lt;br /&gt;
class RepetitionTaskFactory(beam.tasks.TaskFactory):&lt;br /&gt;
  ITERATIONS = 'iterations'&lt;br /&gt;
&lt;br /&gt;
  def __init__(self, task_factory):&lt;br /&gt;
    beam.tasks.TaskFactory.__init__(self)&lt;br /&gt;
    self.task_factory = copy.deepcopy(task_factory)&lt;br /&gt;
    self.define_property(RepetitionTaskFactory.ITERATIONS, 10)&lt;br /&gt;
    self.continuation_task = None&lt;br /&gt;
&lt;br /&gt;
  def create(self):&lt;br /&gt;
    if self.continuation_task is None:&lt;br /&gt;
      return RepetitionTask(self.task_factory,&lt;br /&gt;
        self.get(RepetitionTaskFactory.ITERATIONS))&lt;br /&gt;
    else:&lt;br /&gt;
      continuation = RepetitionTask(self.task_factory,&lt;br /&gt;
        self.get(RepetitionTaskFactory.ITERATIONS) -&lt;br /&gt;
        self.continuation_task.counter)&lt;br /&gt;
      self.continuation_task = None&lt;br /&gt;
      return continuation&lt;br /&gt;
&lt;br /&gt;
  def prepare_continuation(self, task):&lt;br /&gt;
    self.continuation_task = task&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Now that we have factored out the job of repeating tasks we can rewrite our HelloTask as follows:&lt;br /&gt;
&lt;br /&gt;
class HelloTask(beam.tasks.BasicTask):&lt;br /&gt;
  def __init__(self, timer):&lt;br /&gt;
    beam.tasks.BasicTask.__init__(self)&lt;br /&gt;
    self.timer = timer&lt;br /&gt;
    self.tasks = beam.RoutineTaskQueue()&lt;br /&gt;
&lt;br /&gt;
  def on_execute(self):&lt;br /&gt;
    self.timer.get_publisher().monitor(self.tasks.get_slot(self.on_timer))&lt;br /&gt;
    self.timer.start()&lt;br /&gt;
    self.set_active()&lt;br /&gt;
&lt;br /&gt;
  def on_cancel(self):&lt;br /&gt;
    self.tasks.push(self._on_cancel)&lt;br /&gt;
&lt;br /&gt;
  def on_timer(self, result):&lt;br /&gt;
    print 'hello'&lt;br /&gt;
    if result == beam.threading.Timer.Result.EXPIRED:&lt;br /&gt;
      self.set_terminal()&lt;br /&gt;
    else:&lt;br /&gt;
      self.set_terminal(beam.tasks.Task.State.CANCELED)&lt;br /&gt;
&lt;br /&gt;
  def _on_cancel(self):&lt;br /&gt;
    self.timer.cancel()&lt;br /&gt;
&lt;br /&gt;
class HelloTaskFactory(beam.tasks.TaskFactory):&lt;br /&gt;
  def __init__(self, timer_factory):&lt;br /&gt;
    beam.tasks.TaskFactory.__init__(self)&lt;br /&gt;
    self.timer_factory = timer_factory&lt;br /&gt;
&lt;br /&gt;
  def create(self):&lt;br /&gt;
    return HelloTask(self.timer_factory(datetime.timedelta(seconds = 1)))&lt;br /&gt;
&lt;br /&gt;
Finally once these two pieces are in place we can combine them as follows:&lt;br /&gt;
&lt;br /&gt;
def main():&lt;br /&gt;
&lt;br /&gt;
  # First build the HelloTaskFactory&lt;br /&gt;
  hello_factory = HelloTaskFactory(beam.threading.LiveTimer)&lt;br /&gt;
&lt;br /&gt;
  # Pass the above factory into the RepetitionTaskFactory.&lt;br /&gt;
  # The result is a factory that composes a RepetitionTask with&lt;br /&gt;
  # a HelloTask.&lt;br /&gt;
  factory = RepetitionTaskFactory(hello_factory)&lt;br /&gt;
  factory.set(RepetitionTaskFactory.ITERATIONS, 5)&lt;br /&gt;
&lt;br /&gt;
  # Now we can use the factory similarly to how we used it before.&lt;br /&gt;
  task = factory.create()&lt;br /&gt;
  task.execute()&lt;br /&gt;
  time.sleep(2)&lt;br /&gt;
  task.cancel()&lt;br /&gt;
  beam.tasks.wait(task)&lt;br /&gt;
  factory.prepare_continuation(task)&lt;br /&gt;
  factory.set(RepetitionTaskFactory.ITERATIONS, 7)&lt;br /&gt;
  task = factory.create()&lt;br /&gt;
  task.execute()&lt;br /&gt;
  beam.tasks.wait(task)&lt;br /&gt;
&lt;br /&gt;
if __name__ == '__main__':&lt;br /&gt;
  main()&lt;br /&gt;
&lt;br /&gt;
In actuality, we can take this decomposition one step further by factoring out from the HelloTask the responsibility of printing 'hello' with the responsibility of running a task after a specified period of time. If we so desired we would write a TimerTask/TimerTaskFactory and then our final composition would be along the lines of a RepetitionTaskFactory(TimerTaskFactory(HelloTaskFactory(), beam.threading.LiveTimer)).&lt;/div&gt;</summary>
		<author><name>Kman</name></author>
		
	</entry>
	<entry>
		<id>https://wiki.spiretrading.com/index.php?title=Tasks&amp;diff=52</id>
		<title>Tasks</title>
		<link rel="alternate" type="text/html" href="https://wiki.spiretrading.com/index.php?title=Tasks&amp;diff=52"/>
		<updated>2018-09-11T20:14:56Z</updated>

		<summary type="html">&lt;p&gt;Kman: Created page with &amp;quot;Tasks provide a way of encapsulating and managing asynchronous actions in a composable manner. They are primarily used to perform some sort of I/O operation and/or manage a se...&amp;quot;&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Tasks provide a way of encapsulating and managing asynchronous actions in a composable manner. They are primarily used to perform some sort of I/O operation and/or manage a series of sub-tasks. Beam provides several classes to define your own tasks as well as classes that connect tasks to one another.&lt;br /&gt;
&lt;br /&gt;
The task API in Beam is defined by two base classes, the class Beam::Tasks::Task which represents a task, and the class Beam::Tasks::TaskFactory which constructs tasks. In this article we will explore how we can use these two classes in ways that allow us to start, stop, modify and resume asynchronous actions.&lt;br /&gt;
Contents&lt;br /&gt;
&lt;br /&gt;
    1 Interface&lt;br /&gt;
        1.1 Task&lt;br /&gt;
        1.2 Task Factory&lt;br /&gt;
            1.2.1 Continuations&lt;br /&gt;
        1.3 BasicTask&lt;br /&gt;
    2 Example&lt;br /&gt;
        2.1 First Attempt&lt;br /&gt;
        2.2 Decomposition&lt;br /&gt;
&lt;br /&gt;
Interface[edit]&lt;br /&gt;
Task[edit]&lt;br /&gt;
&lt;br /&gt;
The Task class defines two methods, an Execute() method to start the task and a Cancel() method to request that the task stop. Both operations are asynchronous, meaning that they return immediately and the actual operation of the task takes place in a separate thread of execution. In order to keep track of the progress of a task one must monitor its state which can be any of the following:&lt;br /&gt;
State 	Description&lt;br /&gt;
NONE 	The task has not yet been executed.&lt;br /&gt;
INITIALIZING 	The task is performing some initialization, during this state no sub-tasks may be executed.&lt;br /&gt;
ACTIVE 	The task is running, during this state sub-tasks may be executed.&lt;br /&gt;
PENDING_CANCEL 	A request to cancel the task has been made, no new sub-tasks may be executed.&lt;br /&gt;
CANCELED 	The task was canceled.&lt;br /&gt;
FAILED 	The task could not complete due to an error.&lt;br /&gt;
EXPIRED 	The task could not complete due to a time constraint.&lt;br /&gt;
COMPLETE 	The task completed successfully.&lt;br /&gt;
&lt;br /&gt;
The states CANCELED, FAILED, EXPIRED and COMPLETE all represent terminal states. Before a task can transition to a terminal state, all of its sub tasks must be in a terminal state. Furthermore once a task is in a terminal state the task is not permitted to perform any additional action or transition to a different state.&lt;br /&gt;
&lt;br /&gt;
The current state of the task along with all of its transitions is accessed through its Publisher by calling the GetPublisher() method. The publisher will emit objects of type Beam::Tasks::Task::StateEntry which contains two fields as follows:&lt;br /&gt;
Name 	Type 	Description&lt;br /&gt;
m_state 	Beam::Tasks::Task::State 	The state of the task.&lt;br /&gt;
m_message 	std::string 	A message describing the reason for the transition.&lt;br /&gt;
&lt;br /&gt;
In effect a task begins in the NONE state, is then started via the Execute() method, transitions into the INITIALIZATION state where it performs any setup needed, then proceeds to the ACTIVE state where it performs its operation including executing any required sub-tasks, and then finally terminates all of its sub-tasks and performs any final clean-up before ending in a terminal state. During any point after the INITIALIZATION state it may encounter a cancel request (via the Cancel() method) or an error, either of which should result in cleaning-up and terminating its sub-tasks before transitioning to the FAILED or CANCELED state.&lt;br /&gt;
Task Factory[edit]&lt;br /&gt;
&lt;br /&gt;
The task factory is responsible for creating new tasks by invoking its Create() method. In addition to this a task factory also keeps track of the parameters and state needed to create tasks. Setting a task's parameter is done by calling the factory's Set(name, value) method and retrieving a parameter is done via the Get(name) method.&lt;br /&gt;
Continuations[edit]&lt;br /&gt;
&lt;br /&gt;
One additional operation that task factories perform is constructing what is called a continuation task. Continuations are a mechanism that allow us to resume a task that previously terminated, but more than that they also allow us to modify the parameters of that task. In a sense, a continuation lets us take a terminated task, modify it, and then continue running it with those modifications.&lt;br /&gt;
&lt;br /&gt;
To do this, task factories have a method PrepareContinuation(task). To use it you pass into it a task that has terminated, then you modify its properties using the Set(name, value) method, and then finally you invoke the Create() method to get a newly constructed task that represents the continuation of the old task.&lt;br /&gt;
&lt;br /&gt;
Not all tasks support continuations, those that do not will throw a Beam::NotSupportedException.&lt;br /&gt;
BasicTask[edit]&lt;br /&gt;
&lt;br /&gt;
As a great deal of care must be taken to ensure that tasks properly transition from State to State, including managing sub-tasks, handling cancel requests etc... Beam provides the Beam::Tasks::BasicTask as a base class which can be inherited from to take care of much of the work needed to write a proper task. For example it ensures that upon a cancel request that the task transitions into the PENDING_CANCEL state and terminates all managed sub-tasks.&lt;br /&gt;
&lt;br /&gt;
To make use of a the BasicTask you need only implement the OnExecute() method to start your task, and the OnCancel() method to handle cancelling your class.&lt;br /&gt;
Example[edit]&lt;br /&gt;
&lt;br /&gt;
To showcase a simple example, let's build a task that prints &amp;quot;hello&amp;quot; every second a given number of times. We will write a HelloTask class which inherits from BasicTask, and a HelloTaskFactory.&lt;br /&gt;
First Attempt[edit]&lt;br /&gt;
&lt;br /&gt;
import beam&lt;br /&gt;
import datetime&lt;br /&gt;
import time&lt;br /&gt;
&lt;br /&gt;
class HelloTask(beam.tasks.BasicTask):&lt;br /&gt;
  '''Prints hello a specified number of times.'''&lt;br /&gt;
&lt;br /&gt;
  def __init__(self, timer, iterations):&lt;br /&gt;
    ''' Constructs this task.&lt;br /&gt;
    :param timer: The Timer used to wait between successive prints.&lt;br /&gt;
    :param iterations: The number of times to print.&lt;br /&gt;
    '''&lt;br /&gt;
&lt;br /&gt;
    # We must make sure to initialize the base class.&lt;br /&gt;
    beam.tasks.BasicTask.__init__(self)&lt;br /&gt;
    self.timer = timer&lt;br /&gt;
    self.iterations = iterations&lt;br /&gt;
&lt;br /&gt;
    # The number of times we've printed so far.&lt;br /&gt;
    self.counter = 0&lt;br /&gt;
&lt;br /&gt;
    # Used to handle timer callbacks.&lt;br /&gt;
    self.tasks = beam.RoutineTaskQueue()&lt;br /&gt;
&lt;br /&gt;
  # This overrides BasicTask.on_execute.&lt;br /&gt;
  # When called we can assume that our Task is in the INITIALIZATION state.&lt;br /&gt;
  def on_execute(self):&lt;br /&gt;
&lt;br /&gt;
    # To initialize our task we will monitor our timer and then start the timer.&lt;br /&gt;
    self.timer.get_publisher().monitor(self.tasks.get_slot(self.on_timer))&lt;br /&gt;
    self.timer.start()&lt;br /&gt;
&lt;br /&gt;
    # Once the initialization is complete we transition to the ACTIVE state.&lt;br /&gt;
    self.set_active()&lt;br /&gt;
&lt;br /&gt;
  # This overrides BasicTask.on_cancel.&lt;br /&gt;
  # When called we can assume that our Task is in the PENDING_CANCEL state.&lt;br /&gt;
  # No new sub-tasks may be executed.&lt;br /&gt;
  def on_cancel(self):&lt;br /&gt;
&lt;br /&gt;
    # In order to synchronize handling the cancel operation with the timer,&lt;br /&gt;
    # we will push a helper function onto our RoutineTaskQueue.&lt;br /&gt;
    # This ensures no race-conditions take place between the timer and&lt;br /&gt;
    # the cancel request.&lt;br /&gt;
    self.tasks.push(self._on_cancel)&lt;br /&gt;
&lt;br /&gt;
  # This handles the timer expiry.&lt;br /&gt;
  def on_timer(self, result):&lt;br /&gt;
    if result == beam.threading.Timer.Result.EXPIRED:&lt;br /&gt;
&lt;br /&gt;
      # This branch implies that our timer expired normally.&lt;br /&gt;
      print 'hello'&lt;br /&gt;
      self.counter += 1&lt;br /&gt;
      if self.counter &amp;gt;= self.iterations:&lt;br /&gt;
&lt;br /&gt;
        # There is nothing more to print, so transition to&lt;br /&gt;
        # a terminal state, which by default is the COMPLETE state.&lt;br /&gt;
        self.set_terminal()&lt;br /&gt;
      else:&lt;br /&gt;
&lt;br /&gt;
        # There are still further iterations, restart the timer.&lt;br /&gt;
        self.timer.start()&lt;br /&gt;
    else:&lt;br /&gt;
&lt;br /&gt;
        # This branch implies that we canceled the timer in response&lt;br /&gt;
        # to a cancel request.&lt;br /&gt;
        # In this case we set our state to CANCELED.&lt;br /&gt;
        self.set_terminal(beam.tasks.Task.State.CANCELED)&lt;br /&gt;
&lt;br /&gt;
  def _on_cancel(self):&lt;br /&gt;
    if self.counter &amp;lt; self.iterations:&lt;br /&gt;
&lt;br /&gt;
      # Only cancel the timer if there are iterations remaining.&lt;br /&gt;
      self.timer.cancel()&lt;br /&gt;
&lt;br /&gt;
class HelloTaskFactory(beam.tasks.TaskFactory):&lt;br /&gt;
  '''Builds HelloTasks.'''&lt;br /&gt;
&lt;br /&gt;
  # Typically the parameters that get passed into the Task are&lt;br /&gt;
  # defined as static constant strings in the TaskFactory.&lt;br /&gt;
  # This makes it easier to identify the properties of a task&lt;br /&gt;
  # as well as reference them (avoiding potential typos).&lt;br /&gt;
  ITERATIONS = 'iterations'&lt;br /&gt;
&lt;br /&gt;
  def __init__(self, timer_factory):&lt;br /&gt;
    '''Constructs a HelloTaskFactory.&lt;br /&gt;
    :param timer_factory: Used to construct Timers.&lt;br /&gt;
    '''&lt;br /&gt;
&lt;br /&gt;
    # Factories will typically inherit from TaskFactory as a base class.&lt;br /&gt;
    beam.tasks.TaskFactory.__init__(self)&lt;br /&gt;
    self.timer_factory = timer_factory&lt;br /&gt;
&lt;br /&gt;
    # The constructor should define all the properties and default&lt;br /&gt;
    # values for those properties.&lt;br /&gt;
    self.define_property(HelloTaskFactory.ITERATIONS, 10)&lt;br /&gt;
&lt;br /&gt;
    # This variable keeps track of continuations.&lt;br /&gt;
    self.continuation_task = None&lt;br /&gt;
&lt;br /&gt;
  # This overrides the TaskFactory create method.&lt;br /&gt;
  def create(self):&lt;br /&gt;
&lt;br /&gt;
    if self.continuation_task is None:&lt;br /&gt;
&lt;br /&gt;
      # We are not creating a continuation task, so all we need to do is&lt;br /&gt;
      # construct a HelloTask using the ITERATIONS property defined above.&lt;br /&gt;
      return HelloTask(self.timer_factory(datetime.timedelta(seconds = 1)),&lt;br /&gt;
        self.get(HelloTaskFactory.ITERATIONS))&lt;br /&gt;
    else:&lt;br /&gt;
&lt;br /&gt;
      # We are creating a continuation task.  The continuation of a HelloTask of&lt;br /&gt;
      # N iterations that has already printed C times is basically a HelloTask&lt;br /&gt;
      # that prints N - C times.&lt;br /&gt;
      continuation = HelloTask(&lt;br /&gt;
        self.timer_factory(datetime.timedelta(seconds = 1)),&lt;br /&gt;
        self.get(HelloTaskFactory.ITERATIONS) - self.continuation_task.counter)&lt;br /&gt;
      self.continuation_task = None&lt;br /&gt;
      return continuation&lt;br /&gt;
&lt;br /&gt;
  # This overrides the TaskFactory prepare_continuation method.&lt;br /&gt;
  def prepare_continuation(self, task):&lt;br /&gt;
&lt;br /&gt;
    # We store the task to continue.&lt;br /&gt;
    self.continuation_task = task&lt;br /&gt;
&lt;br /&gt;
def main():&lt;br /&gt;
&lt;br /&gt;
  # Construct the HelloTaskFactory using the LiveTimer for 5 iterations.&lt;br /&gt;
  factory = HelloTaskFactory(beam.threading.LiveTimer)&lt;br /&gt;
  factory.set(HelloTaskFactory.ITERATIONS, 5)&lt;br /&gt;
  task = factory.create()&lt;br /&gt;
  task.execute()&lt;br /&gt;
&lt;br /&gt;
  # Let's sleep for 2 seconds before canceling the task.&lt;br /&gt;
  # It should print hello twice.&lt;br /&gt;
  time.sleep(2)&lt;br /&gt;
  task.cancel()&lt;br /&gt;
&lt;br /&gt;
  # Wait for the task to enter the CANCELED state.&lt;br /&gt;
  beam.tasks.wait(task)&lt;br /&gt;
&lt;br /&gt;
  # Build the continuation task and execute it.  To do this we first&lt;br /&gt;
  # call prepare_continuation, then we make our modifications using the set&lt;br /&gt;
  # method, then we create the task and execute it.&lt;br /&gt;
  factory.prepare_continuation(task)&lt;br /&gt;
  factory.set(HelloTaskFactory.ITERATIONS, 7)&lt;br /&gt;
  task = factory.create()&lt;br /&gt;
&lt;br /&gt;
  # We expect it to print hello three times before coming to an end.&lt;br /&gt;
  task.execute()&lt;br /&gt;
  beam.tasks.wait(task)&lt;br /&gt;
&lt;br /&gt;
if __name__ == '__main__':&lt;br /&gt;
  main()&lt;br /&gt;
&lt;br /&gt;
Decomposition[edit]&lt;br /&gt;
&lt;br /&gt;
The above example works, but upon reflection we should notice that this Task is responsible for two distinct things. One is the responsibility of printing, and the other is the responsibility of repeating. Given that the purpose of tasks is to be able to compose asynchronous operations we should separate these two responsibilities from one another. To do that we will change our HelloTask so that all it does is print hello after a specified time period, followed by a RepetitionTask which repeats a task a specified number of times. The benefit of this is that our RepetitionTask can be reused to repeat any task whatsoever down the road.&lt;br /&gt;
&lt;br /&gt;
We will define it as follows:&lt;br /&gt;
&lt;br /&gt;
class RepetitionTask(beam.tasks.BasicTask):&lt;br /&gt;
  '''Repeats a Task a specified number of times.'''&lt;br /&gt;
&lt;br /&gt;
  def __init__(self, task_factory, iterations):&lt;br /&gt;
    '''Constructs the Task.&lt;br /&gt;
    :param task_factory: Builds the Task to repeat.&lt;br /&gt;
    :param iterations: The number of times to repeat the Task.&lt;br /&gt;
    '''&lt;br /&gt;
    beam.tasks.BasicTask.__init__(self)&lt;br /&gt;
&lt;br /&gt;
    # We should always make a deep copy of factories in order to&lt;br /&gt;
    # avoid modifying a factory belonging to another task or having&lt;br /&gt;
    # another task modify our factory.&lt;br /&gt;
    self.task_factory = copy.deepcopy(task_factory)&lt;br /&gt;
    self.iterations = iterations&lt;br /&gt;
    self.counter = 0&lt;br /&gt;
&lt;br /&gt;
    # This stores the task currently being executed.&lt;br /&gt;
    self.task = None&lt;br /&gt;
&lt;br /&gt;
    # This is used to handle callbacks from our tasks.&lt;br /&gt;
    self.tasks = beam.RoutineTaskQueue()&lt;br /&gt;
&lt;br /&gt;
  def on_execute(self):&lt;br /&gt;
&lt;br /&gt;
    # Defer to a helper function.&lt;br /&gt;
    self.execute_task()&lt;br /&gt;
&lt;br /&gt;
  def on_cancel(self):&lt;br /&gt;
&lt;br /&gt;
    # As before, to avoid race conditions between cancels and&lt;br /&gt;
    # our task we will push a callback onto a RoutineTaskQueue&lt;br /&gt;
    # to handle cancellations.&lt;br /&gt;
    self.tasks.push(self._on_cancel)&lt;br /&gt;
&lt;br /&gt;
  def on_state(self, state_entry):&lt;br /&gt;
&lt;br /&gt;
    # This method handles transitions of the task we're repeating.&lt;br /&gt;
    if state_entry.state == beam.tasks.Task.State.CANCELED:&lt;br /&gt;
&lt;br /&gt;
      # This branch indicates that we canceled our task which&lt;br /&gt;
      # means that we're handling a cancel request.&lt;br /&gt;
      self.set_terminal(beam.tasks.Task.State.CANCELED)&lt;br /&gt;
    elif beam.tasks.is_terminal(state_entry.state):&lt;br /&gt;
&lt;br /&gt;
      # This branch indicates that our task terminated and&lt;br /&gt;
      # hence we should repeat.&lt;br /&gt;
      self.execute_task()&lt;br /&gt;
&lt;br /&gt;
  def _on_cancel(self):&lt;br /&gt;
    if self.counter &amp;lt; self.iterations:&lt;br /&gt;
&lt;br /&gt;
      # Similar to before, only cancel if we still have&lt;br /&gt;
      # repetitions to process.&lt;br /&gt;
      self.task.cancel()&lt;br /&gt;
&lt;br /&gt;
  def execute_task(self):&lt;br /&gt;
    if self.counter &amp;gt;= self.iterations:&lt;br /&gt;
&lt;br /&gt;
      # This branch indicates there are no more iterations left.&lt;br /&gt;
      self.set_terminal()&lt;br /&gt;
    else:&lt;br /&gt;
&lt;br /&gt;
      # This branch indicates that we need to repeat the task&lt;br /&gt;
      # by constructing a new one and executing it.&lt;br /&gt;
      self.counter += 1&lt;br /&gt;
      self.task = self.task_factory.create()&lt;br /&gt;
      self.task.get_publisher().monitor(self.tasks.get_slot(self.on_state))&lt;br /&gt;
      self.task.execute()&lt;br /&gt;
&lt;br /&gt;
# This class is very similar to the HelloTaskFactory.&lt;br /&gt;
class RepetitionTaskFactory(beam.tasks.TaskFactory):&lt;br /&gt;
  ITERATIONS = 'iterations'&lt;br /&gt;
&lt;br /&gt;
  def __init__(self, task_factory):&lt;br /&gt;
    beam.tasks.TaskFactory.__init__(self)&lt;br /&gt;
    self.task_factory = copy.deepcopy(task_factory)&lt;br /&gt;
    self.define_property(RepetitionTaskFactory.ITERATIONS, 10)&lt;br /&gt;
    self.continuation_task = None&lt;br /&gt;
&lt;br /&gt;
  def create(self):&lt;br /&gt;
    if self.continuation_task is None:&lt;br /&gt;
      return RepetitionTask(self.task_factory,&lt;br /&gt;
        self.get(RepetitionTaskFactory.ITERATIONS))&lt;br /&gt;
    else:&lt;br /&gt;
      continuation = RepetitionTask(self.task_factory,&lt;br /&gt;
        self.get(RepetitionTaskFactory.ITERATIONS) -&lt;br /&gt;
        self.continuation_task.counter)&lt;br /&gt;
      self.continuation_task = None&lt;br /&gt;
      return continuation&lt;br /&gt;
&lt;br /&gt;
  def prepare_continuation(self, task):&lt;br /&gt;
    self.continuation_task = task&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Now that we have factored out the job of repeating tasks we can rewrite our HelloTask as follows:&lt;br /&gt;
&lt;br /&gt;
class HelloTask(beam.tasks.BasicTask):&lt;br /&gt;
  def __init__(self, timer):&lt;br /&gt;
    beam.tasks.BasicTask.__init__(self)&lt;br /&gt;
    self.timer = timer&lt;br /&gt;
    self.tasks = beam.RoutineTaskQueue()&lt;br /&gt;
&lt;br /&gt;
  def on_execute(self):&lt;br /&gt;
    self.timer.get_publisher().monitor(self.tasks.get_slot(self.on_timer))&lt;br /&gt;
    self.timer.start()&lt;br /&gt;
    self.set_active()&lt;br /&gt;
&lt;br /&gt;
  def on_cancel(self):&lt;br /&gt;
    self.tasks.push(self._on_cancel)&lt;br /&gt;
&lt;br /&gt;
  def on_timer(self, result):&lt;br /&gt;
    print 'hello'&lt;br /&gt;
    if result == beam.threading.Timer.Result.EXPIRED:&lt;br /&gt;
      self.set_terminal()&lt;br /&gt;
    else:&lt;br /&gt;
      self.set_terminal(beam.tasks.Task.State.CANCELED)&lt;br /&gt;
&lt;br /&gt;
  def _on_cancel(self):&lt;br /&gt;
    self.timer.cancel()&lt;br /&gt;
&lt;br /&gt;
class HelloTaskFactory(beam.tasks.TaskFactory):&lt;br /&gt;
  def __init__(self, timer_factory):&lt;br /&gt;
    beam.tasks.TaskFactory.__init__(self)&lt;br /&gt;
    self.timer_factory = timer_factory&lt;br /&gt;
&lt;br /&gt;
  def create(self):&lt;br /&gt;
    return HelloTask(self.timer_factory(datetime.timedelta(seconds = 1)))&lt;br /&gt;
&lt;br /&gt;
Finally once these two pieces are in place we can combine them as follows:&lt;br /&gt;
&lt;br /&gt;
def main():&lt;br /&gt;
&lt;br /&gt;
  # First build the HelloTaskFactory&lt;br /&gt;
  hello_factory = HelloTaskFactory(beam.threading.LiveTimer)&lt;br /&gt;
&lt;br /&gt;
  # Pass the above factory into the RepetitionTaskFactory.&lt;br /&gt;
  # The result is a factory that composes a RepetitionTask with&lt;br /&gt;
  # a HelloTask.&lt;br /&gt;
  factory = RepetitionTaskFactory(hello_factory)&lt;br /&gt;
  factory.set(RepetitionTaskFactory.ITERATIONS, 5)&lt;br /&gt;
&lt;br /&gt;
  # Now we can use the factory similarly to how we used it before.&lt;br /&gt;
  task = factory.create()&lt;br /&gt;
  task.execute()&lt;br /&gt;
  time.sleep(2)&lt;br /&gt;
  task.cancel()&lt;br /&gt;
  beam.tasks.wait(task)&lt;br /&gt;
  factory.prepare_continuation(task)&lt;br /&gt;
  factory.set(RepetitionTaskFactory.ITERATIONS, 7)&lt;br /&gt;
  task = factory.create()&lt;br /&gt;
  task.execute()&lt;br /&gt;
  beam.tasks.wait(task)&lt;br /&gt;
&lt;br /&gt;
if __name__ == '__main__':&lt;br /&gt;
  main()&lt;br /&gt;
&lt;br /&gt;
In actuality, we can take this decomposition one step further by factoring out from the HelloTask the responsibility of printing 'hello' with the responsibility of running a task after a specified period of time. If we so desired we would write a TimerTask/TimerTaskFactory and then our final composition would be along the lines of a RepetitionTaskFactory(TimerTaskFactory(HelloTaskFactory(), beam.threading.LiveTimer)).&lt;/div&gt;</summary>
		<author><name>Kman</name></author>
		
	</entry>
	<entry>
		<id>https://wiki.spiretrading.com/index.php?title=TypeScript_Style_Guide&amp;diff=51</id>
		<title>TypeScript Style Guide</title>
		<link rel="alternate" type="text/html" href="https://wiki.spiretrading.com/index.php?title=TypeScript_Style_Guide&amp;diff=51"/>
		<updated>2018-09-05T15:53:06Z</updated>

		<summary type="html">&lt;p&gt;Kman: /* Naming */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;This article specifies the most general guidelines used for all Spire projects written using TypeScript as the primary programming language. Each individual project may extend or override the guidelines specified herein. The overall aim of this guideline is to provide consistency across the numerous projects developed by Spire in order to promote and benefit from modern web development practices as well as tailor them to our specific requirements.&lt;br /&gt;
&lt;br /&gt;
In general, the guidelines are very specific and opinionated. This is done intentionally to ensure that every detail has been given proper consideration and that every line of code is written with care and diligence. It is taken as a prerequisite that writing robust, clean and maintainable code requires paying close attention to even the smallest of details. As such, when there are two or more ways to write or express any given statement or expression, be it using spaces or tabs, number of characters per line, purple or violet, the guideline will often require that one particular approach be used to the exclusion of others.&lt;br /&gt;
&lt;br /&gt;
Finally, this document is constantly evolving and as such older projects may not be up-to-date with the guidelines found here. In those circumstances one must use their best judgment about how to integrate these guidelines into older codebases. As a general principle, consistency should favor the local over the global, that is it is more important to be consistent with a function definition than within a file, and more important to be consistent within a file than within a directory, project, etc...&lt;br /&gt;
&lt;br /&gt;
=Development Environment=&lt;br /&gt;
&lt;br /&gt;
The primary operating systems supported by Spire projects are Ubuntu 18.02 LTS, Windows 10, and macOS. On all systems, nodejs is used as the build system and webpack is used as the bundler.&lt;br /&gt;
&lt;br /&gt;
For source control, git is used and projects are to be hosted on [https://github.com/spiretrading Spire Trading's Github page].&lt;br /&gt;
&lt;br /&gt;
Each developer is welcome to use an editor of their choice, however [https://code.visualstudio.com/ Visual Studio Code] is recommended.&lt;br /&gt;
&lt;br /&gt;
=File Names=&lt;br /&gt;
&lt;br /&gt;
Use [https://en.wikipedia.org/wiki/Snake_case snake case] using all lower case letters for files and directories. The name of a file should correspond to the primary class that it exports.&lt;br /&gt;
&lt;br /&gt;
The default extension for TypeScript files is ''ts''&lt;br /&gt;
&lt;br /&gt;
The extension used for TypeScript files containing JSX is ''tsx''&lt;br /&gt;
&lt;br /&gt;
All files end with a single new line character.&lt;br /&gt;
&lt;br /&gt;
=Directory Structure=&lt;br /&gt;
&lt;br /&gt;
A project is broken down into a library component, a test component, and one or more application components. These components are referred to as ''artifacts''. The applications go into their own ''applications'' directory and the libraries into the ''library'' directory. Within each artifact is a ''build'' directory containing the build scripts needed to build that artifact. Scripts for POSIX systems are found in the ''posix'' sub-directory and Windows build files are within the ''windows'' sub-directory. The build scripts specified are ''setup'' to download and install any dependencies needed to produce the artifact and the ''build'' script which produces the artifact. Typically the ''setup'' script is run only once or when a new dependency is introduced to the project, and the ''build'' script is run anytime a new build is needed.&lt;br /&gt;
&lt;br /&gt;
Finally there is a top-level ''build'' directory for the project as a whole which produces all artifacts by recursively calling each artifact's individual build scripts. Additionally the top-level build directory also includes a ''setup'' script which downloads all third party dependencies. Some projects may also opt to include an ''install'' script which sets up a suitable development environment, and other scripts for continuous builds, deployment and testing.&lt;br /&gt;
&lt;br /&gt;
Assuming a project named sudoku the following directory structure should be used:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
sudoku                             # Root level directory.&lt;br /&gt;
  build.sh                         # Script used to build all projects on POSIX.&lt;br /&gt;
  build.bat                        # Script used to build all projects on Windows.&lt;br /&gt;
  \applications                    # Contains all applications.&lt;br /&gt;
    \sudoku                        # Contains the source for the sudoku web application.&lt;br /&gt;
      package.json                 # The Node JS package description.&lt;br /&gt;
      tsconfig.json                # The TypeScript compiler configuration.&lt;br /&gt;
      webpack.config.js            # The Webpack configuration.&lt;br /&gt;
      build.sh                     # Script used to build application on POSIX.&lt;br /&gt;
      build.bat                    # Script used to build application Windows.&lt;br /&gt;
      \source                      # Contains the web application source files.&lt;br /&gt;
        \index.html                # The HTML file that loads the JavaScript application.&lt;br /&gt;
        \index.tsx                 # The TypeScript/JSX file containing the application.&lt;br /&gt;
  \library                         # Contains the common library code.&lt;br /&gt;
    package.json                   # The Node JS package description.&lt;br /&gt;
    tsconfig.json                  # The TypeScript compiler configuration.&lt;br /&gt;
    webpack.config.js              # The Webpack configuration.&lt;br /&gt;
    build.sh                       # Script used to build library on POSIX.&lt;br /&gt;
    build.bat                      # Script used to build library on Windows.&lt;br /&gt;
    \source                        # Contains the library source files.&lt;br /&gt;
      index.ts                     # Exports all definitions contained in this directory.&lt;br /&gt;
      \pages                       # Contains the source code for individual web pages.&lt;br /&gt;
        index.ts                   # Exports all definitions for every web page defined&lt;br /&gt;
                                   # in this directory.&lt;br /&gt;
        \landing_page              # Contains the source code for the landing page.&lt;br /&gt;
          index.ts                 # Exports the landing page.&lt;br /&gt;
          landing_page.tsx         # The TypeScript/JSX source code for the landing page.&lt;br /&gt;
        \page_2                    # Contains the source for for another web page.&lt;br /&gt;
          ...                      # Structured in a similar manner as the landing page.&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
An example of the above directory structure containing a basic skeletal implementation of all files can be found here: https://github.com/spiretrading/sudoku&lt;br /&gt;
&lt;br /&gt;
=Syntax=&lt;br /&gt;
&lt;br /&gt;
==Indentation==&lt;br /&gt;
Code is indented using 2 spaces per level, tabs are not permitted.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=typescript line=line&amp;gt;&lt;br /&gt;
function factorial(n: number): number {&lt;br /&gt;
  if(n == 0) {&lt;br /&gt;
    return 1;&lt;br /&gt;
  }&lt;br /&gt;
  return n * factorial(n - 1);&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Line Structure==&lt;br /&gt;
&lt;br /&gt;
Statements must end with a semi-colon ';' or a closing brace '}', even in cases where TypeScript allows them to be optional.&lt;br /&gt;
&lt;br /&gt;
Lines are limited to 80 characters. Exceptions to this rule are long imports and long string literals where breaking up the literal into multiple lines is not possible. In order to break up long statements into multiple lines the following rules are used:&lt;br /&gt;
&lt;br /&gt;
* Break the line at a comma, operator or opening bracket.&lt;br /&gt;
&amp;lt;syntaxhighlight lang=typescript line=line&amp;gt;&lt;br /&gt;
&lt;br /&gt;
// Correct, line break at comma.&lt;br /&gt;
f(a, ..., b,&lt;br /&gt;
  c, ..., d);&lt;br /&gt;
&lt;br /&gt;
// Incorrect, line break after expression.&lt;br /&gt;
f(a, ..., b&lt;br /&gt;
  , c, ..., d);&lt;br /&gt;
&lt;br /&gt;
// Correct, line break after operator.&lt;br /&gt;
a + ... + b +&lt;br /&gt;
  c + ... + d;&lt;br /&gt;
&lt;br /&gt;
// Incorrect, line break after expression.&lt;br /&gt;
a + ... + b&lt;br /&gt;
  + c + ... + d;&lt;br /&gt;
&lt;br /&gt;
// Correct, line break after opening bracket.&lt;br /&gt;
f(&lt;br /&gt;
  a, ..., b, c, ..., d);&lt;br /&gt;
&lt;br /&gt;
// Incorrect, line break after function name.&lt;br /&gt;
f&lt;br /&gt;
  (a, ..., b, c, ..., d);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* For statements that begin new blocks of code (such as if/while/class...), in order to avoid confusing the line continuation with the code block, the line continuation is indented two extra levels. For example consider the following snippet of code:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=typescript line=line&amp;gt;&lt;br /&gt;
// Incorrect.&lt;br /&gt;
if(condition_a &amp;amp;&amp;amp; condition_b &amp;amp;&amp;amp; ... &amp;amp;&amp;amp;&lt;br /&gt;
  condition_c) {&lt;br /&gt;
  console.log('meow');&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The line continuation on line 2 clashes with the code block on line 3. To avoid this clash the above code is indented as follows:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=typescript line=line&amp;gt;&lt;br /&gt;
// Correct.&lt;br /&gt;
if(condition_a &amp;amp;&amp;amp; condition_b &amp;amp;&amp;amp; ... &amp;amp;&amp;amp;&lt;br /&gt;
    condition_c) {&lt;br /&gt;
  console.log('meow');&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The extra level of indentation in the line continuation makes it clear where the condition ends and the code block begins.&lt;br /&gt;
&lt;br /&gt;
==Braces==&lt;br /&gt;
&lt;br /&gt;
Braces are placed using a variant of the [http://wiki.c2.com/?OneTrueBraceStyle OTBS style]. The opening brace is placed on the same line as the declaring statement with one single space preceding it, and the closing brace is placed on a line of its own at the same level of indentation as the declaring statement. For if statements, the else/else if is placed on the same line as the closing brace. For do/while loops, the while is placed on the same line as the closing brace.&lt;br /&gt;
&lt;br /&gt;
Examples:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=typescript line=line&amp;gt;&lt;br /&gt;
// Correct.&lt;br /&gt;
if(&amp;lt;cond&amp;gt;) {&lt;br /&gt;
  &amp;lt;body&amp;gt;&lt;br /&gt;
} else {&lt;br /&gt;
  &amp;lt;default&amp;gt;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
// Correct.&lt;br /&gt;
do {&lt;br /&gt;
  &amp;lt;body&amp;gt;&lt;br /&gt;
} while(&amp;lt;cond&amp;gt;);&lt;br /&gt;
&lt;br /&gt;
// Incorrect.&lt;br /&gt;
if(&amp;lt;cond&amp;gt;)&lt;br /&gt;
{&lt;br /&gt;
  &amp;lt;body&amp;gt;&lt;br /&gt;
}&lt;br /&gt;
else&lt;br /&gt;
{&lt;br /&gt;
  &amp;lt;default&amp;gt;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
// Incorrect.&lt;br /&gt;
do&lt;br /&gt;
{&lt;br /&gt;
  &amp;lt;body&amp;gt;&lt;br /&gt;
}&lt;br /&gt;
while(&amp;lt;cond&amp;gt;);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Spacing==&lt;br /&gt;
&lt;br /&gt;
The following are correct use cases for white spaces:&lt;br /&gt;
&lt;br /&gt;
* Used for indentation.&lt;br /&gt;
* Used to surround binary operations.&lt;br /&gt;
&amp;lt;syntaxhighlight lang=typescript line=line&amp;gt;&lt;br /&gt;
// Correct.&lt;br /&gt;
const x = a + b;&lt;br /&gt;
const y = 5;&lt;br /&gt;
&lt;br /&gt;
//! Incorrect&lt;br /&gt;
const x = a+b;&lt;br /&gt;
const y=5;&lt;br /&gt;
const z= 5;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* One space is placed after a comma.&lt;br /&gt;
&amp;lt;syntaxhighlight lang=typescript line=line&amp;gt;&lt;br /&gt;
// Correct.&lt;br /&gt;
f(1, 2);&lt;br /&gt;
function g(a: number, b: number): number;&lt;br /&gt;
&lt;br /&gt;
//! Incorrect&lt;br /&gt;
f(1,2);&lt;br /&gt;
function g(a:number,b:number);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Naming==&lt;br /&gt;
&lt;br /&gt;
[https://en.wikipedia.org/wiki/Camel_case Camel case] is used for naming whereas variables and functions use mixedCase and namespaces, modules, and types use CapWords. Names should be descriptive but should avoid being verbose.&lt;br /&gt;
&lt;br /&gt;
Classes and variables should be given the name of a noun and functions the name of a verb. Functions that return a boolean or boolean variables should be named in the form of a question starting with isX or hasX.&lt;br /&gt;
&lt;br /&gt;
==Imports==&lt;br /&gt;
Imports are listed in order of most global to local. Where dependencies have the same locality, then they are ordered alphabetically. For example, the first group of dependencies to be imported are third party packages which are listed in alphabetical order based on the package name. In the above snippet the third party dependencies are jquery, react and react-router-dom which are imported in alphabetical order. Then local dependencies are imported where directories further up the hierarchy are imported first. That is, the directory '../../..' which is three levels up is imported before the directory '..' which is only one level up.&lt;br /&gt;
&lt;br /&gt;
When multiple names are imported from a package, they must be listed in alphabetical order.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=typescript line=line&amp;gt;&lt;br /&gt;
import * as $ from 'jquery';&lt;br /&gt;
import * as React from 'react';&lt;br /&gt;
import * as Router from 'react-router-dom';&lt;br /&gt;
import {HBoxLayout, Padding, VBoxLayout} from '../../..';&lt;br /&gt;
import {Model} from '..';&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Declarations==&lt;br /&gt;
&lt;br /&gt;
Any declaration (such as a function or class) that is intended to be imported by another file must be documented using [http://usejsdoc.org/ JSDoc style]. If the definition is local then that documentation should be omitted entirely.&lt;br /&gt;
&lt;br /&gt;
Any documentation should be preceded by a blank line. In the code snippet, Properties is part of the public API so it is documented along with all of its fields, but the State is internal to the file so no aspect of it is documented.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=typescript line=line&amp;gt;&lt;br /&gt;
&lt;br /&gt;
/** Stores the React properties used to render a Page. */&lt;br /&gt;
export interface Properties {&lt;br /&gt;
&lt;br /&gt;
  /** The model used to display the page. */&lt;br /&gt;
  model: Model;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
export interface State {&lt;br /&gt;
  redirect: string;&lt;br /&gt;
  isLoading: boolean;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Variable Declarations==&lt;br /&gt;
&lt;br /&gt;
Variables are declared so that only one variable is declared per line, prefer declaring variables using ''const'' when possible, and deferring to ''let'' otherwise, variables should always be initialized at the point of their declaration.&lt;br /&gt;
&lt;br /&gt;
For complex initialization of values, use an [https://en.wikipedia.org/wiki/Immediately-invoked_function_expression immediately invoked lambda expression] as follows:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=typescript line=line&amp;gt;&lt;br /&gt;
const value = (() =&amp;gt; {&lt;br /&gt;
  if(condition) {&lt;br /&gt;
    return 123;&lt;br /&gt;
  }&lt;br /&gt;
  return 321;&lt;br /&gt;
})();&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=Example=&lt;br /&gt;
&lt;br /&gt;
Below is a full example combining numerous elements of the style guide to define a typical React component. It should be used as a general reference for how code is laid out, structured, and properly spaced.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=typescript line=line&amp;gt;&lt;br /&gt;
import * as $ from 'jquery';&lt;br /&gt;
import * as React from 'react';&lt;br /&gt;
import * as Router from 'react-router-dom';&lt;br /&gt;
import {HBoxLayout, Padding, VBoxLayout} from '..';&lt;br /&gt;
import {Model} from '.';&lt;br /&gt;
&lt;br /&gt;
/** Stores the React properties used to render a Page. */&lt;br /&gt;
export interface Properties {&lt;br /&gt;
&lt;br /&gt;
  /** The model used to display the page. */&lt;br /&gt;
  model: Model;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
export interface State {&lt;br /&gt;
  redirect: string;&lt;br /&gt;
  isLoading: boolean;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/** Displays an HTML page. */&lt;br /&gt;
export class Page extends React.Component&amp;lt;Properties, State&amp;gt; {&lt;br /&gt;
  constructor(props: Properties) {&lt;br /&gt;
    super(props);&lt;br /&gt;
    this.state = {&lt;br /&gt;
      redirect: '',&lt;br /&gt;
      isLoading: true&lt;br /&gt;
    };&lt;br /&gt;
  }&lt;br /&gt;
&lt;br /&gt;
  public componentWillMount(): void {&lt;br /&gt;
    this.props.model.load().then(&lt;br /&gt;
      () =&amp;gt; {&lt;br /&gt;
        this.setState({&lt;br /&gt;
          isLoading: false&lt;br /&gt;
        });&lt;br /&gt;
      });&lt;br /&gt;
  }&lt;br /&gt;
&lt;br /&gt;
  public render(): JSX.Element {&lt;br /&gt;
    if(this.state.redirect) {&lt;br /&gt;
      return &amp;lt;Router.Redirect push to={this.state.redirect}/&amp;gt;;&lt;br /&gt;
    } else if(this.state.isLoading) {&lt;br /&gt;
      return &amp;lt;LoadingPage/&amp;gt;;&lt;br /&gt;
    }&lt;br /&gt;
    const style = {&lt;br /&gt;
      backgroundColor: '#FFFFFF',&lt;br /&gt;
      font: 'Roboto 14px'&lt;br /&gt;
    };&lt;br /&gt;
    return (&lt;br /&gt;
      &amp;lt;div style={style}&amp;gt;&lt;br /&gt;
        &amp;lt;h1&amp;gt;Hello world!&amp;lt;/h1&amp;gt;&lt;br /&gt;
        &amp;lt;img src='cat.jpg'/&amp;gt;&lt;br /&gt;
      &amp;lt;/div&amp;gt;);&lt;br /&gt;
  }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=Additional References=&lt;br /&gt;
&lt;br /&gt;
The bulk of this style guide focuses on syntax rather than good programming practices. The following list are reference materials for best practices on writing portable, efficient, and clean TypeScript:&lt;br /&gt;
&lt;br /&gt;
* [https://www.typescriptlang.org/docs/handbook/basic-types.html TypeScript Hand Book]&lt;/div&gt;</summary>
		<author><name>Kman</name></author>
		
	</entry>
	<entry>
		<id>https://wiki.spiretrading.com/index.php?title=TypeScript_Style_Guide&amp;diff=50</id>
		<title>TypeScript Style Guide</title>
		<link rel="alternate" type="text/html" href="https://wiki.spiretrading.com/index.php?title=TypeScript_Style_Guide&amp;diff=50"/>
		<updated>2018-09-04T02:47:44Z</updated>

		<summary type="html">&lt;p&gt;Kman: /* Directory Structure */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;This article specifies the most general guidelines used for all Spire projects written using TypeScript as the primary programming language. Each individual project may extend or override the guidelines specified herein. The overall aim of this guideline is to provide consistency across the numerous projects developed by Spire in order to promote and benefit from modern web development practices as well as tailor them to our specific requirements.&lt;br /&gt;
&lt;br /&gt;
In general, the guidelines are very specific and opinionated. This is done intentionally to ensure that every detail has been given proper consideration and that every line of code is written with care and diligence. It is taken as a prerequisite that writing robust, clean and maintainable code requires paying close attention to even the smallest of details. As such, when there are two or more ways to write or express any given statement or expression, be it using spaces or tabs, number of characters per line, purple or violet, the guideline will often require that one particular approach be used to the exclusion of others.&lt;br /&gt;
&lt;br /&gt;
Finally, this document is constantly evolving and as such older projects may not be up-to-date with the guidelines found here. In those circumstances one must use their best judgment about how to integrate these guidelines into older codebases. As a general principle, consistency should favor the local over the global, that is it is more important to be consistent with a function definition than within a file, and more important to be consistent within a file than within a directory, project, etc...&lt;br /&gt;
&lt;br /&gt;
=Development Environment=&lt;br /&gt;
&lt;br /&gt;
The primary operating systems supported by Spire projects are Ubuntu 18.02 LTS, Windows 10, and macOS. On all systems, nodejs is used as the build system and webpack is used as the bundler.&lt;br /&gt;
&lt;br /&gt;
For source control, git is used and projects are to be hosted on [https://github.com/spiretrading Spire Trading's Github page].&lt;br /&gt;
&lt;br /&gt;
Each developer is welcome to use an editor of their choice, however [https://code.visualstudio.com/ Visual Studio Code] is recommended.&lt;br /&gt;
&lt;br /&gt;
=File Names=&lt;br /&gt;
&lt;br /&gt;
Use [https://en.wikipedia.org/wiki/Snake_case snake case] using all lower case letters for files and directories. The name of a file should correspond to the primary class that it exports.&lt;br /&gt;
&lt;br /&gt;
The default extension for TypeScript files is ''ts''&lt;br /&gt;
&lt;br /&gt;
The extension used for TypeScript files containing JSX is ''tsx''&lt;br /&gt;
&lt;br /&gt;
All files end with a single new line character.&lt;br /&gt;
&lt;br /&gt;
=Directory Structure=&lt;br /&gt;
&lt;br /&gt;
A project is broken down into a library component, a test component, and one or more application components. These components are referred to as ''artifacts''. The applications go into their own ''applications'' directory and the libraries into the ''library'' directory. Within each artifact is a ''build'' directory containing the build scripts needed to build that artifact. Scripts for POSIX systems are found in the ''posix'' sub-directory and Windows build files are within the ''windows'' sub-directory. The build scripts specified are ''setup'' to download and install any dependencies needed to produce the artifact and the ''build'' script which produces the artifact. Typically the ''setup'' script is run only once or when a new dependency is introduced to the project, and the ''build'' script is run anytime a new build is needed.&lt;br /&gt;
&lt;br /&gt;
Finally there is a top-level ''build'' directory for the project as a whole which produces all artifacts by recursively calling each artifact's individual build scripts. Additionally the top-level build directory also includes a ''setup'' script which downloads all third party dependencies. Some projects may also opt to include an ''install'' script which sets up a suitable development environment, and other scripts for continuous builds, deployment and testing.&lt;br /&gt;
&lt;br /&gt;
Assuming a project named sudoku the following directory structure should be used:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
sudoku                             # Root level directory.&lt;br /&gt;
  build.sh                         # Script used to build all projects on POSIX.&lt;br /&gt;
  build.bat                        # Script used to build all projects on Windows.&lt;br /&gt;
  \applications                    # Contains all applications.&lt;br /&gt;
    \sudoku                        # Contains the source for the sudoku web application.&lt;br /&gt;
      package.json                 # The Node JS package description.&lt;br /&gt;
      tsconfig.json                # The TypeScript compiler configuration.&lt;br /&gt;
      webpack.config.js            # The Webpack configuration.&lt;br /&gt;
      build.sh                     # Script used to build application on POSIX.&lt;br /&gt;
      build.bat                    # Script used to build application Windows.&lt;br /&gt;
      \source                      # Contains the web application source files.&lt;br /&gt;
        \index.html                # The HTML file that loads the JavaScript application.&lt;br /&gt;
        \index.tsx                 # The TypeScript/JSX file containing the application.&lt;br /&gt;
  \library                         # Contains the common library code.&lt;br /&gt;
    package.json                   # The Node JS package description.&lt;br /&gt;
    tsconfig.json                  # The TypeScript compiler configuration.&lt;br /&gt;
    webpack.config.js              # The Webpack configuration.&lt;br /&gt;
    build.sh                       # Script used to build library on POSIX.&lt;br /&gt;
    build.bat                      # Script used to build library on Windows.&lt;br /&gt;
    \source                        # Contains the library source files.&lt;br /&gt;
      index.ts                     # Exports all definitions contained in this directory.&lt;br /&gt;
      \pages                       # Contains the source code for individual web pages.&lt;br /&gt;
        index.ts                   # Exports all definitions for every web page defined&lt;br /&gt;
                                   # in this directory.&lt;br /&gt;
        \landing_page              # Contains the source code for the landing page.&lt;br /&gt;
          index.ts                 # Exports the landing page.&lt;br /&gt;
          landing_page.tsx         # The TypeScript/JSX source code for the landing page.&lt;br /&gt;
        \page_2                    # Contains the source for for another web page.&lt;br /&gt;
          ...                      # Structured in a similar manner as the landing page.&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
An example of the above directory structure containing a basic skeletal implementation of all files can be found here: https://github.com/spiretrading/sudoku&lt;br /&gt;
&lt;br /&gt;
=Syntax=&lt;br /&gt;
&lt;br /&gt;
==Indentation==&lt;br /&gt;
Code is indented using 2 spaces per level, tabs are not permitted.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=typescript line=line&amp;gt;&lt;br /&gt;
function factorial(n: number): number {&lt;br /&gt;
  if(n == 0) {&lt;br /&gt;
    return 1;&lt;br /&gt;
  }&lt;br /&gt;
  return n * factorial(n - 1);&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Line Structure==&lt;br /&gt;
&lt;br /&gt;
Statements must end with a semi-colon ';' or a closing brace '}', even in cases where TypeScript allows them to be optional.&lt;br /&gt;
&lt;br /&gt;
Lines are limited to 80 characters. Exceptions to this rule are long imports and long string literals where breaking up the literal into multiple lines is not possible. In order to break up long statements into multiple lines the following rules are used:&lt;br /&gt;
&lt;br /&gt;
* Break the line at a comma, operator or opening bracket.&lt;br /&gt;
&amp;lt;syntaxhighlight lang=typescript line=line&amp;gt;&lt;br /&gt;
&lt;br /&gt;
// Correct, line break at comma.&lt;br /&gt;
f(a, ..., b,&lt;br /&gt;
  c, ..., d);&lt;br /&gt;
&lt;br /&gt;
// Incorrect, line break after expression.&lt;br /&gt;
f(a, ..., b&lt;br /&gt;
  , c, ..., d);&lt;br /&gt;
&lt;br /&gt;
// Correct, line break after operator.&lt;br /&gt;
a + ... + b +&lt;br /&gt;
  c + ... + d;&lt;br /&gt;
&lt;br /&gt;
// Incorrect, line break after expression.&lt;br /&gt;
a + ... + b&lt;br /&gt;
  + c + ... + d;&lt;br /&gt;
&lt;br /&gt;
// Correct, line break after opening bracket.&lt;br /&gt;
f(&lt;br /&gt;
  a, ..., b, c, ..., d);&lt;br /&gt;
&lt;br /&gt;
// Incorrect, line break after function name.&lt;br /&gt;
f&lt;br /&gt;
  (a, ..., b, c, ..., d);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* For statements that begin new blocks of code (such as if/while/class...), in order to avoid confusing the line continuation with the code block, the line continuation is indented two extra levels. For example consider the following snippet of code:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=typescript line=line&amp;gt;&lt;br /&gt;
// Incorrect.&lt;br /&gt;
if(condition_a &amp;amp;&amp;amp; condition_b &amp;amp;&amp;amp; ... &amp;amp;&amp;amp;&lt;br /&gt;
  condition_c) {&lt;br /&gt;
  console.log('meow');&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The line continuation on line 2 clashes with the code block on line 3. To avoid this clash the above code is indented as follows:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=typescript line=line&amp;gt;&lt;br /&gt;
// Correct.&lt;br /&gt;
if(condition_a &amp;amp;&amp;amp; condition_b &amp;amp;&amp;amp; ... &amp;amp;&amp;amp;&lt;br /&gt;
    condition_c) {&lt;br /&gt;
  console.log('meow');&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The extra level of indentation in the line continuation makes it clear where the condition ends and the code block begins.&lt;br /&gt;
&lt;br /&gt;
==Braces==&lt;br /&gt;
&lt;br /&gt;
Braces are placed using a variant of the [http://wiki.c2.com/?OneTrueBraceStyle OTBS style]. The opening brace is placed on the same line as the declaring statement with one single space preceding it, and the closing brace is placed on a line of its own at the same level of indentation as the declaring statement. For if statements, the else/else if is placed on the same line as the closing brace. For do/while loops, the while is placed on the same line as the closing brace.&lt;br /&gt;
&lt;br /&gt;
Examples:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=typescript line=line&amp;gt;&lt;br /&gt;
// Correct.&lt;br /&gt;
if(&amp;lt;cond&amp;gt;) {&lt;br /&gt;
  &amp;lt;body&amp;gt;&lt;br /&gt;
} else {&lt;br /&gt;
  &amp;lt;default&amp;gt;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
// Correct.&lt;br /&gt;
do {&lt;br /&gt;
  &amp;lt;body&amp;gt;&lt;br /&gt;
} while(&amp;lt;cond&amp;gt;);&lt;br /&gt;
&lt;br /&gt;
// Incorrect.&lt;br /&gt;
if(&amp;lt;cond&amp;gt;)&lt;br /&gt;
{&lt;br /&gt;
  &amp;lt;body&amp;gt;&lt;br /&gt;
}&lt;br /&gt;
else&lt;br /&gt;
{&lt;br /&gt;
  &amp;lt;default&amp;gt;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
// Incorrect.&lt;br /&gt;
do&lt;br /&gt;
{&lt;br /&gt;
  &amp;lt;body&amp;gt;&lt;br /&gt;
}&lt;br /&gt;
while(&amp;lt;cond&amp;gt;);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Spacing==&lt;br /&gt;
&lt;br /&gt;
The following are correct use cases for white spaces:&lt;br /&gt;
&lt;br /&gt;
* Used for indentation.&lt;br /&gt;
* Used to surround binary operations.&lt;br /&gt;
&amp;lt;syntaxhighlight lang=typescript line=line&amp;gt;&lt;br /&gt;
// Correct.&lt;br /&gt;
const x = a + b;&lt;br /&gt;
const y = 5;&lt;br /&gt;
&lt;br /&gt;
//! Incorrect&lt;br /&gt;
const x = a+b;&lt;br /&gt;
const y=5;&lt;br /&gt;
const z= 5;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* One space is placed after a comma.&lt;br /&gt;
&amp;lt;syntaxhighlight lang=typescript line=line&amp;gt;&lt;br /&gt;
// Correct.&lt;br /&gt;
f(1, 2);&lt;br /&gt;
function g(a: number, b: number): number;&lt;br /&gt;
&lt;br /&gt;
//! Incorrect&lt;br /&gt;
f(1,2);&lt;br /&gt;
function g(a:number,b:number);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Naming==&lt;br /&gt;
&lt;br /&gt;
[https://en.wikipedia.org/wiki/Camel_case Camel case] is used for naming where variables and functions use mixedCase and namespaces, modules, and types use CapWords. Names should be descriptive but should avoid being verbose.&lt;br /&gt;
&lt;br /&gt;
Classes and variables should be given the name of a noun and functions the name of a verb. Functions that return a boolean or boolean variables should be named in the form of a question starting with isX or hasX.&lt;br /&gt;
&lt;br /&gt;
==Imports==&lt;br /&gt;
Imports are listed in order of most global to local. Where dependencies have the same locality, then they are ordered alphabetically. For example, the first group of dependencies to be imported are third party packages which are listed in alphabetical order based on the package name. In the above snippet the third party dependencies are jquery, react and react-router-dom which are imported in alphabetical order. Then local dependencies are imported where directories further up the hierarchy are imported first. That is, the directory '../../..' which is three levels up is imported before the directory '..' which is only one level up.&lt;br /&gt;
&lt;br /&gt;
When multiple names are imported from a package, they must be listed in alphabetical order.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=typescript line=line&amp;gt;&lt;br /&gt;
import * as $ from 'jquery';&lt;br /&gt;
import * as React from 'react';&lt;br /&gt;
import * as Router from 'react-router-dom';&lt;br /&gt;
import {HBoxLayout, Padding, VBoxLayout} from '../../..';&lt;br /&gt;
import {Model} from '..';&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Declarations==&lt;br /&gt;
&lt;br /&gt;
Any declaration (such as a function or class) that is intended to be imported by another file must be documented using [http://usejsdoc.org/ JSDoc style]. If the definition is local then that documentation should be omitted entirely.&lt;br /&gt;
&lt;br /&gt;
Any documentation should be preceded by a blank line. In the code snippet, Properties is part of the public API so it is documented along with all of its fields, but the State is internal to the file so no aspect of it is documented.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=typescript line=line&amp;gt;&lt;br /&gt;
&lt;br /&gt;
/** Stores the React properties used to render a Page. */&lt;br /&gt;
export interface Properties {&lt;br /&gt;
&lt;br /&gt;
  /** The model used to display the page. */&lt;br /&gt;
  model: Model;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
export interface State {&lt;br /&gt;
  redirect: string;&lt;br /&gt;
  isLoading: boolean;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Variable Declarations==&lt;br /&gt;
&lt;br /&gt;
Variables are declared so that only one variable is declared per line, prefer declaring variables using ''const'' when possible, and deferring to ''let'' otherwise, variables should always be initialized at the point of their declaration.&lt;br /&gt;
&lt;br /&gt;
For complex initialization of values, use an [https://en.wikipedia.org/wiki/Immediately-invoked_function_expression immediately invoked lambda expression] as follows:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=typescript line=line&amp;gt;&lt;br /&gt;
const value = (() =&amp;gt; {&lt;br /&gt;
  if(condition) {&lt;br /&gt;
    return 123;&lt;br /&gt;
  }&lt;br /&gt;
  return 321;&lt;br /&gt;
})();&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=Example=&lt;br /&gt;
&lt;br /&gt;
Below is a full example combining numerous elements of the style guide to define a typical React component. It should be used as a general reference for how code is laid out, structured, and properly spaced.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=typescript line=line&amp;gt;&lt;br /&gt;
import * as $ from 'jquery';&lt;br /&gt;
import * as React from 'react';&lt;br /&gt;
import * as Router from 'react-router-dom';&lt;br /&gt;
import {HBoxLayout, Padding, VBoxLayout} from '..';&lt;br /&gt;
import {Model} from '.';&lt;br /&gt;
&lt;br /&gt;
/** Stores the React properties used to render a Page. */&lt;br /&gt;
export interface Properties {&lt;br /&gt;
&lt;br /&gt;
  /** The model used to display the page. */&lt;br /&gt;
  model: Model;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
export interface State {&lt;br /&gt;
  redirect: string;&lt;br /&gt;
  isLoading: boolean;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/** Displays an HTML page. */&lt;br /&gt;
export class Page extends React.Component&amp;lt;Properties, State&amp;gt; {&lt;br /&gt;
  constructor(props: Properties) {&lt;br /&gt;
    super(props);&lt;br /&gt;
    this.state = {&lt;br /&gt;
      redirect: '',&lt;br /&gt;
      isLoading: true&lt;br /&gt;
    };&lt;br /&gt;
  }&lt;br /&gt;
&lt;br /&gt;
  public componentWillMount(): void {&lt;br /&gt;
    this.props.model.load().then(&lt;br /&gt;
      () =&amp;gt; {&lt;br /&gt;
        this.setState({&lt;br /&gt;
          isLoading: false&lt;br /&gt;
        });&lt;br /&gt;
      });&lt;br /&gt;
  }&lt;br /&gt;
&lt;br /&gt;
  public render(): JSX.Element {&lt;br /&gt;
    if(this.state.redirect) {&lt;br /&gt;
      return &amp;lt;Router.Redirect push to={this.state.redirect}/&amp;gt;;&lt;br /&gt;
    } else if(this.state.isLoading) {&lt;br /&gt;
      return &amp;lt;LoadingPage/&amp;gt;;&lt;br /&gt;
    }&lt;br /&gt;
    const style = {&lt;br /&gt;
      backgroundColor: '#FFFFFF',&lt;br /&gt;
      font: 'Roboto 14px'&lt;br /&gt;
    };&lt;br /&gt;
    return (&lt;br /&gt;
      &amp;lt;div style={style}&amp;gt;&lt;br /&gt;
        &amp;lt;h1&amp;gt;Hello world!&amp;lt;/h1&amp;gt;&lt;br /&gt;
        &amp;lt;img src='cat.jpg'/&amp;gt;&lt;br /&gt;
      &amp;lt;/div&amp;gt;);&lt;br /&gt;
  }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=Additional References=&lt;br /&gt;
&lt;br /&gt;
The bulk of this style guide focuses on syntax rather than good programming practices. The following list are reference materials for best practices on writing portable, efficient, and clean TypeScript:&lt;br /&gt;
&lt;br /&gt;
* [https://www.typescriptlang.org/docs/handbook/basic-types.html TypeScript Hand Book]&lt;/div&gt;</summary>
		<author><name>Kman</name></author>
		
	</entry>
	<entry>
		<id>https://wiki.spiretrading.com/index.php?title=C%2B%2B_Style_Guide&amp;diff=49</id>
		<title>C++ Style Guide</title>
		<link rel="alternate" type="text/html" href="https://wiki.spiretrading.com/index.php?title=C%2B%2B_Style_Guide&amp;diff=49"/>
		<updated>2018-08-02T14:59:38Z</updated>

		<summary type="html">&lt;p&gt;Kman: /* Namespaces */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;This article specifies the most general guidelines used for all Spire projects written using C++ as the primary programming language. Each individual project may extend or override the guidelines specified herein. The overall aim of this guideline is to provide consistency across the numerous projects developed by Spire in order to promote and benefit from modern C++ practices as well as tailor them to our specific requirements.&lt;br /&gt;
&lt;br /&gt;
In general, the guidelines are very specific and opinionated. This is done intentionally to ensure that every detail has been given proper consideration and that every line of code is written with care and diligence. It is taken as a prerequisite that writing robust, clean and maintainable code requires paying close attention to even the smallest of details. As such, when there are two or more ways to write or express any given statement or expression, be it using spaces or tabs, number of characters per line, purple or violet, the guideline will often require that one particular approach be used to the exclusion of others.&lt;br /&gt;
&lt;br /&gt;
Finally, this document is constantly evolving and as such older projects may not be up-to-date with the guidelines found here. In those circumstances one must use their best judgment about how to integrate these guidelines into older codebases. As a general principle, consistency should favor the local over the global, that is it is more important to be consistent with a function definition than within a file, and more important to be consistent within a file than within a directory, project, etc...&lt;br /&gt;
&lt;br /&gt;
=Core Guidelines=&lt;br /&gt;
This document should be seen as an extension to the Cpp Core Guidelines authored and maintained by Herb Sutter and Bjarne Stroustrup. After reviewing these guidelines one should then become familiar with the Cpp Core Guidelines as documented here:&lt;br /&gt;
&lt;br /&gt;
https://github.com/isocpp/CppCoreGuidelines&lt;br /&gt;
&lt;br /&gt;
Those guidelines specify the best practices for writing modern C++ code. In situations where there is a conflict between the Cpp Core Guidelines and the guidelines set forth in this document, this document takes precedence. For all known situations where a conflict exists, this document should explicitly indicate that conflict to avoid confusion.&lt;br /&gt;
&lt;br /&gt;
=Development Environment=&lt;br /&gt;
&lt;br /&gt;
The two primary development environments supported by Spire projects are Ubuntu Server 18.04 LTS and Windows 10. On POSIX systems the compiler of choice is g++ 7.3 and on Windows 10 it's Microsoft Visual Studio 2017 15.7.5. In order to support these two platforms, CMake is used to produce the appropriate project/make files for each platform.&lt;br /&gt;
&lt;br /&gt;
For source control, git is used and projects are to be hosted on [https://github.com/spiretrading Spire Trading's Github page].&lt;br /&gt;
&lt;br /&gt;
Each developer is welcome to use an editor of their choice. [https://www.visualstudio.com/downloads/ Visual Studio 2017] is typically used for Windows and [https://code.visualstudio.com/ Visual Studio Code] is typically used on Linux and Mac.&lt;br /&gt;
&lt;br /&gt;
=File Names=&lt;br /&gt;
&lt;br /&gt;
Use [https://en.wikipedia.org/wiki/Snake_case snake case] using all lower case letters for files and directories. The main exception is for CMake files which must use the name ''CMakeLists.txt''&lt;br /&gt;
&lt;br /&gt;
Header files should use the extension ''hpp''&lt;br /&gt;
&lt;br /&gt;
Source files should use the extension ''cpp''&lt;br /&gt;
&lt;br /&gt;
All files end with a single new line character.&lt;br /&gt;
&lt;br /&gt;
=Directory Structure=&lt;br /&gt;
&lt;br /&gt;
A project is broken down into one library component and one or more application components. These components are referred to as ''artifacts''. The library is written in a [https://en.wikipedia.org/wiki/Header-only header-only fashion], that is the implementation is provided directly in the header file rather than a separate .cpp source file. This allows for such libraries to easily be incorporated into other projects without the need for complex build configurations. Applications often use a mix of header only files and source files.&lt;br /&gt;
&lt;br /&gt;
The applications go into their own ''applications'' directory and the libraries into the ''library'' directory. Within each artifact is a ''build'' directory containing the build scripts and CMake files needed to build that artifact. Scripts for POSIX systems are found in the ''posix'' sub-directory and Windows build files are within the ''windows'' sub-directory. The build scripts specified are ''run_cmake'' to produce the platform specific build files (make files for POSIX and VS solutions for Windows), ''version'' to produce a header file that contains the version of the artifact produced and the ''build'' script which produces the artifact. In order to build an artifact, one first produces the build files for their platform by running the ''run_cmake'' script, and then they can run the ''build'' script afterwards to produce the artifact.&lt;br /&gt;
&lt;br /&gt;
Finally there is a top-level ''build'' directory for the project as a whole which produces all artifacts by recursively calling each artifact's individual build scripts. Additionally the top-level build directory also includes a ''setup'' script which downloads all third party dependencies. Some projects may also opt to include an ''install'' script which sets up a suitable development environment, and other scripts for continuous builds, deployment and testing.&lt;br /&gt;
&lt;br /&gt;
Assuming a project named tic_tac_toe consisting of applications tic_tac_toe_console and tic_tac_toe_ui sharing code common to both applications, the following directory structure should be used:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
tic_tac_toe                        # Root level directory.&lt;br /&gt;
  \applications                    # Contains all applications.&lt;br /&gt;
    \tic_tac_toe_console           # Contains the source for a console application.&lt;br /&gt;
      \build                       # Files/scripts used to build the console tic-tac-toe game.&lt;br /&gt;
        \config                    # Contains all CMake build files.&lt;br /&gt;
          CMakeLists.txt           # The CMake config file for the overall application.&lt;br /&gt;
          \tic_tac_toe_console     # Contains CMake build files for the main executable.&lt;br /&gt;
            \CMakeLists.txt        # The CMake config file for the executable.&lt;br /&gt;
        \posix                     # Contains scripts to build on POSIX systems.&lt;br /&gt;
          \build.sh                # Script used to build the application.&lt;br /&gt;
          \run_cmake.sh            # Script used to produce the make/build files.&lt;br /&gt;
          \set_env.sh              # Script defining the environment variables.&lt;br /&gt;
          \version.sh              # Script that produces the VERSION stamped header file.&lt;br /&gt;
        \windows                   # Contains scripts to build on Windows.&lt;br /&gt;
          \build.bat               # Script used to build the application.&lt;br /&gt;
          \run_cmake.bat           # Script used to produce the VS solution.&lt;br /&gt;
          \set_env.bat             # Script defining environment variables.&lt;br /&gt;
          \version.bat             # Script that produces the VERSION stamped header file.&lt;br /&gt;
      \source                      # Contains the C++ source files.&lt;br /&gt;
        \tic_tac_toe_console       # Contains the file defining the main function.&lt;br /&gt;
          \main.cpp                # Defines the main function.&lt;br /&gt;
        \source_dir_a              # Contains additional source files specific the console.&lt;br /&gt;
          \source_a.cpp            # C++ source code files.&lt;br /&gt;
          \source_b.cpp&lt;br /&gt;
          \source_c.cpp&lt;br /&gt;
        \source_dir_b              # Contains additional source files specific the console.&lt;br /&gt;
          \source_d.cpp&lt;br /&gt;
          \source_e.cpp&lt;br /&gt;
          \source_f.cpp&lt;br /&gt;
    \tic_tac_toe_ui                # Contains a GUI version of tic-tac-toe.&lt;br /&gt;
      \...                         # The structure is similar to the console application.&lt;br /&gt;
  \build                           # Contains build scripts to build the entire project.&lt;br /&gt;
    \posix                         # Contains scripts to build on POSIX systems.&lt;br /&gt;
      \build.sh                    # Builds all libraries and applications.&lt;br /&gt;
      \local_build.sh              # A helper script containing common build functions.&lt;br /&gt;
      \run_cmake.sh                # Produces all project make/build files.&lt;br /&gt;
      \setup.sh                    # Installs all third party dependencies.&lt;br /&gt;
    \windows                       # Contains scripts to build on Windows.&lt;br /&gt;
      \build.bat                   # Builds all libraries and applications.&lt;br /&gt;
      \run_cmake.bat               # Produces all VS solutions.&lt;br /&gt;
      \setup.bat                   # Installs all third party dependencies.&lt;br /&gt;
  \library                         # Contains the common library code.&lt;br /&gt;
    \build                         # Files/script used to build the library.&lt;br /&gt;
      \config                      # Contains all CMake build files.&lt;br /&gt;
        \CMakeLists.txt            # The CMake config file for the library.&lt;br /&gt;
        \dir_a                     # Contains CMake build files for library component A.&lt;br /&gt;
          \CMakeLists.txt          # The CMake config file to build component A and unit tests.&lt;br /&gt;
        \dir_b                     # Contains CMake build files for library component B.&lt;br /&gt;
          \CMakeLists.txt          # The CMake config file to build component B and unit tests.&lt;br /&gt;
      \posix                       # Contains scripts to build on POSIX systems.&lt;br /&gt;
        \build.sh                  # Script used to build the library.&lt;br /&gt;
        \run_cmake.sh              # Script used to produce make/build files.&lt;br /&gt;
        \set_env.sh                # Script defining the environment variables.&lt;br /&gt;
      \windows                     # Contains scripts to build on Windows.&lt;br /&gt;
        \build.bat                 # Script to build the library.&lt;br /&gt;
        \run_cmake.bat             # Script to produce the VS solution.&lt;br /&gt;
        \set_env.bat               # Script defining the environment variables.&lt;br /&gt;
    \include                       # Contains the library header files (.hpp)&lt;br /&gt;
      \tic_tac_toe&lt;br /&gt;
        \tic_tac_toe               # Contains the top-most generic library header files.&lt;br /&gt;
          \tic_tac_toe.hpp         # Header file containing generic forward declarations.&lt;br /&gt;
        \dir_a                     # Contains header files for library component A.&lt;br /&gt;
          \a.hpp                   # Header file containing forward declarations for component A.&lt;br /&gt;
          \a_header_1.hpp          # Header file for library component A.&lt;br /&gt;
          \a_header_2.hpp&lt;br /&gt;
          \a_header_3.hpp&lt;br /&gt;
        \dir_b&lt;br /&gt;
          \b.hpp                   # Header file containing forward declarations for component B.&lt;br /&gt;
          \b_header_1.hpp          # Contains header files for library component B.&lt;br /&gt;
          \b_header_2.hpp&lt;br /&gt;
          \b_header_3.hpp&lt;br /&gt;
    \source                        # Contains the library source files (.cpp)&lt;br /&gt;
      \tic_tac_toe                 # Dummy directory for the overall library.&lt;br /&gt;
        \dummy.cpp                 # Dummy source code file.&lt;br /&gt;
      \dir_a                       # Dummy directory for library component A.&lt;br /&gt;
        \dummy.cpp                 # Dummy source file.&lt;br /&gt;
      \dir_a_tester                # Contains unit tests for library component A.&lt;br /&gt;
        \a_header_1_tester.cpp     # Contains unit tests for definitions in a_header_1.hpp&lt;br /&gt;
        \a_header_2_tester.cpp&lt;br /&gt;
        \a_header_3_tester.cpp&lt;br /&gt;
        \main.cpp                  # The entry point for component A unit tests.&lt;br /&gt;
      \dir_b                       # Dummy directory for library component B.&lt;br /&gt;
        \dummy.cpp                 # Dummy source file.&lt;br /&gt;
      \dir_b_tester                # Contains unit tests for library component B.&lt;br /&gt;
        \b_header_1_tester.cpp     # Contains unit tests for definitions in b_header_a.hpp&lt;br /&gt;
        \b_header_2_tester.cpp&lt;br /&gt;
        \b_header_3_tester.cpp&lt;br /&gt;
        \main.cpp                  # The entry point for component B unit tests.&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
An example of the above directory structure containing a basic skeletal implementation of all files can be found here: https://github.com/spiretrading/tic_tac_toe&lt;br /&gt;
&lt;br /&gt;
=Header File Structure=&lt;br /&gt;
&lt;br /&gt;
==Include Guard==&lt;br /&gt;
Header files are structured first with an [https://en.wikipedia.org/wiki/Include_guard include guard] defined using capital letter snake case whose name consists of the project name appended to the directory name and finally the file name itself. As a note, all files end with a single new line character.&lt;br /&gt;
&amp;lt;syntaxhighlight lang=c++ line=line&amp;gt;&lt;br /&gt;
#ifndef CPP_CHAT_SERVER_HPP&lt;br /&gt;
#define CPP_CHAT_SERVER_HPP&lt;br /&gt;
  ...&lt;br /&gt;
#endif&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Include Directives==&lt;br /&gt;
Next come the list of #include directives. Include files are ordered based on their category where the first category is standard C++ header files, the second category is external dependency header files, and finally the third category is project header files. Both standard and external dependency header files use angle brackets (#include &amp;lt;...&amp;gt;) and local project header files use quotes (#include &amp;quot;...&amp;quot;). Within each category files are listed in alphabetical order.&lt;br /&gt;
&amp;lt;syntaxhighlight lang=c++ line=line&amp;gt;&lt;br /&gt;
#include &amp;lt;tuple&amp;gt;&lt;br /&gt;
#include &amp;lt;vector&amp;gt;&lt;br /&gt;
#include &amp;lt;boost/noncopyable.hpp&amp;gt;&lt;br /&gt;
#include &amp;quot;cpp_chat/cpp_chat.hpp&amp;quot;&lt;br /&gt;
#include &amp;quot;cpp_chat/definitions.hpp&amp;quot;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Namespaces==&lt;br /&gt;
After include directives the project's namespace is defined. All declarations and definitions must be contained within a namespace so as to avoid polluting the global namespace. Namespace definitions should be preceded by one single new line except when immediately following a namespace definition. The top level namespace is named after the project, and sub-namespaces may be used (although they should be used very sparingly).&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=c++ line=line&amp;gt;&lt;br /&gt;
namespace CppChat {&lt;br /&gt;
namespace SubChatA {&lt;br /&gt;
  ...&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
namespace SubChatB {&lt;br /&gt;
namespace SubSubChatA {&lt;br /&gt;
  ...&lt;br /&gt;
}&lt;br /&gt;
}&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
namespace CppChatExtra {&lt;br /&gt;
  ...&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
One situation where nested namespaces are welcome and encouraged are for implementation details that do not form part of the namespace's public interface. These definitions are put in a nested namespace called ''Details'' and go into a file of their own whose name contains the suffix ''details''. For example if the ''cpp_chat_server.hpp'' contains implementation details, then they should be included in the file ''cpp_chat_server_details.hpp'' and the definitions should go into the namespace ''CppChat::Details''.&lt;br /&gt;
&lt;br /&gt;
=Layout=&lt;br /&gt;
&lt;br /&gt;
==Indentation==&lt;br /&gt;
Code is indented using 2 spaces per level, tabs are not permitted.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=c++ line=line&amp;gt;&lt;br /&gt;
int factorial(int n) {&lt;br /&gt;
  if(n == 0) {&lt;br /&gt;
    return 1;&lt;br /&gt;
  }&lt;br /&gt;
  return n * factorial(n - 1);&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Line Structure==&lt;br /&gt;
Lines are limited to 80 characters. Exceptions to this rule are long include files and long string literals where breaking up the literal into multiple lines is not possible. In order to break up long statements into multiple lines the following rules are used:&lt;br /&gt;
&lt;br /&gt;
* Break the line at a comma, operator or opening bracket.&lt;br /&gt;
&amp;lt;syntaxhighlight lang=c++ line=line&amp;gt;&lt;br /&gt;
&lt;br /&gt;
// Correct, line break at comma.&lt;br /&gt;
f(a, ..., b,&lt;br /&gt;
  c, ..., d);&lt;br /&gt;
&lt;br /&gt;
// Incorrect, line break after expression.&lt;br /&gt;
f(a, ..., b&lt;br /&gt;
  , c, ..., d);&lt;br /&gt;
&lt;br /&gt;
// Correct, line break after operator.&lt;br /&gt;
a + ... + b +&lt;br /&gt;
  c + ... + d;&lt;br /&gt;
&lt;br /&gt;
// Incorrect, line break after expression.&lt;br /&gt;
a + ... + b&lt;br /&gt;
  + c + ... + d;&lt;br /&gt;
&lt;br /&gt;
// Correct, line break after opening bracket.&lt;br /&gt;
f(&lt;br /&gt;
  a, ..., b, c, ..., d);&lt;br /&gt;
&lt;br /&gt;
// Incorrect, line break after function name.&lt;br /&gt;
f&lt;br /&gt;
  (a, ..., b, c, ..., d);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* For statements that begin new blocks of code (such as if/while/class...), in order to avoid confusing the line continuation with the code block, the line continuation is indented two extra levels. For example consider the following snippet of code:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=c++ line=line&amp;gt;&lt;br /&gt;
// Incorrect.&lt;br /&gt;
if(condition_a &amp;amp;&amp;amp; condition_b &amp;amp;&amp;amp; ... &amp;amp;&amp;amp;&lt;br /&gt;
  condition_c) {&lt;br /&gt;
  std::cout &amp;lt;&amp;lt; &amp;quot;meow&amp;quot; &amp;lt;&amp;lt; std::endl;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The line continuation on line 2 clashes with the code block on line 3. To avoid this clash the above code is indented as follows:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=c++ line=line&amp;gt;&lt;br /&gt;
// Correct.&lt;br /&gt;
if(condition_a &amp;amp;&amp;amp; condition_b &amp;amp;&amp;amp; ... &amp;amp;&amp;amp;&lt;br /&gt;
    condition_c) {&lt;br /&gt;
  std::cout &amp;lt;&amp;lt; &amp;quot;meow&amp;quot; &amp;lt;&amp;lt; std::endl;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The extra level of indentation in the line continuation makes it clear where the condition ends and the code block begins.&lt;br /&gt;
&lt;br /&gt;
==Braces==&lt;br /&gt;
&lt;br /&gt;
Braces are placed using a variant of the [http://wiki.c2.com/?OneTrueBraceStyle OTBS style]. The opening brace is placed on the same line as the declaring statement with one single space preceding it, and the closing brace is placed on a line of its own at the same level of indentation as the declaring statement. For if statements, the else/else if is placed on the same line as the closing brace. For do/while loops, the while is placed on the same line as the closing brace.&lt;br /&gt;
&lt;br /&gt;
Examples:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=c++ line=line&amp;gt;&lt;br /&gt;
// Correct.&lt;br /&gt;
if(&amp;lt;cond&amp;gt;) {&lt;br /&gt;
  &amp;lt;body&amp;gt;&lt;br /&gt;
} else {&lt;br /&gt;
  &amp;lt;default&amp;gt;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
// Correct.&lt;br /&gt;
do {&lt;br /&gt;
  &amp;lt;body&amp;gt;&lt;br /&gt;
} while(&amp;lt;cond&amp;gt;);&lt;br /&gt;
&lt;br /&gt;
// Incorrect.&lt;br /&gt;
if(&amp;lt;cond&amp;gt;)&lt;br /&gt;
{&lt;br /&gt;
  &amp;lt;body&amp;gt;&lt;br /&gt;
}&lt;br /&gt;
else&lt;br /&gt;
{&lt;br /&gt;
  &amp;lt;default&amp;gt;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
// Incorrect.&lt;br /&gt;
do&lt;br /&gt;
{&lt;br /&gt;
  &amp;lt;body&amp;gt;&lt;br /&gt;
}&lt;br /&gt;
while(&amp;lt;cond&amp;gt;);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Spacing==&lt;br /&gt;
&lt;br /&gt;
The following are correct use cases for white spaces:&lt;br /&gt;
&lt;br /&gt;
* Used for indentation.&lt;br /&gt;
* Used to surround binary operations.&lt;br /&gt;
&amp;lt;syntaxhighlight lang=c++ line=line&amp;gt;&lt;br /&gt;
// Correct.&lt;br /&gt;
auto x = a + b;&lt;br /&gt;
auto y = 5;&lt;br /&gt;
&lt;br /&gt;
//! Incorrect&lt;br /&gt;
auto x = a+b;&lt;br /&gt;
auto y=5;&lt;br /&gt;
auto z= 5;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* One space is placed after a comma.&lt;br /&gt;
&amp;lt;syntaxhighlight lang=c++ line=line&amp;gt;&lt;br /&gt;
// Correct.&lt;br /&gt;
f(1, 2);&lt;br /&gt;
int g(int a, int b);&lt;br /&gt;
&lt;br /&gt;
//! Incorrect&lt;br /&gt;
f(1,2);&lt;br /&gt;
int g(int a,int b);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=Syntax=&lt;br /&gt;
&lt;br /&gt;
==Function Definitions==&lt;br /&gt;
&lt;br /&gt;
Functions declared and defined in header files are formatted as follows:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=c++ line=line&amp;gt;&lt;br /&gt;
inline int f() {&lt;br /&gt;
  ...&lt;br /&gt;
  return 123;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
template&amp;lt;typename T&amp;gt;&lt;br /&gt;
bool g() {&lt;br /&gt;
  ...&lt;br /&gt;
  return false;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
That is they are declared as inline unless they are function templates in which case the inline specified is omitted.&lt;br /&gt;
&lt;br /&gt;
==Variable Declarations==&lt;br /&gt;
&lt;br /&gt;
Variables are declared so that only one variable is declared per line, the type of the variable should [https://herbsutter.com/2013/08/12/gotw-94-solution-aaa-style-almost-always-auto/ almost always use auto], and variables should almost always be initialized.&lt;br /&gt;
&lt;br /&gt;
Examples of simple declarations:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=c++ line=line&amp;gt;&lt;br /&gt;
auto x = 5;&lt;br /&gt;
auto y = a + b;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
For complex initialization of values, use an [https://en.wikipedia.org/wiki/Immediately-invoked_function_expression immediately invoked lambda expression] as follows:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=c++ line=line&amp;gt;&lt;br /&gt;
auto value = [&amp;amp;] {&lt;br /&gt;
  if(condition) {&lt;br /&gt;
    return 123;&lt;br /&gt;
  }&lt;br /&gt;
  return 321;&lt;br /&gt;
}();&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=Additional References=&lt;br /&gt;
&lt;br /&gt;
The bulk of this style guide focuses on syntax rather than good programming practices. The following list are reference materials (both online and published) for best practices on writing portable, efficient, and clean C++ code:&lt;br /&gt;
&lt;br /&gt;
* S. Meyers, ''Effective Modern C++''. 2014&lt;br /&gt;
* B. Stroustrup ''The C++ Programming Language (4th Edition)''. 2013&lt;br /&gt;
* [https://github.com/isocpp/CppCoreGuidelines Cpp Core Guidelines]&lt;br /&gt;
* [https://isocpp.org/ Standard C++ Blog]&lt;br /&gt;
* [https://cppcon.org/ CppCon - The C++ Conference]&lt;/div&gt;</summary>
		<author><name>Kman</name></author>
		
	</entry>
	<entry>
		<id>https://wiki.spiretrading.com/index.php?title=C%2B%2B_Style_Guide&amp;diff=48</id>
		<title>C++ Style Guide</title>
		<link rel="alternate" type="text/html" href="https://wiki.spiretrading.com/index.php?title=C%2B%2B_Style_Guide&amp;diff=48"/>
		<updated>2018-08-02T14:59:07Z</updated>

		<summary type="html">&lt;p&gt;Kman: /* Namespaces */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;This article specifies the most general guidelines used for all Spire projects written using C++ as the primary programming language. Each individual project may extend or override the guidelines specified herein. The overall aim of this guideline is to provide consistency across the numerous projects developed by Spire in order to promote and benefit from modern C++ practices as well as tailor them to our specific requirements.&lt;br /&gt;
&lt;br /&gt;
In general, the guidelines are very specific and opinionated. This is done intentionally to ensure that every detail has been given proper consideration and that every line of code is written with care and diligence. It is taken as a prerequisite that writing robust, clean and maintainable code requires paying close attention to even the smallest of details. As such, when there are two or more ways to write or express any given statement or expression, be it using spaces or tabs, number of characters per line, purple or violet, the guideline will often require that one particular approach be used to the exclusion of others.&lt;br /&gt;
&lt;br /&gt;
Finally, this document is constantly evolving and as such older projects may not be up-to-date with the guidelines found here. In those circumstances one must use their best judgment about how to integrate these guidelines into older codebases. As a general principle, consistency should favor the local over the global, that is it is more important to be consistent with a function definition than within a file, and more important to be consistent within a file than within a directory, project, etc...&lt;br /&gt;
&lt;br /&gt;
=Core Guidelines=&lt;br /&gt;
This document should be seen as an extension to the Cpp Core Guidelines authored and maintained by Herb Sutter and Bjarne Stroustrup. After reviewing these guidelines one should then become familiar with the Cpp Core Guidelines as documented here:&lt;br /&gt;
&lt;br /&gt;
https://github.com/isocpp/CppCoreGuidelines&lt;br /&gt;
&lt;br /&gt;
Those guidelines specify the best practices for writing modern C++ code. In situations where there is a conflict between the Cpp Core Guidelines and the guidelines set forth in this document, this document takes precedence. For all known situations where a conflict exists, this document should explicitly indicate that conflict to avoid confusion.&lt;br /&gt;
&lt;br /&gt;
=Development Environment=&lt;br /&gt;
&lt;br /&gt;
The two primary development environments supported by Spire projects are Ubuntu Server 18.04 LTS and Windows 10. On POSIX systems the compiler of choice is g++ 7.3 and on Windows 10 it's Microsoft Visual Studio 2017 15.7.5. In order to support these two platforms, CMake is used to produce the appropriate project/make files for each platform.&lt;br /&gt;
&lt;br /&gt;
For source control, git is used and projects are to be hosted on [https://github.com/spiretrading Spire Trading's Github page].&lt;br /&gt;
&lt;br /&gt;
Each developer is welcome to use an editor of their choice. [https://www.visualstudio.com/downloads/ Visual Studio 2017] is typically used for Windows and [https://code.visualstudio.com/ Visual Studio Code] is typically used on Linux and Mac.&lt;br /&gt;
&lt;br /&gt;
=File Names=&lt;br /&gt;
&lt;br /&gt;
Use [https://en.wikipedia.org/wiki/Snake_case snake case] using all lower case letters for files and directories. The main exception is for CMake files which must use the name ''CMakeLists.txt''&lt;br /&gt;
&lt;br /&gt;
Header files should use the extension ''hpp''&lt;br /&gt;
&lt;br /&gt;
Source files should use the extension ''cpp''&lt;br /&gt;
&lt;br /&gt;
All files end with a single new line character.&lt;br /&gt;
&lt;br /&gt;
=Directory Structure=&lt;br /&gt;
&lt;br /&gt;
A project is broken down into one library component and one or more application components. These components are referred to as ''artifacts''. The library is written in a [https://en.wikipedia.org/wiki/Header-only header-only fashion], that is the implementation is provided directly in the header file rather than a separate .cpp source file. This allows for such libraries to easily be incorporated into other projects without the need for complex build configurations. Applications often use a mix of header only files and source files.&lt;br /&gt;
&lt;br /&gt;
The applications go into their own ''applications'' directory and the libraries into the ''library'' directory. Within each artifact is a ''build'' directory containing the build scripts and CMake files needed to build that artifact. Scripts for POSIX systems are found in the ''posix'' sub-directory and Windows build files are within the ''windows'' sub-directory. The build scripts specified are ''run_cmake'' to produce the platform specific build files (make files for POSIX and VS solutions for Windows), ''version'' to produce a header file that contains the version of the artifact produced and the ''build'' script which produces the artifact. In order to build an artifact, one first produces the build files for their platform by running the ''run_cmake'' script, and then they can run the ''build'' script afterwards to produce the artifact.&lt;br /&gt;
&lt;br /&gt;
Finally there is a top-level ''build'' directory for the project as a whole which produces all artifacts by recursively calling each artifact's individual build scripts. Additionally the top-level build directory also includes a ''setup'' script which downloads all third party dependencies. Some projects may also opt to include an ''install'' script which sets up a suitable development environment, and other scripts for continuous builds, deployment and testing.&lt;br /&gt;
&lt;br /&gt;
Assuming a project named tic_tac_toe consisting of applications tic_tac_toe_console and tic_tac_toe_ui sharing code common to both applications, the following directory structure should be used:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
tic_tac_toe                        # Root level directory.&lt;br /&gt;
  \applications                    # Contains all applications.&lt;br /&gt;
    \tic_tac_toe_console           # Contains the source for a console application.&lt;br /&gt;
      \build                       # Files/scripts used to build the console tic-tac-toe game.&lt;br /&gt;
        \config                    # Contains all CMake build files.&lt;br /&gt;
          CMakeLists.txt           # The CMake config file for the overall application.&lt;br /&gt;
          \tic_tac_toe_console     # Contains CMake build files for the main executable.&lt;br /&gt;
            \CMakeLists.txt        # The CMake config file for the executable.&lt;br /&gt;
        \posix                     # Contains scripts to build on POSIX systems.&lt;br /&gt;
          \build.sh                # Script used to build the application.&lt;br /&gt;
          \run_cmake.sh            # Script used to produce the make/build files.&lt;br /&gt;
          \set_env.sh              # Script defining the environment variables.&lt;br /&gt;
          \version.sh              # Script that produces the VERSION stamped header file.&lt;br /&gt;
        \windows                   # Contains scripts to build on Windows.&lt;br /&gt;
          \build.bat               # Script used to build the application.&lt;br /&gt;
          \run_cmake.bat           # Script used to produce the VS solution.&lt;br /&gt;
          \set_env.bat             # Script defining environment variables.&lt;br /&gt;
          \version.bat             # Script that produces the VERSION stamped header file.&lt;br /&gt;
      \source                      # Contains the C++ source files.&lt;br /&gt;
        \tic_tac_toe_console       # Contains the file defining the main function.&lt;br /&gt;
          \main.cpp                # Defines the main function.&lt;br /&gt;
        \source_dir_a              # Contains additional source files specific the console.&lt;br /&gt;
          \source_a.cpp            # C++ source code files.&lt;br /&gt;
          \source_b.cpp&lt;br /&gt;
          \source_c.cpp&lt;br /&gt;
        \source_dir_b              # Contains additional source files specific the console.&lt;br /&gt;
          \source_d.cpp&lt;br /&gt;
          \source_e.cpp&lt;br /&gt;
          \source_f.cpp&lt;br /&gt;
    \tic_tac_toe_ui                # Contains a GUI version of tic-tac-toe.&lt;br /&gt;
      \...                         # The structure is similar to the console application.&lt;br /&gt;
  \build                           # Contains build scripts to build the entire project.&lt;br /&gt;
    \posix                         # Contains scripts to build on POSIX systems.&lt;br /&gt;
      \build.sh                    # Builds all libraries and applications.&lt;br /&gt;
      \local_build.sh              # A helper script containing common build functions.&lt;br /&gt;
      \run_cmake.sh                # Produces all project make/build files.&lt;br /&gt;
      \setup.sh                    # Installs all third party dependencies.&lt;br /&gt;
    \windows                       # Contains scripts to build on Windows.&lt;br /&gt;
      \build.bat                   # Builds all libraries and applications.&lt;br /&gt;
      \run_cmake.bat               # Produces all VS solutions.&lt;br /&gt;
      \setup.bat                   # Installs all third party dependencies.&lt;br /&gt;
  \library                         # Contains the common library code.&lt;br /&gt;
    \build                         # Files/script used to build the library.&lt;br /&gt;
      \config                      # Contains all CMake build files.&lt;br /&gt;
        \CMakeLists.txt            # The CMake config file for the library.&lt;br /&gt;
        \dir_a                     # Contains CMake build files for library component A.&lt;br /&gt;
          \CMakeLists.txt          # The CMake config file to build component A and unit tests.&lt;br /&gt;
        \dir_b                     # Contains CMake build files for library component B.&lt;br /&gt;
          \CMakeLists.txt          # The CMake config file to build component B and unit tests.&lt;br /&gt;
      \posix                       # Contains scripts to build on POSIX systems.&lt;br /&gt;
        \build.sh                  # Script used to build the library.&lt;br /&gt;
        \run_cmake.sh              # Script used to produce make/build files.&lt;br /&gt;
        \set_env.sh                # Script defining the environment variables.&lt;br /&gt;
      \windows                     # Contains scripts to build on Windows.&lt;br /&gt;
        \build.bat                 # Script to build the library.&lt;br /&gt;
        \run_cmake.bat             # Script to produce the VS solution.&lt;br /&gt;
        \set_env.bat               # Script defining the environment variables.&lt;br /&gt;
    \include                       # Contains the library header files (.hpp)&lt;br /&gt;
      \tic_tac_toe&lt;br /&gt;
        \tic_tac_toe               # Contains the top-most generic library header files.&lt;br /&gt;
          \tic_tac_toe.hpp         # Header file containing generic forward declarations.&lt;br /&gt;
        \dir_a                     # Contains header files for library component A.&lt;br /&gt;
          \a.hpp                   # Header file containing forward declarations for component A.&lt;br /&gt;
          \a_header_1.hpp          # Header file for library component A.&lt;br /&gt;
          \a_header_2.hpp&lt;br /&gt;
          \a_header_3.hpp&lt;br /&gt;
        \dir_b&lt;br /&gt;
          \b.hpp                   # Header file containing forward declarations for component B.&lt;br /&gt;
          \b_header_1.hpp          # Contains header files for library component B.&lt;br /&gt;
          \b_header_2.hpp&lt;br /&gt;
          \b_header_3.hpp&lt;br /&gt;
    \source                        # Contains the library source files (.cpp)&lt;br /&gt;
      \tic_tac_toe                 # Dummy directory for the overall library.&lt;br /&gt;
        \dummy.cpp                 # Dummy source code file.&lt;br /&gt;
      \dir_a                       # Dummy directory for library component A.&lt;br /&gt;
        \dummy.cpp                 # Dummy source file.&lt;br /&gt;
      \dir_a_tester                # Contains unit tests for library component A.&lt;br /&gt;
        \a_header_1_tester.cpp     # Contains unit tests for definitions in a_header_1.hpp&lt;br /&gt;
        \a_header_2_tester.cpp&lt;br /&gt;
        \a_header_3_tester.cpp&lt;br /&gt;
        \main.cpp                  # The entry point for component A unit tests.&lt;br /&gt;
      \dir_b                       # Dummy directory for library component B.&lt;br /&gt;
        \dummy.cpp                 # Dummy source file.&lt;br /&gt;
      \dir_b_tester                # Contains unit tests for library component B.&lt;br /&gt;
        \b_header_1_tester.cpp     # Contains unit tests for definitions in b_header_a.hpp&lt;br /&gt;
        \b_header_2_tester.cpp&lt;br /&gt;
        \b_header_3_tester.cpp&lt;br /&gt;
        \main.cpp                  # The entry point for component B unit tests.&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
An example of the above directory structure containing a basic skeletal implementation of all files can be found here: https://github.com/spiretrading/tic_tac_toe&lt;br /&gt;
&lt;br /&gt;
=Header File Structure=&lt;br /&gt;
&lt;br /&gt;
==Include Guard==&lt;br /&gt;
Header files are structured first with an [https://en.wikipedia.org/wiki/Include_guard include guard] defined using capital letter snake case whose name consists of the project name appended to the directory name and finally the file name itself. As a note, all files end with a single new line character.&lt;br /&gt;
&amp;lt;syntaxhighlight lang=c++ line=line&amp;gt;&lt;br /&gt;
#ifndef CPP_CHAT_SERVER_HPP&lt;br /&gt;
#define CPP_CHAT_SERVER_HPP&lt;br /&gt;
  ...&lt;br /&gt;
#endif&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Include Directives==&lt;br /&gt;
Next come the list of #include directives. Include files are ordered based on their category where the first category is standard C++ header files, the second category is external dependency header files, and finally the third category is project header files. Both standard and external dependency header files use angle brackets (#include &amp;lt;...&amp;gt;) and local project header files use quotes (#include &amp;quot;...&amp;quot;). Within each category files are listed in alphabetical order.&lt;br /&gt;
&amp;lt;syntaxhighlight lang=c++ line=line&amp;gt;&lt;br /&gt;
#include &amp;lt;tuple&amp;gt;&lt;br /&gt;
#include &amp;lt;vector&amp;gt;&lt;br /&gt;
#include &amp;lt;boost/noncopyable.hpp&amp;gt;&lt;br /&gt;
#include &amp;quot;cpp_chat/cpp_chat.hpp&amp;quot;&lt;br /&gt;
#include &amp;quot;cpp_chat/definitions.hpp&amp;quot;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Namespaces==&lt;br /&gt;
After include directives the project's namespace is defined. All declarations and definitions must be contained within a namespace so as to avoid polluting the global namespace. Namespace definitions should be preceded by one single new line except when immediately following a namespace definition. The top level namespace is named after the project, and sub-namespaces may be used (although they should be used very sparingly).&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=c++ line=line&amp;gt;&lt;br /&gt;
namespace CppChat {&lt;br /&gt;
namespace SubChatA {&lt;br /&gt;
  ...&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
namespace SubChatB {&lt;br /&gt;
namespace SubSubChatA {&lt;br /&gt;
  ...&lt;br /&gt;
}&lt;br /&gt;
}&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
namespace CppChatExtra {&lt;br /&gt;
  ...&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
One situation where nested namespaces are welcome and encouraged are for implementation details that do not form part of the namespace's public interface. These definitions are put in a nested namespace called ''details'' and go into a file of their own whose name contains the suffix ''details''. For example if the ''cpp_chat_server.hpp'' contains implementation details, then they should be included in the file ''cpp_chat_server_details.hpp'' and the definitions should go into the namespace ''cpp_chat::details''.&lt;br /&gt;
&lt;br /&gt;
=Layout=&lt;br /&gt;
&lt;br /&gt;
==Indentation==&lt;br /&gt;
Code is indented using 2 spaces per level, tabs are not permitted.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=c++ line=line&amp;gt;&lt;br /&gt;
int factorial(int n) {&lt;br /&gt;
  if(n == 0) {&lt;br /&gt;
    return 1;&lt;br /&gt;
  }&lt;br /&gt;
  return n * factorial(n - 1);&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Line Structure==&lt;br /&gt;
Lines are limited to 80 characters. Exceptions to this rule are long include files and long string literals where breaking up the literal into multiple lines is not possible. In order to break up long statements into multiple lines the following rules are used:&lt;br /&gt;
&lt;br /&gt;
* Break the line at a comma, operator or opening bracket.&lt;br /&gt;
&amp;lt;syntaxhighlight lang=c++ line=line&amp;gt;&lt;br /&gt;
&lt;br /&gt;
// Correct, line break at comma.&lt;br /&gt;
f(a, ..., b,&lt;br /&gt;
  c, ..., d);&lt;br /&gt;
&lt;br /&gt;
// Incorrect, line break after expression.&lt;br /&gt;
f(a, ..., b&lt;br /&gt;
  , c, ..., d);&lt;br /&gt;
&lt;br /&gt;
// Correct, line break after operator.&lt;br /&gt;
a + ... + b +&lt;br /&gt;
  c + ... + d;&lt;br /&gt;
&lt;br /&gt;
// Incorrect, line break after expression.&lt;br /&gt;
a + ... + b&lt;br /&gt;
  + c + ... + d;&lt;br /&gt;
&lt;br /&gt;
// Correct, line break after opening bracket.&lt;br /&gt;
f(&lt;br /&gt;
  a, ..., b, c, ..., d);&lt;br /&gt;
&lt;br /&gt;
// Incorrect, line break after function name.&lt;br /&gt;
f&lt;br /&gt;
  (a, ..., b, c, ..., d);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* For statements that begin new blocks of code (such as if/while/class...), in order to avoid confusing the line continuation with the code block, the line continuation is indented two extra levels. For example consider the following snippet of code:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=c++ line=line&amp;gt;&lt;br /&gt;
// Incorrect.&lt;br /&gt;
if(condition_a &amp;amp;&amp;amp; condition_b &amp;amp;&amp;amp; ... &amp;amp;&amp;amp;&lt;br /&gt;
  condition_c) {&lt;br /&gt;
  std::cout &amp;lt;&amp;lt; &amp;quot;meow&amp;quot; &amp;lt;&amp;lt; std::endl;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The line continuation on line 2 clashes with the code block on line 3. To avoid this clash the above code is indented as follows:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=c++ line=line&amp;gt;&lt;br /&gt;
// Correct.&lt;br /&gt;
if(condition_a &amp;amp;&amp;amp; condition_b &amp;amp;&amp;amp; ... &amp;amp;&amp;amp;&lt;br /&gt;
    condition_c) {&lt;br /&gt;
  std::cout &amp;lt;&amp;lt; &amp;quot;meow&amp;quot; &amp;lt;&amp;lt; std::endl;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The extra level of indentation in the line continuation makes it clear where the condition ends and the code block begins.&lt;br /&gt;
&lt;br /&gt;
==Braces==&lt;br /&gt;
&lt;br /&gt;
Braces are placed using a variant of the [http://wiki.c2.com/?OneTrueBraceStyle OTBS style]. The opening brace is placed on the same line as the declaring statement with one single space preceding it, and the closing brace is placed on a line of its own at the same level of indentation as the declaring statement. For if statements, the else/else if is placed on the same line as the closing brace. For do/while loops, the while is placed on the same line as the closing brace.&lt;br /&gt;
&lt;br /&gt;
Examples:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=c++ line=line&amp;gt;&lt;br /&gt;
// Correct.&lt;br /&gt;
if(&amp;lt;cond&amp;gt;) {&lt;br /&gt;
  &amp;lt;body&amp;gt;&lt;br /&gt;
} else {&lt;br /&gt;
  &amp;lt;default&amp;gt;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
// Correct.&lt;br /&gt;
do {&lt;br /&gt;
  &amp;lt;body&amp;gt;&lt;br /&gt;
} while(&amp;lt;cond&amp;gt;);&lt;br /&gt;
&lt;br /&gt;
// Incorrect.&lt;br /&gt;
if(&amp;lt;cond&amp;gt;)&lt;br /&gt;
{&lt;br /&gt;
  &amp;lt;body&amp;gt;&lt;br /&gt;
}&lt;br /&gt;
else&lt;br /&gt;
{&lt;br /&gt;
  &amp;lt;default&amp;gt;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
// Incorrect.&lt;br /&gt;
do&lt;br /&gt;
{&lt;br /&gt;
  &amp;lt;body&amp;gt;&lt;br /&gt;
}&lt;br /&gt;
while(&amp;lt;cond&amp;gt;);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Spacing==&lt;br /&gt;
&lt;br /&gt;
The following are correct use cases for white spaces:&lt;br /&gt;
&lt;br /&gt;
* Used for indentation.&lt;br /&gt;
* Used to surround binary operations.&lt;br /&gt;
&amp;lt;syntaxhighlight lang=c++ line=line&amp;gt;&lt;br /&gt;
// Correct.&lt;br /&gt;
auto x = a + b;&lt;br /&gt;
auto y = 5;&lt;br /&gt;
&lt;br /&gt;
//! Incorrect&lt;br /&gt;
auto x = a+b;&lt;br /&gt;
auto y=5;&lt;br /&gt;
auto z= 5;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* One space is placed after a comma.&lt;br /&gt;
&amp;lt;syntaxhighlight lang=c++ line=line&amp;gt;&lt;br /&gt;
// Correct.&lt;br /&gt;
f(1, 2);&lt;br /&gt;
int g(int a, int b);&lt;br /&gt;
&lt;br /&gt;
//! Incorrect&lt;br /&gt;
f(1,2);&lt;br /&gt;
int g(int a,int b);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=Syntax=&lt;br /&gt;
&lt;br /&gt;
==Function Definitions==&lt;br /&gt;
&lt;br /&gt;
Functions declared and defined in header files are formatted as follows:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=c++ line=line&amp;gt;&lt;br /&gt;
inline int f() {&lt;br /&gt;
  ...&lt;br /&gt;
  return 123;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
template&amp;lt;typename T&amp;gt;&lt;br /&gt;
bool g() {&lt;br /&gt;
  ...&lt;br /&gt;
  return false;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
That is they are declared as inline unless they are function templates in which case the inline specified is omitted.&lt;br /&gt;
&lt;br /&gt;
==Variable Declarations==&lt;br /&gt;
&lt;br /&gt;
Variables are declared so that only one variable is declared per line, the type of the variable should [https://herbsutter.com/2013/08/12/gotw-94-solution-aaa-style-almost-always-auto/ almost always use auto], and variables should almost always be initialized.&lt;br /&gt;
&lt;br /&gt;
Examples of simple declarations:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=c++ line=line&amp;gt;&lt;br /&gt;
auto x = 5;&lt;br /&gt;
auto y = a + b;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
For complex initialization of values, use an [https://en.wikipedia.org/wiki/Immediately-invoked_function_expression immediately invoked lambda expression] as follows:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=c++ line=line&amp;gt;&lt;br /&gt;
auto value = [&amp;amp;] {&lt;br /&gt;
  if(condition) {&lt;br /&gt;
    return 123;&lt;br /&gt;
  }&lt;br /&gt;
  return 321;&lt;br /&gt;
}();&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=Additional References=&lt;br /&gt;
&lt;br /&gt;
The bulk of this style guide focuses on syntax rather than good programming practices. The following list are reference materials (both online and published) for best practices on writing portable, efficient, and clean C++ code:&lt;br /&gt;
&lt;br /&gt;
* S. Meyers, ''Effective Modern C++''. 2014&lt;br /&gt;
* B. Stroustrup ''The C++ Programming Language (4th Edition)''. 2013&lt;br /&gt;
* [https://github.com/isocpp/CppCoreGuidelines Cpp Core Guidelines]&lt;br /&gt;
* [https://isocpp.org/ Standard C++ Blog]&lt;br /&gt;
* [https://cppcon.org/ CppCon - The C++ Conference]&lt;/div&gt;</summary>
		<author><name>Kman</name></author>
		
	</entry>
	<entry>
		<id>https://wiki.spiretrading.com/index.php?title=C%2B%2B_Style_Guide&amp;diff=47</id>
		<title>C++ Style Guide</title>
		<link rel="alternate" type="text/html" href="https://wiki.spiretrading.com/index.php?title=C%2B%2B_Style_Guide&amp;diff=47"/>
		<updated>2018-08-02T14:57:01Z</updated>

		<summary type="html">&lt;p&gt;Kman: /* Development Environment */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;This article specifies the most general guidelines used for all Spire projects written using C++ as the primary programming language. Each individual project may extend or override the guidelines specified herein. The overall aim of this guideline is to provide consistency across the numerous projects developed by Spire in order to promote and benefit from modern C++ practices as well as tailor them to our specific requirements.&lt;br /&gt;
&lt;br /&gt;
In general, the guidelines are very specific and opinionated. This is done intentionally to ensure that every detail has been given proper consideration and that every line of code is written with care and diligence. It is taken as a prerequisite that writing robust, clean and maintainable code requires paying close attention to even the smallest of details. As such, when there are two or more ways to write or express any given statement or expression, be it using spaces or tabs, number of characters per line, purple or violet, the guideline will often require that one particular approach be used to the exclusion of others.&lt;br /&gt;
&lt;br /&gt;
Finally, this document is constantly evolving and as such older projects may not be up-to-date with the guidelines found here. In those circumstances one must use their best judgment about how to integrate these guidelines into older codebases. As a general principle, consistency should favor the local over the global, that is it is more important to be consistent with a function definition than within a file, and more important to be consistent within a file than within a directory, project, etc...&lt;br /&gt;
&lt;br /&gt;
=Core Guidelines=&lt;br /&gt;
This document should be seen as an extension to the Cpp Core Guidelines authored and maintained by Herb Sutter and Bjarne Stroustrup. After reviewing these guidelines one should then become familiar with the Cpp Core Guidelines as documented here:&lt;br /&gt;
&lt;br /&gt;
https://github.com/isocpp/CppCoreGuidelines&lt;br /&gt;
&lt;br /&gt;
Those guidelines specify the best practices for writing modern C++ code. In situations where there is a conflict between the Cpp Core Guidelines and the guidelines set forth in this document, this document takes precedence. For all known situations where a conflict exists, this document should explicitly indicate that conflict to avoid confusion.&lt;br /&gt;
&lt;br /&gt;
=Development Environment=&lt;br /&gt;
&lt;br /&gt;
The two primary development environments supported by Spire projects are Ubuntu Server 18.04 LTS and Windows 10. On POSIX systems the compiler of choice is g++ 7.3 and on Windows 10 it's Microsoft Visual Studio 2017 15.7.5. In order to support these two platforms, CMake is used to produce the appropriate project/make files for each platform.&lt;br /&gt;
&lt;br /&gt;
For source control, git is used and projects are to be hosted on [https://github.com/spiretrading Spire Trading's Github page].&lt;br /&gt;
&lt;br /&gt;
Each developer is welcome to use an editor of their choice. [https://www.visualstudio.com/downloads/ Visual Studio 2017] is typically used for Windows and [https://code.visualstudio.com/ Visual Studio Code] is typically used on Linux and Mac.&lt;br /&gt;
&lt;br /&gt;
=File Names=&lt;br /&gt;
&lt;br /&gt;
Use [https://en.wikipedia.org/wiki/Snake_case snake case] using all lower case letters for files and directories. The main exception is for CMake files which must use the name ''CMakeLists.txt''&lt;br /&gt;
&lt;br /&gt;
Header files should use the extension ''hpp''&lt;br /&gt;
&lt;br /&gt;
Source files should use the extension ''cpp''&lt;br /&gt;
&lt;br /&gt;
All files end with a single new line character.&lt;br /&gt;
&lt;br /&gt;
=Directory Structure=&lt;br /&gt;
&lt;br /&gt;
A project is broken down into one library component and one or more application components. These components are referred to as ''artifacts''. The library is written in a [https://en.wikipedia.org/wiki/Header-only header-only fashion], that is the implementation is provided directly in the header file rather than a separate .cpp source file. This allows for such libraries to easily be incorporated into other projects without the need for complex build configurations. Applications often use a mix of header only files and source files.&lt;br /&gt;
&lt;br /&gt;
The applications go into their own ''applications'' directory and the libraries into the ''library'' directory. Within each artifact is a ''build'' directory containing the build scripts and CMake files needed to build that artifact. Scripts for POSIX systems are found in the ''posix'' sub-directory and Windows build files are within the ''windows'' sub-directory. The build scripts specified are ''run_cmake'' to produce the platform specific build files (make files for POSIX and VS solutions for Windows), ''version'' to produce a header file that contains the version of the artifact produced and the ''build'' script which produces the artifact. In order to build an artifact, one first produces the build files for their platform by running the ''run_cmake'' script, and then they can run the ''build'' script afterwards to produce the artifact.&lt;br /&gt;
&lt;br /&gt;
Finally there is a top-level ''build'' directory for the project as a whole which produces all artifacts by recursively calling each artifact's individual build scripts. Additionally the top-level build directory also includes a ''setup'' script which downloads all third party dependencies. Some projects may also opt to include an ''install'' script which sets up a suitable development environment, and other scripts for continuous builds, deployment and testing.&lt;br /&gt;
&lt;br /&gt;
Assuming a project named tic_tac_toe consisting of applications tic_tac_toe_console and tic_tac_toe_ui sharing code common to both applications, the following directory structure should be used:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
tic_tac_toe                        # Root level directory.&lt;br /&gt;
  \applications                    # Contains all applications.&lt;br /&gt;
    \tic_tac_toe_console           # Contains the source for a console application.&lt;br /&gt;
      \build                       # Files/scripts used to build the console tic-tac-toe game.&lt;br /&gt;
        \config                    # Contains all CMake build files.&lt;br /&gt;
          CMakeLists.txt           # The CMake config file for the overall application.&lt;br /&gt;
          \tic_tac_toe_console     # Contains CMake build files for the main executable.&lt;br /&gt;
            \CMakeLists.txt        # The CMake config file for the executable.&lt;br /&gt;
        \posix                     # Contains scripts to build on POSIX systems.&lt;br /&gt;
          \build.sh                # Script used to build the application.&lt;br /&gt;
          \run_cmake.sh            # Script used to produce the make/build files.&lt;br /&gt;
          \set_env.sh              # Script defining the environment variables.&lt;br /&gt;
          \version.sh              # Script that produces the VERSION stamped header file.&lt;br /&gt;
        \windows                   # Contains scripts to build on Windows.&lt;br /&gt;
          \build.bat               # Script used to build the application.&lt;br /&gt;
          \run_cmake.bat           # Script used to produce the VS solution.&lt;br /&gt;
          \set_env.bat             # Script defining environment variables.&lt;br /&gt;
          \version.bat             # Script that produces the VERSION stamped header file.&lt;br /&gt;
      \source                      # Contains the C++ source files.&lt;br /&gt;
        \tic_tac_toe_console       # Contains the file defining the main function.&lt;br /&gt;
          \main.cpp                # Defines the main function.&lt;br /&gt;
        \source_dir_a              # Contains additional source files specific the console.&lt;br /&gt;
          \source_a.cpp            # C++ source code files.&lt;br /&gt;
          \source_b.cpp&lt;br /&gt;
          \source_c.cpp&lt;br /&gt;
        \source_dir_b              # Contains additional source files specific the console.&lt;br /&gt;
          \source_d.cpp&lt;br /&gt;
          \source_e.cpp&lt;br /&gt;
          \source_f.cpp&lt;br /&gt;
    \tic_tac_toe_ui                # Contains a GUI version of tic-tac-toe.&lt;br /&gt;
      \...                         # The structure is similar to the console application.&lt;br /&gt;
  \build                           # Contains build scripts to build the entire project.&lt;br /&gt;
    \posix                         # Contains scripts to build on POSIX systems.&lt;br /&gt;
      \build.sh                    # Builds all libraries and applications.&lt;br /&gt;
      \local_build.sh              # A helper script containing common build functions.&lt;br /&gt;
      \run_cmake.sh                # Produces all project make/build files.&lt;br /&gt;
      \setup.sh                    # Installs all third party dependencies.&lt;br /&gt;
    \windows                       # Contains scripts to build on Windows.&lt;br /&gt;
      \build.bat                   # Builds all libraries and applications.&lt;br /&gt;
      \run_cmake.bat               # Produces all VS solutions.&lt;br /&gt;
      \setup.bat                   # Installs all third party dependencies.&lt;br /&gt;
  \library                         # Contains the common library code.&lt;br /&gt;
    \build                         # Files/script used to build the library.&lt;br /&gt;
      \config                      # Contains all CMake build files.&lt;br /&gt;
        \CMakeLists.txt            # The CMake config file for the library.&lt;br /&gt;
        \dir_a                     # Contains CMake build files for library component A.&lt;br /&gt;
          \CMakeLists.txt          # The CMake config file to build component A and unit tests.&lt;br /&gt;
        \dir_b                     # Contains CMake build files for library component B.&lt;br /&gt;
          \CMakeLists.txt          # The CMake config file to build component B and unit tests.&lt;br /&gt;
      \posix                       # Contains scripts to build on POSIX systems.&lt;br /&gt;
        \build.sh                  # Script used to build the library.&lt;br /&gt;
        \run_cmake.sh              # Script used to produce make/build files.&lt;br /&gt;
        \set_env.sh                # Script defining the environment variables.&lt;br /&gt;
      \windows                     # Contains scripts to build on Windows.&lt;br /&gt;
        \build.bat                 # Script to build the library.&lt;br /&gt;
        \run_cmake.bat             # Script to produce the VS solution.&lt;br /&gt;
        \set_env.bat               # Script defining the environment variables.&lt;br /&gt;
    \include                       # Contains the library header files (.hpp)&lt;br /&gt;
      \tic_tac_toe&lt;br /&gt;
        \tic_tac_toe               # Contains the top-most generic library header files.&lt;br /&gt;
          \tic_tac_toe.hpp         # Header file containing generic forward declarations.&lt;br /&gt;
        \dir_a                     # Contains header files for library component A.&lt;br /&gt;
          \a.hpp                   # Header file containing forward declarations for component A.&lt;br /&gt;
          \a_header_1.hpp          # Header file for library component A.&lt;br /&gt;
          \a_header_2.hpp&lt;br /&gt;
          \a_header_3.hpp&lt;br /&gt;
        \dir_b&lt;br /&gt;
          \b.hpp                   # Header file containing forward declarations for component B.&lt;br /&gt;
          \b_header_1.hpp          # Contains header files for library component B.&lt;br /&gt;
          \b_header_2.hpp&lt;br /&gt;
          \b_header_3.hpp&lt;br /&gt;
    \source                        # Contains the library source files (.cpp)&lt;br /&gt;
      \tic_tac_toe                 # Dummy directory for the overall library.&lt;br /&gt;
        \dummy.cpp                 # Dummy source code file.&lt;br /&gt;
      \dir_a                       # Dummy directory for library component A.&lt;br /&gt;
        \dummy.cpp                 # Dummy source file.&lt;br /&gt;
      \dir_a_tester                # Contains unit tests for library component A.&lt;br /&gt;
        \a_header_1_tester.cpp     # Contains unit tests for definitions in a_header_1.hpp&lt;br /&gt;
        \a_header_2_tester.cpp&lt;br /&gt;
        \a_header_3_tester.cpp&lt;br /&gt;
        \main.cpp                  # The entry point for component A unit tests.&lt;br /&gt;
      \dir_b                       # Dummy directory for library component B.&lt;br /&gt;
        \dummy.cpp                 # Dummy source file.&lt;br /&gt;
      \dir_b_tester                # Contains unit tests for library component B.&lt;br /&gt;
        \b_header_1_tester.cpp     # Contains unit tests for definitions in b_header_a.hpp&lt;br /&gt;
        \b_header_2_tester.cpp&lt;br /&gt;
        \b_header_3_tester.cpp&lt;br /&gt;
        \main.cpp                  # The entry point for component B unit tests.&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
An example of the above directory structure containing a basic skeletal implementation of all files can be found here: https://github.com/spiretrading/tic_tac_toe&lt;br /&gt;
&lt;br /&gt;
=Header File Structure=&lt;br /&gt;
&lt;br /&gt;
==Include Guard==&lt;br /&gt;
Header files are structured first with an [https://en.wikipedia.org/wiki/Include_guard include guard] defined using capital letter snake case whose name consists of the project name appended to the directory name and finally the file name itself. As a note, all files end with a single new line character.&lt;br /&gt;
&amp;lt;syntaxhighlight lang=c++ line=line&amp;gt;&lt;br /&gt;
#ifndef CPP_CHAT_SERVER_HPP&lt;br /&gt;
#define CPP_CHAT_SERVER_HPP&lt;br /&gt;
  ...&lt;br /&gt;
#endif&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Include Directives==&lt;br /&gt;
Next come the list of #include directives. Include files are ordered based on their category where the first category is standard C++ header files, the second category is external dependency header files, and finally the third category is project header files. Both standard and external dependency header files use angle brackets (#include &amp;lt;...&amp;gt;) and local project header files use quotes (#include &amp;quot;...&amp;quot;). Within each category files are listed in alphabetical order.&lt;br /&gt;
&amp;lt;syntaxhighlight lang=c++ line=line&amp;gt;&lt;br /&gt;
#include &amp;lt;tuple&amp;gt;&lt;br /&gt;
#include &amp;lt;vector&amp;gt;&lt;br /&gt;
#include &amp;lt;boost/noncopyable.hpp&amp;gt;&lt;br /&gt;
#include &amp;quot;cpp_chat/cpp_chat.hpp&amp;quot;&lt;br /&gt;
#include &amp;quot;cpp_chat/definitions.hpp&amp;quot;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Namespaces==&lt;br /&gt;
After include directives the project's namespace is defined. All declarations and definitions must be contained within a namespace so as to avoid polluting the global namespace. Namespace definitions should be preceded by one single new line except when immediately following a namespace definition. The top level namespace is named after the project, and sub-namespaces may be used (although they should be used very sparingly).&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=c++ line=line&amp;gt;&lt;br /&gt;
namespace cpp_chat {&lt;br /&gt;
namespace sub_chat_a {&lt;br /&gt;
  ...&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
namespace sub_chat_b {&lt;br /&gt;
namespace sub_sub_chat_a {&lt;br /&gt;
  ...&lt;br /&gt;
}&lt;br /&gt;
}&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
namespace cpp_chat_extra {&lt;br /&gt;
  ...&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
One situation where nested namespaces are welcome and encouraged are for implementation details that do not form part of the namespace's public interface. These definitions are put in a nested namespace called ''details'' and go into a file of their own whose name contains the suffix ''details''. For example if the ''cpp_chat_server.hpp'' contains implementation details, then they should be included in the file ''cpp_chat_server_details.hpp'' and the definitions should go into the namespace ''cpp_chat::details''.&lt;br /&gt;
&lt;br /&gt;
=Layout=&lt;br /&gt;
&lt;br /&gt;
==Indentation==&lt;br /&gt;
Code is indented using 2 spaces per level, tabs are not permitted.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=c++ line=line&amp;gt;&lt;br /&gt;
int factorial(int n) {&lt;br /&gt;
  if(n == 0) {&lt;br /&gt;
    return 1;&lt;br /&gt;
  }&lt;br /&gt;
  return n * factorial(n - 1);&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Line Structure==&lt;br /&gt;
Lines are limited to 80 characters. Exceptions to this rule are long include files and long string literals where breaking up the literal into multiple lines is not possible. In order to break up long statements into multiple lines the following rules are used:&lt;br /&gt;
&lt;br /&gt;
* Break the line at a comma, operator or opening bracket.&lt;br /&gt;
&amp;lt;syntaxhighlight lang=c++ line=line&amp;gt;&lt;br /&gt;
&lt;br /&gt;
// Correct, line break at comma.&lt;br /&gt;
f(a, ..., b,&lt;br /&gt;
  c, ..., d);&lt;br /&gt;
&lt;br /&gt;
// Incorrect, line break after expression.&lt;br /&gt;
f(a, ..., b&lt;br /&gt;
  , c, ..., d);&lt;br /&gt;
&lt;br /&gt;
// Correct, line break after operator.&lt;br /&gt;
a + ... + b +&lt;br /&gt;
  c + ... + d;&lt;br /&gt;
&lt;br /&gt;
// Incorrect, line break after expression.&lt;br /&gt;
a + ... + b&lt;br /&gt;
  + c + ... + d;&lt;br /&gt;
&lt;br /&gt;
// Correct, line break after opening bracket.&lt;br /&gt;
f(&lt;br /&gt;
  a, ..., b, c, ..., d);&lt;br /&gt;
&lt;br /&gt;
// Incorrect, line break after function name.&lt;br /&gt;
f&lt;br /&gt;
  (a, ..., b, c, ..., d);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* For statements that begin new blocks of code (such as if/while/class...), in order to avoid confusing the line continuation with the code block, the line continuation is indented two extra levels. For example consider the following snippet of code:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=c++ line=line&amp;gt;&lt;br /&gt;
// Incorrect.&lt;br /&gt;
if(condition_a &amp;amp;&amp;amp; condition_b &amp;amp;&amp;amp; ... &amp;amp;&amp;amp;&lt;br /&gt;
  condition_c) {&lt;br /&gt;
  std::cout &amp;lt;&amp;lt; &amp;quot;meow&amp;quot; &amp;lt;&amp;lt; std::endl;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The line continuation on line 2 clashes with the code block on line 3. To avoid this clash the above code is indented as follows:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=c++ line=line&amp;gt;&lt;br /&gt;
// Correct.&lt;br /&gt;
if(condition_a &amp;amp;&amp;amp; condition_b &amp;amp;&amp;amp; ... &amp;amp;&amp;amp;&lt;br /&gt;
    condition_c) {&lt;br /&gt;
  std::cout &amp;lt;&amp;lt; &amp;quot;meow&amp;quot; &amp;lt;&amp;lt; std::endl;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The extra level of indentation in the line continuation makes it clear where the condition ends and the code block begins.&lt;br /&gt;
&lt;br /&gt;
==Braces==&lt;br /&gt;
&lt;br /&gt;
Braces are placed using a variant of the [http://wiki.c2.com/?OneTrueBraceStyle OTBS style]. The opening brace is placed on the same line as the declaring statement with one single space preceding it, and the closing brace is placed on a line of its own at the same level of indentation as the declaring statement. For if statements, the else/else if is placed on the same line as the closing brace. For do/while loops, the while is placed on the same line as the closing brace.&lt;br /&gt;
&lt;br /&gt;
Examples:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=c++ line=line&amp;gt;&lt;br /&gt;
// Correct.&lt;br /&gt;
if(&amp;lt;cond&amp;gt;) {&lt;br /&gt;
  &amp;lt;body&amp;gt;&lt;br /&gt;
} else {&lt;br /&gt;
  &amp;lt;default&amp;gt;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
// Correct.&lt;br /&gt;
do {&lt;br /&gt;
  &amp;lt;body&amp;gt;&lt;br /&gt;
} while(&amp;lt;cond&amp;gt;);&lt;br /&gt;
&lt;br /&gt;
// Incorrect.&lt;br /&gt;
if(&amp;lt;cond&amp;gt;)&lt;br /&gt;
{&lt;br /&gt;
  &amp;lt;body&amp;gt;&lt;br /&gt;
}&lt;br /&gt;
else&lt;br /&gt;
{&lt;br /&gt;
  &amp;lt;default&amp;gt;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
// Incorrect.&lt;br /&gt;
do&lt;br /&gt;
{&lt;br /&gt;
  &amp;lt;body&amp;gt;&lt;br /&gt;
}&lt;br /&gt;
while(&amp;lt;cond&amp;gt;);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Spacing==&lt;br /&gt;
&lt;br /&gt;
The following are correct use cases for white spaces:&lt;br /&gt;
&lt;br /&gt;
* Used for indentation.&lt;br /&gt;
* Used to surround binary operations.&lt;br /&gt;
&amp;lt;syntaxhighlight lang=c++ line=line&amp;gt;&lt;br /&gt;
// Correct.&lt;br /&gt;
auto x = a + b;&lt;br /&gt;
auto y = 5;&lt;br /&gt;
&lt;br /&gt;
//! Incorrect&lt;br /&gt;
auto x = a+b;&lt;br /&gt;
auto y=5;&lt;br /&gt;
auto z= 5;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* One space is placed after a comma.&lt;br /&gt;
&amp;lt;syntaxhighlight lang=c++ line=line&amp;gt;&lt;br /&gt;
// Correct.&lt;br /&gt;
f(1, 2);&lt;br /&gt;
int g(int a, int b);&lt;br /&gt;
&lt;br /&gt;
//! Incorrect&lt;br /&gt;
f(1,2);&lt;br /&gt;
int g(int a,int b);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=Syntax=&lt;br /&gt;
&lt;br /&gt;
==Function Definitions==&lt;br /&gt;
&lt;br /&gt;
Functions declared and defined in header files are formatted as follows:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=c++ line=line&amp;gt;&lt;br /&gt;
inline int f() {&lt;br /&gt;
  ...&lt;br /&gt;
  return 123;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
template&amp;lt;typename T&amp;gt;&lt;br /&gt;
bool g() {&lt;br /&gt;
  ...&lt;br /&gt;
  return false;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
That is they are declared as inline unless they are function templates in which case the inline specified is omitted.&lt;br /&gt;
&lt;br /&gt;
==Variable Declarations==&lt;br /&gt;
&lt;br /&gt;
Variables are declared so that only one variable is declared per line, the type of the variable should [https://herbsutter.com/2013/08/12/gotw-94-solution-aaa-style-almost-always-auto/ almost always use auto], and variables should almost always be initialized.&lt;br /&gt;
&lt;br /&gt;
Examples of simple declarations:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=c++ line=line&amp;gt;&lt;br /&gt;
auto x = 5;&lt;br /&gt;
auto y = a + b;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
For complex initialization of values, use an [https://en.wikipedia.org/wiki/Immediately-invoked_function_expression immediately invoked lambda expression] as follows:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=c++ line=line&amp;gt;&lt;br /&gt;
auto value = [&amp;amp;] {&lt;br /&gt;
  if(condition) {&lt;br /&gt;
    return 123;&lt;br /&gt;
  }&lt;br /&gt;
  return 321;&lt;br /&gt;
}();&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=Additional References=&lt;br /&gt;
&lt;br /&gt;
The bulk of this style guide focuses on syntax rather than good programming practices. The following list are reference materials (both online and published) for best practices on writing portable, efficient, and clean C++ code:&lt;br /&gt;
&lt;br /&gt;
* S. Meyers, ''Effective Modern C++''. 2014&lt;br /&gt;
* B. Stroustrup ''The C++ Programming Language (4th Edition)''. 2013&lt;br /&gt;
* [https://github.com/isocpp/CppCoreGuidelines Cpp Core Guidelines]&lt;br /&gt;
* [https://isocpp.org/ Standard C++ Blog]&lt;br /&gt;
* [https://cppcon.org/ CppCon - The C++ Conference]&lt;/div&gt;</summary>
		<author><name>Kman</name></author>
		
	</entry>
	<entry>
		<id>https://wiki.spiretrading.com/index.php?title=Workflow&amp;diff=46</id>
		<title>Workflow</title>
		<link rel="alternate" type="text/html" href="https://wiki.spiretrading.com/index.php?title=Workflow&amp;diff=46"/>
		<updated>2018-06-21T01:55:20Z</updated>

		<summary type="html">&lt;p&gt;Kman: Created page with &amp;quot;The following workflow is used to ensure the timely and organized delivery of most software development related tasks. Each software developer is assigned to one or more proje...&amp;quot;&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;The following workflow is used to ensure the timely and organized delivery of most software development related tasks. Each software developer is assigned to one or more projects that they are expected to contribute to, and the management of these projects is handled using [https://www.manuscript.com/ Manuscript] (formerly known as Fogbugz).&lt;br /&gt;
&lt;br /&gt;
To begin, login to Manuscript using your e-mail address and subscribe to your assigned projects. Doing so ensures that you are notified by e-mail of any updates made to your project. Subscribing to your projects involves first clicking on your avatar located at the bottom left corner of the page (indicated by the green arrow), and then clicking on the Subscribe menu item (indicated by the red arrow):&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[File:Workflow_subscribe.png]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Choose to Add New Subscription:&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[File:Workflow_new_subscription.png]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Individually select all projects assigned to you from the drop down menu:&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[File:Workflow_project_subscription.png]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
At this point your list of subscriptions should look like the below image indicating that you are subscribed to all assigned projects.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[File:Workflow_subscription_final.png]]&lt;/div&gt;</summary>
		<author><name>Kman</name></author>
		
	</entry>
	<entry>
		<id>https://wiki.spiretrading.com/index.php?title=File:Workflow_subscription_final.png&amp;diff=45</id>
		<title>File:Workflow subscription final.png</title>
		<link rel="alternate" type="text/html" href="https://wiki.spiretrading.com/index.php?title=File:Workflow_subscription_final.png&amp;diff=45"/>
		<updated>2018-06-21T01:55:05Z</updated>

		<summary type="html">&lt;p&gt;Kman: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;/div&gt;</summary>
		<author><name>Kman</name></author>
		
	</entry>
</feed>