<?xml version="1.0"?>
<feed xmlns="http://www.w3.org/2005/Atom" xml:lang="en">
		<id>https://www.computercraft.info/wiki/api.php?action=feedcontributions&amp;feedformat=atom&amp;user=YoYoYonnY</id>
		<title>ComputerCraft Wiki - User contributions [en]</title>
		<link rel="self" type="application/atom+xml" href="https://www.computercraft.info/wiki/api.php?action=feedcontributions&amp;feedformat=atom&amp;user=YoYoYonnY"/>
		<link rel="alternate" type="text/html" href="https://www.computercraft.info/wiki/Special:Contributions/YoYoYonnY"/>
		<updated>2026-07-11T18:26:58Z</updated>
		<subtitle>User contributions</subtitle>
		<generator>MediaWiki 1.24.1</generator>

	<entry>
		<id>https://www.computercraft.info/wiki/index.php?title=Category:OSes&amp;diff=6103</id>
		<title>Category:OSes</title>
		<link rel="alternate" type="text/html" href="https://www.computercraft.info/wiki/index.php?title=Category:OSes&amp;diff=6103"/>
				<updated>2014-02-02T15:35:18Z</updated>
		
		<summary type="html">&lt;p&gt;YoYoYonnY: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;This is a list of all OSes, or OS supplements which have enough change to make it seem like a new OS, for ComputerCraft. EDIT: Not yet confirmed by Admin (please make an admin confirm): Feel free to add your own OS, aslong it is a acceptable OS and works in the latest ComputerCraft version without any problems.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;!-- IF YOU ARE NOT COMFORTABLE WITH HTML TABLES, DO NOT TOUCH THIS. --&amp;gt;&lt;br /&gt;
&amp;lt;!-- ALWAYS, ALWAYS PRESS PREVIEW BEFORE SUBMITTING, WIKIANS!  ~ALL --&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;!-- Note: This table alternates rows between #FFFFFF (white) and the&lt;br /&gt;
     off-white grey counterpart #E8E8E8. Please try and preserver this. --&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;table style=&amp;quot;width: 100%; border: solid 1px black; margin: 2px; border-spacing: 0px;&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&amp;lt;td colspan=&amp;quot;3&amp;quot; style=&amp;quot;font-weight: bold; font-size: large; padding-bottom: .3em; border-bottom: solid #C9C9C9 1px; background: #D3FFC2; line-height:28px;&amp;quot;&amp;gt;[[File:Grid_disk.png|24px]]&amp;amp;nbsp;&amp;amp;nbsp;Operating Systems&amp;lt;/td&amp;gt;&amp;lt;/tr&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tr&amp;gt;&amp;lt;td style=&amp;quot;width: 350px; background: #E0E0E0; padding: .4em; font-weight:bold;&amp;quot;&amp;gt;Name&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td style=&amp;quot;background: #E0E0E0; padding: .4em; font-weight:bold;&amp;quot;&amp;gt;Requirements&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td style=&amp;quot;background: #E0E0E0; padding: .4em; font-weight:bold;&amp;quot;&amp;gt;Description&amp;lt;/td&amp;gt;&amp;lt;/tr&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tr style=&amp;quot;background-color: #FFFFFF;&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;td style=&amp;quot;border-top: solid #C9C9C9 1px; padding: .4em;&amp;quot;&amp;gt;[[Redworks]]&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td style=&amp;quot;border-top: solid #C9C9C9 1px; padding: .4em;&amp;quot;&amp;gt;HTTP&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td style=&amp;quot;border-top: solid #C9C9C9 1px; padding: .4em;&amp;quot;&amp;gt;Lots of programs &amp;amp; APIs, login system&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;/tr&amp;gt;&lt;br /&gt;
&amp;lt;/table&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[Category:Lists]]&lt;/div&gt;</summary>
		<author><name>YoYoYonnY</name></author>	</entry>

	<entry>
		<id>https://www.computercraft.info/wiki/index.php?title=Colors_(API)&amp;diff=6078</id>
		<title>Colors (API)</title>
		<link rel="alternate" type="text/html" href="https://www.computercraft.info/wiki/index.php?title=Colors_(API)&amp;diff=6078"/>
				<updated>2013-12-24T11:37:00Z</updated>
		
		<summary type="html">&lt;p&gt;YoYoYonnY: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;The Colors API allows you to manipulate sets of colors. This is useful in conjunction with Bundled Cables from the RedPower mod, RedNet Cables from the MineFactory Reloaded mod, and colors on [[Advanced Computer|Advanced Computers]] and [[Advanced Monitor|Advanced Monitors]].&lt;br /&gt;
&lt;br /&gt;
For the non-American English version just replace 'colors' with 'colours' and it will use the other API, colours—which is exactly the same, except in non-American English (e.g. gray is spelt grey and lightGray is spelt lightGrey).&lt;br /&gt;
&lt;br /&gt;
{{API table|Colors|image=Grid_disk.png|2=&lt;br /&gt;
&lt;br /&gt;
{{API table/row|[[colors.combine]]({{Type|number}} color1, {{Type|number}} color2, ...)|{{type|number}} value|&lt;br /&gt;
Combines a one or more colors (or sets of colors) into a larger set.&lt;br /&gt;
|odd}}&lt;br /&gt;
&lt;br /&gt;
{{API table/row|[[colors.subtract]]({{Type|number}} colors, {{Type|number}} color1, {{Type|number}} color2, ...)|{{type|number}} value|&lt;br /&gt;
Removes one or more colors (or sets of colors) from an initial set.&lt;br /&gt;
|}}&lt;br /&gt;
&lt;br /&gt;
{{API table/row|[[colors.test]]({{type|number}} colors, {{type|number}} color)|{{type|boolean}} contained|&lt;br /&gt;
Tests whether ''color'' is contained within '''colors'''.&lt;br /&gt;
|odd}}&lt;br /&gt;
&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
'''Note:''' The standard addition (+) and subtraction (-) operators while able to be used on colors instead of colors.combine and colors.subtract should be avoided due to the nature of the colour format. For example&amp;lt;pre&amp;gt;print(colors.white + colors.white)&amp;lt;/pre&amp;gt;will output 2 which is orange as opposed to&amp;lt;pre&amp;gt;print(colors.combine(colors.white, colors.white))&amp;lt;/pre&amp;gt;will output 1 which is white.&lt;br /&gt;
&lt;br /&gt;
Furthermore, the [[Bit (API)]] may be used on sets of colors. For example, &lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
bCableLeft  = rs.getBundledInput(&amp;quot;left&amp;quot;)&lt;br /&gt;
bCableRight = rs.getBundledInput(&amp;quot;right&amp;quot;)&lt;br /&gt;
&lt;br /&gt;
-- Get a number representing colors on in both right and left bundled cables&lt;br /&gt;
commonColors    = bit.band(bCableLeft, bCableRight)&lt;br /&gt;
&lt;br /&gt;
-- Get all the colors active on either right or left&lt;br /&gt;
totalColors     = bit.bor(bCableLeft, bCableRight)&lt;br /&gt;
&lt;br /&gt;
-- Get the colors which are active on right, or left, but not both at the same time&lt;br /&gt;
exclusiveColors = bit.bxor(bCableLeft, bCableRight)&lt;br /&gt;
&lt;br /&gt;
-- Get the colors that are not active on the left&lt;br /&gt;
offColorsA      = bit.bnot(bCableLeft)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Colors==&lt;br /&gt;
Color constants include, in ascending bit order (including character used in the paint program):&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; width=&amp;quot;200px&amp;quot;&lt;br /&gt;
! Color&lt;br /&gt;
! Decimal&lt;br /&gt;
! Hexadecimal&lt;br /&gt;
! Binary&lt;br /&gt;
! Paint Default&lt;br /&gt;
|-&lt;br /&gt;
| colors.white&lt;br /&gt;
| align=&amp;quot;right&amp;quot; | 1&lt;br /&gt;
| align=&amp;quot;right&amp;quot; | 0x1&lt;br /&gt;
| align=&amp;quot;right&amp;quot; | 0000000000000001&lt;br /&gt;
| 0&lt;br /&gt;
|-&lt;br /&gt;
| colors.orange&lt;br /&gt;
| align=&amp;quot;right&amp;quot; | 2&lt;br /&gt;
| align=&amp;quot;right&amp;quot; | 0x2&lt;br /&gt;
| align=&amp;quot;right&amp;quot; | 0000000000000010&lt;br /&gt;
| 1&lt;br /&gt;
|-&lt;br /&gt;
| colors.magenta&lt;br /&gt;
| align=&amp;quot;right&amp;quot; | 4&lt;br /&gt;
| align=&amp;quot;right&amp;quot; | 0x4&lt;br /&gt;
| align=&amp;quot;right&amp;quot; | 0000000000000100&lt;br /&gt;
| 2&lt;br /&gt;
|-&lt;br /&gt;
| colors.lightBlue&lt;br /&gt;
| align=&amp;quot;right&amp;quot; | 8&lt;br /&gt;
| align=&amp;quot;right&amp;quot; | 0x8&lt;br /&gt;
| align=&amp;quot;right&amp;quot; | 0000000000001000&lt;br /&gt;
| 3&lt;br /&gt;
|-&lt;br /&gt;
| colors.yellow&lt;br /&gt;
| align=&amp;quot;right&amp;quot; | 16&lt;br /&gt;
| align=&amp;quot;right&amp;quot; | 0x10&lt;br /&gt;
| align=&amp;quot;right&amp;quot; | 0000000000010000&lt;br /&gt;
| 4&lt;br /&gt;
|-&lt;br /&gt;
| colors.lime&lt;br /&gt;
| align=&amp;quot;right&amp;quot; | 32&lt;br /&gt;
| align=&amp;quot;right&amp;quot; | 0x20&lt;br /&gt;
| align=&amp;quot;right&amp;quot; | 0000000000100000&lt;br /&gt;
| 5&lt;br /&gt;
|-&lt;br /&gt;
| colors.pink&lt;br /&gt;
| align=&amp;quot;right&amp;quot; | 64&lt;br /&gt;
| align=&amp;quot;right&amp;quot; | 0x40&lt;br /&gt;
| align=&amp;quot;right&amp;quot; | 0000000001000000&lt;br /&gt;
| 6&lt;br /&gt;
|-&lt;br /&gt;
| colors.gray&lt;br /&gt;
| align=&amp;quot;right&amp;quot; | 128&lt;br /&gt;
| align=&amp;quot;right&amp;quot; | 0x80&lt;br /&gt;
| align=&amp;quot;right&amp;quot; | 0000000010000000&lt;br /&gt;
| 7&lt;br /&gt;
|-&lt;br /&gt;
| colors.lightGray&lt;br /&gt;
| align=&amp;quot;right&amp;quot; | 256&lt;br /&gt;
| align=&amp;quot;right&amp;quot; | 0x100&lt;br /&gt;
| align=&amp;quot;right&amp;quot; | 0000000100000000&lt;br /&gt;
| 8&lt;br /&gt;
|-&lt;br /&gt;
| colors.cyan&lt;br /&gt;
| align=&amp;quot;right&amp;quot; | 512&lt;br /&gt;
| align=&amp;quot;right&amp;quot; | 0x200&lt;br /&gt;
| align=&amp;quot;right&amp;quot; | 0000001000000000&lt;br /&gt;
| 9&lt;br /&gt;
|-&lt;br /&gt;
| colors.purple&lt;br /&gt;
| align=&amp;quot;right&amp;quot; | 1024&lt;br /&gt;
| align=&amp;quot;right&amp;quot; | 0x400&lt;br /&gt;
| align=&amp;quot;right&amp;quot; | 0000010000000000&lt;br /&gt;
| a&lt;br /&gt;
|-&lt;br /&gt;
| colors.blue&lt;br /&gt;
| align=&amp;quot;right&amp;quot; | 2048&lt;br /&gt;
| align=&amp;quot;right&amp;quot; | 0x800&lt;br /&gt;
| align=&amp;quot;right&amp;quot; | 0000100000000000&lt;br /&gt;
| b&lt;br /&gt;
|-&lt;br /&gt;
| colors.brown&lt;br /&gt;
| align=&amp;quot;right&amp;quot; | 4096&lt;br /&gt;
| align=&amp;quot;right&amp;quot; | 0x1000&lt;br /&gt;
| align=&amp;quot;right&amp;quot; | 0001000000000000&lt;br /&gt;
| c&lt;br /&gt;
|-&lt;br /&gt;
| colors.green&lt;br /&gt;
| align=&amp;quot;right&amp;quot; | 8192&lt;br /&gt;
| align=&amp;quot;right&amp;quot; | 0x2000&lt;br /&gt;
| align=&amp;quot;right&amp;quot; | 0010000000000000&lt;br /&gt;
| d&lt;br /&gt;
|-&lt;br /&gt;
| colors.red&lt;br /&gt;
| align=&amp;quot;right&amp;quot; | 16384&lt;br /&gt;
| align=&amp;quot;right&amp;quot; | 0x4000&lt;br /&gt;
| align=&amp;quot;right&amp;quot; | 0100000000000000&lt;br /&gt;
| e&lt;br /&gt;
|-&lt;br /&gt;
| colors.black&lt;br /&gt;
| align=&amp;quot;right&amp;quot; | 32768&lt;br /&gt;
| align=&amp;quot;right&amp;quot; | 0x8000&lt;br /&gt;
| align=&amp;quot;right&amp;quot; | 1000000000000000&lt;br /&gt;
| f&lt;br /&gt;
|}&lt;br /&gt;
[[Category:APIs]]&lt;/div&gt;</summary>
		<author><name>YoYoYonnY</name></author>	</entry>

	<entry>
		<id>https://www.computercraft.info/wiki/index.php?title=Coroutine_(API)&amp;diff=5779</id>
		<title>Coroutine (API)</title>
		<link rel="alternate" type="text/html" href="https://www.computercraft.info/wiki/index.php?title=Coroutine_(API)&amp;diff=5779"/>
				<updated>2013-07-03T04:36:25Z</updated>
		
		<summary type="html">&lt;p&gt;YoYoYonnY: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{NeedsWork}}&lt;br /&gt;
:{| border=&amp;quot;1&amp;quot; class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
| '''Bug'''&lt;br /&gt;
'''From ComputerCraft 1.3''' this API suffers from the problem of potentially spawning Java threads that live forever therefore, use of coroutines should be minimized. This is '''fixed in ComputerCraft 1.32+''', though.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
''This is for the Coroutine API. For the Coroutine Object, visit [[Coroutine (type)]].''&lt;br /&gt;
&lt;br /&gt;
Coroutine is a default Lua 5.1 API defined [http://www.lua.org/manual/5.1/manual.html#5.2 here]. Please list any non-working functions on this page.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;table style=&amp;quot;width: 100%; border: solid 1px black; margin: 2px; border-spacing: 0px;&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&amp;lt;td colspan=&amp;quot;3&amp;quot; style=&amp;quot;font-weight: bold; font-size: large; padding-bottom: .3em; border-bottom: solid #C9C9C9 1px; background: #D3FFC2; line-height:28px;&amp;quot;&amp;gt;&lt;br /&gt;
[[File:Grid_disk.png|24px]]&amp;amp;nbsp;&amp;amp;nbsp;&lt;br /&gt;
Coroutine (API)&lt;br /&gt;
&amp;lt;/td&amp;gt;&amp;lt;/tr&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tr&amp;gt;&amp;lt;td style=&amp;quot;width: 100px; background: #E0E0E0; padding: .4em; font-weight:bold;&amp;quot;&amp;gt;Return&amp;lt;/td&amp;gt;&amp;lt;td style=&amp;quot;width: 350px; background: #E0E0E0; padding: .4em; font-weight:bold;&amp;quot;&amp;gt;Method Name&amp;lt;/td&amp;gt;&amp;lt;td style=&amp;quot;background: #E0E0E0; padding: .4em; font-weight:bold;&amp;quot;&amp;gt;Description&amp;lt;/td&amp;gt;&amp;lt;/tr&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tr style=&amp;quot;background-color: #FFFFFF;&amp;quot;&amp;gt;&amp;lt;td style=&amp;quot;border-top: solid #C9C9C9 1px; padding: .4em;&amp;quot;&amp;gt;[[Coroutine (type)|coroutine]] coro&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td style=&amp;quot;border-top: solid #C9C9C9 1px; padding: .4em;&amp;quot;&amp;gt;[[coroutine.create]]({{type|function}} f)&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td style=&amp;quot;border-top: solid #C9C9C9 1px; padding: .4em;&amp;quot;&amp;gt;Creates a new coroutine.&amp;lt;/td&amp;gt;&amp;lt;/tr&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tr style=&amp;quot;background-color: #E8E8E8;&amp;quot;&amp;gt;&amp;lt;td style=&amp;quot;border-top: solid #C9C9C9 1px; padding: .4em;&amp;quot;&amp;gt;[[Boolean (type)|boolean]] success, …&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td style=&amp;quot;border-top: solid #C9C9C9 1px; padding: .4em;&amp;quot;&amp;gt;[[coroutine.resume]]({{type|coroutine}} coro, [var1], [var2], ...)&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td style=&amp;quot;border-top: solid #C9C9C9 1px; padding: .4em;&amp;quot;&amp;gt;Starts or resumes an existing coroutine.&amp;lt;/td&amp;gt;&amp;lt;/tr&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tr style=&amp;quot;background-color: #FFFFFF;&amp;quot;&amp;gt;&amp;lt;td style=&amp;quot;border-top: solid #C9C9C9 1px; padding: .4em;&amp;quot;&amp;gt;[[Coroutine (type)|coroutine]] coro&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td style=&amp;quot;border-top: solid #C9C9C9 1px; padding: .4em;&amp;quot;&amp;gt;[[coroutine.running]]()&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td style=&amp;quot;border-top: solid #C9C9C9 1px; padding: .4em;&amp;quot;&amp;gt;Returns the currently executing coroutine.&amp;lt;/td&amp;gt;&amp;lt;/tr&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tr style=&amp;quot;background-color: #E8E8E8;&amp;quot;&amp;gt;&amp;lt;td style=&amp;quot;border-top: solid #C9C9C9 1px; padding: .4em;&amp;quot;&amp;gt;[[String (type)|string]] status&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td style=&amp;quot;border-top: solid #C9C9C9 1px; padding: .4em;&amp;quot;&amp;gt;[[coroutine.status]]({{type|coroutine}} coroutine)&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td style=&amp;quot;border-top: solid #C9C9C9 1px; padding: .4em;&amp;quot;&amp;gt;Returns the status of the given coroutine.&amp;lt;/td&amp;gt;&amp;lt;/tr&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tr style=&amp;quot;background-color: #FFFFFF;&amp;quot;&amp;gt;&amp;lt;td style=&amp;quot;border-top: solid #C9C9C9 1px; padding: .4em;&amp;quot;&amp;gt;[[Function (type)|function]] coroutine wrapper&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td style=&amp;quot;border-top: solid #C9C9C9 1px; padding: .4em;&amp;quot;&amp;gt;[[coroutine.wrap]]({{type|function}} function)&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td style=&amp;quot;border-top: solid #C9C9C9 1px; padding: .4em;&amp;quot;&amp;gt;Creates a new coroutine and wraps it in a function.&amp;lt;/td&amp;gt;&amp;lt;/tr&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tr style=&amp;quot;background-color: #E8E8E8;&amp;quot;&amp;gt;&amp;lt;td style=&amp;quot;border-top: solid #C9C9C9 1px; padding: .4em;&amp;quot;&amp;gt;[var3], [var4], …&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td style=&amp;quot;border-top: solid #C9C9C9 1px; padding: .4em;&amp;quot;&amp;gt;[[coroutine.yield]]([var1], [var2], …)&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td style=&amp;quot;border-top: solid #C9C9C9 1px; padding: .4em;&amp;quot;&amp;gt;Pauses the currently executing coroutine and passes control to its caller.&amp;lt;/td&amp;gt;&amp;lt;/tr&amp;gt;&lt;br /&gt;
&amp;lt;/table&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Coroutine States and Ancestry ==&lt;br /&gt;
Every coroutine is in one of four states:&lt;br /&gt;
* A ''suspended'' coroutine is one that has not yet been started or that has yielded. A suspended coroutine can become running if it is passed to [[coroutine.resume]].&lt;br /&gt;
* A ''running'' coroutine is one that is currently executing code. Only one coroutine can be running at a time on a particular computer. A running coroutine can become suspended if it [[coroutine.yield]], normal if it calls [[coroutine.resume]] on another coroutine, or dead by if it returns from its body function.&lt;br /&gt;
* A ''normal'' coroutine is one that, while running, resumed another coroutine (the ''child coroutine''). A normal coroutine can become running if its child calls [[coroutine.yield]] or returns from its function body.&lt;br /&gt;
* A ''dead'' coroutine is one that, while running, returned from its function body. A dead coroutine can never change state.&lt;br /&gt;
&lt;br /&gt;
While suspended and dead coroutines simply sit loose with no connections to other coroutines, normal and running coroutines have an ancestry relationship between them. Exactly one coroutine is running at any given time, and the running coroutine has no children. Every running or normal coroutine except the top-level BIOS coroutine has a parent, and this relationship forms a chain with one end (the furthest ancestor) being the top-level BIOS coroutine and the other end (the furthest descendant) being the running coroutine. Remember that only the running coroutine can actually execute code, so any functions invoked must be invoked by that coroutine. Then, calling [[coroutine.resume]] makes the chain longer by taking a previously suspended coroutine, hanging it underneath the current coroutine as a new child, and making the current coroutine normal and the new child running. Meanwhile, calling [[coroutine.yield]] makes the chain shorter by turning the currently executing coroutine into a suspended coroutine, detaching it from the chain, and letting its former parent become running.&lt;br /&gt;
&lt;br /&gt;
It is important not to confuse this coroutine chain with the function call stack. Each individual coroutine contains a complete function call stack of its own, rooted at the coroutine’s body function, whether the coroutine is running, normal, or suspended; the chain described in the previous paragraph refers to how entire coroutines are connected together.&lt;br /&gt;
&lt;br /&gt;
== Examples ==&lt;br /&gt;
As the coroutine API is very tightly coupled and many of its function must be used to get any interesting results, examples are shown here instead of on the individual function pages.&lt;br /&gt;
&lt;br /&gt;
=== Using the Basic Coroutine Functions ===&lt;br /&gt;
This example demonstrates using the basic coroutine functions to pass control and data between coroutines. This example prints the numbers 1 through 17 in order, showing how control flow moves through the main program coroutine and the two created coroutines, while using assertions to show how data flows through the program:&lt;br /&gt;
&lt;br /&gt;
 -- These variables will hold the coroutine objects.&lt;br /&gt;
 local c1 = nil&lt;br /&gt;
 local c2 = nil&lt;br /&gt;
 &lt;br /&gt;
 -- This function will be the body of the first coroutine.&lt;br /&gt;
 local function f1(x)&lt;br /&gt;
   -- The main code, below, starts c1 first, passing 1.&lt;br /&gt;
   -- Thus c1 should be running, c2 should be suspended (not started yet), and x should receive the value from main, 1.&lt;br /&gt;
   -- STEP 2: Check these assumptions.&lt;br /&gt;
   print(2)&lt;br /&gt;
   assert(coroutine.status(c1) == &amp;quot;running&amp;quot;)&lt;br /&gt;
   assert(coroutine.status(c2) == &amp;quot;suspended&amp;quot;)&lt;br /&gt;
   assert(x == 1)&lt;br /&gt;
   -- STEP 3: Run c2 until it yields, start it off with the value 2.&lt;br /&gt;
   print(3)&lt;br /&gt;
   success, value = coroutine.resume(c2, 2)&lt;br /&gt;
   assert(success)&lt;br /&gt;
   -- In step 6, c2 yields and passes back the value 3.&lt;br /&gt;
   -- Then c2, having yielded, should be suspended, and c1 should be running again.&lt;br /&gt;
   -- STEP 7: Check all that.&lt;br /&gt;
   print(7)&lt;br /&gt;
   assert(coroutine.status(c1) == &amp;quot;running&amp;quot;)&lt;br /&gt;
   assert(coroutine.status(c2) == &amp;quot;suspended&amp;quot;)&lt;br /&gt;
   assert(value == 3)&lt;br /&gt;
   -- STEP 8: Run c2 again, passing it the value 4.&lt;br /&gt;
   -- Since c2 has already run before, this time the 4 will come out of the yield() instead of appear as a function parameter.&lt;br /&gt;
   print(8)&lt;br /&gt;
   success, value = coroutine.resume(c2, 4)&lt;br /&gt;
   -- In step 10, c2 yields and passes back the value 5.&lt;br /&gt;
   -- Then c2, having yielded, should be suspended, and c1 should be running again.&lt;br /&gt;
   -- STEP 11: Check all that.&lt;br /&gt;
   print(11)&lt;br /&gt;
   assert(coroutine.status(c1) == &amp;quot;running&amp;quot;)&lt;br /&gt;
   assert(coroutine.status(c2) == &amp;quot;suspended&amp;quot;)&lt;br /&gt;
   assert(value == 5)&lt;br /&gt;
   -- STEP 12: Yield, turning c1 back into a suspended coroutine and continuing execution of the main program, passing back value 6.&lt;br /&gt;
   print(12)&lt;br /&gt;
   value = coroutine.yield(6)&lt;br /&gt;
 end&lt;br /&gt;
 &lt;br /&gt;
 -- This function will be the body of the second coroutine.&lt;br /&gt;
 local function f2(x)&lt;br /&gt;
   -- The first time c2 is run, it is run from f1, which passes 2.&lt;br /&gt;
   -- Thus c1 should be normal (as we are nested inside it), c2 should be running, and x should receive the value from f1, 2.&lt;br /&gt;
   -- STEP 4: Check these assumptions.&lt;br /&gt;
   print(4)&lt;br /&gt;
   assert(coroutine.status(c1) == &amp;quot;normal&amp;quot;)&lt;br /&gt;
   assert(coroutine.status(c2) == &amp;quot;running&amp;quot;)&lt;br /&gt;
   assert(x == 2)&lt;br /&gt;
   -- Because c1 is not suspended, we should not be able to resume it.&lt;br /&gt;
   -- STEP 5: Check this is correct.&lt;br /&gt;
   print(5)&lt;br /&gt;
   success, value = coroutine.resume(c1)&lt;br /&gt;
   assert(not success)&lt;br /&gt;
   assert(value == &amp;quot;cannot resume normal coroutine&amp;quot;)&lt;br /&gt;
   -- STEP 6: Yield, turning c2 back into a suspended coroutine and continuing execution of c1, passing back value 3.&lt;br /&gt;
   print(6)&lt;br /&gt;
   value = coroutine.yield(3)&lt;br /&gt;
   -- In step 8, c1 resumed c2 again and passed the value 4.&lt;br /&gt;
   -- c2 should now be running again, and c1 normal again.&lt;br /&gt;
   -- STEP 9: Check all that.&lt;br /&gt;
   print(9)&lt;br /&gt;
   assert(coroutine.status(c1) == &amp;quot;normal&amp;quot;)&lt;br /&gt;
   assert(coroutine.status(c2) == &amp;quot;running&amp;quot;)&lt;br /&gt;
   assert(value == 4)&lt;br /&gt;
   -- STEP 10: Yield, turning c2 back into a suspended coroutine and continuing execution of c1, passing back value 5.&lt;br /&gt;
   print(10)&lt;br /&gt;
   value = coroutine.yield(5)&lt;br /&gt;
   -- In step 14, the main program resumed c2 directly and passed the value 7, bypassing c1.&lt;br /&gt;
   -- So c2 should be running and c1 should be suspended.&lt;br /&gt;
   -- STEP 15: Check all that.&lt;br /&gt;
   print(15)&lt;br /&gt;
   assert(coroutine.status(c1) == &amp;quot;suspended&amp;quot;)&lt;br /&gt;
   assert(coroutine.status(c2) == &amp;quot;running&amp;quot;)&lt;br /&gt;
   assert(value == 7)&lt;br /&gt;
   -- STEP 16: Now die, returning value 8 to the main program.&lt;br /&gt;
   print(16)&lt;br /&gt;
   return 8&lt;br /&gt;
 end&lt;br /&gt;
 &lt;br /&gt;
 -- Construct the two coroutines.&lt;br /&gt;
 c1 = coroutine.create(f1)&lt;br /&gt;
 c2 = coroutine.create(f2)&lt;br /&gt;
 &lt;br /&gt;
 -- Newly constructed coroutines are always suspended.&lt;br /&gt;
 assert(coroutine.status(c1) == &amp;quot;suspended&amp;quot;)&lt;br /&gt;
 assert(coroutine.status(c2) == &amp;quot;suspended&amp;quot;)&lt;br /&gt;
 &lt;br /&gt;
 -- STEP 1: Run c1 until it yields, starting it off with the value 1.&lt;br /&gt;
 print(1)&lt;br /&gt;
 success, value = coroutine.resume(c1, 1)&lt;br /&gt;
 assert(success)&lt;br /&gt;
 &lt;br /&gt;
 -- In step 12, c1 should have yielded and returned the value 6.&lt;br /&gt;
 -- So now c1 and c2 should both be suspended.&lt;br /&gt;
 -- STEP 13: Check all that.&lt;br /&gt;
 print(13)&lt;br /&gt;
 assert(coroutine.status(c1) == &amp;quot;suspended&amp;quot;)&lt;br /&gt;
 assert(coroutine.status(c2) == &amp;quot;suspended&amp;quot;)&lt;br /&gt;
 assert(value == 6)&lt;br /&gt;
 &lt;br /&gt;
 -- STEP 14: Run c2 directly, NOT nested inside c1 this time, passing it the value 7.&lt;br /&gt;
 print(14)&lt;br /&gt;
 success, value = coroutine.resume(c2, 7)&lt;br /&gt;
 assert(success)&lt;br /&gt;
 &lt;br /&gt;
 -- c2 should have exited normally, returning the value 8.&lt;br /&gt;
 -- Therefore c1 should still be suspended, but c2 should be dead.&lt;br /&gt;
 -- STEP 17: Check all that.&lt;br /&gt;
 print(17)&lt;br /&gt;
 assert(coroutine.status(c1) == &amp;quot;suspended&amp;quot;)&lt;br /&gt;
 assert(coroutine.status(c2) == &amp;quot;dead&amp;quot;)&lt;br /&gt;
 assert(value == 8)&lt;br /&gt;
&lt;br /&gt;
=== Using Coroutine Wrapper Functions ===&lt;br /&gt;
This second example is virtually identical, but shows using [[coroutine.wrap]] and wrapper functions instead of the basic coroutine functions (checks of [[coroutine.status]] have been removed as the raw coroutine objects are not available):&lt;br /&gt;
&lt;br /&gt;
 -- These variables will hold the coroutine wrapper functions.&lt;br /&gt;
 local cw1 = nil&lt;br /&gt;
 local cw2 = nil&lt;br /&gt;
 &lt;br /&gt;
 -- This function will be the body of the first coroutine.&lt;br /&gt;
 local function f1(x)&lt;br /&gt;
   -- The main code, below, starts c1 first, passing 1.&lt;br /&gt;
   -- Thus c1 should be running, c2 should be suspended (not started yet), and x should receive the value from main, 1.&lt;br /&gt;
   -- STEP 2: Check these assumptions.&lt;br /&gt;
   print(2)&lt;br /&gt;
   assert(x == 1)&lt;br /&gt;
   -- STEP 3: Run c2 until it yields, start it off with the value 2.&lt;br /&gt;
   print(3)&lt;br /&gt;
   value = cw2(2)&lt;br /&gt;
   -- In step 6, c2 yields and passes back the value 3.&lt;br /&gt;
   -- Then c2, having yielded, should be suspended, and c1 should be running again.&lt;br /&gt;
   -- STEP 7: Check all that.&lt;br /&gt;
   print(7)&lt;br /&gt;
   assert(value == 3)&lt;br /&gt;
   -- STEP 8: Run c2 again, passing it the value 4.&lt;br /&gt;
   -- Since c2 has already run before, this time the 4 will come out of the yield() instead of appear as a function parameter.&lt;br /&gt;
   print(8)&lt;br /&gt;
   value = cw2(4)&lt;br /&gt;
   -- In step 10, c2 yields and passes back the value 5.&lt;br /&gt;
   -- Then c2, having yielded, should be suspended, and c1 should be running again.&lt;br /&gt;
   -- STEP 11: Check all that.&lt;br /&gt;
   print(11)&lt;br /&gt;
   assert(value == 5)&lt;br /&gt;
   -- STEP 12: Yield, turning c1 back into a suspended coroutine and continuing execution of the main program, passing back value 6.&lt;br /&gt;
   print(12)&lt;br /&gt;
   value = coroutine.yield(6)&lt;br /&gt;
 end&lt;br /&gt;
 &lt;br /&gt;
 -- This function will be the body of the second coroutine.&lt;br /&gt;
 local function f2(x)&lt;br /&gt;
   -- The first time c2 is run, it is run from f1, which passes 2.&lt;br /&gt;
   -- Thus c1 should be normal (as we are nested inside it), c2 should be running, and x should receive the value from f1, 2.&lt;br /&gt;
   -- STEP 4: Check these assumptions.&lt;br /&gt;
   print(4)&lt;br /&gt;
   assert(x == 2)&lt;br /&gt;
   -- Because c1 is not suspended, we should not be able to resume it.&lt;br /&gt;
   -- STEP 5: Check this is correct (we must use pcall because an error will be raised).&lt;br /&gt;
   print(5)&lt;br /&gt;
   success, value = pcall(cw1)&lt;br /&gt;
   assert(not success)&lt;br /&gt;
   -- STEP 6: Yield, turning c2 back into a suspended coroutine and continuing execution of c1, passing back value 3.&lt;br /&gt;
   print(6)&lt;br /&gt;
   value = coroutine.yield(3)&lt;br /&gt;
   -- In step 8, c1 resumed c2 again and passed the value 4.&lt;br /&gt;
   -- c2 should now be running again, and c1 normal again.&lt;br /&gt;
   -- STEP 9: Check all that.&lt;br /&gt;
   print(9)&lt;br /&gt;
   assert(value == 4)&lt;br /&gt;
   -- STEP 10: Yield, turning c2 back into a suspended coroutine and continuing execution of c1, passing back value 5.&lt;br /&gt;
   print(10)&lt;br /&gt;
   value = coroutine.yield(5)&lt;br /&gt;
   -- In step 14, the main program resumed c2 directly and passed the value 7, bypassing c1.&lt;br /&gt;
   -- So c2 should be running and c1 should be suspended.&lt;br /&gt;
   -- STEP 15: Check all that.&lt;br /&gt;
   print(15)&lt;br /&gt;
   assert(value == 7)&lt;br /&gt;
   -- STEP 16: Now die, returning value 8 to the main program.&lt;br /&gt;
   print(16)&lt;br /&gt;
   return 8&lt;br /&gt;
 end&lt;br /&gt;
 &lt;br /&gt;
 -- Construct the two coroutine wrappers.&lt;br /&gt;
 cw1 = coroutine.wrap(f1)&lt;br /&gt;
 cw2 = coroutine.wrap(f2)&lt;br /&gt;
 &lt;br /&gt;
 -- STEP 1: Run cw1 until it yields, starting it off with the value 1.&lt;br /&gt;
 print(1)&lt;br /&gt;
 value = cw1(1)&lt;br /&gt;
 &lt;br /&gt;
 -- In step 12, c1 should have yielded and returned the value 6.&lt;br /&gt;
 -- So now c1 and c2 should both be suspended.&lt;br /&gt;
 -- STEP 13: Check all that.&lt;br /&gt;
 print(13)&lt;br /&gt;
 assert(value == 6)&lt;br /&gt;
 &lt;br /&gt;
 -- STEP 14: Run c2 directly, NOT nested inside c1 this time, passing it the value 7.&lt;br /&gt;
 print(14)&lt;br /&gt;
 value = cw2(7)&lt;br /&gt;
 &lt;br /&gt;
 -- c2 should have exited normally, returning the value 8.&lt;br /&gt;
 -- Therefore c1 should still be suspended, but c2 should be dead.&lt;br /&gt;
 -- STEP 17: Check all that.&lt;br /&gt;
 print(17)&lt;br /&gt;
 assert(value == 8)&lt;br /&gt;
&lt;br /&gt;
== Interaction with Other APIs ==&lt;br /&gt;
The [[OS (API)#pullEvent|os.pullEventRaw]] (and therefore [[os.pullEvent]]) functions are built on top of coroutines: &amp;lt;code&amp;gt;os.pullEventRaw&amp;lt;/code&amp;gt; actually just calls [[coroutine.yield]], passing the event type filter up to the parent coroutine. The parent coroutine is expected to wait until an event of the required type arrives, then use [[coroutine.resume]] to pass the event to the suspended coroutine (where it will be returned from &amp;lt;code&amp;gt;os.pullEventRaw&amp;lt;/code&amp;gt;). If you use the [[Parallel (API)|parallel API]], this is exactly what [[parallel.waitForAny]] and [[parallel.waitForAll]] do: they pull events from the system event queue (or even from a higher invocation of &amp;lt;code&amp;gt;parallel.waitForAny&amp;lt;/code&amp;gt; or &amp;lt;code&amp;gt;parallel.waitForAll&amp;lt;/code&amp;gt;!) and deliver them to all nested coroutines. Therefore, the easiest way to use coroutines is the parallel API, if it works for your situation. However, in the event that you are not able to use the parallel API (e.g. if you need to add and remove coroutines from the executing set dynamically), you can build your own dispatcher that delivers events in the same way as the parallel API—looking at the source code to the parallel API may be useful here.&lt;br /&gt;
&lt;br /&gt;
If you choose to use coroutines in a different way, then &amp;lt;code&amp;gt;os.pullEventRaw&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;os.pullEvent&amp;lt;/code&amp;gt; will not work. This in turn will break any other API function which is written on top of &amp;lt;code&amp;gt;os.pullEvent&amp;lt;/code&amp;gt;. As a guideline, nearly any API function that can possibly take time to complete will fall into this category; some examples are:&lt;br /&gt;
* [[rednet.receive]] blocks until either a [[Rednet message (event)|rednet_message event]] or (if a timeout was requested) a matching [[Timer (event)|timer event]] occurs.&lt;br /&gt;
* [[Gps (API)|gps.locate]] blocks until either a number of [[Modem message (event)|modem_message events]] or (if a timeout was requested) a matching [[Timer (event)|timer event]] occurs.&lt;br /&gt;
* [[http.get]] blocks until an [[Http success (event)|HTTP success event]] or [[Http failure (event)|HTTP failure event]] occurs.&lt;br /&gt;
* [[IO (API)|io.read]] and the built-in [[read]] functions block waiting for, presumably, either [[Char (event)|char events]] or [[Key (event)|key events]].&lt;br /&gt;
* [[os.sleep]] blocks until a matching [[Timer (event)|timer event]] occurs.&lt;br /&gt;
* [[textutils.slowPrint]] calls [[os.sleep]].&lt;br /&gt;
* [[textutils.pagedPrint]] blocks until a [[Key (event)|key event]] occurs for each page.&lt;br /&gt;
* Most of the functions in the [[Turtle (API)|turtle API]] (with the exception of [[turtle.getItemCount]], [[turtle.getItemSpace]], and [[turtle.getFuelLevel]]) block waiting for a [[Turtle response (event)|turtle response event]].&lt;br /&gt;
&lt;br /&gt;
Most of these can be worked around by using non-blocking equivalents that return immediately and then queue an event on completion (such as using [[http.request]]) or that deliver an event unconditionally (such as [[Char_(event)|char]] for keyboard input), then handling events in a way that is suitable for the application. However, if possible, it will often be easier to implement event dispatching instead, remembering that [[os.queueEvent]] can be used for inter-coroutine communication within an application. Another alternative, if you must use a custom protocol between your coroutines and dispatcher, might be to replace &amp;lt;code&amp;gt;os.pullEventRaw&amp;lt;/code&amp;gt; with a new function that uses a mechanism appropriate to the application.&lt;br /&gt;
&lt;br /&gt;
[[Category:APIs]]&lt;/div&gt;</summary>
		<author><name>YoYoYonnY</name></author>	</entry>

	<entry>
		<id>https://www.computercraft.info/wiki/index.php?title=Coroutine_(API)&amp;diff=5778</id>
		<title>Coroutine (API)</title>
		<link rel="alternate" type="text/html" href="https://www.computercraft.info/wiki/index.php?title=Coroutine_(API)&amp;diff=5778"/>
				<updated>2013-07-03T04:35:57Z</updated>
		
		<summary type="html">&lt;p&gt;YoYoYonnY: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{NeedsWork}}&lt;br /&gt;
:{| border=&amp;quot;1&amp;quot; class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
| '''Bug'''&lt;br /&gt;
'''From ComputerCraft 1.3''' this API suffers from the problem of potentially spawning Java threads that live forever therefore, use of coroutines should be minimized. This is '''fixed in ComputerCraft 1.32+''', though.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
''This is for the Coroutine API. For the Coroutine Object, visit [[Coroutine (type)]].''&lt;br /&gt;
&lt;br /&gt;
Coroutine is a default Lua 5.1 API defined [http://www.lua.org/manual/5.1/manual.html#5.2 here]. Please list any non-working functions on this page.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;table style=&amp;quot;width: 100%; border: solid 1px black; margin: 2px; border-spacing: 0px;&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&amp;lt;td colspan=&amp;quot;3&amp;quot; style=&amp;quot;font-weight: bold; font-size: large; padding-bottom: .3em; border-bottom: solid #C9C9C9 1px; background: #D3FFC2; line-height:28px;&amp;quot;&amp;gt;&lt;br /&gt;
[[File:Grid_disk.png|24px]]&amp;amp;nbsp;&amp;amp;nbsp;&lt;br /&gt;
Coroutine (API)&lt;br /&gt;
&amp;lt;/td&amp;gt;&amp;lt;/tr&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tr&amp;gt;&amp;lt;td style=&amp;quot;width: 100px; background: #E0E0E0; padding: .4em; font-weight:bold;&amp;quot;&amp;gt;Return&amp;lt;/td&amp;gt;&amp;lt;td style=&amp;quot;width: 350px; background: #E0E0E0; padding: .4em; font-weight:bold;&amp;quot;&amp;gt;Method Name&amp;lt;/td&amp;gt;&amp;lt;td style=&amp;quot;background: #E0E0E0; padding: .4em; font-weight:bold;&amp;quot;&amp;gt;Description&amp;lt;/td&amp;gt;&amp;lt;/tr&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tr style=&amp;quot;background-color: #FFFFFF;&amp;quot;&amp;gt;&amp;lt;td style=&amp;quot;border-top: solid #C9C9C9 1px; padding: .4em;&amp;quot;&amp;gt;[[Coroutine (type)|coroutine]] coro&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td style=&amp;quot;border-top: solid #C9C9C9 1px; padding: .4em;&amp;quot;&amp;gt;[[coroutine.create]]({{Type|function}} f)&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td style=&amp;quot;border-top: solid #C9C9C9 1px; padding: .4em;&amp;quot;&amp;gt;Creates a new coroutine.&amp;lt;/td&amp;gt;&amp;lt;/tr&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tr style=&amp;quot;background-color: #E8E8E8;&amp;quot;&amp;gt;&amp;lt;td style=&amp;quot;border-top: solid #C9C9C9 1px; padding: .4em;&amp;quot;&amp;gt;[[Boolean (type)|boolean]] success, …&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td style=&amp;quot;border-top: solid #C9C9C9 1px; padding: .4em;&amp;quot;&amp;gt;[[coroutine.resume]]({{Type|coroutine}} coro, [var1], [var2], ...)&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td style=&amp;quot;border-top: solid #C9C9C9 1px; padding: .4em;&amp;quot;&amp;gt;Starts or resumes an existing coroutine.&amp;lt;/td&amp;gt;&amp;lt;/tr&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tr style=&amp;quot;background-color: #FFFFFF;&amp;quot;&amp;gt;&amp;lt;td style=&amp;quot;border-top: solid #C9C9C9 1px; padding: .4em;&amp;quot;&amp;gt;[[Coroutine (type)|coroutine]] coro&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td style=&amp;quot;border-top: solid #C9C9C9 1px; padding: .4em;&amp;quot;&amp;gt;[[coroutine.running]]()&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td style=&amp;quot;border-top: solid #C9C9C9 1px; padding: .4em;&amp;quot;&amp;gt;Returns the currently executing coroutine.&amp;lt;/td&amp;gt;&amp;lt;/tr&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tr style=&amp;quot;background-color: #E8E8E8;&amp;quot;&amp;gt;&amp;lt;td style=&amp;quot;border-top: solid #C9C9C9 1px; padding: .4em;&amp;quot;&amp;gt;[[String (type)|string]] status&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td style=&amp;quot;border-top: solid #C9C9C9 1px; padding: .4em;&amp;quot;&amp;gt;[[coroutine.status]]({{type|coroutine}} coroutine)&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td style=&amp;quot;border-top: solid #C9C9C9 1px; padding: .4em;&amp;quot;&amp;gt;Returns the status of the given coroutine.&amp;lt;/td&amp;gt;&amp;lt;/tr&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tr style=&amp;quot;background-color: #FFFFFF;&amp;quot;&amp;gt;&amp;lt;td style=&amp;quot;border-top: solid #C9C9C9 1px; padding: .4em;&amp;quot;&amp;gt;[[Function (type)|function]] coroutine wrapper&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td style=&amp;quot;border-top: solid #C9C9C9 1px; padding: .4em;&amp;quot;&amp;gt;[[coroutine.wrap]]({{type|function}} function)&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td style=&amp;quot;border-top: solid #C9C9C9 1px; padding: .4em;&amp;quot;&amp;gt;Creates a new coroutine and wraps it in a function.&amp;lt;/td&amp;gt;&amp;lt;/tr&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tr style=&amp;quot;background-color: #E8E8E8;&amp;quot;&amp;gt;&amp;lt;td style=&amp;quot;border-top: solid #C9C9C9 1px; padding: .4em;&amp;quot;&amp;gt;[var3], [var4], …&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td style=&amp;quot;border-top: solid #C9C9C9 1px; padding: .4em;&amp;quot;&amp;gt;[[coroutine.yield]]([var1], [var2], …)&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td style=&amp;quot;border-top: solid #C9C9C9 1px; padding: .4em;&amp;quot;&amp;gt;Pauses the currently executing coroutine and passes control to its caller.&amp;lt;/td&amp;gt;&amp;lt;/tr&amp;gt;&lt;br /&gt;
&amp;lt;/table&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Coroutine States and Ancestry ==&lt;br /&gt;
Every coroutine is in one of four states:&lt;br /&gt;
* A ''suspended'' coroutine is one that has not yet been started or that has yielded. A suspended coroutine can become running if it is passed to [[coroutine.resume]].&lt;br /&gt;
* A ''running'' coroutine is one that is currently executing code. Only one coroutine can be running at a time on a particular computer. A running coroutine can become suspended if it [[coroutine.yield]], normal if it calls [[coroutine.resume]] on another coroutine, or dead by if it returns from its body function.&lt;br /&gt;
* A ''normal'' coroutine is one that, while running, resumed another coroutine (the ''child coroutine''). A normal coroutine can become running if its child calls [[coroutine.yield]] or returns from its function body.&lt;br /&gt;
* A ''dead'' coroutine is one that, while running, returned from its function body. A dead coroutine can never change state.&lt;br /&gt;
&lt;br /&gt;
While suspended and dead coroutines simply sit loose with no connections to other coroutines, normal and running coroutines have an ancestry relationship between them. Exactly one coroutine is running at any given time, and the running coroutine has no children. Every running or normal coroutine except the top-level BIOS coroutine has a parent, and this relationship forms a chain with one end (the furthest ancestor) being the top-level BIOS coroutine and the other end (the furthest descendant) being the running coroutine. Remember that only the running coroutine can actually execute code, so any functions invoked must be invoked by that coroutine. Then, calling [[coroutine.resume]] makes the chain longer by taking a previously suspended coroutine, hanging it underneath the current coroutine as a new child, and making the current coroutine normal and the new child running. Meanwhile, calling [[coroutine.yield]] makes the chain shorter by turning the currently executing coroutine into a suspended coroutine, detaching it from the chain, and letting its former parent become running.&lt;br /&gt;
&lt;br /&gt;
It is important not to confuse this coroutine chain with the function call stack. Each individual coroutine contains a complete function call stack of its own, rooted at the coroutine’s body function, whether the coroutine is running, normal, or suspended; the chain described in the previous paragraph refers to how entire coroutines are connected together.&lt;br /&gt;
&lt;br /&gt;
== Examples ==&lt;br /&gt;
As the coroutine API is very tightly coupled and many of its function must be used to get any interesting results, examples are shown here instead of on the individual function pages.&lt;br /&gt;
&lt;br /&gt;
=== Using the Basic Coroutine Functions ===&lt;br /&gt;
This example demonstrates using the basic coroutine functions to pass control and data between coroutines. This example prints the numbers 1 through 17 in order, showing how control flow moves through the main program coroutine and the two created coroutines, while using assertions to show how data flows through the program:&lt;br /&gt;
&lt;br /&gt;
 -- These variables will hold the coroutine objects.&lt;br /&gt;
 local c1 = nil&lt;br /&gt;
 local c2 = nil&lt;br /&gt;
 &lt;br /&gt;
 -- This function will be the body of the first coroutine.&lt;br /&gt;
 local function f1(x)&lt;br /&gt;
   -- The main code, below, starts c1 first, passing 1.&lt;br /&gt;
   -- Thus c1 should be running, c2 should be suspended (not started yet), and x should receive the value from main, 1.&lt;br /&gt;
   -- STEP 2: Check these assumptions.&lt;br /&gt;
   print(2)&lt;br /&gt;
   assert(coroutine.status(c1) == &amp;quot;running&amp;quot;)&lt;br /&gt;
   assert(coroutine.status(c2) == &amp;quot;suspended&amp;quot;)&lt;br /&gt;
   assert(x == 1)&lt;br /&gt;
   -- STEP 3: Run c2 until it yields, start it off with the value 2.&lt;br /&gt;
   print(3)&lt;br /&gt;
   success, value = coroutine.resume(c2, 2)&lt;br /&gt;
   assert(success)&lt;br /&gt;
   -- In step 6, c2 yields and passes back the value 3.&lt;br /&gt;
   -- Then c2, having yielded, should be suspended, and c1 should be running again.&lt;br /&gt;
   -- STEP 7: Check all that.&lt;br /&gt;
   print(7)&lt;br /&gt;
   assert(coroutine.status(c1) == &amp;quot;running&amp;quot;)&lt;br /&gt;
   assert(coroutine.status(c2) == &amp;quot;suspended&amp;quot;)&lt;br /&gt;
   assert(value == 3)&lt;br /&gt;
   -- STEP 8: Run c2 again, passing it the value 4.&lt;br /&gt;
   -- Since c2 has already run before, this time the 4 will come out of the yield() instead of appear as a function parameter.&lt;br /&gt;
   print(8)&lt;br /&gt;
   success, value = coroutine.resume(c2, 4)&lt;br /&gt;
   -- In step 10, c2 yields and passes back the value 5.&lt;br /&gt;
   -- Then c2, having yielded, should be suspended, and c1 should be running again.&lt;br /&gt;
   -- STEP 11: Check all that.&lt;br /&gt;
   print(11)&lt;br /&gt;
   assert(coroutine.status(c1) == &amp;quot;running&amp;quot;)&lt;br /&gt;
   assert(coroutine.status(c2) == &amp;quot;suspended&amp;quot;)&lt;br /&gt;
   assert(value == 5)&lt;br /&gt;
   -- STEP 12: Yield, turning c1 back into a suspended coroutine and continuing execution of the main program, passing back value 6.&lt;br /&gt;
   print(12)&lt;br /&gt;
   value = coroutine.yield(6)&lt;br /&gt;
 end&lt;br /&gt;
 &lt;br /&gt;
 -- This function will be the body of the second coroutine.&lt;br /&gt;
 local function f2(x)&lt;br /&gt;
   -- The first time c2 is run, it is run from f1, which passes 2.&lt;br /&gt;
   -- Thus c1 should be normal (as we are nested inside it), c2 should be running, and x should receive the value from f1, 2.&lt;br /&gt;
   -- STEP 4: Check these assumptions.&lt;br /&gt;
   print(4)&lt;br /&gt;
   assert(coroutine.status(c1) == &amp;quot;normal&amp;quot;)&lt;br /&gt;
   assert(coroutine.status(c2) == &amp;quot;running&amp;quot;)&lt;br /&gt;
   assert(x == 2)&lt;br /&gt;
   -- Because c1 is not suspended, we should not be able to resume it.&lt;br /&gt;
   -- STEP 5: Check this is correct.&lt;br /&gt;
   print(5)&lt;br /&gt;
   success, value = coroutine.resume(c1)&lt;br /&gt;
   assert(not success)&lt;br /&gt;
   assert(value == &amp;quot;cannot resume normal coroutine&amp;quot;)&lt;br /&gt;
   -- STEP 6: Yield, turning c2 back into a suspended coroutine and continuing execution of c1, passing back value 3.&lt;br /&gt;
   print(6)&lt;br /&gt;
   value = coroutine.yield(3)&lt;br /&gt;
   -- In step 8, c1 resumed c2 again and passed the value 4.&lt;br /&gt;
   -- c2 should now be running again, and c1 normal again.&lt;br /&gt;
   -- STEP 9: Check all that.&lt;br /&gt;
   print(9)&lt;br /&gt;
   assert(coroutine.status(c1) == &amp;quot;normal&amp;quot;)&lt;br /&gt;
   assert(coroutine.status(c2) == &amp;quot;running&amp;quot;)&lt;br /&gt;
   assert(value == 4)&lt;br /&gt;
   -- STEP 10: Yield, turning c2 back into a suspended coroutine and continuing execution of c1, passing back value 5.&lt;br /&gt;
   print(10)&lt;br /&gt;
   value = coroutine.yield(5)&lt;br /&gt;
   -- In step 14, the main program resumed c2 directly and passed the value 7, bypassing c1.&lt;br /&gt;
   -- So c2 should be running and c1 should be suspended.&lt;br /&gt;
   -- STEP 15: Check all that.&lt;br /&gt;
   print(15)&lt;br /&gt;
   assert(coroutine.status(c1) == &amp;quot;suspended&amp;quot;)&lt;br /&gt;
   assert(coroutine.status(c2) == &amp;quot;running&amp;quot;)&lt;br /&gt;
   assert(value == 7)&lt;br /&gt;
   -- STEP 16: Now die, returning value 8 to the main program.&lt;br /&gt;
   print(16)&lt;br /&gt;
   return 8&lt;br /&gt;
 end&lt;br /&gt;
 &lt;br /&gt;
 -- Construct the two coroutines.&lt;br /&gt;
 c1 = coroutine.create(f1)&lt;br /&gt;
 c2 = coroutine.create(f2)&lt;br /&gt;
 &lt;br /&gt;
 -- Newly constructed coroutines are always suspended.&lt;br /&gt;
 assert(coroutine.status(c1) == &amp;quot;suspended&amp;quot;)&lt;br /&gt;
 assert(coroutine.status(c2) == &amp;quot;suspended&amp;quot;)&lt;br /&gt;
 &lt;br /&gt;
 -- STEP 1: Run c1 until it yields, starting it off with the value 1.&lt;br /&gt;
 print(1)&lt;br /&gt;
 success, value = coroutine.resume(c1, 1)&lt;br /&gt;
 assert(success)&lt;br /&gt;
 &lt;br /&gt;
 -- In step 12, c1 should have yielded and returned the value 6.&lt;br /&gt;
 -- So now c1 and c2 should both be suspended.&lt;br /&gt;
 -- STEP 13: Check all that.&lt;br /&gt;
 print(13)&lt;br /&gt;
 assert(coroutine.status(c1) == &amp;quot;suspended&amp;quot;)&lt;br /&gt;
 assert(coroutine.status(c2) == &amp;quot;suspended&amp;quot;)&lt;br /&gt;
 assert(value == 6)&lt;br /&gt;
 &lt;br /&gt;
 -- STEP 14: Run c2 directly, NOT nested inside c1 this time, passing it the value 7.&lt;br /&gt;
 print(14)&lt;br /&gt;
 success, value = coroutine.resume(c2, 7)&lt;br /&gt;
 assert(success)&lt;br /&gt;
 &lt;br /&gt;
 -- c2 should have exited normally, returning the value 8.&lt;br /&gt;
 -- Therefore c1 should still be suspended, but c2 should be dead.&lt;br /&gt;
 -- STEP 17: Check all that.&lt;br /&gt;
 print(17)&lt;br /&gt;
 assert(coroutine.status(c1) == &amp;quot;suspended&amp;quot;)&lt;br /&gt;
 assert(coroutine.status(c2) == &amp;quot;dead&amp;quot;)&lt;br /&gt;
 assert(value == 8)&lt;br /&gt;
&lt;br /&gt;
=== Using Coroutine Wrapper Functions ===&lt;br /&gt;
This second example is virtually identical, but shows using [[coroutine.wrap]] and wrapper functions instead of the basic coroutine functions (checks of [[coroutine.status]] have been removed as the raw coroutine objects are not available):&lt;br /&gt;
&lt;br /&gt;
 -- These variables will hold the coroutine wrapper functions.&lt;br /&gt;
 local cw1 = nil&lt;br /&gt;
 local cw2 = nil&lt;br /&gt;
 &lt;br /&gt;
 -- This function will be the body of the first coroutine.&lt;br /&gt;
 local function f1(x)&lt;br /&gt;
   -- The main code, below, starts c1 first, passing 1.&lt;br /&gt;
   -- Thus c1 should be running, c2 should be suspended (not started yet), and x should receive the value from main, 1.&lt;br /&gt;
   -- STEP 2: Check these assumptions.&lt;br /&gt;
   print(2)&lt;br /&gt;
   assert(x == 1)&lt;br /&gt;
   -- STEP 3: Run c2 until it yields, start it off with the value 2.&lt;br /&gt;
   print(3)&lt;br /&gt;
   value = cw2(2)&lt;br /&gt;
   -- In step 6, c2 yields and passes back the value 3.&lt;br /&gt;
   -- Then c2, having yielded, should be suspended, and c1 should be running again.&lt;br /&gt;
   -- STEP 7: Check all that.&lt;br /&gt;
   print(7)&lt;br /&gt;
   assert(value == 3)&lt;br /&gt;
   -- STEP 8: Run c2 again, passing it the value 4.&lt;br /&gt;
   -- Since c2 has already run before, this time the 4 will come out of the yield() instead of appear as a function parameter.&lt;br /&gt;
   print(8)&lt;br /&gt;
   value = cw2(4)&lt;br /&gt;
   -- In step 10, c2 yields and passes back the value 5.&lt;br /&gt;
   -- Then c2, having yielded, should be suspended, and c1 should be running again.&lt;br /&gt;
   -- STEP 11: Check all that.&lt;br /&gt;
   print(11)&lt;br /&gt;
   assert(value == 5)&lt;br /&gt;
   -- STEP 12: Yield, turning c1 back into a suspended coroutine and continuing execution of the main program, passing back value 6.&lt;br /&gt;
   print(12)&lt;br /&gt;
   value = coroutine.yield(6)&lt;br /&gt;
 end&lt;br /&gt;
 &lt;br /&gt;
 -- This function will be the body of the second coroutine.&lt;br /&gt;
 local function f2(x)&lt;br /&gt;
   -- The first time c2 is run, it is run from f1, which passes 2.&lt;br /&gt;
   -- Thus c1 should be normal (as we are nested inside it), c2 should be running, and x should receive the value from f1, 2.&lt;br /&gt;
   -- STEP 4: Check these assumptions.&lt;br /&gt;
   print(4)&lt;br /&gt;
   assert(x == 2)&lt;br /&gt;
   -- Because c1 is not suspended, we should not be able to resume it.&lt;br /&gt;
   -- STEP 5: Check this is correct (we must use pcall because an error will be raised).&lt;br /&gt;
   print(5)&lt;br /&gt;
   success, value = pcall(cw1)&lt;br /&gt;
   assert(not success)&lt;br /&gt;
   -- STEP 6: Yield, turning c2 back into a suspended coroutine and continuing execution of c1, passing back value 3.&lt;br /&gt;
   print(6)&lt;br /&gt;
   value = coroutine.yield(3)&lt;br /&gt;
   -- In step 8, c1 resumed c2 again and passed the value 4.&lt;br /&gt;
   -- c2 should now be running again, and c1 normal again.&lt;br /&gt;
   -- STEP 9: Check all that.&lt;br /&gt;
   print(9)&lt;br /&gt;
   assert(value == 4)&lt;br /&gt;
   -- STEP 10: Yield, turning c2 back into a suspended coroutine and continuing execution of c1, passing back value 5.&lt;br /&gt;
   print(10)&lt;br /&gt;
   value = coroutine.yield(5)&lt;br /&gt;
   -- In step 14, the main program resumed c2 directly and passed the value 7, bypassing c1.&lt;br /&gt;
   -- So c2 should be running and c1 should be suspended.&lt;br /&gt;
   -- STEP 15: Check all that.&lt;br /&gt;
   print(15)&lt;br /&gt;
   assert(value == 7)&lt;br /&gt;
   -- STEP 16: Now die, returning value 8 to the main program.&lt;br /&gt;
   print(16)&lt;br /&gt;
   return 8&lt;br /&gt;
 end&lt;br /&gt;
 &lt;br /&gt;
 -- Construct the two coroutine wrappers.&lt;br /&gt;
 cw1 = coroutine.wrap(f1)&lt;br /&gt;
 cw2 = coroutine.wrap(f2)&lt;br /&gt;
 &lt;br /&gt;
 -- STEP 1: Run cw1 until it yields, starting it off with the value 1.&lt;br /&gt;
 print(1)&lt;br /&gt;
 value = cw1(1)&lt;br /&gt;
 &lt;br /&gt;
 -- In step 12, c1 should have yielded and returned the value 6.&lt;br /&gt;
 -- So now c1 and c2 should both be suspended.&lt;br /&gt;
 -- STEP 13: Check all that.&lt;br /&gt;
 print(13)&lt;br /&gt;
 assert(value == 6)&lt;br /&gt;
 &lt;br /&gt;
 -- STEP 14: Run c2 directly, NOT nested inside c1 this time, passing it the value 7.&lt;br /&gt;
 print(14)&lt;br /&gt;
 value = cw2(7)&lt;br /&gt;
 &lt;br /&gt;
 -- c2 should have exited normally, returning the value 8.&lt;br /&gt;
 -- Therefore c1 should still be suspended, but c2 should be dead.&lt;br /&gt;
 -- STEP 17: Check all that.&lt;br /&gt;
 print(17)&lt;br /&gt;
 assert(value == 8)&lt;br /&gt;
&lt;br /&gt;
== Interaction with Other APIs ==&lt;br /&gt;
The [[OS (API)#pullEvent|os.pullEventRaw]] (and therefore [[os.pullEvent]]) functions are built on top of coroutines: &amp;lt;code&amp;gt;os.pullEventRaw&amp;lt;/code&amp;gt; actually just calls [[coroutine.yield]], passing the event type filter up to the parent coroutine. The parent coroutine is expected to wait until an event of the required type arrives, then use [[coroutine.resume]] to pass the event to the suspended coroutine (where it will be returned from &amp;lt;code&amp;gt;os.pullEventRaw&amp;lt;/code&amp;gt;). If you use the [[Parallel (API)|parallel API]], this is exactly what [[parallel.waitForAny]] and [[parallel.waitForAll]] do: they pull events from the system event queue (or even from a higher invocation of &amp;lt;code&amp;gt;parallel.waitForAny&amp;lt;/code&amp;gt; or &amp;lt;code&amp;gt;parallel.waitForAll&amp;lt;/code&amp;gt;!) and deliver them to all nested coroutines. Therefore, the easiest way to use coroutines is the parallel API, if it works for your situation. However, in the event that you are not able to use the parallel API (e.g. if you need to add and remove coroutines from the executing set dynamically), you can build your own dispatcher that delivers events in the same way as the parallel API—looking at the source code to the parallel API may be useful here.&lt;br /&gt;
&lt;br /&gt;
If you choose to use coroutines in a different way, then &amp;lt;code&amp;gt;os.pullEventRaw&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;os.pullEvent&amp;lt;/code&amp;gt; will not work. This in turn will break any other API function which is written on top of &amp;lt;code&amp;gt;os.pullEvent&amp;lt;/code&amp;gt;. As a guideline, nearly any API function that can possibly take time to complete will fall into this category; some examples are:&lt;br /&gt;
* [[rednet.receive]] blocks until either a [[Rednet message (event)|rednet_message event]] or (if a timeout was requested) a matching [[Timer (event)|timer event]] occurs.&lt;br /&gt;
* [[Gps (API)|gps.locate]] blocks until either a number of [[Modem message (event)|modem_message events]] or (if a timeout was requested) a matching [[Timer (event)|timer event]] occurs.&lt;br /&gt;
* [[http.get]] blocks until an [[Http success (event)|HTTP success event]] or [[Http failure (event)|HTTP failure event]] occurs.&lt;br /&gt;
* [[IO (API)|io.read]] and the built-in [[read]] functions block waiting for, presumably, either [[Char (event)|char events]] or [[Key (event)|key events]].&lt;br /&gt;
* [[os.sleep]] blocks until a matching [[Timer (event)|timer event]] occurs.&lt;br /&gt;
* [[textutils.slowPrint]] calls [[os.sleep]].&lt;br /&gt;
* [[textutils.pagedPrint]] blocks until a [[Key (event)|key event]] occurs for each page.&lt;br /&gt;
* Most of the functions in the [[Turtle (API)|turtle API]] (with the exception of [[turtle.getItemCount]], [[turtle.getItemSpace]], and [[turtle.getFuelLevel]]) block waiting for a [[Turtle response (event)|turtle response event]].&lt;br /&gt;
&lt;br /&gt;
Most of these can be worked around by using non-blocking equivalents that return immediately and then queue an event on completion (such as using [[http.request]]) or that deliver an event unconditionally (such as [[Char_(event)|char]] for keyboard input), then handling events in a way that is suitable for the application. However, if possible, it will often be easier to implement event dispatching instead, remembering that [[os.queueEvent]] can be used for inter-coroutine communication within an application. Another alternative, if you must use a custom protocol between your coroutines and dispatcher, might be to replace &amp;lt;code&amp;gt;os.pullEventRaw&amp;lt;/code&amp;gt; with a new function that uses a mechanism appropriate to the application.&lt;br /&gt;
&lt;br /&gt;
[[Category:APIs]]&lt;/div&gt;</summary>
		<author><name>YoYoYonnY</name></author>	</entry>

	<entry>
		<id>https://www.computercraft.info/wiki/index.php?title=Coroutine_(API)&amp;diff=5777</id>
		<title>Coroutine (API)</title>
		<link rel="alternate" type="text/html" href="https://www.computercraft.info/wiki/index.php?title=Coroutine_(API)&amp;diff=5777"/>
				<updated>2013-07-03T04:35:14Z</updated>
		
		<summary type="html">&lt;p&gt;YoYoYonnY: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{NeedsWork}}&lt;br /&gt;
:{| border=&amp;quot;1&amp;quot; class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
| '''Bug'''&lt;br /&gt;
'''From ComputerCraft 1.3''' this API suffers from the problem of potentially spawning Java threads that live forever therefore, use of coroutines should be minimized. This is '''fixed in ComputerCraft 1.32+''', though.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
''This is for the Coroutine API. For the Coroutine Object, visit [[Coroutine (type)]].''&lt;br /&gt;
&lt;br /&gt;
Coroutine is a default Lua 5.1 API defined [http://www.lua.org/manual/5.1/manual.html#5.2 here]. Please list any non-working functions on this page.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;table style=&amp;quot;width: 100%; border: solid 1px black; margin: 2px; border-spacing: 0px;&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&amp;lt;td colspan=&amp;quot;3&amp;quot; style=&amp;quot;font-weight: bold; font-size: large; padding-bottom: .3em; border-bottom: solid #C9C9C9 1px; background: #D3FFC2; line-height:28px;&amp;quot;&amp;gt;&lt;br /&gt;
[[File:Grid_disk.png|24px]]&amp;amp;nbsp;&amp;amp;nbsp;&lt;br /&gt;
Coroutine (API)&lt;br /&gt;
&amp;lt;/td&amp;gt;&amp;lt;/tr&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tr&amp;gt;&amp;lt;td style=&amp;quot;width: 100px; background: #E0E0E0; padding: .4em; font-weight:bold;&amp;quot;&amp;gt;Return&amp;lt;/td&amp;gt;&amp;lt;td style=&amp;quot;width: 350px; background: #E0E0E0; padding: .4em; font-weight:bold;&amp;quot;&amp;gt;Method Name&amp;lt;/td&amp;gt;&amp;lt;td style=&amp;quot;background: #E0E0E0; padding: .4em; font-weight:bold;&amp;quot;&amp;gt;Description&amp;lt;/td&amp;gt;&amp;lt;/tr&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tr style=&amp;quot;background-color: #FFFFFF;&amp;quot;&amp;gt;&amp;lt;td style=&amp;quot;border-top: solid #C9C9C9 1px; padding: .4em;&amp;quot;&amp;gt;[[Coroutine (Type)|coroutine]] coro&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td style=&amp;quot;border-top: solid #C9C9C9 1px; padding: .4em;&amp;quot;&amp;gt;[[coroutine.create]]({{Type|function}} f)&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td style=&amp;quot;border-top: solid #C9C9C9 1px; padding: .4em;&amp;quot;&amp;gt;Creates a new coroutine.&amp;lt;/td&amp;gt;&amp;lt;/tr&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tr style=&amp;quot;background-color: #E8E8E8;&amp;quot;&amp;gt;&amp;lt;td style=&amp;quot;border-top: solid #C9C9C9 1px; padding: .4em;&amp;quot;&amp;gt;[[Boolean (type)|boolean]] success, …&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td style=&amp;quot;border-top: solid #C9C9C9 1px; padding: .4em;&amp;quot;&amp;gt;[[coroutine.resume]]({{Type|coroutine}} coro, [var1], [var2], ...)&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td style=&amp;quot;border-top: solid #C9C9C9 1px; padding: .4em;&amp;quot;&amp;gt;Starts or resumes an existing coroutine.&amp;lt;/td&amp;gt;&amp;lt;/tr&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tr style=&amp;quot;background-color: #FFFFFF;&amp;quot;&amp;gt;&amp;lt;td style=&amp;quot;border-top: solid #C9C9C9 1px; padding: .4em;&amp;quot;&amp;gt;[[Coroutine (Type)|coroutine]] coro&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td style=&amp;quot;border-top: solid #C9C9C9 1px; padding: .4em;&amp;quot;&amp;gt;[[coroutine.running]]()&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td style=&amp;quot;border-top: solid #C9C9C9 1px; padding: .4em;&amp;quot;&amp;gt;Returns the currently executing coroutine.&amp;lt;/td&amp;gt;&amp;lt;/tr&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tr style=&amp;quot;background-color: #E8E8E8;&amp;quot;&amp;gt;&amp;lt;td style=&amp;quot;border-top: solid #C9C9C9 1px; padding: .4em;&amp;quot;&amp;gt;[[String (Type)|string]] status&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td style=&amp;quot;border-top: solid #C9C9C9 1px; padding: .4em;&amp;quot;&amp;gt;[[coroutine.status]]({{type|coroutine}} coroutine)&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td style=&amp;quot;border-top: solid #C9C9C9 1px; padding: .4em;&amp;quot;&amp;gt;Returns the status of the given coroutine.&amp;lt;/td&amp;gt;&amp;lt;/tr&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tr style=&amp;quot;background-color: #FFFFFF;&amp;quot;&amp;gt;&amp;lt;td style=&amp;quot;border-top: solid #C9C9C9 1px; padding: .4em;&amp;quot;&amp;gt;[[Function (Type)|function]] coroutine wrapper&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td style=&amp;quot;border-top: solid #C9C9C9 1px; padding: .4em;&amp;quot;&amp;gt;[[coroutine.wrap]]({{type|function}} function)&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td style=&amp;quot;border-top: solid #C9C9C9 1px; padding: .4em;&amp;quot;&amp;gt;Creates a new coroutine and wraps it in a function.&amp;lt;/td&amp;gt;&amp;lt;/tr&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tr style=&amp;quot;background-color: #E8E8E8;&amp;quot;&amp;gt;&amp;lt;td style=&amp;quot;border-top: solid #C9C9C9 1px; padding: .4em;&amp;quot;&amp;gt;[var3], [var4], …&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td style=&amp;quot;border-top: solid #C9C9C9 1px; padding: .4em;&amp;quot;&amp;gt;[[coroutine.yield]]([var1], [var2], …)&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td style=&amp;quot;border-top: solid #C9C9C9 1px; padding: .4em;&amp;quot;&amp;gt;Pauses the currently executing coroutine and passes control to its caller.&amp;lt;/td&amp;gt;&amp;lt;/tr&amp;gt;&lt;br /&gt;
&amp;lt;/table&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Coroutine States and Ancestry ==&lt;br /&gt;
Every coroutine is in one of four states:&lt;br /&gt;
* A ''suspended'' coroutine is one that has not yet been started or that has yielded. A suspended coroutine can become running if it is passed to [[coroutine.resume]].&lt;br /&gt;
* A ''running'' coroutine is one that is currently executing code. Only one coroutine can be running at a time on a particular computer. A running coroutine can become suspended if it [[coroutine.yield]], normal if it calls [[coroutine.resume]] on another coroutine, or dead by if it returns from its body function.&lt;br /&gt;
* A ''normal'' coroutine is one that, while running, resumed another coroutine (the ''child coroutine''). A normal coroutine can become running if its child calls [[coroutine.yield]] or returns from its function body.&lt;br /&gt;
* A ''dead'' coroutine is one that, while running, returned from its function body. A dead coroutine can never change state.&lt;br /&gt;
&lt;br /&gt;
While suspended and dead coroutines simply sit loose with no connections to other coroutines, normal and running coroutines have an ancestry relationship between them. Exactly one coroutine is running at any given time, and the running coroutine has no children. Every running or normal coroutine except the top-level BIOS coroutine has a parent, and this relationship forms a chain with one end (the furthest ancestor) being the top-level BIOS coroutine and the other end (the furthest descendant) being the running coroutine. Remember that only the running coroutine can actually execute code, so any functions invoked must be invoked by that coroutine. Then, calling [[coroutine.resume]] makes the chain longer by taking a previously suspended coroutine, hanging it underneath the current coroutine as a new child, and making the current coroutine normal and the new child running. Meanwhile, calling [[coroutine.yield]] makes the chain shorter by turning the currently executing coroutine into a suspended coroutine, detaching it from the chain, and letting its former parent become running.&lt;br /&gt;
&lt;br /&gt;
It is important not to confuse this coroutine chain with the function call stack. Each individual coroutine contains a complete function call stack of its own, rooted at the coroutine’s body function, whether the coroutine is running, normal, or suspended; the chain described in the previous paragraph refers to how entire coroutines are connected together.&lt;br /&gt;
&lt;br /&gt;
== Examples ==&lt;br /&gt;
As the coroutine API is very tightly coupled and many of its function must be used to get any interesting results, examples are shown here instead of on the individual function pages.&lt;br /&gt;
&lt;br /&gt;
=== Using the Basic Coroutine Functions ===&lt;br /&gt;
This example demonstrates using the basic coroutine functions to pass control and data between coroutines. This example prints the numbers 1 through 17 in order, showing how control flow moves through the main program coroutine and the two created coroutines, while using assertions to show how data flows through the program:&lt;br /&gt;
&lt;br /&gt;
 -- These variables will hold the coroutine objects.&lt;br /&gt;
 local c1 = nil&lt;br /&gt;
 local c2 = nil&lt;br /&gt;
 &lt;br /&gt;
 -- This function will be the body of the first coroutine.&lt;br /&gt;
 local function f1(x)&lt;br /&gt;
   -- The main code, below, starts c1 first, passing 1.&lt;br /&gt;
   -- Thus c1 should be running, c2 should be suspended (not started yet), and x should receive the value from main, 1.&lt;br /&gt;
   -- STEP 2: Check these assumptions.&lt;br /&gt;
   print(2)&lt;br /&gt;
   assert(coroutine.status(c1) == &amp;quot;running&amp;quot;)&lt;br /&gt;
   assert(coroutine.status(c2) == &amp;quot;suspended&amp;quot;)&lt;br /&gt;
   assert(x == 1)&lt;br /&gt;
   -- STEP 3: Run c2 until it yields, start it off with the value 2.&lt;br /&gt;
   print(3)&lt;br /&gt;
   success, value = coroutine.resume(c2, 2)&lt;br /&gt;
   assert(success)&lt;br /&gt;
   -- In step 6, c2 yields and passes back the value 3.&lt;br /&gt;
   -- Then c2, having yielded, should be suspended, and c1 should be running again.&lt;br /&gt;
   -- STEP 7: Check all that.&lt;br /&gt;
   print(7)&lt;br /&gt;
   assert(coroutine.status(c1) == &amp;quot;running&amp;quot;)&lt;br /&gt;
   assert(coroutine.status(c2) == &amp;quot;suspended&amp;quot;)&lt;br /&gt;
   assert(value == 3)&lt;br /&gt;
   -- STEP 8: Run c2 again, passing it the value 4.&lt;br /&gt;
   -- Since c2 has already run before, this time the 4 will come out of the yield() instead of appear as a function parameter.&lt;br /&gt;
   print(8)&lt;br /&gt;
   success, value = coroutine.resume(c2, 4)&lt;br /&gt;
   -- In step 10, c2 yields and passes back the value 5.&lt;br /&gt;
   -- Then c2, having yielded, should be suspended, and c1 should be running again.&lt;br /&gt;
   -- STEP 11: Check all that.&lt;br /&gt;
   print(11)&lt;br /&gt;
   assert(coroutine.status(c1) == &amp;quot;running&amp;quot;)&lt;br /&gt;
   assert(coroutine.status(c2) == &amp;quot;suspended&amp;quot;)&lt;br /&gt;
   assert(value == 5)&lt;br /&gt;
   -- STEP 12: Yield, turning c1 back into a suspended coroutine and continuing execution of the main program, passing back value 6.&lt;br /&gt;
   print(12)&lt;br /&gt;
   value = coroutine.yield(6)&lt;br /&gt;
 end&lt;br /&gt;
 &lt;br /&gt;
 -- This function will be the body of the second coroutine.&lt;br /&gt;
 local function f2(x)&lt;br /&gt;
   -- The first time c2 is run, it is run from f1, which passes 2.&lt;br /&gt;
   -- Thus c1 should be normal (as we are nested inside it), c2 should be running, and x should receive the value from f1, 2.&lt;br /&gt;
   -- STEP 4: Check these assumptions.&lt;br /&gt;
   print(4)&lt;br /&gt;
   assert(coroutine.status(c1) == &amp;quot;normal&amp;quot;)&lt;br /&gt;
   assert(coroutine.status(c2) == &amp;quot;running&amp;quot;)&lt;br /&gt;
   assert(x == 2)&lt;br /&gt;
   -- Because c1 is not suspended, we should not be able to resume it.&lt;br /&gt;
   -- STEP 5: Check this is correct.&lt;br /&gt;
   print(5)&lt;br /&gt;
   success, value = coroutine.resume(c1)&lt;br /&gt;
   assert(not success)&lt;br /&gt;
   assert(value == &amp;quot;cannot resume normal coroutine&amp;quot;)&lt;br /&gt;
   -- STEP 6: Yield, turning c2 back into a suspended coroutine and continuing execution of c1, passing back value 3.&lt;br /&gt;
   print(6)&lt;br /&gt;
   value = coroutine.yield(3)&lt;br /&gt;
   -- In step 8, c1 resumed c2 again and passed the value 4.&lt;br /&gt;
   -- c2 should now be running again, and c1 normal again.&lt;br /&gt;
   -- STEP 9: Check all that.&lt;br /&gt;
   print(9)&lt;br /&gt;
   assert(coroutine.status(c1) == &amp;quot;normal&amp;quot;)&lt;br /&gt;
   assert(coroutine.status(c2) == &amp;quot;running&amp;quot;)&lt;br /&gt;
   assert(value == 4)&lt;br /&gt;
   -- STEP 10: Yield, turning c2 back into a suspended coroutine and continuing execution of c1, passing back value 5.&lt;br /&gt;
   print(10)&lt;br /&gt;
   value = coroutine.yield(5)&lt;br /&gt;
   -- In step 14, the main program resumed c2 directly and passed the value 7, bypassing c1.&lt;br /&gt;
   -- So c2 should be running and c1 should be suspended.&lt;br /&gt;
   -- STEP 15: Check all that.&lt;br /&gt;
   print(15)&lt;br /&gt;
   assert(coroutine.status(c1) == &amp;quot;suspended&amp;quot;)&lt;br /&gt;
   assert(coroutine.status(c2) == &amp;quot;running&amp;quot;)&lt;br /&gt;
   assert(value == 7)&lt;br /&gt;
   -- STEP 16: Now die, returning value 8 to the main program.&lt;br /&gt;
   print(16)&lt;br /&gt;
   return 8&lt;br /&gt;
 end&lt;br /&gt;
 &lt;br /&gt;
 -- Construct the two coroutines.&lt;br /&gt;
 c1 = coroutine.create(f1)&lt;br /&gt;
 c2 = coroutine.create(f2)&lt;br /&gt;
 &lt;br /&gt;
 -- Newly constructed coroutines are always suspended.&lt;br /&gt;
 assert(coroutine.status(c1) == &amp;quot;suspended&amp;quot;)&lt;br /&gt;
 assert(coroutine.status(c2) == &amp;quot;suspended&amp;quot;)&lt;br /&gt;
 &lt;br /&gt;
 -- STEP 1: Run c1 until it yields, starting it off with the value 1.&lt;br /&gt;
 print(1)&lt;br /&gt;
 success, value = coroutine.resume(c1, 1)&lt;br /&gt;
 assert(success)&lt;br /&gt;
 &lt;br /&gt;
 -- In step 12, c1 should have yielded and returned the value 6.&lt;br /&gt;
 -- So now c1 and c2 should both be suspended.&lt;br /&gt;
 -- STEP 13: Check all that.&lt;br /&gt;
 print(13)&lt;br /&gt;
 assert(coroutine.status(c1) == &amp;quot;suspended&amp;quot;)&lt;br /&gt;
 assert(coroutine.status(c2) == &amp;quot;suspended&amp;quot;)&lt;br /&gt;
 assert(value == 6)&lt;br /&gt;
 &lt;br /&gt;
 -- STEP 14: Run c2 directly, NOT nested inside c1 this time, passing it the value 7.&lt;br /&gt;
 print(14)&lt;br /&gt;
 success, value = coroutine.resume(c2, 7)&lt;br /&gt;
 assert(success)&lt;br /&gt;
 &lt;br /&gt;
 -- c2 should have exited normally, returning the value 8.&lt;br /&gt;
 -- Therefore c1 should still be suspended, but c2 should be dead.&lt;br /&gt;
 -- STEP 17: Check all that.&lt;br /&gt;
 print(17)&lt;br /&gt;
 assert(coroutine.status(c1) == &amp;quot;suspended&amp;quot;)&lt;br /&gt;
 assert(coroutine.status(c2) == &amp;quot;dead&amp;quot;)&lt;br /&gt;
 assert(value == 8)&lt;br /&gt;
&lt;br /&gt;
=== Using Coroutine Wrapper Functions ===&lt;br /&gt;
This second example is virtually identical, but shows using [[coroutine.wrap]] and wrapper functions instead of the basic coroutine functions (checks of [[coroutine.status]] have been removed as the raw coroutine objects are not available):&lt;br /&gt;
&lt;br /&gt;
 -- These variables will hold the coroutine wrapper functions.&lt;br /&gt;
 local cw1 = nil&lt;br /&gt;
 local cw2 = nil&lt;br /&gt;
 &lt;br /&gt;
 -- This function will be the body of the first coroutine.&lt;br /&gt;
 local function f1(x)&lt;br /&gt;
   -- The main code, below, starts c1 first, passing 1.&lt;br /&gt;
   -- Thus c1 should be running, c2 should be suspended (not started yet), and x should receive the value from main, 1.&lt;br /&gt;
   -- STEP 2: Check these assumptions.&lt;br /&gt;
   print(2)&lt;br /&gt;
   assert(x == 1)&lt;br /&gt;
   -- STEP 3: Run c2 until it yields, start it off with the value 2.&lt;br /&gt;
   print(3)&lt;br /&gt;
   value = cw2(2)&lt;br /&gt;
   -- In step 6, c2 yields and passes back the value 3.&lt;br /&gt;
   -- Then c2, having yielded, should be suspended, and c1 should be running again.&lt;br /&gt;
   -- STEP 7: Check all that.&lt;br /&gt;
   print(7)&lt;br /&gt;
   assert(value == 3)&lt;br /&gt;
   -- STEP 8: Run c2 again, passing it the value 4.&lt;br /&gt;
   -- Since c2 has already run before, this time the 4 will come out of the yield() instead of appear as a function parameter.&lt;br /&gt;
   print(8)&lt;br /&gt;
   value = cw2(4)&lt;br /&gt;
   -- In step 10, c2 yields and passes back the value 5.&lt;br /&gt;
   -- Then c2, having yielded, should be suspended, and c1 should be running again.&lt;br /&gt;
   -- STEP 11: Check all that.&lt;br /&gt;
   print(11)&lt;br /&gt;
   assert(value == 5)&lt;br /&gt;
   -- STEP 12: Yield, turning c1 back into a suspended coroutine and continuing execution of the main program, passing back value 6.&lt;br /&gt;
   print(12)&lt;br /&gt;
   value = coroutine.yield(6)&lt;br /&gt;
 end&lt;br /&gt;
 &lt;br /&gt;
 -- This function will be the body of the second coroutine.&lt;br /&gt;
 local function f2(x)&lt;br /&gt;
   -- The first time c2 is run, it is run from f1, which passes 2.&lt;br /&gt;
   -- Thus c1 should be normal (as we are nested inside it), c2 should be running, and x should receive the value from f1, 2.&lt;br /&gt;
   -- STEP 4: Check these assumptions.&lt;br /&gt;
   print(4)&lt;br /&gt;
   assert(x == 2)&lt;br /&gt;
   -- Because c1 is not suspended, we should not be able to resume it.&lt;br /&gt;
   -- STEP 5: Check this is correct (we must use pcall because an error will be raised).&lt;br /&gt;
   print(5)&lt;br /&gt;
   success, value = pcall(cw1)&lt;br /&gt;
   assert(not success)&lt;br /&gt;
   -- STEP 6: Yield, turning c2 back into a suspended coroutine and continuing execution of c1, passing back value 3.&lt;br /&gt;
   print(6)&lt;br /&gt;
   value = coroutine.yield(3)&lt;br /&gt;
   -- In step 8, c1 resumed c2 again and passed the value 4.&lt;br /&gt;
   -- c2 should now be running again, and c1 normal again.&lt;br /&gt;
   -- STEP 9: Check all that.&lt;br /&gt;
   print(9)&lt;br /&gt;
   assert(value == 4)&lt;br /&gt;
   -- STEP 10: Yield, turning c2 back into a suspended coroutine and continuing execution of c1, passing back value 5.&lt;br /&gt;
   print(10)&lt;br /&gt;
   value = coroutine.yield(5)&lt;br /&gt;
   -- In step 14, the main program resumed c2 directly and passed the value 7, bypassing c1.&lt;br /&gt;
   -- So c2 should be running and c1 should be suspended.&lt;br /&gt;
   -- STEP 15: Check all that.&lt;br /&gt;
   print(15)&lt;br /&gt;
   assert(value == 7)&lt;br /&gt;
   -- STEP 16: Now die, returning value 8 to the main program.&lt;br /&gt;
   print(16)&lt;br /&gt;
   return 8&lt;br /&gt;
 end&lt;br /&gt;
 &lt;br /&gt;
 -- Construct the two coroutine wrappers.&lt;br /&gt;
 cw1 = coroutine.wrap(f1)&lt;br /&gt;
 cw2 = coroutine.wrap(f2)&lt;br /&gt;
 &lt;br /&gt;
 -- STEP 1: Run cw1 until it yields, starting it off with the value 1.&lt;br /&gt;
 print(1)&lt;br /&gt;
 value = cw1(1)&lt;br /&gt;
 &lt;br /&gt;
 -- In step 12, c1 should have yielded and returned the value 6.&lt;br /&gt;
 -- So now c1 and c2 should both be suspended.&lt;br /&gt;
 -- STEP 13: Check all that.&lt;br /&gt;
 print(13)&lt;br /&gt;
 assert(value == 6)&lt;br /&gt;
 &lt;br /&gt;
 -- STEP 14: Run c2 directly, NOT nested inside c1 this time, passing it the value 7.&lt;br /&gt;
 print(14)&lt;br /&gt;
 value = cw2(7)&lt;br /&gt;
 &lt;br /&gt;
 -- c2 should have exited normally, returning the value 8.&lt;br /&gt;
 -- Therefore c1 should still be suspended, but c2 should be dead.&lt;br /&gt;
 -- STEP 17: Check all that.&lt;br /&gt;
 print(17)&lt;br /&gt;
 assert(value == 8)&lt;br /&gt;
&lt;br /&gt;
== Interaction with Other APIs ==&lt;br /&gt;
The [[OS (API)#pullEvent|os.pullEventRaw]] (and therefore [[os.pullEvent]]) functions are built on top of coroutines: &amp;lt;code&amp;gt;os.pullEventRaw&amp;lt;/code&amp;gt; actually just calls [[coroutine.yield]], passing the event type filter up to the parent coroutine. The parent coroutine is expected to wait until an event of the required type arrives, then use [[coroutine.resume]] to pass the event to the suspended coroutine (where it will be returned from &amp;lt;code&amp;gt;os.pullEventRaw&amp;lt;/code&amp;gt;). If you use the [[Parallel (API)|parallel API]], this is exactly what [[parallel.waitForAny]] and [[parallel.waitForAll]] do: they pull events from the system event queue (or even from a higher invocation of &amp;lt;code&amp;gt;parallel.waitForAny&amp;lt;/code&amp;gt; or &amp;lt;code&amp;gt;parallel.waitForAll&amp;lt;/code&amp;gt;!) and deliver them to all nested coroutines. Therefore, the easiest way to use coroutines is the parallel API, if it works for your situation. However, in the event that you are not able to use the parallel API (e.g. if you need to add and remove coroutines from the executing set dynamically), you can build your own dispatcher that delivers events in the same way as the parallel API—looking at the source code to the parallel API may be useful here.&lt;br /&gt;
&lt;br /&gt;
If you choose to use coroutines in a different way, then &amp;lt;code&amp;gt;os.pullEventRaw&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;os.pullEvent&amp;lt;/code&amp;gt; will not work. This in turn will break any other API function which is written on top of &amp;lt;code&amp;gt;os.pullEvent&amp;lt;/code&amp;gt;. As a guideline, nearly any API function that can possibly take time to complete will fall into this category; some examples are:&lt;br /&gt;
* [[rednet.receive]] blocks until either a [[Rednet message (event)|rednet_message event]] or (if a timeout was requested) a matching [[Timer (event)|timer event]] occurs.&lt;br /&gt;
* [[Gps (API)|gps.locate]] blocks until either a number of [[Modem message (event)|modem_message events]] or (if a timeout was requested) a matching [[Timer (event)|timer event]] occurs.&lt;br /&gt;
* [[http.get]] blocks until an [[Http success (event)|HTTP success event]] or [[Http failure (event)|HTTP failure event]] occurs.&lt;br /&gt;
* [[IO (API)|io.read]] and the built-in [[read]] functions block waiting for, presumably, either [[Char (event)|char events]] or [[Key (event)|key events]].&lt;br /&gt;
* [[os.sleep]] blocks until a matching [[Timer (event)|timer event]] occurs.&lt;br /&gt;
* [[textutils.slowPrint]] calls [[os.sleep]].&lt;br /&gt;
* [[textutils.pagedPrint]] blocks until a [[Key (event)|key event]] occurs for each page.&lt;br /&gt;
* Most of the functions in the [[Turtle (API)|turtle API]] (with the exception of [[turtle.getItemCount]], [[turtle.getItemSpace]], and [[turtle.getFuelLevel]]) block waiting for a [[Turtle response (event)|turtle response event]].&lt;br /&gt;
&lt;br /&gt;
Most of these can be worked around by using non-blocking equivalents that return immediately and then queue an event on completion (such as using [[http.request]]) or that deliver an event unconditionally (such as [[Char_(event)|char]] for keyboard input), then handling events in a way that is suitable for the application. However, if possible, it will often be easier to implement event dispatching instead, remembering that [[os.queueEvent]] can be used for inter-coroutine communication within an application. Another alternative, if you must use a custom protocol between your coroutines and dispatcher, might be to replace &amp;lt;code&amp;gt;os.pullEventRaw&amp;lt;/code&amp;gt; with a new function that uses a mechanism appropriate to the application.&lt;br /&gt;
&lt;br /&gt;
[[Category:APIs]]&lt;/div&gt;</summary>
		<author><name>YoYoYonnY</name></author>	</entry>

	<entry>
		<id>https://www.computercraft.info/wiki/index.php?title=Coroutine_(API)&amp;diff=5776</id>
		<title>Coroutine (API)</title>
		<link rel="alternate" type="text/html" href="https://www.computercraft.info/wiki/index.php?title=Coroutine_(API)&amp;diff=5776"/>
				<updated>2013-07-03T04:34:56Z</updated>
		
		<summary type="html">&lt;p&gt;YoYoYonnY: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{NeedsWork}}&lt;br /&gt;
:{| border=&amp;quot;1&amp;quot; class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
| '''Bug'''&lt;br /&gt;
'''From ComputerCraft 1.3''' this API suffers from the problem of potentially spawning Java threads that live forever therefore, use of coroutines should be minimized. This is '''fixed in ComputerCraft 1.32+''', though.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
''This is for the Coroutine API. For the Coroutine Object, visit [[Coroutine (type)]].''&lt;br /&gt;
&lt;br /&gt;
Coroutine is a default Lua 5.1 API defined [http://www.lua.org/manual/5.1/manual.html#5.2 here]. Please list any non-working functions on this page.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;table style=&amp;quot;width: 100%; border: solid 1px black; margin: 2px; border-spacing: 0px;&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&amp;lt;td colspan=&amp;quot;3&amp;quot; style=&amp;quot;font-weight: bold; font-size: large; padding-bottom: .3em; border-bottom: solid #C9C9C9 1px; background: #D3FFC2; line-height:28px;&amp;quot;&amp;gt;&lt;br /&gt;
[[File:Grid_disk.png|24px]]&amp;amp;nbsp;&amp;amp;nbsp;&lt;br /&gt;
Coroutine (API)&lt;br /&gt;
&amp;lt;/td&amp;gt;&amp;lt;/tr&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tr&amp;gt;&amp;lt;td style=&amp;quot;width: 100px; background: #E0E0E0; padding: .4em; font-weight:bold;&amp;quot;&amp;gt;Return&amp;lt;/td&amp;gt;&amp;lt;td style=&amp;quot;width: 350px; background: #E0E0E0; padding: .4em; font-weight:bold;&amp;quot;&amp;gt;Method Name&amp;lt;/td&amp;gt;&amp;lt;td style=&amp;quot;background: #E0E0E0; padding: .4em; font-weight:bold;&amp;quot;&amp;gt;Description&amp;lt;/td&amp;gt;&amp;lt;/tr&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tr style=&amp;quot;background-color: #FFFFFF;&amp;quot;&amp;gt;&amp;lt;td style=&amp;quot;border-top: solid #C9C9C9 1px; padding: .4em;&amp;quot;&amp;gt;[[Coroutine_(Type)|coroutine]] coro&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td style=&amp;quot;border-top: solid #C9C9C9 1px; padding: .4em;&amp;quot;&amp;gt;[[coroutine.create]]({{Type|function}} f)&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td style=&amp;quot;border-top: solid #C9C9C9 1px; padding: .4em;&amp;quot;&amp;gt;Creates a new coroutine.&amp;lt;/td&amp;gt;&amp;lt;/tr&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tr style=&amp;quot;background-color: #E8E8E8;&amp;quot;&amp;gt;&amp;lt;td style=&amp;quot;border-top: solid #C9C9C9 1px; padding: .4em;&amp;quot;&amp;gt;[[Boolean (type)|boolean]] success, …&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td style=&amp;quot;border-top: solid #C9C9C9 1px; padding: .4em;&amp;quot;&amp;gt;[[coroutine.resume]]({{Type|coroutine}} coro, [var1], [var2], ...)&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td style=&amp;quot;border-top: solid #C9C9C9 1px; padding: .4em;&amp;quot;&amp;gt;Starts or resumes an existing coroutine.&amp;lt;/td&amp;gt;&amp;lt;/tr&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tr style=&amp;quot;background-color: #FFFFFF;&amp;quot;&amp;gt;&amp;lt;td style=&amp;quot;border-top: solid #C9C9C9 1px; padding: .4em;&amp;quot;&amp;gt;[[Coroutine_(Type)|coroutine]] coro&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td style=&amp;quot;border-top: solid #C9C9C9 1px; padding: .4em;&amp;quot;&amp;gt;[[coroutine.running]]()&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td style=&amp;quot;border-top: solid #C9C9C9 1px; padding: .4em;&amp;quot;&amp;gt;Returns the currently executing coroutine.&amp;lt;/td&amp;gt;&amp;lt;/tr&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tr style=&amp;quot;background-color: #E8E8E8;&amp;quot;&amp;gt;&amp;lt;td style=&amp;quot;border-top: solid #C9C9C9 1px; padding: .4em;&amp;quot;&amp;gt;[[String_(Type)|string]] status&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td style=&amp;quot;border-top: solid #C9C9C9 1px; padding: .4em;&amp;quot;&amp;gt;[[coroutine.status]]({{type|coroutine}} coroutine)&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td style=&amp;quot;border-top: solid #C9C9C9 1px; padding: .4em;&amp;quot;&amp;gt;Returns the status of the given coroutine.&amp;lt;/td&amp;gt;&amp;lt;/tr&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tr style=&amp;quot;background-color: #FFFFFF;&amp;quot;&amp;gt;&amp;lt;td style=&amp;quot;border-top: solid #C9C9C9 1px; padding: .4em;&amp;quot;&amp;gt;[[Function_(Type)|function]] coroutine wrapper&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td style=&amp;quot;border-top: solid #C9C9C9 1px; padding: .4em;&amp;quot;&amp;gt;[[coroutine.wrap]]({{type|function}} function)&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td style=&amp;quot;border-top: solid #C9C9C9 1px; padding: .4em;&amp;quot;&amp;gt;Creates a new coroutine and wraps it in a function.&amp;lt;/td&amp;gt;&amp;lt;/tr&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tr style=&amp;quot;background-color: #E8E8E8;&amp;quot;&amp;gt;&amp;lt;td style=&amp;quot;border-top: solid #C9C9C9 1px; padding: .4em;&amp;quot;&amp;gt;[var3], [var4], …&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td style=&amp;quot;border-top: solid #C9C9C9 1px; padding: .4em;&amp;quot;&amp;gt;[[coroutine.yield]]([var1], [var2], …)&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td style=&amp;quot;border-top: solid #C9C9C9 1px; padding: .4em;&amp;quot;&amp;gt;Pauses the currently executing coroutine and passes control to its caller.&amp;lt;/td&amp;gt;&amp;lt;/tr&amp;gt;&lt;br /&gt;
&amp;lt;/table&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Coroutine States and Ancestry ==&lt;br /&gt;
Every coroutine is in one of four states:&lt;br /&gt;
* A ''suspended'' coroutine is one that has not yet been started or that has yielded. A suspended coroutine can become running if it is passed to [[coroutine.resume]].&lt;br /&gt;
* A ''running'' coroutine is one that is currently executing code. Only one coroutine can be running at a time on a particular computer. A running coroutine can become suspended if it [[coroutine.yield]], normal if it calls [[coroutine.resume]] on another coroutine, or dead by if it returns from its body function.&lt;br /&gt;
* A ''normal'' coroutine is one that, while running, resumed another coroutine (the ''child coroutine''). A normal coroutine can become running if its child calls [[coroutine.yield]] or returns from its function body.&lt;br /&gt;
* A ''dead'' coroutine is one that, while running, returned from its function body. A dead coroutine can never change state.&lt;br /&gt;
&lt;br /&gt;
While suspended and dead coroutines simply sit loose with no connections to other coroutines, normal and running coroutines have an ancestry relationship between them. Exactly one coroutine is running at any given time, and the running coroutine has no children. Every running or normal coroutine except the top-level BIOS coroutine has a parent, and this relationship forms a chain with one end (the furthest ancestor) being the top-level BIOS coroutine and the other end (the furthest descendant) being the running coroutine. Remember that only the running coroutine can actually execute code, so any functions invoked must be invoked by that coroutine. Then, calling [[coroutine.resume]] makes the chain longer by taking a previously suspended coroutine, hanging it underneath the current coroutine as a new child, and making the current coroutine normal and the new child running. Meanwhile, calling [[coroutine.yield]] makes the chain shorter by turning the currently executing coroutine into a suspended coroutine, detaching it from the chain, and letting its former parent become running.&lt;br /&gt;
&lt;br /&gt;
It is important not to confuse this coroutine chain with the function call stack. Each individual coroutine contains a complete function call stack of its own, rooted at the coroutine’s body function, whether the coroutine is running, normal, or suspended; the chain described in the previous paragraph refers to how entire coroutines are connected together.&lt;br /&gt;
&lt;br /&gt;
== Examples ==&lt;br /&gt;
As the coroutine API is very tightly coupled and many of its function must be used to get any interesting results, examples are shown here instead of on the individual function pages.&lt;br /&gt;
&lt;br /&gt;
=== Using the Basic Coroutine Functions ===&lt;br /&gt;
This example demonstrates using the basic coroutine functions to pass control and data between coroutines. This example prints the numbers 1 through 17 in order, showing how control flow moves through the main program coroutine and the two created coroutines, while using assertions to show how data flows through the program:&lt;br /&gt;
&lt;br /&gt;
 -- These variables will hold the coroutine objects.&lt;br /&gt;
 local c1 = nil&lt;br /&gt;
 local c2 = nil&lt;br /&gt;
 &lt;br /&gt;
 -- This function will be the body of the first coroutine.&lt;br /&gt;
 local function f1(x)&lt;br /&gt;
   -- The main code, below, starts c1 first, passing 1.&lt;br /&gt;
   -- Thus c1 should be running, c2 should be suspended (not started yet), and x should receive the value from main, 1.&lt;br /&gt;
   -- STEP 2: Check these assumptions.&lt;br /&gt;
   print(2)&lt;br /&gt;
   assert(coroutine.status(c1) == &amp;quot;running&amp;quot;)&lt;br /&gt;
   assert(coroutine.status(c2) == &amp;quot;suspended&amp;quot;)&lt;br /&gt;
   assert(x == 1)&lt;br /&gt;
   -- STEP 3: Run c2 until it yields, start it off with the value 2.&lt;br /&gt;
   print(3)&lt;br /&gt;
   success, value = coroutine.resume(c2, 2)&lt;br /&gt;
   assert(success)&lt;br /&gt;
   -- In step 6, c2 yields and passes back the value 3.&lt;br /&gt;
   -- Then c2, having yielded, should be suspended, and c1 should be running again.&lt;br /&gt;
   -- STEP 7: Check all that.&lt;br /&gt;
   print(7)&lt;br /&gt;
   assert(coroutine.status(c1) == &amp;quot;running&amp;quot;)&lt;br /&gt;
   assert(coroutine.status(c2) == &amp;quot;suspended&amp;quot;)&lt;br /&gt;
   assert(value == 3)&lt;br /&gt;
   -- STEP 8: Run c2 again, passing it the value 4.&lt;br /&gt;
   -- Since c2 has already run before, this time the 4 will come out of the yield() instead of appear as a function parameter.&lt;br /&gt;
   print(8)&lt;br /&gt;
   success, value = coroutine.resume(c2, 4)&lt;br /&gt;
   -- In step 10, c2 yields and passes back the value 5.&lt;br /&gt;
   -- Then c2, having yielded, should be suspended, and c1 should be running again.&lt;br /&gt;
   -- STEP 11: Check all that.&lt;br /&gt;
   print(11)&lt;br /&gt;
   assert(coroutine.status(c1) == &amp;quot;running&amp;quot;)&lt;br /&gt;
   assert(coroutine.status(c2) == &amp;quot;suspended&amp;quot;)&lt;br /&gt;
   assert(value == 5)&lt;br /&gt;
   -- STEP 12: Yield, turning c1 back into a suspended coroutine and continuing execution of the main program, passing back value 6.&lt;br /&gt;
   print(12)&lt;br /&gt;
   value = coroutine.yield(6)&lt;br /&gt;
 end&lt;br /&gt;
 &lt;br /&gt;
 -- This function will be the body of the second coroutine.&lt;br /&gt;
 local function f2(x)&lt;br /&gt;
   -- The first time c2 is run, it is run from f1, which passes 2.&lt;br /&gt;
   -- Thus c1 should be normal (as we are nested inside it), c2 should be running, and x should receive the value from f1, 2.&lt;br /&gt;
   -- STEP 4: Check these assumptions.&lt;br /&gt;
   print(4)&lt;br /&gt;
   assert(coroutine.status(c1) == &amp;quot;normal&amp;quot;)&lt;br /&gt;
   assert(coroutine.status(c2) == &amp;quot;running&amp;quot;)&lt;br /&gt;
   assert(x == 2)&lt;br /&gt;
   -- Because c1 is not suspended, we should not be able to resume it.&lt;br /&gt;
   -- STEP 5: Check this is correct.&lt;br /&gt;
   print(5)&lt;br /&gt;
   success, value = coroutine.resume(c1)&lt;br /&gt;
   assert(not success)&lt;br /&gt;
   assert(value == &amp;quot;cannot resume normal coroutine&amp;quot;)&lt;br /&gt;
   -- STEP 6: Yield, turning c2 back into a suspended coroutine and continuing execution of c1, passing back value 3.&lt;br /&gt;
   print(6)&lt;br /&gt;
   value = coroutine.yield(3)&lt;br /&gt;
   -- In step 8, c1 resumed c2 again and passed the value 4.&lt;br /&gt;
   -- c2 should now be running again, and c1 normal again.&lt;br /&gt;
   -- STEP 9: Check all that.&lt;br /&gt;
   print(9)&lt;br /&gt;
   assert(coroutine.status(c1) == &amp;quot;normal&amp;quot;)&lt;br /&gt;
   assert(coroutine.status(c2) == &amp;quot;running&amp;quot;)&lt;br /&gt;
   assert(value == 4)&lt;br /&gt;
   -- STEP 10: Yield, turning c2 back into a suspended coroutine and continuing execution of c1, passing back value 5.&lt;br /&gt;
   print(10)&lt;br /&gt;
   value = coroutine.yield(5)&lt;br /&gt;
   -- In step 14, the main program resumed c2 directly and passed the value 7, bypassing c1.&lt;br /&gt;
   -- So c2 should be running and c1 should be suspended.&lt;br /&gt;
   -- STEP 15: Check all that.&lt;br /&gt;
   print(15)&lt;br /&gt;
   assert(coroutine.status(c1) == &amp;quot;suspended&amp;quot;)&lt;br /&gt;
   assert(coroutine.status(c2) == &amp;quot;running&amp;quot;)&lt;br /&gt;
   assert(value == 7)&lt;br /&gt;
   -- STEP 16: Now die, returning value 8 to the main program.&lt;br /&gt;
   print(16)&lt;br /&gt;
   return 8&lt;br /&gt;
 end&lt;br /&gt;
 &lt;br /&gt;
 -- Construct the two coroutines.&lt;br /&gt;
 c1 = coroutine.create(f1)&lt;br /&gt;
 c2 = coroutine.create(f2)&lt;br /&gt;
 &lt;br /&gt;
 -- Newly constructed coroutines are always suspended.&lt;br /&gt;
 assert(coroutine.status(c1) == &amp;quot;suspended&amp;quot;)&lt;br /&gt;
 assert(coroutine.status(c2) == &amp;quot;suspended&amp;quot;)&lt;br /&gt;
 &lt;br /&gt;
 -- STEP 1: Run c1 until it yields, starting it off with the value 1.&lt;br /&gt;
 print(1)&lt;br /&gt;
 success, value = coroutine.resume(c1, 1)&lt;br /&gt;
 assert(success)&lt;br /&gt;
 &lt;br /&gt;
 -- In step 12, c1 should have yielded and returned the value 6.&lt;br /&gt;
 -- So now c1 and c2 should both be suspended.&lt;br /&gt;
 -- STEP 13: Check all that.&lt;br /&gt;
 print(13)&lt;br /&gt;
 assert(coroutine.status(c1) == &amp;quot;suspended&amp;quot;)&lt;br /&gt;
 assert(coroutine.status(c2) == &amp;quot;suspended&amp;quot;)&lt;br /&gt;
 assert(value == 6)&lt;br /&gt;
 &lt;br /&gt;
 -- STEP 14: Run c2 directly, NOT nested inside c1 this time, passing it the value 7.&lt;br /&gt;
 print(14)&lt;br /&gt;
 success, value = coroutine.resume(c2, 7)&lt;br /&gt;
 assert(success)&lt;br /&gt;
 &lt;br /&gt;
 -- c2 should have exited normally, returning the value 8.&lt;br /&gt;
 -- Therefore c1 should still be suspended, but c2 should be dead.&lt;br /&gt;
 -- STEP 17: Check all that.&lt;br /&gt;
 print(17)&lt;br /&gt;
 assert(coroutine.status(c1) == &amp;quot;suspended&amp;quot;)&lt;br /&gt;
 assert(coroutine.status(c2) == &amp;quot;dead&amp;quot;)&lt;br /&gt;
 assert(value == 8)&lt;br /&gt;
&lt;br /&gt;
=== Using Coroutine Wrapper Functions ===&lt;br /&gt;
This second example is virtually identical, but shows using [[coroutine.wrap]] and wrapper functions instead of the basic coroutine functions (checks of [[coroutine.status]] have been removed as the raw coroutine objects are not available):&lt;br /&gt;
&lt;br /&gt;
 -- These variables will hold the coroutine wrapper functions.&lt;br /&gt;
 local cw1 = nil&lt;br /&gt;
 local cw2 = nil&lt;br /&gt;
 &lt;br /&gt;
 -- This function will be the body of the first coroutine.&lt;br /&gt;
 local function f1(x)&lt;br /&gt;
   -- The main code, below, starts c1 first, passing 1.&lt;br /&gt;
   -- Thus c1 should be running, c2 should be suspended (not started yet), and x should receive the value from main, 1.&lt;br /&gt;
   -- STEP 2: Check these assumptions.&lt;br /&gt;
   print(2)&lt;br /&gt;
   assert(x == 1)&lt;br /&gt;
   -- STEP 3: Run c2 until it yields, start it off with the value 2.&lt;br /&gt;
   print(3)&lt;br /&gt;
   value = cw2(2)&lt;br /&gt;
   -- In step 6, c2 yields and passes back the value 3.&lt;br /&gt;
   -- Then c2, having yielded, should be suspended, and c1 should be running again.&lt;br /&gt;
   -- STEP 7: Check all that.&lt;br /&gt;
   print(7)&lt;br /&gt;
   assert(value == 3)&lt;br /&gt;
   -- STEP 8: Run c2 again, passing it the value 4.&lt;br /&gt;
   -- Since c2 has already run before, this time the 4 will come out of the yield() instead of appear as a function parameter.&lt;br /&gt;
   print(8)&lt;br /&gt;
   value = cw2(4)&lt;br /&gt;
   -- In step 10, c2 yields and passes back the value 5.&lt;br /&gt;
   -- Then c2, having yielded, should be suspended, and c1 should be running again.&lt;br /&gt;
   -- STEP 11: Check all that.&lt;br /&gt;
   print(11)&lt;br /&gt;
   assert(value == 5)&lt;br /&gt;
   -- STEP 12: Yield, turning c1 back into a suspended coroutine and continuing execution of the main program, passing back value 6.&lt;br /&gt;
   print(12)&lt;br /&gt;
   value = coroutine.yield(6)&lt;br /&gt;
 end&lt;br /&gt;
 &lt;br /&gt;
 -- This function will be the body of the second coroutine.&lt;br /&gt;
 local function f2(x)&lt;br /&gt;
   -- The first time c2 is run, it is run from f1, which passes 2.&lt;br /&gt;
   -- Thus c1 should be normal (as we are nested inside it), c2 should be running, and x should receive the value from f1, 2.&lt;br /&gt;
   -- STEP 4: Check these assumptions.&lt;br /&gt;
   print(4)&lt;br /&gt;
   assert(x == 2)&lt;br /&gt;
   -- Because c1 is not suspended, we should not be able to resume it.&lt;br /&gt;
   -- STEP 5: Check this is correct (we must use pcall because an error will be raised).&lt;br /&gt;
   print(5)&lt;br /&gt;
   success, value = pcall(cw1)&lt;br /&gt;
   assert(not success)&lt;br /&gt;
   -- STEP 6: Yield, turning c2 back into a suspended coroutine and continuing execution of c1, passing back value 3.&lt;br /&gt;
   print(6)&lt;br /&gt;
   value = coroutine.yield(3)&lt;br /&gt;
   -- In step 8, c1 resumed c2 again and passed the value 4.&lt;br /&gt;
   -- c2 should now be running again, and c1 normal again.&lt;br /&gt;
   -- STEP 9: Check all that.&lt;br /&gt;
   print(9)&lt;br /&gt;
   assert(value == 4)&lt;br /&gt;
   -- STEP 10: Yield, turning c2 back into a suspended coroutine and continuing execution of c1, passing back value 5.&lt;br /&gt;
   print(10)&lt;br /&gt;
   value = coroutine.yield(5)&lt;br /&gt;
   -- In step 14, the main program resumed c2 directly and passed the value 7, bypassing c1.&lt;br /&gt;
   -- So c2 should be running and c1 should be suspended.&lt;br /&gt;
   -- STEP 15: Check all that.&lt;br /&gt;
   print(15)&lt;br /&gt;
   assert(value == 7)&lt;br /&gt;
   -- STEP 16: Now die, returning value 8 to the main program.&lt;br /&gt;
   print(16)&lt;br /&gt;
   return 8&lt;br /&gt;
 end&lt;br /&gt;
 &lt;br /&gt;
 -- Construct the two coroutine wrappers.&lt;br /&gt;
 cw1 = coroutine.wrap(f1)&lt;br /&gt;
 cw2 = coroutine.wrap(f2)&lt;br /&gt;
 &lt;br /&gt;
 -- STEP 1: Run cw1 until it yields, starting it off with the value 1.&lt;br /&gt;
 print(1)&lt;br /&gt;
 value = cw1(1)&lt;br /&gt;
 &lt;br /&gt;
 -- In step 12, c1 should have yielded and returned the value 6.&lt;br /&gt;
 -- So now c1 and c2 should both be suspended.&lt;br /&gt;
 -- STEP 13: Check all that.&lt;br /&gt;
 print(13)&lt;br /&gt;
 assert(value == 6)&lt;br /&gt;
 &lt;br /&gt;
 -- STEP 14: Run c2 directly, NOT nested inside c1 this time, passing it the value 7.&lt;br /&gt;
 print(14)&lt;br /&gt;
 value = cw2(7)&lt;br /&gt;
 &lt;br /&gt;
 -- c2 should have exited normally, returning the value 8.&lt;br /&gt;
 -- Therefore c1 should still be suspended, but c2 should be dead.&lt;br /&gt;
 -- STEP 17: Check all that.&lt;br /&gt;
 print(17)&lt;br /&gt;
 assert(value == 8)&lt;br /&gt;
&lt;br /&gt;
== Interaction with Other APIs ==&lt;br /&gt;
The [[OS (API)#pullEvent|os.pullEventRaw]] (and therefore [[os.pullEvent]]) functions are built on top of coroutines: &amp;lt;code&amp;gt;os.pullEventRaw&amp;lt;/code&amp;gt; actually just calls [[coroutine.yield]], passing the event type filter up to the parent coroutine. The parent coroutine is expected to wait until an event of the required type arrives, then use [[coroutine.resume]] to pass the event to the suspended coroutine (where it will be returned from &amp;lt;code&amp;gt;os.pullEventRaw&amp;lt;/code&amp;gt;). If you use the [[Parallel (API)|parallel API]], this is exactly what [[parallel.waitForAny]] and [[parallel.waitForAll]] do: they pull events from the system event queue (or even from a higher invocation of &amp;lt;code&amp;gt;parallel.waitForAny&amp;lt;/code&amp;gt; or &amp;lt;code&amp;gt;parallel.waitForAll&amp;lt;/code&amp;gt;!) and deliver them to all nested coroutines. Therefore, the easiest way to use coroutines is the parallel API, if it works for your situation. However, in the event that you are not able to use the parallel API (e.g. if you need to add and remove coroutines from the executing set dynamically), you can build your own dispatcher that delivers events in the same way as the parallel API—looking at the source code to the parallel API may be useful here.&lt;br /&gt;
&lt;br /&gt;
If you choose to use coroutines in a different way, then &amp;lt;code&amp;gt;os.pullEventRaw&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;os.pullEvent&amp;lt;/code&amp;gt; will not work. This in turn will break any other API function which is written on top of &amp;lt;code&amp;gt;os.pullEvent&amp;lt;/code&amp;gt;. As a guideline, nearly any API function that can possibly take time to complete will fall into this category; some examples are:&lt;br /&gt;
* [[rednet.receive]] blocks until either a [[Rednet message (event)|rednet_message event]] or (if a timeout was requested) a matching [[Timer (event)|timer event]] occurs.&lt;br /&gt;
* [[Gps (API)|gps.locate]] blocks until either a number of [[Modem message (event)|modem_message events]] or (if a timeout was requested) a matching [[Timer (event)|timer event]] occurs.&lt;br /&gt;
* [[http.get]] blocks until an [[Http success (event)|HTTP success event]] or [[Http failure (event)|HTTP failure event]] occurs.&lt;br /&gt;
* [[IO (API)|io.read]] and the built-in [[read]] functions block waiting for, presumably, either [[Char (event)|char events]] or [[Key (event)|key events]].&lt;br /&gt;
* [[os.sleep]] blocks until a matching [[Timer (event)|timer event]] occurs.&lt;br /&gt;
* [[textutils.slowPrint]] calls [[os.sleep]].&lt;br /&gt;
* [[textutils.pagedPrint]] blocks until a [[Key (event)|key event]] occurs for each page.&lt;br /&gt;
* Most of the functions in the [[Turtle (API)|turtle API]] (with the exception of [[turtle.getItemCount]], [[turtle.getItemSpace]], and [[turtle.getFuelLevel]]) block waiting for a [[Turtle response (event)|turtle response event]].&lt;br /&gt;
&lt;br /&gt;
Most of these can be worked around by using non-blocking equivalents that return immediately and then queue an event on completion (such as using [[http.request]]) or that deliver an event unconditionally (such as [[Char_(event)|char]] for keyboard input), then handling events in a way that is suitable for the application. However, if possible, it will often be easier to implement event dispatching instead, remembering that [[os.queueEvent]] can be used for inter-coroutine communication within an application. Another alternative, if you must use a custom protocol between your coroutines and dispatcher, might be to replace &amp;lt;code&amp;gt;os.pullEventRaw&amp;lt;/code&amp;gt; with a new function that uses a mechanism appropriate to the application.&lt;br /&gt;
&lt;br /&gt;
[[Category:APIs]]&lt;/div&gt;</summary>
		<author><name>YoYoYonnY</name></author>	</entry>

	<entry>
		<id>https://www.computercraft.info/wiki/index.php?title=Coroutine_(API)&amp;diff=5775</id>
		<title>Coroutine (API)</title>
		<link rel="alternate" type="text/html" href="https://www.computercraft.info/wiki/index.php?title=Coroutine_(API)&amp;diff=5775"/>
				<updated>2013-07-03T04:33:59Z</updated>
		
		<summary type="html">&lt;p&gt;YoYoYonnY: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{NeedsWork}}&lt;br /&gt;
:{| border=&amp;quot;1&amp;quot; class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
| '''Bug'''&lt;br /&gt;
'''From ComputerCraft 1.3''' this API suffers from the problem of potentially spawning Java threads that live forever therefore, use of coroutines should be minimized. This is '''fixed in ComputerCraft 1.32+''', though.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
''This is for the Coroutine API. For the Coroutine Object, visit [[Coroutine (type)]].''&lt;br /&gt;
&lt;br /&gt;
Coroutine is a default Lua 5.1 API defined [http://www.lua.org/manual/5.1/manual.html#5.2 here]. Please list any non-working functions on this page.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;table style=&amp;quot;width: 100%; border: solid 1px black; margin: 2px; border-spacing: 0px;&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&amp;lt;td colspan=&amp;quot;3&amp;quot; style=&amp;quot;font-weight: bold; font-size: large; padding-bottom: .3em; border-bottom: solid #C9C9C9 1px; background: #D3FFC2; line-height:28px;&amp;quot;&amp;gt;&lt;br /&gt;
[[File:Grid_disk.png|24px]]&amp;amp;nbsp;&amp;amp;nbsp;&lt;br /&gt;
Coroutine (API)&lt;br /&gt;
&amp;lt;/td&amp;gt;&amp;lt;/tr&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tr&amp;gt;&amp;lt;td style=&amp;quot;width: 100px; background: #E0E0E0; padding: .4em; font-weight:bold;&amp;quot;&amp;gt;Return&amp;lt;/td&amp;gt;&amp;lt;td style=&amp;quot;width: 350px; background: #E0E0E0; padding: .4em; font-weight:bold;&amp;quot;&amp;gt;Method Name&amp;lt;/td&amp;gt;&amp;lt;td style=&amp;quot;background: #E0E0E0; padding: .4em; font-weight:bold;&amp;quot;&amp;gt;Description&amp;lt;/td&amp;gt;&amp;lt;/tr&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tr style=&amp;quot;background-color: #FFFFFF;&amp;quot;&amp;gt;&amp;lt;td style=&amp;quot;border-top: solid #C9C9C9 1px; padding: .4em;&amp;quot;&amp;gt;[[Coroutine_(Type)|coroutine]] coro&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td style=&amp;quot;border-top: solid #C9C9C9 1px; padding: .4em;&amp;quot;&amp;gt;[[coroutine.create]]({{Type|function}} f)&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td style=&amp;quot;border-top: solid #C9C9C9 1px; padding: .4em;&amp;quot;&amp;gt;Creates a new coroutine.&amp;lt;/td&amp;gt;&amp;lt;/tr&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tr style=&amp;quot;background-color: #E8E8E8;&amp;quot;&amp;gt;&amp;lt;td style=&amp;quot;border-top: solid #C9C9C9 1px; padding: .4em;&amp;quot;&amp;gt;[[Boolean_(Type)|boolean]] success, …&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td style=&amp;quot;border-top: solid #C9C9C9 1px; padding: .4em;&amp;quot;&amp;gt;[[coroutine.resume]]({{Type|coroutine}} coro, [var1], [var2], ...)&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td style=&amp;quot;border-top: solid #C9C9C9 1px; padding: .4em;&amp;quot;&amp;gt;Starts or resumes an existing coroutine.&amp;lt;/td&amp;gt;&amp;lt;/tr&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tr style=&amp;quot;background-color: #FFFFFF;&amp;quot;&amp;gt;&amp;lt;td style=&amp;quot;border-top: solid #C9C9C9 1px; padding: .4em;&amp;quot;&amp;gt;[[Coroutine_(Type)|coroutine]] coro&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td style=&amp;quot;border-top: solid #C9C9C9 1px; padding: .4em;&amp;quot;&amp;gt;[[coroutine.running]]()&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td style=&amp;quot;border-top: solid #C9C9C9 1px; padding: .4em;&amp;quot;&amp;gt;Returns the currently executing coroutine.&amp;lt;/td&amp;gt;&amp;lt;/tr&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tr style=&amp;quot;background-color: #E8E8E8;&amp;quot;&amp;gt;&amp;lt;td style=&amp;quot;border-top: solid #C9C9C9 1px; padding: .4em;&amp;quot;&amp;gt;[[String_(Type)|string]] status&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td style=&amp;quot;border-top: solid #C9C9C9 1px; padding: .4em;&amp;quot;&amp;gt;[[coroutine.status]]({{type|coroutine}} coroutine)&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td style=&amp;quot;border-top: solid #C9C9C9 1px; padding: .4em;&amp;quot;&amp;gt;Returns the status of the given coroutine.&amp;lt;/td&amp;gt;&amp;lt;/tr&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tr style=&amp;quot;background-color: #FFFFFF;&amp;quot;&amp;gt;&amp;lt;td style=&amp;quot;border-top: solid #C9C9C9 1px; padding: .4em;&amp;quot;&amp;gt;[[Function_(Type)|function]] coroutine wrapper&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td style=&amp;quot;border-top: solid #C9C9C9 1px; padding: .4em;&amp;quot;&amp;gt;[[coroutine.wrap]]({{type|function}} function)&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td style=&amp;quot;border-top: solid #C9C9C9 1px; padding: .4em;&amp;quot;&amp;gt;Creates a new coroutine and wraps it in a function.&amp;lt;/td&amp;gt;&amp;lt;/tr&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tr style=&amp;quot;background-color: #E8E8E8;&amp;quot;&amp;gt;&amp;lt;td style=&amp;quot;border-top: solid #C9C9C9 1px; padding: .4em;&amp;quot;&amp;gt;[var3], [var4], …&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td style=&amp;quot;border-top: solid #C9C9C9 1px; padding: .4em;&amp;quot;&amp;gt;[[coroutine.yield]]([var1], [var2], …)&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td style=&amp;quot;border-top: solid #C9C9C9 1px; padding: .4em;&amp;quot;&amp;gt;Pauses the currently executing coroutine and passes control to its caller.&amp;lt;/td&amp;gt;&amp;lt;/tr&amp;gt;&lt;br /&gt;
&amp;lt;/table&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Coroutine States and Ancestry ==&lt;br /&gt;
Every coroutine is in one of four states:&lt;br /&gt;
* A ''suspended'' coroutine is one that has not yet been started or that has yielded. A suspended coroutine can become running if it is passed to [[coroutine.resume]].&lt;br /&gt;
* A ''running'' coroutine is one that is currently executing code. Only one coroutine can be running at a time on a particular computer. A running coroutine can become suspended if it [[coroutine.yield]], normal if it calls [[coroutine.resume]] on another coroutine, or dead by if it returns from its body function.&lt;br /&gt;
* A ''normal'' coroutine is one that, while running, resumed another coroutine (the ''child coroutine''). A normal coroutine can become running if its child calls [[coroutine.yield]] or returns from its function body.&lt;br /&gt;
* A ''dead'' coroutine is one that, while running, returned from its function body. A dead coroutine can never change state.&lt;br /&gt;
&lt;br /&gt;
While suspended and dead coroutines simply sit loose with no connections to other coroutines, normal and running coroutines have an ancestry relationship between them. Exactly one coroutine is running at any given time, and the running coroutine has no children. Every running or normal coroutine except the top-level BIOS coroutine has a parent, and this relationship forms a chain with one end (the furthest ancestor) being the top-level BIOS coroutine and the other end (the furthest descendant) being the running coroutine. Remember that only the running coroutine can actually execute code, so any functions invoked must be invoked by that coroutine. Then, calling [[coroutine.resume]] makes the chain longer by taking a previously suspended coroutine, hanging it underneath the current coroutine as a new child, and making the current coroutine normal and the new child running. Meanwhile, calling [[coroutine.yield]] makes the chain shorter by turning the currently executing coroutine into a suspended coroutine, detaching it from the chain, and letting its former parent become running.&lt;br /&gt;
&lt;br /&gt;
It is important not to confuse this coroutine chain with the function call stack. Each individual coroutine contains a complete function call stack of its own, rooted at the coroutine’s body function, whether the coroutine is running, normal, or suspended; the chain described in the previous paragraph refers to how entire coroutines are connected together.&lt;br /&gt;
&lt;br /&gt;
== Examples ==&lt;br /&gt;
As the coroutine API is very tightly coupled and many of its function must be used to get any interesting results, examples are shown here instead of on the individual function pages.&lt;br /&gt;
&lt;br /&gt;
=== Using the Basic Coroutine Functions ===&lt;br /&gt;
This example demonstrates using the basic coroutine functions to pass control and data between coroutines. This example prints the numbers 1 through 17 in order, showing how control flow moves through the main program coroutine and the two created coroutines, while using assertions to show how data flows through the program:&lt;br /&gt;
&lt;br /&gt;
 -- These variables will hold the coroutine objects.&lt;br /&gt;
 local c1 = nil&lt;br /&gt;
 local c2 = nil&lt;br /&gt;
 &lt;br /&gt;
 -- This function will be the body of the first coroutine.&lt;br /&gt;
 local function f1(x)&lt;br /&gt;
   -- The main code, below, starts c1 first, passing 1.&lt;br /&gt;
   -- Thus c1 should be running, c2 should be suspended (not started yet), and x should receive the value from main, 1.&lt;br /&gt;
   -- STEP 2: Check these assumptions.&lt;br /&gt;
   print(2)&lt;br /&gt;
   assert(coroutine.status(c1) == &amp;quot;running&amp;quot;)&lt;br /&gt;
   assert(coroutine.status(c2) == &amp;quot;suspended&amp;quot;)&lt;br /&gt;
   assert(x == 1)&lt;br /&gt;
   -- STEP 3: Run c2 until it yields, start it off with the value 2.&lt;br /&gt;
   print(3)&lt;br /&gt;
   success, value = coroutine.resume(c2, 2)&lt;br /&gt;
   assert(success)&lt;br /&gt;
   -- In step 6, c2 yields and passes back the value 3.&lt;br /&gt;
   -- Then c2, having yielded, should be suspended, and c1 should be running again.&lt;br /&gt;
   -- STEP 7: Check all that.&lt;br /&gt;
   print(7)&lt;br /&gt;
   assert(coroutine.status(c1) == &amp;quot;running&amp;quot;)&lt;br /&gt;
   assert(coroutine.status(c2) == &amp;quot;suspended&amp;quot;)&lt;br /&gt;
   assert(value == 3)&lt;br /&gt;
   -- STEP 8: Run c2 again, passing it the value 4.&lt;br /&gt;
   -- Since c2 has already run before, this time the 4 will come out of the yield() instead of appear as a function parameter.&lt;br /&gt;
   print(8)&lt;br /&gt;
   success, value = coroutine.resume(c2, 4)&lt;br /&gt;
   -- In step 10, c2 yields and passes back the value 5.&lt;br /&gt;
   -- Then c2, having yielded, should be suspended, and c1 should be running again.&lt;br /&gt;
   -- STEP 11: Check all that.&lt;br /&gt;
   print(11)&lt;br /&gt;
   assert(coroutine.status(c1) == &amp;quot;running&amp;quot;)&lt;br /&gt;
   assert(coroutine.status(c2) == &amp;quot;suspended&amp;quot;)&lt;br /&gt;
   assert(value == 5)&lt;br /&gt;
   -- STEP 12: Yield, turning c1 back into a suspended coroutine and continuing execution of the main program, passing back value 6.&lt;br /&gt;
   print(12)&lt;br /&gt;
   value = coroutine.yield(6)&lt;br /&gt;
 end&lt;br /&gt;
 &lt;br /&gt;
 -- This function will be the body of the second coroutine.&lt;br /&gt;
 local function f2(x)&lt;br /&gt;
   -- The first time c2 is run, it is run from f1, which passes 2.&lt;br /&gt;
   -- Thus c1 should be normal (as we are nested inside it), c2 should be running, and x should receive the value from f1, 2.&lt;br /&gt;
   -- STEP 4: Check these assumptions.&lt;br /&gt;
   print(4)&lt;br /&gt;
   assert(coroutine.status(c1) == &amp;quot;normal&amp;quot;)&lt;br /&gt;
   assert(coroutine.status(c2) == &amp;quot;running&amp;quot;)&lt;br /&gt;
   assert(x == 2)&lt;br /&gt;
   -- Because c1 is not suspended, we should not be able to resume it.&lt;br /&gt;
   -- STEP 5: Check this is correct.&lt;br /&gt;
   print(5)&lt;br /&gt;
   success, value = coroutine.resume(c1)&lt;br /&gt;
   assert(not success)&lt;br /&gt;
   assert(value == &amp;quot;cannot resume normal coroutine&amp;quot;)&lt;br /&gt;
   -- STEP 6: Yield, turning c2 back into a suspended coroutine and continuing execution of c1, passing back value 3.&lt;br /&gt;
   print(6)&lt;br /&gt;
   value = coroutine.yield(3)&lt;br /&gt;
   -- In step 8, c1 resumed c2 again and passed the value 4.&lt;br /&gt;
   -- c2 should now be running again, and c1 normal again.&lt;br /&gt;
   -- STEP 9: Check all that.&lt;br /&gt;
   print(9)&lt;br /&gt;
   assert(coroutine.status(c1) == &amp;quot;normal&amp;quot;)&lt;br /&gt;
   assert(coroutine.status(c2) == &amp;quot;running&amp;quot;)&lt;br /&gt;
   assert(value == 4)&lt;br /&gt;
   -- STEP 10: Yield, turning c2 back into a suspended coroutine and continuing execution of c1, passing back value 5.&lt;br /&gt;
   print(10)&lt;br /&gt;
   value = coroutine.yield(5)&lt;br /&gt;
   -- In step 14, the main program resumed c2 directly and passed the value 7, bypassing c1.&lt;br /&gt;
   -- So c2 should be running and c1 should be suspended.&lt;br /&gt;
   -- STEP 15: Check all that.&lt;br /&gt;
   print(15)&lt;br /&gt;
   assert(coroutine.status(c1) == &amp;quot;suspended&amp;quot;)&lt;br /&gt;
   assert(coroutine.status(c2) == &amp;quot;running&amp;quot;)&lt;br /&gt;
   assert(value == 7)&lt;br /&gt;
   -- STEP 16: Now die, returning value 8 to the main program.&lt;br /&gt;
   print(16)&lt;br /&gt;
   return 8&lt;br /&gt;
 end&lt;br /&gt;
 &lt;br /&gt;
 -- Construct the two coroutines.&lt;br /&gt;
 c1 = coroutine.create(f1)&lt;br /&gt;
 c2 = coroutine.create(f2)&lt;br /&gt;
 &lt;br /&gt;
 -- Newly constructed coroutines are always suspended.&lt;br /&gt;
 assert(coroutine.status(c1) == &amp;quot;suspended&amp;quot;)&lt;br /&gt;
 assert(coroutine.status(c2) == &amp;quot;suspended&amp;quot;)&lt;br /&gt;
 &lt;br /&gt;
 -- STEP 1: Run c1 until it yields, starting it off with the value 1.&lt;br /&gt;
 print(1)&lt;br /&gt;
 success, value = coroutine.resume(c1, 1)&lt;br /&gt;
 assert(success)&lt;br /&gt;
 &lt;br /&gt;
 -- In step 12, c1 should have yielded and returned the value 6.&lt;br /&gt;
 -- So now c1 and c2 should both be suspended.&lt;br /&gt;
 -- STEP 13: Check all that.&lt;br /&gt;
 print(13)&lt;br /&gt;
 assert(coroutine.status(c1) == &amp;quot;suspended&amp;quot;)&lt;br /&gt;
 assert(coroutine.status(c2) == &amp;quot;suspended&amp;quot;)&lt;br /&gt;
 assert(value == 6)&lt;br /&gt;
 &lt;br /&gt;
 -- STEP 14: Run c2 directly, NOT nested inside c1 this time, passing it the value 7.&lt;br /&gt;
 print(14)&lt;br /&gt;
 success, value = coroutine.resume(c2, 7)&lt;br /&gt;
 assert(success)&lt;br /&gt;
 &lt;br /&gt;
 -- c2 should have exited normally, returning the value 8.&lt;br /&gt;
 -- Therefore c1 should still be suspended, but c2 should be dead.&lt;br /&gt;
 -- STEP 17: Check all that.&lt;br /&gt;
 print(17)&lt;br /&gt;
 assert(coroutine.status(c1) == &amp;quot;suspended&amp;quot;)&lt;br /&gt;
 assert(coroutine.status(c2) == &amp;quot;dead&amp;quot;)&lt;br /&gt;
 assert(value == 8)&lt;br /&gt;
&lt;br /&gt;
=== Using Coroutine Wrapper Functions ===&lt;br /&gt;
This second example is virtually identical, but shows using [[coroutine.wrap]] and wrapper functions instead of the basic coroutine functions (checks of [[coroutine.status]] have been removed as the raw coroutine objects are not available):&lt;br /&gt;
&lt;br /&gt;
 -- These variables will hold the coroutine wrapper functions.&lt;br /&gt;
 local cw1 = nil&lt;br /&gt;
 local cw2 = nil&lt;br /&gt;
 &lt;br /&gt;
 -- This function will be the body of the first coroutine.&lt;br /&gt;
 local function f1(x)&lt;br /&gt;
   -- The main code, below, starts c1 first, passing 1.&lt;br /&gt;
   -- Thus c1 should be running, c2 should be suspended (not started yet), and x should receive the value from main, 1.&lt;br /&gt;
   -- STEP 2: Check these assumptions.&lt;br /&gt;
   print(2)&lt;br /&gt;
   assert(x == 1)&lt;br /&gt;
   -- STEP 3: Run c2 until it yields, start it off with the value 2.&lt;br /&gt;
   print(3)&lt;br /&gt;
   value = cw2(2)&lt;br /&gt;
   -- In step 6, c2 yields and passes back the value 3.&lt;br /&gt;
   -- Then c2, having yielded, should be suspended, and c1 should be running again.&lt;br /&gt;
   -- STEP 7: Check all that.&lt;br /&gt;
   print(7)&lt;br /&gt;
   assert(value == 3)&lt;br /&gt;
   -- STEP 8: Run c2 again, passing it the value 4.&lt;br /&gt;
   -- Since c2 has already run before, this time the 4 will come out of the yield() instead of appear as a function parameter.&lt;br /&gt;
   print(8)&lt;br /&gt;
   value = cw2(4)&lt;br /&gt;
   -- In step 10, c2 yields and passes back the value 5.&lt;br /&gt;
   -- Then c2, having yielded, should be suspended, and c1 should be running again.&lt;br /&gt;
   -- STEP 11: Check all that.&lt;br /&gt;
   print(11)&lt;br /&gt;
   assert(value == 5)&lt;br /&gt;
   -- STEP 12: Yield, turning c1 back into a suspended coroutine and continuing execution of the main program, passing back value 6.&lt;br /&gt;
   print(12)&lt;br /&gt;
   value = coroutine.yield(6)&lt;br /&gt;
 end&lt;br /&gt;
 &lt;br /&gt;
 -- This function will be the body of the second coroutine.&lt;br /&gt;
 local function f2(x)&lt;br /&gt;
   -- The first time c2 is run, it is run from f1, which passes 2.&lt;br /&gt;
   -- Thus c1 should be normal (as we are nested inside it), c2 should be running, and x should receive the value from f1, 2.&lt;br /&gt;
   -- STEP 4: Check these assumptions.&lt;br /&gt;
   print(4)&lt;br /&gt;
   assert(x == 2)&lt;br /&gt;
   -- Because c1 is not suspended, we should not be able to resume it.&lt;br /&gt;
   -- STEP 5: Check this is correct (we must use pcall because an error will be raised).&lt;br /&gt;
   print(5)&lt;br /&gt;
   success, value = pcall(cw1)&lt;br /&gt;
   assert(not success)&lt;br /&gt;
   -- STEP 6: Yield, turning c2 back into a suspended coroutine and continuing execution of c1, passing back value 3.&lt;br /&gt;
   print(6)&lt;br /&gt;
   value = coroutine.yield(3)&lt;br /&gt;
   -- In step 8, c1 resumed c2 again and passed the value 4.&lt;br /&gt;
   -- c2 should now be running again, and c1 normal again.&lt;br /&gt;
   -- STEP 9: Check all that.&lt;br /&gt;
   print(9)&lt;br /&gt;
   assert(value == 4)&lt;br /&gt;
   -- STEP 10: Yield, turning c2 back into a suspended coroutine and continuing execution of c1, passing back value 5.&lt;br /&gt;
   print(10)&lt;br /&gt;
   value = coroutine.yield(5)&lt;br /&gt;
   -- In step 14, the main program resumed c2 directly and passed the value 7, bypassing c1.&lt;br /&gt;
   -- So c2 should be running and c1 should be suspended.&lt;br /&gt;
   -- STEP 15: Check all that.&lt;br /&gt;
   print(15)&lt;br /&gt;
   assert(value == 7)&lt;br /&gt;
   -- STEP 16: Now die, returning value 8 to the main program.&lt;br /&gt;
   print(16)&lt;br /&gt;
   return 8&lt;br /&gt;
 end&lt;br /&gt;
 &lt;br /&gt;
 -- Construct the two coroutine wrappers.&lt;br /&gt;
 cw1 = coroutine.wrap(f1)&lt;br /&gt;
 cw2 = coroutine.wrap(f2)&lt;br /&gt;
 &lt;br /&gt;
 -- STEP 1: Run cw1 until it yields, starting it off with the value 1.&lt;br /&gt;
 print(1)&lt;br /&gt;
 value = cw1(1)&lt;br /&gt;
 &lt;br /&gt;
 -- In step 12, c1 should have yielded and returned the value 6.&lt;br /&gt;
 -- So now c1 and c2 should both be suspended.&lt;br /&gt;
 -- STEP 13: Check all that.&lt;br /&gt;
 print(13)&lt;br /&gt;
 assert(value == 6)&lt;br /&gt;
 &lt;br /&gt;
 -- STEP 14: Run c2 directly, NOT nested inside c1 this time, passing it the value 7.&lt;br /&gt;
 print(14)&lt;br /&gt;
 value = cw2(7)&lt;br /&gt;
 &lt;br /&gt;
 -- c2 should have exited normally, returning the value 8.&lt;br /&gt;
 -- Therefore c1 should still be suspended, but c2 should be dead.&lt;br /&gt;
 -- STEP 17: Check all that.&lt;br /&gt;
 print(17)&lt;br /&gt;
 assert(value == 8)&lt;br /&gt;
&lt;br /&gt;
== Interaction with Other APIs ==&lt;br /&gt;
The [[OS (API)#pullEvent|os.pullEventRaw]] (and therefore [[os.pullEvent]]) functions are built on top of coroutines: &amp;lt;code&amp;gt;os.pullEventRaw&amp;lt;/code&amp;gt; actually just calls [[coroutine.yield]], passing the event type filter up to the parent coroutine. The parent coroutine is expected to wait until an event of the required type arrives, then use [[coroutine.resume]] to pass the event to the suspended coroutine (where it will be returned from &amp;lt;code&amp;gt;os.pullEventRaw&amp;lt;/code&amp;gt;). If you use the [[Parallel (API)|parallel API]], this is exactly what [[parallel.waitForAny]] and [[parallel.waitForAll]] do: they pull events from the system event queue (or even from a higher invocation of &amp;lt;code&amp;gt;parallel.waitForAny&amp;lt;/code&amp;gt; or &amp;lt;code&amp;gt;parallel.waitForAll&amp;lt;/code&amp;gt;!) and deliver them to all nested coroutines. Therefore, the easiest way to use coroutines is the parallel API, if it works for your situation. However, in the event that you are not able to use the parallel API (e.g. if you need to add and remove coroutines from the executing set dynamically), you can build your own dispatcher that delivers events in the same way as the parallel API—looking at the source code to the parallel API may be useful here.&lt;br /&gt;
&lt;br /&gt;
If you choose to use coroutines in a different way, then &amp;lt;code&amp;gt;os.pullEventRaw&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;os.pullEvent&amp;lt;/code&amp;gt; will not work. This in turn will break any other API function which is written on top of &amp;lt;code&amp;gt;os.pullEvent&amp;lt;/code&amp;gt;. As a guideline, nearly any API function that can possibly take time to complete will fall into this category; some examples are:&lt;br /&gt;
* [[rednet.receive]] blocks until either a [[Rednet message (event)|rednet_message event]] or (if a timeout was requested) a matching [[Timer (event)|timer event]] occurs.&lt;br /&gt;
* [[Gps (API)|gps.locate]] blocks until either a number of [[Modem message (event)|modem_message events]] or (if a timeout was requested) a matching [[Timer (event)|timer event]] occurs.&lt;br /&gt;
* [[http.get]] blocks until an [[Http success (event)|HTTP success event]] or [[Http failure (event)|HTTP failure event]] occurs.&lt;br /&gt;
* [[IO (API)|io.read]] and the built-in [[read]] functions block waiting for, presumably, either [[Char (event)|char events]] or [[Key (event)|key events]].&lt;br /&gt;
* [[os.sleep]] blocks until a matching [[Timer (event)|timer event]] occurs.&lt;br /&gt;
* [[textutils.slowPrint]] calls [[os.sleep]].&lt;br /&gt;
* [[textutils.pagedPrint]] blocks until a [[Key (event)|key event]] occurs for each page.&lt;br /&gt;
* Most of the functions in the [[Turtle (API)|turtle API]] (with the exception of [[turtle.getItemCount]], [[turtle.getItemSpace]], and [[turtle.getFuelLevel]]) block waiting for a [[Turtle response (event)|turtle response event]].&lt;br /&gt;
&lt;br /&gt;
Most of these can be worked around by using non-blocking equivalents that return immediately and then queue an event on completion (such as using [[http.request]]) or that deliver an event unconditionally (such as [[Char_(event)|char]] for keyboard input), then handling events in a way that is suitable for the application. However, if possible, it will often be easier to implement event dispatching instead, remembering that [[os.queueEvent]] can be used for inter-coroutine communication within an application. Another alternative, if you must use a custom protocol between your coroutines and dispatcher, might be to replace &amp;lt;code&amp;gt;os.pullEventRaw&amp;lt;/code&amp;gt; with a new function that uses a mechanism appropriate to the application.&lt;br /&gt;
&lt;br /&gt;
[[Category:APIs]]&lt;/div&gt;</summary>
		<author><name>YoYoYonnY</name></author>	</entry>

	<entry>
		<id>https://www.computercraft.info/wiki/index.php?title=Coroutine_(API)&amp;diff=5774</id>
		<title>Coroutine (API)</title>
		<link rel="alternate" type="text/html" href="https://www.computercraft.info/wiki/index.php?title=Coroutine_(API)&amp;diff=5774"/>
				<updated>2013-07-03T04:33:31Z</updated>
		
		<summary type="html">&lt;p&gt;YoYoYonnY: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{NeedsWork}}&lt;br /&gt;
:{| border=&amp;quot;1&amp;quot; class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
| '''Bug'''&lt;br /&gt;
'''From ComputerCraft 1.3''' this API suffers from the problem of potentially spawning Java threads that live forever therefore, use of coroutines should be minimized. This is '''fixed in ComputerCraft 1.32+''', though.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
''This is for the Coroutine API. For the Coroutine Object, visit [[Coroutine (type)]].''&lt;br /&gt;
&lt;br /&gt;
Coroutine is a default Lua 5.1 API defined [http://www.lua.org/manual/5.1/manual.html#5.2 here]. Please list any non-working functions on this page.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;table style=&amp;quot;width: 100%; border: solid 1px black; margin: 2px; border-spacing: 0px;&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&amp;lt;td colspan=&amp;quot;3&amp;quot; style=&amp;quot;font-weight: bold; font-size: large; padding-bottom: .3em; border-bottom: solid #C9C9C9 1px; background: #D3FFC2; line-height:28px;&amp;quot;&amp;gt;&lt;br /&gt;
[[File:Grid_disk.png|24px]]&amp;amp;nbsp;&amp;amp;nbsp;&lt;br /&gt;
Coroutine (API)&lt;br /&gt;
&amp;lt;/td&amp;gt;&amp;lt;/tr&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tr&amp;gt;&amp;lt;td style=&amp;quot;width: 100px; background: #E0E0E0; padding: .4em; font-weight:bold;&amp;quot;&amp;gt;Return&amp;lt;/td&amp;gt;&amp;lt;td style=&amp;quot;width: 350px; background: #E0E0E0; padding: .4em; font-weight:bold;&amp;quot;&amp;gt;Method Name&amp;lt;/td&amp;gt;&amp;lt;td style=&amp;quot;background: #E0E0E0; padding: .4em; font-weight:bold;&amp;quot;&amp;gt;Description&amp;lt;/td&amp;gt;&amp;lt;/tr&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tr style=&amp;quot;background-color: #FFFFFF;&amp;quot;&amp;gt;&amp;lt;td style=&amp;quot;border-top: solid #C9C9C9 1px; padding: .4em;&amp;quot;&amp;gt;[[coroutine_(Type)|coroutine]] coro&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td style=&amp;quot;border-top: solid #C9C9C9 1px; padding: .4em;&amp;quot;&amp;gt;[[coroutine.create]]({{Type|function}} f)&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td style=&amp;quot;border-top: solid #C9C9C9 1px; padding: .4em;&amp;quot;&amp;gt;Creates a new coroutine.&amp;lt;/td&amp;gt;&amp;lt;/tr&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tr style=&amp;quot;background-color: #E8E8E8;&amp;quot;&amp;gt;&amp;lt;td style=&amp;quot;border-top: solid #C9C9C9 1px; padding: .4em;&amp;quot;&amp;gt;[[boolean_(Type)|boolean]] success, …&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td style=&amp;quot;border-top: solid #C9C9C9 1px; padding: .4em;&amp;quot;&amp;gt;[[coroutine.resume]]({{Type|coroutine}} coro, [var1], [var2], ...)&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td style=&amp;quot;border-top: solid #C9C9C9 1px; padding: .4em;&amp;quot;&amp;gt;Starts or resumes an existing coroutine.&amp;lt;/td&amp;gt;&amp;lt;/tr&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tr style=&amp;quot;background-color: #FFFFFF;&amp;quot;&amp;gt;&amp;lt;td style=&amp;quot;border-top: solid #C9C9C9 1px; padding: .4em;&amp;quot;&amp;gt;[[coroutine_(Type)|coroutine]] coro&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td style=&amp;quot;border-top: solid #C9C9C9 1px; padding: .4em;&amp;quot;&amp;gt;[[coroutine.running]]()&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td style=&amp;quot;border-top: solid #C9C9C9 1px; padding: .4em;&amp;quot;&amp;gt;Returns the currently executing coroutine.&amp;lt;/td&amp;gt;&amp;lt;/tr&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tr style=&amp;quot;background-color: #E8E8E8;&amp;quot;&amp;gt;&amp;lt;td style=&amp;quot;border-top: solid #C9C9C9 1px; padding: .4em;&amp;quot;&amp;gt;[[string_(Type)|string]] status&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td style=&amp;quot;border-top: solid #C9C9C9 1px; padding: .4em;&amp;quot;&amp;gt;[[coroutine.status]]({{type|coroutine}} coroutine)&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td style=&amp;quot;border-top: solid #C9C9C9 1px; padding: .4em;&amp;quot;&amp;gt;Returns the status of the given coroutine.&amp;lt;/td&amp;gt;&amp;lt;/tr&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tr style=&amp;quot;background-color: #FFFFFF;&amp;quot;&amp;gt;&amp;lt;td style=&amp;quot;border-top: solid #C9C9C9 1px; padding: .4em;&amp;quot;&amp;gt;[[function_(Type)|function]] coroutine wrapper&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td style=&amp;quot;border-top: solid #C9C9C9 1px; padding: .4em;&amp;quot;&amp;gt;[[coroutine.wrap]]({{type|function}} function)&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td style=&amp;quot;border-top: solid #C9C9C9 1px; padding: .4em;&amp;quot;&amp;gt;Creates a new coroutine and wraps it in a function.&amp;lt;/td&amp;gt;&amp;lt;/tr&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tr style=&amp;quot;background-color: #E8E8E8;&amp;quot;&amp;gt;&amp;lt;td style=&amp;quot;border-top: solid #C9C9C9 1px; padding: .4em;&amp;quot;&amp;gt;[var3], [var4], …&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td style=&amp;quot;border-top: solid #C9C9C9 1px; padding: .4em;&amp;quot;&amp;gt;[[coroutine.yield]]([var1], [var2], …)&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td style=&amp;quot;border-top: solid #C9C9C9 1px; padding: .4em;&amp;quot;&amp;gt;Pauses the currently executing coroutine and passes control to its caller.&amp;lt;/td&amp;gt;&amp;lt;/tr&amp;gt;&lt;br /&gt;
&amp;lt;/table&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Coroutine States and Ancestry ==&lt;br /&gt;
Every coroutine is in one of four states:&lt;br /&gt;
* A ''suspended'' coroutine is one that has not yet been started or that has yielded. A suspended coroutine can become running if it is passed to [[coroutine.resume]].&lt;br /&gt;
* A ''running'' coroutine is one that is currently executing code. Only one coroutine can be running at a time on a particular computer. A running coroutine can become suspended if it [[coroutine.yield]], normal if it calls [[coroutine.resume]] on another coroutine, or dead by if it returns from its body function.&lt;br /&gt;
* A ''normal'' coroutine is one that, while running, resumed another coroutine (the ''child coroutine''). A normal coroutine can become running if its child calls [[coroutine.yield]] or returns from its function body.&lt;br /&gt;
* A ''dead'' coroutine is one that, while running, returned from its function body. A dead coroutine can never change state.&lt;br /&gt;
&lt;br /&gt;
While suspended and dead coroutines simply sit loose with no connections to other coroutines, normal and running coroutines have an ancestry relationship between them. Exactly one coroutine is running at any given time, and the running coroutine has no children. Every running or normal coroutine except the top-level BIOS coroutine has a parent, and this relationship forms a chain with one end (the furthest ancestor) being the top-level BIOS coroutine and the other end (the furthest descendant) being the running coroutine. Remember that only the running coroutine can actually execute code, so any functions invoked must be invoked by that coroutine. Then, calling [[coroutine.resume]] makes the chain longer by taking a previously suspended coroutine, hanging it underneath the current coroutine as a new child, and making the current coroutine normal and the new child running. Meanwhile, calling [[coroutine.yield]] makes the chain shorter by turning the currently executing coroutine into a suspended coroutine, detaching it from the chain, and letting its former parent become running.&lt;br /&gt;
&lt;br /&gt;
It is important not to confuse this coroutine chain with the function call stack. Each individual coroutine contains a complete function call stack of its own, rooted at the coroutine’s body function, whether the coroutine is running, normal, or suspended; the chain described in the previous paragraph refers to how entire coroutines are connected together.&lt;br /&gt;
&lt;br /&gt;
== Examples ==&lt;br /&gt;
As the coroutine API is very tightly coupled and many of its function must be used to get any interesting results, examples are shown here instead of on the individual function pages.&lt;br /&gt;
&lt;br /&gt;
=== Using the Basic Coroutine Functions ===&lt;br /&gt;
This example demonstrates using the basic coroutine functions to pass control and data between coroutines. This example prints the numbers 1 through 17 in order, showing how control flow moves through the main program coroutine and the two created coroutines, while using assertions to show how data flows through the program:&lt;br /&gt;
&lt;br /&gt;
 -- These variables will hold the coroutine objects.&lt;br /&gt;
 local c1 = nil&lt;br /&gt;
 local c2 = nil&lt;br /&gt;
 &lt;br /&gt;
 -- This function will be the body of the first coroutine.&lt;br /&gt;
 local function f1(x)&lt;br /&gt;
   -- The main code, below, starts c1 first, passing 1.&lt;br /&gt;
   -- Thus c1 should be running, c2 should be suspended (not started yet), and x should receive the value from main, 1.&lt;br /&gt;
   -- STEP 2: Check these assumptions.&lt;br /&gt;
   print(2)&lt;br /&gt;
   assert(coroutine.status(c1) == &amp;quot;running&amp;quot;)&lt;br /&gt;
   assert(coroutine.status(c2) == &amp;quot;suspended&amp;quot;)&lt;br /&gt;
   assert(x == 1)&lt;br /&gt;
   -- STEP 3: Run c2 until it yields, start it off with the value 2.&lt;br /&gt;
   print(3)&lt;br /&gt;
   success, value = coroutine.resume(c2, 2)&lt;br /&gt;
   assert(success)&lt;br /&gt;
   -- In step 6, c2 yields and passes back the value 3.&lt;br /&gt;
   -- Then c2, having yielded, should be suspended, and c1 should be running again.&lt;br /&gt;
   -- STEP 7: Check all that.&lt;br /&gt;
   print(7)&lt;br /&gt;
   assert(coroutine.status(c1) == &amp;quot;running&amp;quot;)&lt;br /&gt;
   assert(coroutine.status(c2) == &amp;quot;suspended&amp;quot;)&lt;br /&gt;
   assert(value == 3)&lt;br /&gt;
   -- STEP 8: Run c2 again, passing it the value 4.&lt;br /&gt;
   -- Since c2 has already run before, this time the 4 will come out of the yield() instead of appear as a function parameter.&lt;br /&gt;
   print(8)&lt;br /&gt;
   success, value = coroutine.resume(c2, 4)&lt;br /&gt;
   -- In step 10, c2 yields and passes back the value 5.&lt;br /&gt;
   -- Then c2, having yielded, should be suspended, and c1 should be running again.&lt;br /&gt;
   -- STEP 11: Check all that.&lt;br /&gt;
   print(11)&lt;br /&gt;
   assert(coroutine.status(c1) == &amp;quot;running&amp;quot;)&lt;br /&gt;
   assert(coroutine.status(c2) == &amp;quot;suspended&amp;quot;)&lt;br /&gt;
   assert(value == 5)&lt;br /&gt;
   -- STEP 12: Yield, turning c1 back into a suspended coroutine and continuing execution of the main program, passing back value 6.&lt;br /&gt;
   print(12)&lt;br /&gt;
   value = coroutine.yield(6)&lt;br /&gt;
 end&lt;br /&gt;
 &lt;br /&gt;
 -- This function will be the body of the second coroutine.&lt;br /&gt;
 local function f2(x)&lt;br /&gt;
   -- The first time c2 is run, it is run from f1, which passes 2.&lt;br /&gt;
   -- Thus c1 should be normal (as we are nested inside it), c2 should be running, and x should receive the value from f1, 2.&lt;br /&gt;
   -- STEP 4: Check these assumptions.&lt;br /&gt;
   print(4)&lt;br /&gt;
   assert(coroutine.status(c1) == &amp;quot;normal&amp;quot;)&lt;br /&gt;
   assert(coroutine.status(c2) == &amp;quot;running&amp;quot;)&lt;br /&gt;
   assert(x == 2)&lt;br /&gt;
   -- Because c1 is not suspended, we should not be able to resume it.&lt;br /&gt;
   -- STEP 5: Check this is correct.&lt;br /&gt;
   print(5)&lt;br /&gt;
   success, value = coroutine.resume(c1)&lt;br /&gt;
   assert(not success)&lt;br /&gt;
   assert(value == &amp;quot;cannot resume normal coroutine&amp;quot;)&lt;br /&gt;
   -- STEP 6: Yield, turning c2 back into a suspended coroutine and continuing execution of c1, passing back value 3.&lt;br /&gt;
   print(6)&lt;br /&gt;
   value = coroutine.yield(3)&lt;br /&gt;
   -- In step 8, c1 resumed c2 again and passed the value 4.&lt;br /&gt;
   -- c2 should now be running again, and c1 normal again.&lt;br /&gt;
   -- STEP 9: Check all that.&lt;br /&gt;
   print(9)&lt;br /&gt;
   assert(coroutine.status(c1) == &amp;quot;normal&amp;quot;)&lt;br /&gt;
   assert(coroutine.status(c2) == &amp;quot;running&amp;quot;)&lt;br /&gt;
   assert(value == 4)&lt;br /&gt;
   -- STEP 10: Yield, turning c2 back into a suspended coroutine and continuing execution of c1, passing back value 5.&lt;br /&gt;
   print(10)&lt;br /&gt;
   value = coroutine.yield(5)&lt;br /&gt;
   -- In step 14, the main program resumed c2 directly and passed the value 7, bypassing c1.&lt;br /&gt;
   -- So c2 should be running and c1 should be suspended.&lt;br /&gt;
   -- STEP 15: Check all that.&lt;br /&gt;
   print(15)&lt;br /&gt;
   assert(coroutine.status(c1) == &amp;quot;suspended&amp;quot;)&lt;br /&gt;
   assert(coroutine.status(c2) == &amp;quot;running&amp;quot;)&lt;br /&gt;
   assert(value == 7)&lt;br /&gt;
   -- STEP 16: Now die, returning value 8 to the main program.&lt;br /&gt;
   print(16)&lt;br /&gt;
   return 8&lt;br /&gt;
 end&lt;br /&gt;
 &lt;br /&gt;
 -- Construct the two coroutines.&lt;br /&gt;
 c1 = coroutine.create(f1)&lt;br /&gt;
 c2 = coroutine.create(f2)&lt;br /&gt;
 &lt;br /&gt;
 -- Newly constructed coroutines are always suspended.&lt;br /&gt;
 assert(coroutine.status(c1) == &amp;quot;suspended&amp;quot;)&lt;br /&gt;
 assert(coroutine.status(c2) == &amp;quot;suspended&amp;quot;)&lt;br /&gt;
 &lt;br /&gt;
 -- STEP 1: Run c1 until it yields, starting it off with the value 1.&lt;br /&gt;
 print(1)&lt;br /&gt;
 success, value = coroutine.resume(c1, 1)&lt;br /&gt;
 assert(success)&lt;br /&gt;
 &lt;br /&gt;
 -- In step 12, c1 should have yielded and returned the value 6.&lt;br /&gt;
 -- So now c1 and c2 should both be suspended.&lt;br /&gt;
 -- STEP 13: Check all that.&lt;br /&gt;
 print(13)&lt;br /&gt;
 assert(coroutine.status(c1) == &amp;quot;suspended&amp;quot;)&lt;br /&gt;
 assert(coroutine.status(c2) == &amp;quot;suspended&amp;quot;)&lt;br /&gt;
 assert(value == 6)&lt;br /&gt;
 &lt;br /&gt;
 -- STEP 14: Run c2 directly, NOT nested inside c1 this time, passing it the value 7.&lt;br /&gt;
 print(14)&lt;br /&gt;
 success, value = coroutine.resume(c2, 7)&lt;br /&gt;
 assert(success)&lt;br /&gt;
 &lt;br /&gt;
 -- c2 should have exited normally, returning the value 8.&lt;br /&gt;
 -- Therefore c1 should still be suspended, but c2 should be dead.&lt;br /&gt;
 -- STEP 17: Check all that.&lt;br /&gt;
 print(17)&lt;br /&gt;
 assert(coroutine.status(c1) == &amp;quot;suspended&amp;quot;)&lt;br /&gt;
 assert(coroutine.status(c2) == &amp;quot;dead&amp;quot;)&lt;br /&gt;
 assert(value == 8)&lt;br /&gt;
&lt;br /&gt;
=== Using Coroutine Wrapper Functions ===&lt;br /&gt;
This second example is virtually identical, but shows using [[coroutine.wrap]] and wrapper functions instead of the basic coroutine functions (checks of [[coroutine.status]] have been removed as the raw coroutine objects are not available):&lt;br /&gt;
&lt;br /&gt;
 -- These variables will hold the coroutine wrapper functions.&lt;br /&gt;
 local cw1 = nil&lt;br /&gt;
 local cw2 = nil&lt;br /&gt;
 &lt;br /&gt;
 -- This function will be the body of the first coroutine.&lt;br /&gt;
 local function f1(x)&lt;br /&gt;
   -- The main code, below, starts c1 first, passing 1.&lt;br /&gt;
   -- Thus c1 should be running, c2 should be suspended (not started yet), and x should receive the value from main, 1.&lt;br /&gt;
   -- STEP 2: Check these assumptions.&lt;br /&gt;
   print(2)&lt;br /&gt;
   assert(x == 1)&lt;br /&gt;
   -- STEP 3: Run c2 until it yields, start it off with the value 2.&lt;br /&gt;
   print(3)&lt;br /&gt;
   value = cw2(2)&lt;br /&gt;
   -- In step 6, c2 yields and passes back the value 3.&lt;br /&gt;
   -- Then c2, having yielded, should be suspended, and c1 should be running again.&lt;br /&gt;
   -- STEP 7: Check all that.&lt;br /&gt;
   print(7)&lt;br /&gt;
   assert(value == 3)&lt;br /&gt;
   -- STEP 8: Run c2 again, passing it the value 4.&lt;br /&gt;
   -- Since c2 has already run before, this time the 4 will come out of the yield() instead of appear as a function parameter.&lt;br /&gt;
   print(8)&lt;br /&gt;
   value = cw2(4)&lt;br /&gt;
   -- In step 10, c2 yields and passes back the value 5.&lt;br /&gt;
   -- Then c2, having yielded, should be suspended, and c1 should be running again.&lt;br /&gt;
   -- STEP 11: Check all that.&lt;br /&gt;
   print(11)&lt;br /&gt;
   assert(value == 5)&lt;br /&gt;
   -- STEP 12: Yield, turning c1 back into a suspended coroutine and continuing execution of the main program, passing back value 6.&lt;br /&gt;
   print(12)&lt;br /&gt;
   value = coroutine.yield(6)&lt;br /&gt;
 end&lt;br /&gt;
 &lt;br /&gt;
 -- This function will be the body of the second coroutine.&lt;br /&gt;
 local function f2(x)&lt;br /&gt;
   -- The first time c2 is run, it is run from f1, which passes 2.&lt;br /&gt;
   -- Thus c1 should be normal (as we are nested inside it), c2 should be running, and x should receive the value from f1, 2.&lt;br /&gt;
   -- STEP 4: Check these assumptions.&lt;br /&gt;
   print(4)&lt;br /&gt;
   assert(x == 2)&lt;br /&gt;
   -- Because c1 is not suspended, we should not be able to resume it.&lt;br /&gt;
   -- STEP 5: Check this is correct (we must use pcall because an error will be raised).&lt;br /&gt;
   print(5)&lt;br /&gt;
   success, value = pcall(cw1)&lt;br /&gt;
   assert(not success)&lt;br /&gt;
   -- STEP 6: Yield, turning c2 back into a suspended coroutine and continuing execution of c1, passing back value 3.&lt;br /&gt;
   print(6)&lt;br /&gt;
   value = coroutine.yield(3)&lt;br /&gt;
   -- In step 8, c1 resumed c2 again and passed the value 4.&lt;br /&gt;
   -- c2 should now be running again, and c1 normal again.&lt;br /&gt;
   -- STEP 9: Check all that.&lt;br /&gt;
   print(9)&lt;br /&gt;
   assert(value == 4)&lt;br /&gt;
   -- STEP 10: Yield, turning c2 back into a suspended coroutine and continuing execution of c1, passing back value 5.&lt;br /&gt;
   print(10)&lt;br /&gt;
   value = coroutine.yield(5)&lt;br /&gt;
   -- In step 14, the main program resumed c2 directly and passed the value 7, bypassing c1.&lt;br /&gt;
   -- So c2 should be running and c1 should be suspended.&lt;br /&gt;
   -- STEP 15: Check all that.&lt;br /&gt;
   print(15)&lt;br /&gt;
   assert(value == 7)&lt;br /&gt;
   -- STEP 16: Now die, returning value 8 to the main program.&lt;br /&gt;
   print(16)&lt;br /&gt;
   return 8&lt;br /&gt;
 end&lt;br /&gt;
 &lt;br /&gt;
 -- Construct the two coroutine wrappers.&lt;br /&gt;
 cw1 = coroutine.wrap(f1)&lt;br /&gt;
 cw2 = coroutine.wrap(f2)&lt;br /&gt;
 &lt;br /&gt;
 -- STEP 1: Run cw1 until it yields, starting it off with the value 1.&lt;br /&gt;
 print(1)&lt;br /&gt;
 value = cw1(1)&lt;br /&gt;
 &lt;br /&gt;
 -- In step 12, c1 should have yielded and returned the value 6.&lt;br /&gt;
 -- So now c1 and c2 should both be suspended.&lt;br /&gt;
 -- STEP 13: Check all that.&lt;br /&gt;
 print(13)&lt;br /&gt;
 assert(value == 6)&lt;br /&gt;
 &lt;br /&gt;
 -- STEP 14: Run c2 directly, NOT nested inside c1 this time, passing it the value 7.&lt;br /&gt;
 print(14)&lt;br /&gt;
 value = cw2(7)&lt;br /&gt;
 &lt;br /&gt;
 -- c2 should have exited normally, returning the value 8.&lt;br /&gt;
 -- Therefore c1 should still be suspended, but c2 should be dead.&lt;br /&gt;
 -- STEP 17: Check all that.&lt;br /&gt;
 print(17)&lt;br /&gt;
 assert(value == 8)&lt;br /&gt;
&lt;br /&gt;
== Interaction with Other APIs ==&lt;br /&gt;
The [[OS (API)#pullEvent|os.pullEventRaw]] (and therefore [[os.pullEvent]]) functions are built on top of coroutines: &amp;lt;code&amp;gt;os.pullEventRaw&amp;lt;/code&amp;gt; actually just calls [[coroutine.yield]], passing the event type filter up to the parent coroutine. The parent coroutine is expected to wait until an event of the required type arrives, then use [[coroutine.resume]] to pass the event to the suspended coroutine (where it will be returned from &amp;lt;code&amp;gt;os.pullEventRaw&amp;lt;/code&amp;gt;). If you use the [[Parallel (API)|parallel API]], this is exactly what [[parallel.waitForAny]] and [[parallel.waitForAll]] do: they pull events from the system event queue (or even from a higher invocation of &amp;lt;code&amp;gt;parallel.waitForAny&amp;lt;/code&amp;gt; or &amp;lt;code&amp;gt;parallel.waitForAll&amp;lt;/code&amp;gt;!) and deliver them to all nested coroutines. Therefore, the easiest way to use coroutines is the parallel API, if it works for your situation. However, in the event that you are not able to use the parallel API (e.g. if you need to add and remove coroutines from the executing set dynamically), you can build your own dispatcher that delivers events in the same way as the parallel API—looking at the source code to the parallel API may be useful here.&lt;br /&gt;
&lt;br /&gt;
If you choose to use coroutines in a different way, then &amp;lt;code&amp;gt;os.pullEventRaw&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;os.pullEvent&amp;lt;/code&amp;gt; will not work. This in turn will break any other API function which is written on top of &amp;lt;code&amp;gt;os.pullEvent&amp;lt;/code&amp;gt;. As a guideline, nearly any API function that can possibly take time to complete will fall into this category; some examples are:&lt;br /&gt;
* [[rednet.receive]] blocks until either a [[Rednet message (event)|rednet_message event]] or (if a timeout was requested) a matching [[Timer (event)|timer event]] occurs.&lt;br /&gt;
* [[Gps (API)|gps.locate]] blocks until either a number of [[Modem message (event)|modem_message events]] or (if a timeout was requested) a matching [[Timer (event)|timer event]] occurs.&lt;br /&gt;
* [[http.get]] blocks until an [[Http success (event)|HTTP success event]] or [[Http failure (event)|HTTP failure event]] occurs.&lt;br /&gt;
* [[IO (API)|io.read]] and the built-in [[read]] functions block waiting for, presumably, either [[Char (event)|char events]] or [[Key (event)|key events]].&lt;br /&gt;
* [[os.sleep]] blocks until a matching [[Timer (event)|timer event]] occurs.&lt;br /&gt;
* [[textutils.slowPrint]] calls [[os.sleep]].&lt;br /&gt;
* [[textutils.pagedPrint]] blocks until a [[Key (event)|key event]] occurs for each page.&lt;br /&gt;
* Most of the functions in the [[Turtle (API)|turtle API]] (with the exception of [[turtle.getItemCount]], [[turtle.getItemSpace]], and [[turtle.getFuelLevel]]) block waiting for a [[Turtle response (event)|turtle response event]].&lt;br /&gt;
&lt;br /&gt;
Most of these can be worked around by using non-blocking equivalents that return immediately and then queue an event on completion (such as using [[http.request]]) or that deliver an event unconditionally (such as [[Char_(event)|char]] for keyboard input), then handling events in a way that is suitable for the application. However, if possible, it will often be easier to implement event dispatching instead, remembering that [[os.queueEvent]] can be used for inter-coroutine communication within an application. Another alternative, if you must use a custom protocol between your coroutines and dispatcher, might be to replace &amp;lt;code&amp;gt;os.pullEventRaw&amp;lt;/code&amp;gt; with a new function that uses a mechanism appropriate to the application.&lt;br /&gt;
&lt;br /&gt;
[[Category:APIs]]&lt;/div&gt;</summary>
		<author><name>YoYoYonnY</name></author>	</entry>

	<entry>
		<id>https://www.computercraft.info/wiki/index.php?title=Coroutine_(API)&amp;diff=5773</id>
		<title>Coroutine (API)</title>
		<link rel="alternate" type="text/html" href="https://www.computercraft.info/wiki/index.php?title=Coroutine_(API)&amp;diff=5773"/>
				<updated>2013-07-03T04:32:56Z</updated>
		
		<summary type="html">&lt;p&gt;YoYoYonnY: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{NeedsWork}}&lt;br /&gt;
:{| border=&amp;quot;1&amp;quot; class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
| '''Bug'''&lt;br /&gt;
'''From ComputerCraft 1.3''' this API suffers from the problem of potentially spawning Java threads that live forever therefore, use of coroutines should be minimized. This is '''fixed in ComputerCraft 1.32+''', though.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
''This is for the Coroutine API. For the Coroutine Object, visit [[Coroutine (type)]].''&lt;br /&gt;
&lt;br /&gt;
Coroutine is a default Lua 5.1 API defined [http://www.lua.org/manual/5.1/manual.html#5.2 here]. Please list any non-working functions on this page.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;table style=&amp;quot;width: 100%; border: solid 1px black; margin: 2px; border-spacing: 0px;&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&amp;lt;td colspan=&amp;quot;3&amp;quot; style=&amp;quot;font-weight: bold; font-size: large; padding-bottom: .3em; border-bottom: solid #C9C9C9 1px; background: #D3FFC2; line-height:28px;&amp;quot;&amp;gt;&lt;br /&gt;
[[File:Grid_disk.png|24px]]&amp;amp;nbsp;&amp;amp;nbsp;&lt;br /&gt;
Coroutine (API)&lt;br /&gt;
&amp;lt;/td&amp;gt;&amp;lt;/tr&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tr&amp;gt;&amp;lt;td style=&amp;quot;width: 100px; background: #E0E0E0; padding: .4em; font-weight:bold;&amp;quot;&amp;gt;Return&amp;lt;/td&amp;gt;&amp;lt;td style=&amp;quot;width: 350px; background: #E0E0E0; padding: .4em; font-weight:bold;&amp;quot;&amp;gt;Method Name&amp;lt;/td&amp;gt;&amp;lt;td style=&amp;quot;background: #E0E0E0; padding: .4em; font-weight:bold;&amp;quot;&amp;gt;Description&amp;lt;/td&amp;gt;&amp;lt;/tr&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tr style=&amp;quot;background-color: #FFFFFF;&amp;quot;&amp;gt;&amp;lt;td style=&amp;quot;border-top: solid #C9C9C9 1px; padding: .4em;&amp;quot;&amp;gt;[[coroutine_Type|coroutine]] coro&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td style=&amp;quot;border-top: solid #C9C9C9 1px; padding: .4em;&amp;quot;&amp;gt;[[coroutine.create]]({{Type|function}} f)&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td style=&amp;quot;border-top: solid #C9C9C9 1px; padding: .4em;&amp;quot;&amp;gt;Creates a new coroutine.&amp;lt;/td&amp;gt;&amp;lt;/tr&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tr style=&amp;quot;background-color: #E8E8E8;&amp;quot;&amp;gt;&amp;lt;td style=&amp;quot;border-top: solid #C9C9C9 1px; padding: .4em;&amp;quot;&amp;gt;[[boolean_Type|boolean]] success, …&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td style=&amp;quot;border-top: solid #C9C9C9 1px; padding: .4em;&amp;quot;&amp;gt;[[coroutine.resume]]({{Type|coroutine}} coro, [var1], [var2], ...)&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td style=&amp;quot;border-top: solid #C9C9C9 1px; padding: .4em;&amp;quot;&amp;gt;Starts or resumes an existing coroutine.&amp;lt;/td&amp;gt;&amp;lt;/tr&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tr style=&amp;quot;background-color: #FFFFFF;&amp;quot;&amp;gt;&amp;lt;td style=&amp;quot;border-top: solid #C9C9C9 1px; padding: .4em;&amp;quot;&amp;gt;[[coroutine_Type|coroutine]] coro&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td style=&amp;quot;border-top: solid #C9C9C9 1px; padding: .4em;&amp;quot;&amp;gt;[[coroutine.running]]()&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td style=&amp;quot;border-top: solid #C9C9C9 1px; padding: .4em;&amp;quot;&amp;gt;Returns the currently executing coroutine.&amp;lt;/td&amp;gt;&amp;lt;/tr&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tr style=&amp;quot;background-color: #E8E8E8;&amp;quot;&amp;gt;&amp;lt;td style=&amp;quot;border-top: solid #C9C9C9 1px; padding: .4em;&amp;quot;&amp;gt;[[string_Type|string]] status&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td style=&amp;quot;border-top: solid #C9C9C9 1px; padding: .4em;&amp;quot;&amp;gt;[[coroutine.status]]({{type|coroutine}} coroutine)&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td style=&amp;quot;border-top: solid #C9C9C9 1px; padding: .4em;&amp;quot;&amp;gt;Returns the status of the given coroutine.&amp;lt;/td&amp;gt;&amp;lt;/tr&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tr style=&amp;quot;background-color: #FFFFFF;&amp;quot;&amp;gt;&amp;lt;td style=&amp;quot;border-top: solid #C9C9C9 1px; padding: .4em;&amp;quot;&amp;gt;[[function_Type|function]] coroutine wrapper&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td style=&amp;quot;border-top: solid #C9C9C9 1px; padding: .4em;&amp;quot;&amp;gt;[[coroutine.wrap]]({{type|function}} function)&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td style=&amp;quot;border-top: solid #C9C9C9 1px; padding: .4em;&amp;quot;&amp;gt;Creates a new coroutine and wraps it in a function.&amp;lt;/td&amp;gt;&amp;lt;/tr&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tr style=&amp;quot;background-color: #E8E8E8;&amp;quot;&amp;gt;&amp;lt;td style=&amp;quot;border-top: solid #C9C9C9 1px; padding: .4em;&amp;quot;&amp;gt;[var3], [var4], …&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td style=&amp;quot;border-top: solid #C9C9C9 1px; padding: .4em;&amp;quot;&amp;gt;[[coroutine.yield]]([var1], [var2], …)&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td style=&amp;quot;border-top: solid #C9C9C9 1px; padding: .4em;&amp;quot;&amp;gt;Pauses the currently executing coroutine and passes control to its caller.&amp;lt;/td&amp;gt;&amp;lt;/tr&amp;gt;&lt;br /&gt;
&amp;lt;/table&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Coroutine States and Ancestry ==&lt;br /&gt;
Every coroutine is in one of four states:&lt;br /&gt;
* A ''suspended'' coroutine is one that has not yet been started or that has yielded. A suspended coroutine can become running if it is passed to [[coroutine.resume]].&lt;br /&gt;
* A ''running'' coroutine is one that is currently executing code. Only one coroutine can be running at a time on a particular computer. A running coroutine can become suspended if it [[coroutine.yield]], normal if it calls [[coroutine.resume]] on another coroutine, or dead by if it returns from its body function.&lt;br /&gt;
* A ''normal'' coroutine is one that, while running, resumed another coroutine (the ''child coroutine''). A normal coroutine can become running if its child calls [[coroutine.yield]] or returns from its function body.&lt;br /&gt;
* A ''dead'' coroutine is one that, while running, returned from its function body. A dead coroutine can never change state.&lt;br /&gt;
&lt;br /&gt;
While suspended and dead coroutines simply sit loose with no connections to other coroutines, normal and running coroutines have an ancestry relationship between them. Exactly one coroutine is running at any given time, and the running coroutine has no children. Every running or normal coroutine except the top-level BIOS coroutine has a parent, and this relationship forms a chain with one end (the furthest ancestor) being the top-level BIOS coroutine and the other end (the furthest descendant) being the running coroutine. Remember that only the running coroutine can actually execute code, so any functions invoked must be invoked by that coroutine. Then, calling [[coroutine.resume]] makes the chain longer by taking a previously suspended coroutine, hanging it underneath the current coroutine as a new child, and making the current coroutine normal and the new child running. Meanwhile, calling [[coroutine.yield]] makes the chain shorter by turning the currently executing coroutine into a suspended coroutine, detaching it from the chain, and letting its former parent become running.&lt;br /&gt;
&lt;br /&gt;
It is important not to confuse this coroutine chain with the function call stack. Each individual coroutine contains a complete function call stack of its own, rooted at the coroutine’s body function, whether the coroutine is running, normal, or suspended; the chain described in the previous paragraph refers to how entire coroutines are connected together.&lt;br /&gt;
&lt;br /&gt;
== Examples ==&lt;br /&gt;
As the coroutine API is very tightly coupled and many of its function must be used to get any interesting results, examples are shown here instead of on the individual function pages.&lt;br /&gt;
&lt;br /&gt;
=== Using the Basic Coroutine Functions ===&lt;br /&gt;
This example demonstrates using the basic coroutine functions to pass control and data between coroutines. This example prints the numbers 1 through 17 in order, showing how control flow moves through the main program coroutine and the two created coroutines, while using assertions to show how data flows through the program:&lt;br /&gt;
&lt;br /&gt;
 -- These variables will hold the coroutine objects.&lt;br /&gt;
 local c1 = nil&lt;br /&gt;
 local c2 = nil&lt;br /&gt;
 &lt;br /&gt;
 -- This function will be the body of the first coroutine.&lt;br /&gt;
 local function f1(x)&lt;br /&gt;
   -- The main code, below, starts c1 first, passing 1.&lt;br /&gt;
   -- Thus c1 should be running, c2 should be suspended (not started yet), and x should receive the value from main, 1.&lt;br /&gt;
   -- STEP 2: Check these assumptions.&lt;br /&gt;
   print(2)&lt;br /&gt;
   assert(coroutine.status(c1) == &amp;quot;running&amp;quot;)&lt;br /&gt;
   assert(coroutine.status(c2) == &amp;quot;suspended&amp;quot;)&lt;br /&gt;
   assert(x == 1)&lt;br /&gt;
   -- STEP 3: Run c2 until it yields, start it off with the value 2.&lt;br /&gt;
   print(3)&lt;br /&gt;
   success, value = coroutine.resume(c2, 2)&lt;br /&gt;
   assert(success)&lt;br /&gt;
   -- In step 6, c2 yields and passes back the value 3.&lt;br /&gt;
   -- Then c2, having yielded, should be suspended, and c1 should be running again.&lt;br /&gt;
   -- STEP 7: Check all that.&lt;br /&gt;
   print(7)&lt;br /&gt;
   assert(coroutine.status(c1) == &amp;quot;running&amp;quot;)&lt;br /&gt;
   assert(coroutine.status(c2) == &amp;quot;suspended&amp;quot;)&lt;br /&gt;
   assert(value == 3)&lt;br /&gt;
   -- STEP 8: Run c2 again, passing it the value 4.&lt;br /&gt;
   -- Since c2 has already run before, this time the 4 will come out of the yield() instead of appear as a function parameter.&lt;br /&gt;
   print(8)&lt;br /&gt;
   success, value = coroutine.resume(c2, 4)&lt;br /&gt;
   -- In step 10, c2 yields and passes back the value 5.&lt;br /&gt;
   -- Then c2, having yielded, should be suspended, and c1 should be running again.&lt;br /&gt;
   -- STEP 11: Check all that.&lt;br /&gt;
   print(11)&lt;br /&gt;
   assert(coroutine.status(c1) == &amp;quot;running&amp;quot;)&lt;br /&gt;
   assert(coroutine.status(c2) == &amp;quot;suspended&amp;quot;)&lt;br /&gt;
   assert(value == 5)&lt;br /&gt;
   -- STEP 12: Yield, turning c1 back into a suspended coroutine and continuing execution of the main program, passing back value 6.&lt;br /&gt;
   print(12)&lt;br /&gt;
   value = coroutine.yield(6)&lt;br /&gt;
 end&lt;br /&gt;
 &lt;br /&gt;
 -- This function will be the body of the second coroutine.&lt;br /&gt;
 local function f2(x)&lt;br /&gt;
   -- The first time c2 is run, it is run from f1, which passes 2.&lt;br /&gt;
   -- Thus c1 should be normal (as we are nested inside it), c2 should be running, and x should receive the value from f1, 2.&lt;br /&gt;
   -- STEP 4: Check these assumptions.&lt;br /&gt;
   print(4)&lt;br /&gt;
   assert(coroutine.status(c1) == &amp;quot;normal&amp;quot;)&lt;br /&gt;
   assert(coroutine.status(c2) == &amp;quot;running&amp;quot;)&lt;br /&gt;
   assert(x == 2)&lt;br /&gt;
   -- Because c1 is not suspended, we should not be able to resume it.&lt;br /&gt;
   -- STEP 5: Check this is correct.&lt;br /&gt;
   print(5)&lt;br /&gt;
   success, value = coroutine.resume(c1)&lt;br /&gt;
   assert(not success)&lt;br /&gt;
   assert(value == &amp;quot;cannot resume normal coroutine&amp;quot;)&lt;br /&gt;
   -- STEP 6: Yield, turning c2 back into a suspended coroutine and continuing execution of c1, passing back value 3.&lt;br /&gt;
   print(6)&lt;br /&gt;
   value = coroutine.yield(3)&lt;br /&gt;
   -- In step 8, c1 resumed c2 again and passed the value 4.&lt;br /&gt;
   -- c2 should now be running again, and c1 normal again.&lt;br /&gt;
   -- STEP 9: Check all that.&lt;br /&gt;
   print(9)&lt;br /&gt;
   assert(coroutine.status(c1) == &amp;quot;normal&amp;quot;)&lt;br /&gt;
   assert(coroutine.status(c2) == &amp;quot;running&amp;quot;)&lt;br /&gt;
   assert(value == 4)&lt;br /&gt;
   -- STEP 10: Yield, turning c2 back into a suspended coroutine and continuing execution of c1, passing back value 5.&lt;br /&gt;
   print(10)&lt;br /&gt;
   value = coroutine.yield(5)&lt;br /&gt;
   -- In step 14, the main program resumed c2 directly and passed the value 7, bypassing c1.&lt;br /&gt;
   -- So c2 should be running and c1 should be suspended.&lt;br /&gt;
   -- STEP 15: Check all that.&lt;br /&gt;
   print(15)&lt;br /&gt;
   assert(coroutine.status(c1) == &amp;quot;suspended&amp;quot;)&lt;br /&gt;
   assert(coroutine.status(c2) == &amp;quot;running&amp;quot;)&lt;br /&gt;
   assert(value == 7)&lt;br /&gt;
   -- STEP 16: Now die, returning value 8 to the main program.&lt;br /&gt;
   print(16)&lt;br /&gt;
   return 8&lt;br /&gt;
 end&lt;br /&gt;
 &lt;br /&gt;
 -- Construct the two coroutines.&lt;br /&gt;
 c1 = coroutine.create(f1)&lt;br /&gt;
 c2 = coroutine.create(f2)&lt;br /&gt;
 &lt;br /&gt;
 -- Newly constructed coroutines are always suspended.&lt;br /&gt;
 assert(coroutine.status(c1) == &amp;quot;suspended&amp;quot;)&lt;br /&gt;
 assert(coroutine.status(c2) == &amp;quot;suspended&amp;quot;)&lt;br /&gt;
 &lt;br /&gt;
 -- STEP 1: Run c1 until it yields, starting it off with the value 1.&lt;br /&gt;
 print(1)&lt;br /&gt;
 success, value = coroutine.resume(c1, 1)&lt;br /&gt;
 assert(success)&lt;br /&gt;
 &lt;br /&gt;
 -- In step 12, c1 should have yielded and returned the value 6.&lt;br /&gt;
 -- So now c1 and c2 should both be suspended.&lt;br /&gt;
 -- STEP 13: Check all that.&lt;br /&gt;
 print(13)&lt;br /&gt;
 assert(coroutine.status(c1) == &amp;quot;suspended&amp;quot;)&lt;br /&gt;
 assert(coroutine.status(c2) == &amp;quot;suspended&amp;quot;)&lt;br /&gt;
 assert(value == 6)&lt;br /&gt;
 &lt;br /&gt;
 -- STEP 14: Run c2 directly, NOT nested inside c1 this time, passing it the value 7.&lt;br /&gt;
 print(14)&lt;br /&gt;
 success, value = coroutine.resume(c2, 7)&lt;br /&gt;
 assert(success)&lt;br /&gt;
 &lt;br /&gt;
 -- c2 should have exited normally, returning the value 8.&lt;br /&gt;
 -- Therefore c1 should still be suspended, but c2 should be dead.&lt;br /&gt;
 -- STEP 17: Check all that.&lt;br /&gt;
 print(17)&lt;br /&gt;
 assert(coroutine.status(c1) == &amp;quot;suspended&amp;quot;)&lt;br /&gt;
 assert(coroutine.status(c2) == &amp;quot;dead&amp;quot;)&lt;br /&gt;
 assert(value == 8)&lt;br /&gt;
&lt;br /&gt;
=== Using Coroutine Wrapper Functions ===&lt;br /&gt;
This second example is virtually identical, but shows using [[coroutine.wrap]] and wrapper functions instead of the basic coroutine functions (checks of [[coroutine.status]] have been removed as the raw coroutine objects are not available):&lt;br /&gt;
&lt;br /&gt;
 -- These variables will hold the coroutine wrapper functions.&lt;br /&gt;
 local cw1 = nil&lt;br /&gt;
 local cw2 = nil&lt;br /&gt;
 &lt;br /&gt;
 -- This function will be the body of the first coroutine.&lt;br /&gt;
 local function f1(x)&lt;br /&gt;
   -- The main code, below, starts c1 first, passing 1.&lt;br /&gt;
   -- Thus c1 should be running, c2 should be suspended (not started yet), and x should receive the value from main, 1.&lt;br /&gt;
   -- STEP 2: Check these assumptions.&lt;br /&gt;
   print(2)&lt;br /&gt;
   assert(x == 1)&lt;br /&gt;
   -- STEP 3: Run c2 until it yields, start it off with the value 2.&lt;br /&gt;
   print(3)&lt;br /&gt;
   value = cw2(2)&lt;br /&gt;
   -- In step 6, c2 yields and passes back the value 3.&lt;br /&gt;
   -- Then c2, having yielded, should be suspended, and c1 should be running again.&lt;br /&gt;
   -- STEP 7: Check all that.&lt;br /&gt;
   print(7)&lt;br /&gt;
   assert(value == 3)&lt;br /&gt;
   -- STEP 8: Run c2 again, passing it the value 4.&lt;br /&gt;
   -- Since c2 has already run before, this time the 4 will come out of the yield() instead of appear as a function parameter.&lt;br /&gt;
   print(8)&lt;br /&gt;
   value = cw2(4)&lt;br /&gt;
   -- In step 10, c2 yields and passes back the value 5.&lt;br /&gt;
   -- Then c2, having yielded, should be suspended, and c1 should be running again.&lt;br /&gt;
   -- STEP 11: Check all that.&lt;br /&gt;
   print(11)&lt;br /&gt;
   assert(value == 5)&lt;br /&gt;
   -- STEP 12: Yield, turning c1 back into a suspended coroutine and continuing execution of the main program, passing back value 6.&lt;br /&gt;
   print(12)&lt;br /&gt;
   value = coroutine.yield(6)&lt;br /&gt;
 end&lt;br /&gt;
 &lt;br /&gt;
 -- This function will be the body of the second coroutine.&lt;br /&gt;
 local function f2(x)&lt;br /&gt;
   -- The first time c2 is run, it is run from f1, which passes 2.&lt;br /&gt;
   -- Thus c1 should be normal (as we are nested inside it), c2 should be running, and x should receive the value from f1, 2.&lt;br /&gt;
   -- STEP 4: Check these assumptions.&lt;br /&gt;
   print(4)&lt;br /&gt;
   assert(x == 2)&lt;br /&gt;
   -- Because c1 is not suspended, we should not be able to resume it.&lt;br /&gt;
   -- STEP 5: Check this is correct (we must use pcall because an error will be raised).&lt;br /&gt;
   print(5)&lt;br /&gt;
   success, value = pcall(cw1)&lt;br /&gt;
   assert(not success)&lt;br /&gt;
   -- STEP 6: Yield, turning c2 back into a suspended coroutine and continuing execution of c1, passing back value 3.&lt;br /&gt;
   print(6)&lt;br /&gt;
   value = coroutine.yield(3)&lt;br /&gt;
   -- In step 8, c1 resumed c2 again and passed the value 4.&lt;br /&gt;
   -- c2 should now be running again, and c1 normal again.&lt;br /&gt;
   -- STEP 9: Check all that.&lt;br /&gt;
   print(9)&lt;br /&gt;
   assert(value == 4)&lt;br /&gt;
   -- STEP 10: Yield, turning c2 back into a suspended coroutine and continuing execution of c1, passing back value 5.&lt;br /&gt;
   print(10)&lt;br /&gt;
   value = coroutine.yield(5)&lt;br /&gt;
   -- In step 14, the main program resumed c2 directly and passed the value 7, bypassing c1.&lt;br /&gt;
   -- So c2 should be running and c1 should be suspended.&lt;br /&gt;
   -- STEP 15: Check all that.&lt;br /&gt;
   print(15)&lt;br /&gt;
   assert(value == 7)&lt;br /&gt;
   -- STEP 16: Now die, returning value 8 to the main program.&lt;br /&gt;
   print(16)&lt;br /&gt;
   return 8&lt;br /&gt;
 end&lt;br /&gt;
 &lt;br /&gt;
 -- Construct the two coroutine wrappers.&lt;br /&gt;
 cw1 = coroutine.wrap(f1)&lt;br /&gt;
 cw2 = coroutine.wrap(f2)&lt;br /&gt;
 &lt;br /&gt;
 -- STEP 1: Run cw1 until it yields, starting it off with the value 1.&lt;br /&gt;
 print(1)&lt;br /&gt;
 value = cw1(1)&lt;br /&gt;
 &lt;br /&gt;
 -- In step 12, c1 should have yielded and returned the value 6.&lt;br /&gt;
 -- So now c1 and c2 should both be suspended.&lt;br /&gt;
 -- STEP 13: Check all that.&lt;br /&gt;
 print(13)&lt;br /&gt;
 assert(value == 6)&lt;br /&gt;
 &lt;br /&gt;
 -- STEP 14: Run c2 directly, NOT nested inside c1 this time, passing it the value 7.&lt;br /&gt;
 print(14)&lt;br /&gt;
 value = cw2(7)&lt;br /&gt;
 &lt;br /&gt;
 -- c2 should have exited normally, returning the value 8.&lt;br /&gt;
 -- Therefore c1 should still be suspended, but c2 should be dead.&lt;br /&gt;
 -- STEP 17: Check all that.&lt;br /&gt;
 print(17)&lt;br /&gt;
 assert(value == 8)&lt;br /&gt;
&lt;br /&gt;
== Interaction with Other APIs ==&lt;br /&gt;
The [[OS (API)#pullEvent|os.pullEventRaw]] (and therefore [[os.pullEvent]]) functions are built on top of coroutines: &amp;lt;code&amp;gt;os.pullEventRaw&amp;lt;/code&amp;gt; actually just calls [[coroutine.yield]], passing the event type filter up to the parent coroutine. The parent coroutine is expected to wait until an event of the required type arrives, then use [[coroutine.resume]] to pass the event to the suspended coroutine (where it will be returned from &amp;lt;code&amp;gt;os.pullEventRaw&amp;lt;/code&amp;gt;). If you use the [[Parallel (API)|parallel API]], this is exactly what [[parallel.waitForAny]] and [[parallel.waitForAll]] do: they pull events from the system event queue (or even from a higher invocation of &amp;lt;code&amp;gt;parallel.waitForAny&amp;lt;/code&amp;gt; or &amp;lt;code&amp;gt;parallel.waitForAll&amp;lt;/code&amp;gt;!) and deliver them to all nested coroutines. Therefore, the easiest way to use coroutines is the parallel API, if it works for your situation. However, in the event that you are not able to use the parallel API (e.g. if you need to add and remove coroutines from the executing set dynamically), you can build your own dispatcher that delivers events in the same way as the parallel API—looking at the source code to the parallel API may be useful here.&lt;br /&gt;
&lt;br /&gt;
If you choose to use coroutines in a different way, then &amp;lt;code&amp;gt;os.pullEventRaw&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;os.pullEvent&amp;lt;/code&amp;gt; will not work. This in turn will break any other API function which is written on top of &amp;lt;code&amp;gt;os.pullEvent&amp;lt;/code&amp;gt;. As a guideline, nearly any API function that can possibly take time to complete will fall into this category; some examples are:&lt;br /&gt;
* [[rednet.receive]] blocks until either a [[Rednet message (event)|rednet_message event]] or (if a timeout was requested) a matching [[Timer (event)|timer event]] occurs.&lt;br /&gt;
* [[Gps (API)|gps.locate]] blocks until either a number of [[Modem message (event)|modem_message events]] or (if a timeout was requested) a matching [[Timer (event)|timer event]] occurs.&lt;br /&gt;
* [[http.get]] blocks until an [[Http success (event)|HTTP success event]] or [[Http failure (event)|HTTP failure event]] occurs.&lt;br /&gt;
* [[IO (API)|io.read]] and the built-in [[read]] functions block waiting for, presumably, either [[Char (event)|char events]] or [[Key (event)|key events]].&lt;br /&gt;
* [[os.sleep]] blocks until a matching [[Timer (event)|timer event]] occurs.&lt;br /&gt;
* [[textutils.slowPrint]] calls [[os.sleep]].&lt;br /&gt;
* [[textutils.pagedPrint]] blocks until a [[Key (event)|key event]] occurs for each page.&lt;br /&gt;
* Most of the functions in the [[Turtle (API)|turtle API]] (with the exception of [[turtle.getItemCount]], [[turtle.getItemSpace]], and [[turtle.getFuelLevel]]) block waiting for a [[Turtle response (event)|turtle response event]].&lt;br /&gt;
&lt;br /&gt;
Most of these can be worked around by using non-blocking equivalents that return immediately and then queue an event on completion (such as using [[http.request]]) or that deliver an event unconditionally (such as [[Char_(event)|char]] for keyboard input), then handling events in a way that is suitable for the application. However, if possible, it will often be easier to implement event dispatching instead, remembering that [[os.queueEvent]] can be used for inter-coroutine communication within an application. Another alternative, if you must use a custom protocol between your coroutines and dispatcher, might be to replace &amp;lt;code&amp;gt;os.pullEventRaw&amp;lt;/code&amp;gt; with a new function that uses a mechanism appropriate to the application.&lt;br /&gt;
&lt;br /&gt;
[[Category:APIs]]&lt;/div&gt;</summary>
		<author><name>YoYoYonnY</name></author>	</entry>

	<entry>
		<id>https://www.computercraft.info/wiki/index.php?title=Coroutine_(API)&amp;diff=5772</id>
		<title>Coroutine (API)</title>
		<link rel="alternate" type="text/html" href="https://www.computercraft.info/wiki/index.php?title=Coroutine_(API)&amp;diff=5772"/>
				<updated>2013-07-03T04:32:08Z</updated>
		
		<summary type="html">&lt;p&gt;YoYoYonnY: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{NeedsWork}}&lt;br /&gt;
:{| border=&amp;quot;1&amp;quot; class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
| '''Bug'''&lt;br /&gt;
'''From ComputerCraft 1.3''' this API suffers from the problem of potentially spawning Java threads that live forever therefore, use of coroutines should be minimized. This is '''fixed in ComputerCraft 1.32+''', though.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
''This is for the Coroutine API. For the Coroutine Object, visit [[Coroutine (type)]].''&lt;br /&gt;
&lt;br /&gt;
Coroutine is a default Lua 5.1 API defined [http://www.lua.org/manual/5.1/manual.html#5.2 here]. Please list any non-working functions on this page.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;table style=&amp;quot;width: 100%; border: solid 1px black; margin: 2px; border-spacing: 0px;&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&amp;lt;td colspan=&amp;quot;3&amp;quot; style=&amp;quot;font-weight: bold; font-size: large; padding-bottom: .3em; border-bottom: solid #C9C9C9 1px; background: #D3FFC2; line-height:28px;&amp;quot;&amp;gt;&lt;br /&gt;
[[File:Grid_disk.png|24px]]&amp;amp;nbsp;&amp;amp;nbsp;&lt;br /&gt;
Coroutine (API)&lt;br /&gt;
&amp;lt;/td&amp;gt;&amp;lt;/tr&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tr&amp;gt;&amp;lt;td style=&amp;quot;width: 100px; background: #E0E0E0; padding: .4em; font-weight:bold;&amp;quot;&amp;gt;Return&amp;lt;/td&amp;gt;&amp;lt;td style=&amp;quot;width: 350px; background: #E0E0E0; padding: .4em; font-weight:bold;&amp;quot;&amp;gt;Method Name&amp;lt;/td&amp;gt;&amp;lt;td style=&amp;quot;background: #E0E0E0; padding: .4em; font-weight:bold;&amp;quot;&amp;gt;Description&amp;lt;/td&amp;gt;&amp;lt;/tr&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tr style=&amp;quot;background-color: #FFFFFF;&amp;quot;&amp;gt;&amp;lt;td style=&amp;quot;border-top: solid #C9C9C9 1px; padding: .4em;&amp;quot;&amp;gt;{{coroutine_Type|coroutine}} coro&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td style=&amp;quot;border-top: solid #C9C9C9 1px; padding: .4em;&amp;quot;&amp;gt;[[coroutine.create]]({{Type|function}} f)&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td style=&amp;quot;border-top: solid #C9C9C9 1px; padding: .4em;&amp;quot;&amp;gt;Creates a new coroutine.&amp;lt;/td&amp;gt;&amp;lt;/tr&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tr style=&amp;quot;background-color: #E8E8E8;&amp;quot;&amp;gt;&amp;lt;td style=&amp;quot;border-top: solid #C9C9C9 1px; padding: .4em;&amp;quot;&amp;gt;{{boolean_Type|boolean}} success, …&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td style=&amp;quot;border-top: solid #C9C9C9 1px; padding: .4em;&amp;quot;&amp;gt;[[coroutine.resume]]({{Type|coroutine}} coro, [var1], [var2], ...)&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td style=&amp;quot;border-top: solid #C9C9C9 1px; padding: .4em;&amp;quot;&amp;gt;Starts or resumes an existing coroutine.&amp;lt;/td&amp;gt;&amp;lt;/tr&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tr style=&amp;quot;background-color: #FFFFFF;&amp;quot;&amp;gt;&amp;lt;td style=&amp;quot;border-top: solid #C9C9C9 1px; padding: .4em;&amp;quot;&amp;gt;{{coroutine_Type|coroutine}} coro&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td style=&amp;quot;border-top: solid #C9C9C9 1px; padding: .4em;&amp;quot;&amp;gt;[[coroutine.running]]()&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td style=&amp;quot;border-top: solid #C9C9C9 1px; padding: .4em;&amp;quot;&amp;gt;Returns the currently executing coroutine.&amp;lt;/td&amp;gt;&amp;lt;/tr&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tr style=&amp;quot;background-color: #E8E8E8;&amp;quot;&amp;gt;&amp;lt;td style=&amp;quot;border-top: solid #C9C9C9 1px; padding: .4em;&amp;quot;&amp;gt;{{string_Type|string}} status&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td style=&amp;quot;border-top: solid #C9C9C9 1px; padding: .4em;&amp;quot;&amp;gt;[[coroutine.status]]({{type|coroutine}} coroutine)&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td style=&amp;quot;border-top: solid #C9C9C9 1px; padding: .4em;&amp;quot;&amp;gt;Returns the status of the given coroutine.&amp;lt;/td&amp;gt;&amp;lt;/tr&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tr style=&amp;quot;background-color: #FFFFFF;&amp;quot;&amp;gt;&amp;lt;td style=&amp;quot;border-top: solid #C9C9C9 1px; padding: .4em;&amp;quot;&amp;gt;{{function_Type|function}} coroutine wrapper&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td style=&amp;quot;border-top: solid #C9C9C9 1px; padding: .4em;&amp;quot;&amp;gt;[[coroutine.wrap]]({{type|function}} function)&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td style=&amp;quot;border-top: solid #C9C9C9 1px; padding: .4em;&amp;quot;&amp;gt;Creates a new coroutine and wraps it in a function.&amp;lt;/td&amp;gt;&amp;lt;/tr&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tr style=&amp;quot;background-color: #E8E8E8;&amp;quot;&amp;gt;&amp;lt;td style=&amp;quot;border-top: solid #C9C9C9 1px; padding: .4em;&amp;quot;&amp;gt;[var3], [var4], …&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td style=&amp;quot;border-top: solid #C9C9C9 1px; padding: .4em;&amp;quot;&amp;gt;[[coroutine.yield]]([var1], [var2], …)&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td style=&amp;quot;border-top: solid #C9C9C9 1px; padding: .4em;&amp;quot;&amp;gt;Pauses the currently executing coroutine and passes control to its caller.&amp;lt;/td&amp;gt;&amp;lt;/tr&amp;gt;&lt;br /&gt;
&amp;lt;/table&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Coroutine States and Ancestry ==&lt;br /&gt;
Every coroutine is in one of four states:&lt;br /&gt;
* A ''suspended'' coroutine is one that has not yet been started or that has yielded. A suspended coroutine can become running if it is passed to [[coroutine.resume]].&lt;br /&gt;
* A ''running'' coroutine is one that is currently executing code. Only one coroutine can be running at a time on a particular computer. A running coroutine can become suspended if it [[coroutine.yield]], normal if it calls [[coroutine.resume]] on another coroutine, or dead by if it returns from its body function.&lt;br /&gt;
* A ''normal'' coroutine is one that, while running, resumed another coroutine (the ''child coroutine''). A normal coroutine can become running if its child calls [[coroutine.yield]] or returns from its function body.&lt;br /&gt;
* A ''dead'' coroutine is one that, while running, returned from its function body. A dead coroutine can never change state.&lt;br /&gt;
&lt;br /&gt;
While suspended and dead coroutines simply sit loose with no connections to other coroutines, normal and running coroutines have an ancestry relationship between them. Exactly one coroutine is running at any given time, and the running coroutine has no children. Every running or normal coroutine except the top-level BIOS coroutine has a parent, and this relationship forms a chain with one end (the furthest ancestor) being the top-level BIOS coroutine and the other end (the furthest descendant) being the running coroutine. Remember that only the running coroutine can actually execute code, so any functions invoked must be invoked by that coroutine. Then, calling [[coroutine.resume]] makes the chain longer by taking a previously suspended coroutine, hanging it underneath the current coroutine as a new child, and making the current coroutine normal and the new child running. Meanwhile, calling [[coroutine.yield]] makes the chain shorter by turning the currently executing coroutine into a suspended coroutine, detaching it from the chain, and letting its former parent become running.&lt;br /&gt;
&lt;br /&gt;
It is important not to confuse this coroutine chain with the function call stack. Each individual coroutine contains a complete function call stack of its own, rooted at the coroutine’s body function, whether the coroutine is running, normal, or suspended; the chain described in the previous paragraph refers to how entire coroutines are connected together.&lt;br /&gt;
&lt;br /&gt;
== Examples ==&lt;br /&gt;
As the coroutine API is very tightly coupled and many of its function must be used to get any interesting results, examples are shown here instead of on the individual function pages.&lt;br /&gt;
&lt;br /&gt;
=== Using the Basic Coroutine Functions ===&lt;br /&gt;
This example demonstrates using the basic coroutine functions to pass control and data between coroutines. This example prints the numbers 1 through 17 in order, showing how control flow moves through the main program coroutine and the two created coroutines, while using assertions to show how data flows through the program:&lt;br /&gt;
&lt;br /&gt;
 -- These variables will hold the coroutine objects.&lt;br /&gt;
 local c1 = nil&lt;br /&gt;
 local c2 = nil&lt;br /&gt;
 &lt;br /&gt;
 -- This function will be the body of the first coroutine.&lt;br /&gt;
 local function f1(x)&lt;br /&gt;
   -- The main code, below, starts c1 first, passing 1.&lt;br /&gt;
   -- Thus c1 should be running, c2 should be suspended (not started yet), and x should receive the value from main, 1.&lt;br /&gt;
   -- STEP 2: Check these assumptions.&lt;br /&gt;
   print(2)&lt;br /&gt;
   assert(coroutine.status(c1) == &amp;quot;running&amp;quot;)&lt;br /&gt;
   assert(coroutine.status(c2) == &amp;quot;suspended&amp;quot;)&lt;br /&gt;
   assert(x == 1)&lt;br /&gt;
   -- STEP 3: Run c2 until it yields, start it off with the value 2.&lt;br /&gt;
   print(3)&lt;br /&gt;
   success, value = coroutine.resume(c2, 2)&lt;br /&gt;
   assert(success)&lt;br /&gt;
   -- In step 6, c2 yields and passes back the value 3.&lt;br /&gt;
   -- Then c2, having yielded, should be suspended, and c1 should be running again.&lt;br /&gt;
   -- STEP 7: Check all that.&lt;br /&gt;
   print(7)&lt;br /&gt;
   assert(coroutine.status(c1) == &amp;quot;running&amp;quot;)&lt;br /&gt;
   assert(coroutine.status(c2) == &amp;quot;suspended&amp;quot;)&lt;br /&gt;
   assert(value == 3)&lt;br /&gt;
   -- STEP 8: Run c2 again, passing it the value 4.&lt;br /&gt;
   -- Since c2 has already run before, this time the 4 will come out of the yield() instead of appear as a function parameter.&lt;br /&gt;
   print(8)&lt;br /&gt;
   success, value = coroutine.resume(c2, 4)&lt;br /&gt;
   -- In step 10, c2 yields and passes back the value 5.&lt;br /&gt;
   -- Then c2, having yielded, should be suspended, and c1 should be running again.&lt;br /&gt;
   -- STEP 11: Check all that.&lt;br /&gt;
   print(11)&lt;br /&gt;
   assert(coroutine.status(c1) == &amp;quot;running&amp;quot;)&lt;br /&gt;
   assert(coroutine.status(c2) == &amp;quot;suspended&amp;quot;)&lt;br /&gt;
   assert(value == 5)&lt;br /&gt;
   -- STEP 12: Yield, turning c1 back into a suspended coroutine and continuing execution of the main program, passing back value 6.&lt;br /&gt;
   print(12)&lt;br /&gt;
   value = coroutine.yield(6)&lt;br /&gt;
 end&lt;br /&gt;
 &lt;br /&gt;
 -- This function will be the body of the second coroutine.&lt;br /&gt;
 local function f2(x)&lt;br /&gt;
   -- The first time c2 is run, it is run from f1, which passes 2.&lt;br /&gt;
   -- Thus c1 should be normal (as we are nested inside it), c2 should be running, and x should receive the value from f1, 2.&lt;br /&gt;
   -- STEP 4: Check these assumptions.&lt;br /&gt;
   print(4)&lt;br /&gt;
   assert(coroutine.status(c1) == &amp;quot;normal&amp;quot;)&lt;br /&gt;
   assert(coroutine.status(c2) == &amp;quot;running&amp;quot;)&lt;br /&gt;
   assert(x == 2)&lt;br /&gt;
   -- Because c1 is not suspended, we should not be able to resume it.&lt;br /&gt;
   -- STEP 5: Check this is correct.&lt;br /&gt;
   print(5)&lt;br /&gt;
   success, value = coroutine.resume(c1)&lt;br /&gt;
   assert(not success)&lt;br /&gt;
   assert(value == &amp;quot;cannot resume normal coroutine&amp;quot;)&lt;br /&gt;
   -- STEP 6: Yield, turning c2 back into a suspended coroutine and continuing execution of c1, passing back value 3.&lt;br /&gt;
   print(6)&lt;br /&gt;
   value = coroutine.yield(3)&lt;br /&gt;
   -- In step 8, c1 resumed c2 again and passed the value 4.&lt;br /&gt;
   -- c2 should now be running again, and c1 normal again.&lt;br /&gt;
   -- STEP 9: Check all that.&lt;br /&gt;
   print(9)&lt;br /&gt;
   assert(coroutine.status(c1) == &amp;quot;normal&amp;quot;)&lt;br /&gt;
   assert(coroutine.status(c2) == &amp;quot;running&amp;quot;)&lt;br /&gt;
   assert(value == 4)&lt;br /&gt;
   -- STEP 10: Yield, turning c2 back into a suspended coroutine and continuing execution of c1, passing back value 5.&lt;br /&gt;
   print(10)&lt;br /&gt;
   value = coroutine.yield(5)&lt;br /&gt;
   -- In step 14, the main program resumed c2 directly and passed the value 7, bypassing c1.&lt;br /&gt;
   -- So c2 should be running and c1 should be suspended.&lt;br /&gt;
   -- STEP 15: Check all that.&lt;br /&gt;
   print(15)&lt;br /&gt;
   assert(coroutine.status(c1) == &amp;quot;suspended&amp;quot;)&lt;br /&gt;
   assert(coroutine.status(c2) == &amp;quot;running&amp;quot;)&lt;br /&gt;
   assert(value == 7)&lt;br /&gt;
   -- STEP 16: Now die, returning value 8 to the main program.&lt;br /&gt;
   print(16)&lt;br /&gt;
   return 8&lt;br /&gt;
 end&lt;br /&gt;
 &lt;br /&gt;
 -- Construct the two coroutines.&lt;br /&gt;
 c1 = coroutine.create(f1)&lt;br /&gt;
 c2 = coroutine.create(f2)&lt;br /&gt;
 &lt;br /&gt;
 -- Newly constructed coroutines are always suspended.&lt;br /&gt;
 assert(coroutine.status(c1) == &amp;quot;suspended&amp;quot;)&lt;br /&gt;
 assert(coroutine.status(c2) == &amp;quot;suspended&amp;quot;)&lt;br /&gt;
 &lt;br /&gt;
 -- STEP 1: Run c1 until it yields, starting it off with the value 1.&lt;br /&gt;
 print(1)&lt;br /&gt;
 success, value = coroutine.resume(c1, 1)&lt;br /&gt;
 assert(success)&lt;br /&gt;
 &lt;br /&gt;
 -- In step 12, c1 should have yielded and returned the value 6.&lt;br /&gt;
 -- So now c1 and c2 should both be suspended.&lt;br /&gt;
 -- STEP 13: Check all that.&lt;br /&gt;
 print(13)&lt;br /&gt;
 assert(coroutine.status(c1) == &amp;quot;suspended&amp;quot;)&lt;br /&gt;
 assert(coroutine.status(c2) == &amp;quot;suspended&amp;quot;)&lt;br /&gt;
 assert(value == 6)&lt;br /&gt;
 &lt;br /&gt;
 -- STEP 14: Run c2 directly, NOT nested inside c1 this time, passing it the value 7.&lt;br /&gt;
 print(14)&lt;br /&gt;
 success, value = coroutine.resume(c2, 7)&lt;br /&gt;
 assert(success)&lt;br /&gt;
 &lt;br /&gt;
 -- c2 should have exited normally, returning the value 8.&lt;br /&gt;
 -- Therefore c1 should still be suspended, but c2 should be dead.&lt;br /&gt;
 -- STEP 17: Check all that.&lt;br /&gt;
 print(17)&lt;br /&gt;
 assert(coroutine.status(c1) == &amp;quot;suspended&amp;quot;)&lt;br /&gt;
 assert(coroutine.status(c2) == &amp;quot;dead&amp;quot;)&lt;br /&gt;
 assert(value == 8)&lt;br /&gt;
&lt;br /&gt;
=== Using Coroutine Wrapper Functions ===&lt;br /&gt;
This second example is virtually identical, but shows using [[coroutine.wrap]] and wrapper functions instead of the basic coroutine functions (checks of [[coroutine.status]] have been removed as the raw coroutine objects are not available):&lt;br /&gt;
&lt;br /&gt;
 -- These variables will hold the coroutine wrapper functions.&lt;br /&gt;
 local cw1 = nil&lt;br /&gt;
 local cw2 = nil&lt;br /&gt;
 &lt;br /&gt;
 -- This function will be the body of the first coroutine.&lt;br /&gt;
 local function f1(x)&lt;br /&gt;
   -- The main code, below, starts c1 first, passing 1.&lt;br /&gt;
   -- Thus c1 should be running, c2 should be suspended (not started yet), and x should receive the value from main, 1.&lt;br /&gt;
   -- STEP 2: Check these assumptions.&lt;br /&gt;
   print(2)&lt;br /&gt;
   assert(x == 1)&lt;br /&gt;
   -- STEP 3: Run c2 until it yields, start it off with the value 2.&lt;br /&gt;
   print(3)&lt;br /&gt;
   value = cw2(2)&lt;br /&gt;
   -- In step 6, c2 yields and passes back the value 3.&lt;br /&gt;
   -- Then c2, having yielded, should be suspended, and c1 should be running again.&lt;br /&gt;
   -- STEP 7: Check all that.&lt;br /&gt;
   print(7)&lt;br /&gt;
   assert(value == 3)&lt;br /&gt;
   -- STEP 8: Run c2 again, passing it the value 4.&lt;br /&gt;
   -- Since c2 has already run before, this time the 4 will come out of the yield() instead of appear as a function parameter.&lt;br /&gt;
   print(8)&lt;br /&gt;
   value = cw2(4)&lt;br /&gt;
   -- In step 10, c2 yields and passes back the value 5.&lt;br /&gt;
   -- Then c2, having yielded, should be suspended, and c1 should be running again.&lt;br /&gt;
   -- STEP 11: Check all that.&lt;br /&gt;
   print(11)&lt;br /&gt;
   assert(value == 5)&lt;br /&gt;
   -- STEP 12: Yield, turning c1 back into a suspended coroutine and continuing execution of the main program, passing back value 6.&lt;br /&gt;
   print(12)&lt;br /&gt;
   value = coroutine.yield(6)&lt;br /&gt;
 end&lt;br /&gt;
 &lt;br /&gt;
 -- This function will be the body of the second coroutine.&lt;br /&gt;
 local function f2(x)&lt;br /&gt;
   -- The first time c2 is run, it is run from f1, which passes 2.&lt;br /&gt;
   -- Thus c1 should be normal (as we are nested inside it), c2 should be running, and x should receive the value from f1, 2.&lt;br /&gt;
   -- STEP 4: Check these assumptions.&lt;br /&gt;
   print(4)&lt;br /&gt;
   assert(x == 2)&lt;br /&gt;
   -- Because c1 is not suspended, we should not be able to resume it.&lt;br /&gt;
   -- STEP 5: Check this is correct (we must use pcall because an error will be raised).&lt;br /&gt;
   print(5)&lt;br /&gt;
   success, value = pcall(cw1)&lt;br /&gt;
   assert(not success)&lt;br /&gt;
   -- STEP 6: Yield, turning c2 back into a suspended coroutine and continuing execution of c1, passing back value 3.&lt;br /&gt;
   print(6)&lt;br /&gt;
   value = coroutine.yield(3)&lt;br /&gt;
   -- In step 8, c1 resumed c2 again and passed the value 4.&lt;br /&gt;
   -- c2 should now be running again, and c1 normal again.&lt;br /&gt;
   -- STEP 9: Check all that.&lt;br /&gt;
   print(9)&lt;br /&gt;
   assert(value == 4)&lt;br /&gt;
   -- STEP 10: Yield, turning c2 back into a suspended coroutine and continuing execution of c1, passing back value 5.&lt;br /&gt;
   print(10)&lt;br /&gt;
   value = coroutine.yield(5)&lt;br /&gt;
   -- In step 14, the main program resumed c2 directly and passed the value 7, bypassing c1.&lt;br /&gt;
   -- So c2 should be running and c1 should be suspended.&lt;br /&gt;
   -- STEP 15: Check all that.&lt;br /&gt;
   print(15)&lt;br /&gt;
   assert(value == 7)&lt;br /&gt;
   -- STEP 16: Now die, returning value 8 to the main program.&lt;br /&gt;
   print(16)&lt;br /&gt;
   return 8&lt;br /&gt;
 end&lt;br /&gt;
 &lt;br /&gt;
 -- Construct the two coroutine wrappers.&lt;br /&gt;
 cw1 = coroutine.wrap(f1)&lt;br /&gt;
 cw2 = coroutine.wrap(f2)&lt;br /&gt;
 &lt;br /&gt;
 -- STEP 1: Run cw1 until it yields, starting it off with the value 1.&lt;br /&gt;
 print(1)&lt;br /&gt;
 value = cw1(1)&lt;br /&gt;
 &lt;br /&gt;
 -- In step 12, c1 should have yielded and returned the value 6.&lt;br /&gt;
 -- So now c1 and c2 should both be suspended.&lt;br /&gt;
 -- STEP 13: Check all that.&lt;br /&gt;
 print(13)&lt;br /&gt;
 assert(value == 6)&lt;br /&gt;
 &lt;br /&gt;
 -- STEP 14: Run c2 directly, NOT nested inside c1 this time, passing it the value 7.&lt;br /&gt;
 print(14)&lt;br /&gt;
 value = cw2(7)&lt;br /&gt;
 &lt;br /&gt;
 -- c2 should have exited normally, returning the value 8.&lt;br /&gt;
 -- Therefore c1 should still be suspended, but c2 should be dead.&lt;br /&gt;
 -- STEP 17: Check all that.&lt;br /&gt;
 print(17)&lt;br /&gt;
 assert(value == 8)&lt;br /&gt;
&lt;br /&gt;
== Interaction with Other APIs ==&lt;br /&gt;
The [[OS (API)#pullEvent|os.pullEventRaw]] (and therefore [[os.pullEvent]]) functions are built on top of coroutines: &amp;lt;code&amp;gt;os.pullEventRaw&amp;lt;/code&amp;gt; actually just calls [[coroutine.yield]], passing the event type filter up to the parent coroutine. The parent coroutine is expected to wait until an event of the required type arrives, then use [[coroutine.resume]] to pass the event to the suspended coroutine (where it will be returned from &amp;lt;code&amp;gt;os.pullEventRaw&amp;lt;/code&amp;gt;). If you use the [[Parallel (API)|parallel API]], this is exactly what [[parallel.waitForAny]] and [[parallel.waitForAll]] do: they pull events from the system event queue (or even from a higher invocation of &amp;lt;code&amp;gt;parallel.waitForAny&amp;lt;/code&amp;gt; or &amp;lt;code&amp;gt;parallel.waitForAll&amp;lt;/code&amp;gt;!) and deliver them to all nested coroutines. Therefore, the easiest way to use coroutines is the parallel API, if it works for your situation. However, in the event that you are not able to use the parallel API (e.g. if you need to add and remove coroutines from the executing set dynamically), you can build your own dispatcher that delivers events in the same way as the parallel API—looking at the source code to the parallel API may be useful here.&lt;br /&gt;
&lt;br /&gt;
If you choose to use coroutines in a different way, then &amp;lt;code&amp;gt;os.pullEventRaw&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;os.pullEvent&amp;lt;/code&amp;gt; will not work. This in turn will break any other API function which is written on top of &amp;lt;code&amp;gt;os.pullEvent&amp;lt;/code&amp;gt;. As a guideline, nearly any API function that can possibly take time to complete will fall into this category; some examples are:&lt;br /&gt;
* [[rednet.receive]] blocks until either a [[Rednet message (event)|rednet_message event]] or (if a timeout was requested) a matching [[Timer (event)|timer event]] occurs.&lt;br /&gt;
* [[Gps (API)|gps.locate]] blocks until either a number of [[Modem message (event)|modem_message events]] or (if a timeout was requested) a matching [[Timer (event)|timer event]] occurs.&lt;br /&gt;
* [[http.get]] blocks until an [[Http success (event)|HTTP success event]] or [[Http failure (event)|HTTP failure event]] occurs.&lt;br /&gt;
* [[IO (API)|io.read]] and the built-in [[read]] functions block waiting for, presumably, either [[Char (event)|char events]] or [[Key (event)|key events]].&lt;br /&gt;
* [[os.sleep]] blocks until a matching [[Timer (event)|timer event]] occurs.&lt;br /&gt;
* [[textutils.slowPrint]] calls [[os.sleep]].&lt;br /&gt;
* [[textutils.pagedPrint]] blocks until a [[Key (event)|key event]] occurs for each page.&lt;br /&gt;
* Most of the functions in the [[Turtle (API)|turtle API]] (with the exception of [[turtle.getItemCount]], [[turtle.getItemSpace]], and [[turtle.getFuelLevel]]) block waiting for a [[Turtle response (event)|turtle response event]].&lt;br /&gt;
&lt;br /&gt;
Most of these can be worked around by using non-blocking equivalents that return immediately and then queue an event on completion (such as using [[http.request]]) or that deliver an event unconditionally (such as [[Char_(event)|char]] for keyboard input), then handling events in a way that is suitable for the application. However, if possible, it will often be easier to implement event dispatching instead, remembering that [[os.queueEvent]] can be used for inter-coroutine communication within an application. Another alternative, if you must use a custom protocol between your coroutines and dispatcher, might be to replace &amp;lt;code&amp;gt;os.pullEventRaw&amp;lt;/code&amp;gt; with a new function that uses a mechanism appropriate to the application.&lt;br /&gt;
&lt;br /&gt;
[[Category:APIs]]&lt;/div&gt;</summary>
		<author><name>YoYoYonnY</name></author>	</entry>

	<entry>
		<id>https://www.computercraft.info/wiki/index.php?title=Coroutine_(API)&amp;diff=5771</id>
		<title>Coroutine (API)</title>
		<link rel="alternate" type="text/html" href="https://www.computercraft.info/wiki/index.php?title=Coroutine_(API)&amp;diff=5771"/>
				<updated>2013-07-03T04:31:22Z</updated>
		
		<summary type="html">&lt;p&gt;YoYoYonnY: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{NeedsWork}}&lt;br /&gt;
:{| border=&amp;quot;1&amp;quot; class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
| '''Bug'''&lt;br /&gt;
'''From ComputerCraft 1.3''' this API suffers from the problem of potentially spawning Java threads that live forever therefore, use of coroutines should be minimized. This is '''fixed in ComputerCraft 1.32+''', though.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
''This is for the Coroutine API. For the Coroutine Object, visit [[Coroutine (type)]].''&lt;br /&gt;
&lt;br /&gt;
Coroutine is a default Lua 5.1 API defined [http://www.lua.org/manual/5.1/manual.html#5.2 here]. Please list any non-working functions on this page.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;table style=&amp;quot;width: 100%; border: solid 1px black; margin: 2px; border-spacing: 0px;&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&amp;lt;td colspan=&amp;quot;3&amp;quot; style=&amp;quot;font-weight: bold; font-size: large; padding-bottom: .3em; border-bottom: solid #C9C9C9 1px; background: #D3FFC2; line-height:28px;&amp;quot;&amp;gt;&lt;br /&gt;
[[File:Grid_disk.png|24px]]&amp;amp;nbsp;&amp;amp;nbsp;&lt;br /&gt;
Coroutine (API)&lt;br /&gt;
&amp;lt;/td&amp;gt;&amp;lt;/tr&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tr&amp;gt;&amp;lt;td style=&amp;quot;width: 100px; background: #E0E0E0; padding: .4em; font-weight:bold;&amp;quot;&amp;gt;Return&amp;lt;/td&amp;gt;&amp;lt;td style=&amp;quot;width: 350px; background: #E0E0E0; padding: .4em; font-weight:bold;&amp;quot;&amp;gt;Method Name&amp;lt;/td&amp;gt;&amp;lt;td style=&amp;quot;background: #E0E0E0; padding: .4em; font-weight:bold;&amp;quot;&amp;gt;Description&amp;lt;/td&amp;gt;&amp;lt;/tr&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tr style=&amp;quot;background-color: #FFFFFF;&amp;quot;&amp;gt;&amp;lt;td style=&amp;quot;border-top: solid #C9C9C9 1px; padding: .4em;&amp;quot;&amp;gt;{{Type|coroutine_Type}} coro&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td style=&amp;quot;border-top: solid #C9C9C9 1px; padding: .4em;&amp;quot;&amp;gt;[[coroutine.create]]({{Type|function}} f)&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td style=&amp;quot;border-top: solid #C9C9C9 1px; padding: .4em;&amp;quot;&amp;gt;Creates a new coroutine.&amp;lt;/td&amp;gt;&amp;lt;/tr&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tr style=&amp;quot;background-color: #E8E8E8;&amp;quot;&amp;gt;&amp;lt;td style=&amp;quot;border-top: solid #C9C9C9 1px; padding: .4em;&amp;quot;&amp;gt;{{Type|boolean_Type}} success, …&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td style=&amp;quot;border-top: solid #C9C9C9 1px; padding: .4em;&amp;quot;&amp;gt;[[coroutine.resume]]({{Type|coroutine}} coro, [var1], [var2], ...)&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td style=&amp;quot;border-top: solid #C9C9C9 1px; padding: .4em;&amp;quot;&amp;gt;Starts or resumes an existing coroutine.&amp;lt;/td&amp;gt;&amp;lt;/tr&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tr style=&amp;quot;background-color: #FFFFFF;&amp;quot;&amp;gt;&amp;lt;td style=&amp;quot;border-top: solid #C9C9C9 1px; padding: .4em;&amp;quot;&amp;gt;{{Type|coroutine_Type}} coro&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td style=&amp;quot;border-top: solid #C9C9C9 1px; padding: .4em;&amp;quot;&amp;gt;[[coroutine.running]]()&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td style=&amp;quot;border-top: solid #C9C9C9 1px; padding: .4em;&amp;quot;&amp;gt;Returns the currently executing coroutine.&amp;lt;/td&amp;gt;&amp;lt;/tr&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tr style=&amp;quot;background-color: #E8E8E8;&amp;quot;&amp;gt;&amp;lt;td style=&amp;quot;border-top: solid #C9C9C9 1px; padding: .4em;&amp;quot;&amp;gt;{{Type|string_Type}} status&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td style=&amp;quot;border-top: solid #C9C9C9 1px; padding: .4em;&amp;quot;&amp;gt;[[coroutine.status]]({{type|coroutine}} coroutine)&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td style=&amp;quot;border-top: solid #C9C9C9 1px; padding: .4em;&amp;quot;&amp;gt;Returns the status of the given coroutine.&amp;lt;/td&amp;gt;&amp;lt;/tr&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tr style=&amp;quot;background-color: #FFFFFF;&amp;quot;&amp;gt;&amp;lt;td style=&amp;quot;border-top: solid #C9C9C9 1px; padding: .4em;&amp;quot;&amp;gt;{{Type|function_Type}} coroutine wrapper&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td style=&amp;quot;border-top: solid #C9C9C9 1px; padding: .4em;&amp;quot;&amp;gt;[[coroutine.wrap]]({{type|function}} function)&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td style=&amp;quot;border-top: solid #C9C9C9 1px; padding: .4em;&amp;quot;&amp;gt;Creates a new coroutine and wraps it in a function.&amp;lt;/td&amp;gt;&amp;lt;/tr&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tr style=&amp;quot;background-color: #E8E8E8;&amp;quot;&amp;gt;&amp;lt;td style=&amp;quot;border-top: solid #C9C9C9 1px; padding: .4em;&amp;quot;&amp;gt;[var3], [var4], …&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td style=&amp;quot;border-top: solid #C9C9C9 1px; padding: .4em;&amp;quot;&amp;gt;[[coroutine.yield]]([var1], [var2], …)&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td style=&amp;quot;border-top: solid #C9C9C9 1px; padding: .4em;&amp;quot;&amp;gt;Pauses the currently executing coroutine and passes control to its caller.&amp;lt;/td&amp;gt;&amp;lt;/tr&amp;gt;&lt;br /&gt;
&amp;lt;/table&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Coroutine States and Ancestry ==&lt;br /&gt;
Every coroutine is in one of four states:&lt;br /&gt;
* A ''suspended'' coroutine is one that has not yet been started or that has yielded. A suspended coroutine can become running if it is passed to [[coroutine.resume]].&lt;br /&gt;
* A ''running'' coroutine is one that is currently executing code. Only one coroutine can be running at a time on a particular computer. A running coroutine can become suspended if it [[coroutine.yield]], normal if it calls [[coroutine.resume]] on another coroutine, or dead by if it returns from its body function.&lt;br /&gt;
* A ''normal'' coroutine is one that, while running, resumed another coroutine (the ''child coroutine''). A normal coroutine can become running if its child calls [[coroutine.yield]] or returns from its function body.&lt;br /&gt;
* A ''dead'' coroutine is one that, while running, returned from its function body. A dead coroutine can never change state.&lt;br /&gt;
&lt;br /&gt;
While suspended and dead coroutines simply sit loose with no connections to other coroutines, normal and running coroutines have an ancestry relationship between them. Exactly one coroutine is running at any given time, and the running coroutine has no children. Every running or normal coroutine except the top-level BIOS coroutine has a parent, and this relationship forms a chain with one end (the furthest ancestor) being the top-level BIOS coroutine and the other end (the furthest descendant) being the running coroutine. Remember that only the running coroutine can actually execute code, so any functions invoked must be invoked by that coroutine. Then, calling [[coroutine.resume]] makes the chain longer by taking a previously suspended coroutine, hanging it underneath the current coroutine as a new child, and making the current coroutine normal and the new child running. Meanwhile, calling [[coroutine.yield]] makes the chain shorter by turning the currently executing coroutine into a suspended coroutine, detaching it from the chain, and letting its former parent become running.&lt;br /&gt;
&lt;br /&gt;
It is important not to confuse this coroutine chain with the function call stack. Each individual coroutine contains a complete function call stack of its own, rooted at the coroutine’s body function, whether the coroutine is running, normal, or suspended; the chain described in the previous paragraph refers to how entire coroutines are connected together.&lt;br /&gt;
&lt;br /&gt;
== Examples ==&lt;br /&gt;
As the coroutine API is very tightly coupled and many of its function must be used to get any interesting results, examples are shown here instead of on the individual function pages.&lt;br /&gt;
&lt;br /&gt;
=== Using the Basic Coroutine Functions ===&lt;br /&gt;
This example demonstrates using the basic coroutine functions to pass control and data between coroutines. This example prints the numbers 1 through 17 in order, showing how control flow moves through the main program coroutine and the two created coroutines, while using assertions to show how data flows through the program:&lt;br /&gt;
&lt;br /&gt;
 -- These variables will hold the coroutine objects.&lt;br /&gt;
 local c1 = nil&lt;br /&gt;
 local c2 = nil&lt;br /&gt;
 &lt;br /&gt;
 -- This function will be the body of the first coroutine.&lt;br /&gt;
 local function f1(x)&lt;br /&gt;
   -- The main code, below, starts c1 first, passing 1.&lt;br /&gt;
   -- Thus c1 should be running, c2 should be suspended (not started yet), and x should receive the value from main, 1.&lt;br /&gt;
   -- STEP 2: Check these assumptions.&lt;br /&gt;
   print(2)&lt;br /&gt;
   assert(coroutine.status(c1) == &amp;quot;running&amp;quot;)&lt;br /&gt;
   assert(coroutine.status(c2) == &amp;quot;suspended&amp;quot;)&lt;br /&gt;
   assert(x == 1)&lt;br /&gt;
   -- STEP 3: Run c2 until it yields, start it off with the value 2.&lt;br /&gt;
   print(3)&lt;br /&gt;
   success, value = coroutine.resume(c2, 2)&lt;br /&gt;
   assert(success)&lt;br /&gt;
   -- In step 6, c2 yields and passes back the value 3.&lt;br /&gt;
   -- Then c2, having yielded, should be suspended, and c1 should be running again.&lt;br /&gt;
   -- STEP 7: Check all that.&lt;br /&gt;
   print(7)&lt;br /&gt;
   assert(coroutine.status(c1) == &amp;quot;running&amp;quot;)&lt;br /&gt;
   assert(coroutine.status(c2) == &amp;quot;suspended&amp;quot;)&lt;br /&gt;
   assert(value == 3)&lt;br /&gt;
   -- STEP 8: Run c2 again, passing it the value 4.&lt;br /&gt;
   -- Since c2 has already run before, this time the 4 will come out of the yield() instead of appear as a function parameter.&lt;br /&gt;
   print(8)&lt;br /&gt;
   success, value = coroutine.resume(c2, 4)&lt;br /&gt;
   -- In step 10, c2 yields and passes back the value 5.&lt;br /&gt;
   -- Then c2, having yielded, should be suspended, and c1 should be running again.&lt;br /&gt;
   -- STEP 11: Check all that.&lt;br /&gt;
   print(11)&lt;br /&gt;
   assert(coroutine.status(c1) == &amp;quot;running&amp;quot;)&lt;br /&gt;
   assert(coroutine.status(c2) == &amp;quot;suspended&amp;quot;)&lt;br /&gt;
   assert(value == 5)&lt;br /&gt;
   -- STEP 12: Yield, turning c1 back into a suspended coroutine and continuing execution of the main program, passing back value 6.&lt;br /&gt;
   print(12)&lt;br /&gt;
   value = coroutine.yield(6)&lt;br /&gt;
 end&lt;br /&gt;
 &lt;br /&gt;
 -- This function will be the body of the second coroutine.&lt;br /&gt;
 local function f2(x)&lt;br /&gt;
   -- The first time c2 is run, it is run from f1, which passes 2.&lt;br /&gt;
   -- Thus c1 should be normal (as we are nested inside it), c2 should be running, and x should receive the value from f1, 2.&lt;br /&gt;
   -- STEP 4: Check these assumptions.&lt;br /&gt;
   print(4)&lt;br /&gt;
   assert(coroutine.status(c1) == &amp;quot;normal&amp;quot;)&lt;br /&gt;
   assert(coroutine.status(c2) == &amp;quot;running&amp;quot;)&lt;br /&gt;
   assert(x == 2)&lt;br /&gt;
   -- Because c1 is not suspended, we should not be able to resume it.&lt;br /&gt;
   -- STEP 5: Check this is correct.&lt;br /&gt;
   print(5)&lt;br /&gt;
   success, value = coroutine.resume(c1)&lt;br /&gt;
   assert(not success)&lt;br /&gt;
   assert(value == &amp;quot;cannot resume normal coroutine&amp;quot;)&lt;br /&gt;
   -- STEP 6: Yield, turning c2 back into a suspended coroutine and continuing execution of c1, passing back value 3.&lt;br /&gt;
   print(6)&lt;br /&gt;
   value = coroutine.yield(3)&lt;br /&gt;
   -- In step 8, c1 resumed c2 again and passed the value 4.&lt;br /&gt;
   -- c2 should now be running again, and c1 normal again.&lt;br /&gt;
   -- STEP 9: Check all that.&lt;br /&gt;
   print(9)&lt;br /&gt;
   assert(coroutine.status(c1) == &amp;quot;normal&amp;quot;)&lt;br /&gt;
   assert(coroutine.status(c2) == &amp;quot;running&amp;quot;)&lt;br /&gt;
   assert(value == 4)&lt;br /&gt;
   -- STEP 10: Yield, turning c2 back into a suspended coroutine and continuing execution of c1, passing back value 5.&lt;br /&gt;
   print(10)&lt;br /&gt;
   value = coroutine.yield(5)&lt;br /&gt;
   -- In step 14, the main program resumed c2 directly and passed the value 7, bypassing c1.&lt;br /&gt;
   -- So c2 should be running and c1 should be suspended.&lt;br /&gt;
   -- STEP 15: Check all that.&lt;br /&gt;
   print(15)&lt;br /&gt;
   assert(coroutine.status(c1) == &amp;quot;suspended&amp;quot;)&lt;br /&gt;
   assert(coroutine.status(c2) == &amp;quot;running&amp;quot;)&lt;br /&gt;
   assert(value == 7)&lt;br /&gt;
   -- STEP 16: Now die, returning value 8 to the main program.&lt;br /&gt;
   print(16)&lt;br /&gt;
   return 8&lt;br /&gt;
 end&lt;br /&gt;
 &lt;br /&gt;
 -- Construct the two coroutines.&lt;br /&gt;
 c1 = coroutine.create(f1)&lt;br /&gt;
 c2 = coroutine.create(f2)&lt;br /&gt;
 &lt;br /&gt;
 -- Newly constructed coroutines are always suspended.&lt;br /&gt;
 assert(coroutine.status(c1) == &amp;quot;suspended&amp;quot;)&lt;br /&gt;
 assert(coroutine.status(c2) == &amp;quot;suspended&amp;quot;)&lt;br /&gt;
 &lt;br /&gt;
 -- STEP 1: Run c1 until it yields, starting it off with the value 1.&lt;br /&gt;
 print(1)&lt;br /&gt;
 success, value = coroutine.resume(c1, 1)&lt;br /&gt;
 assert(success)&lt;br /&gt;
 &lt;br /&gt;
 -- In step 12, c1 should have yielded and returned the value 6.&lt;br /&gt;
 -- So now c1 and c2 should both be suspended.&lt;br /&gt;
 -- STEP 13: Check all that.&lt;br /&gt;
 print(13)&lt;br /&gt;
 assert(coroutine.status(c1) == &amp;quot;suspended&amp;quot;)&lt;br /&gt;
 assert(coroutine.status(c2) == &amp;quot;suspended&amp;quot;)&lt;br /&gt;
 assert(value == 6)&lt;br /&gt;
 &lt;br /&gt;
 -- STEP 14: Run c2 directly, NOT nested inside c1 this time, passing it the value 7.&lt;br /&gt;
 print(14)&lt;br /&gt;
 success, value = coroutine.resume(c2, 7)&lt;br /&gt;
 assert(success)&lt;br /&gt;
 &lt;br /&gt;
 -- c2 should have exited normally, returning the value 8.&lt;br /&gt;
 -- Therefore c1 should still be suspended, but c2 should be dead.&lt;br /&gt;
 -- STEP 17: Check all that.&lt;br /&gt;
 print(17)&lt;br /&gt;
 assert(coroutine.status(c1) == &amp;quot;suspended&amp;quot;)&lt;br /&gt;
 assert(coroutine.status(c2) == &amp;quot;dead&amp;quot;)&lt;br /&gt;
 assert(value == 8)&lt;br /&gt;
&lt;br /&gt;
=== Using Coroutine Wrapper Functions ===&lt;br /&gt;
This second example is virtually identical, but shows using [[coroutine.wrap]] and wrapper functions instead of the basic coroutine functions (checks of [[coroutine.status]] have been removed as the raw coroutine objects are not available):&lt;br /&gt;
&lt;br /&gt;
 -- These variables will hold the coroutine wrapper functions.&lt;br /&gt;
 local cw1 = nil&lt;br /&gt;
 local cw2 = nil&lt;br /&gt;
 &lt;br /&gt;
 -- This function will be the body of the first coroutine.&lt;br /&gt;
 local function f1(x)&lt;br /&gt;
   -- The main code, below, starts c1 first, passing 1.&lt;br /&gt;
   -- Thus c1 should be running, c2 should be suspended (not started yet), and x should receive the value from main, 1.&lt;br /&gt;
   -- STEP 2: Check these assumptions.&lt;br /&gt;
   print(2)&lt;br /&gt;
   assert(x == 1)&lt;br /&gt;
   -- STEP 3: Run c2 until it yields, start it off with the value 2.&lt;br /&gt;
   print(3)&lt;br /&gt;
   value = cw2(2)&lt;br /&gt;
   -- In step 6, c2 yields and passes back the value 3.&lt;br /&gt;
   -- Then c2, having yielded, should be suspended, and c1 should be running again.&lt;br /&gt;
   -- STEP 7: Check all that.&lt;br /&gt;
   print(7)&lt;br /&gt;
   assert(value == 3)&lt;br /&gt;
   -- STEP 8: Run c2 again, passing it the value 4.&lt;br /&gt;
   -- Since c2 has already run before, this time the 4 will come out of the yield() instead of appear as a function parameter.&lt;br /&gt;
   print(8)&lt;br /&gt;
   value = cw2(4)&lt;br /&gt;
   -- In step 10, c2 yields and passes back the value 5.&lt;br /&gt;
   -- Then c2, having yielded, should be suspended, and c1 should be running again.&lt;br /&gt;
   -- STEP 11: Check all that.&lt;br /&gt;
   print(11)&lt;br /&gt;
   assert(value == 5)&lt;br /&gt;
   -- STEP 12: Yield, turning c1 back into a suspended coroutine and continuing execution of the main program, passing back value 6.&lt;br /&gt;
   print(12)&lt;br /&gt;
   value = coroutine.yield(6)&lt;br /&gt;
 end&lt;br /&gt;
 &lt;br /&gt;
 -- This function will be the body of the second coroutine.&lt;br /&gt;
 local function f2(x)&lt;br /&gt;
   -- The first time c2 is run, it is run from f1, which passes 2.&lt;br /&gt;
   -- Thus c1 should be normal (as we are nested inside it), c2 should be running, and x should receive the value from f1, 2.&lt;br /&gt;
   -- STEP 4: Check these assumptions.&lt;br /&gt;
   print(4)&lt;br /&gt;
   assert(x == 2)&lt;br /&gt;
   -- Because c1 is not suspended, we should not be able to resume it.&lt;br /&gt;
   -- STEP 5: Check this is correct (we must use pcall because an error will be raised).&lt;br /&gt;
   print(5)&lt;br /&gt;
   success, value = pcall(cw1)&lt;br /&gt;
   assert(not success)&lt;br /&gt;
   -- STEP 6: Yield, turning c2 back into a suspended coroutine and continuing execution of c1, passing back value 3.&lt;br /&gt;
   print(6)&lt;br /&gt;
   value = coroutine.yield(3)&lt;br /&gt;
   -- In step 8, c1 resumed c2 again and passed the value 4.&lt;br /&gt;
   -- c2 should now be running again, and c1 normal again.&lt;br /&gt;
   -- STEP 9: Check all that.&lt;br /&gt;
   print(9)&lt;br /&gt;
   assert(value == 4)&lt;br /&gt;
   -- STEP 10: Yield, turning c2 back into a suspended coroutine and continuing execution of c1, passing back value 5.&lt;br /&gt;
   print(10)&lt;br /&gt;
   value = coroutine.yield(5)&lt;br /&gt;
   -- In step 14, the main program resumed c2 directly and passed the value 7, bypassing c1.&lt;br /&gt;
   -- So c2 should be running and c1 should be suspended.&lt;br /&gt;
   -- STEP 15: Check all that.&lt;br /&gt;
   print(15)&lt;br /&gt;
   assert(value == 7)&lt;br /&gt;
   -- STEP 16: Now die, returning value 8 to the main program.&lt;br /&gt;
   print(16)&lt;br /&gt;
   return 8&lt;br /&gt;
 end&lt;br /&gt;
 &lt;br /&gt;
 -- Construct the two coroutine wrappers.&lt;br /&gt;
 cw1 = coroutine.wrap(f1)&lt;br /&gt;
 cw2 = coroutine.wrap(f2)&lt;br /&gt;
 &lt;br /&gt;
 -- STEP 1: Run cw1 until it yields, starting it off with the value 1.&lt;br /&gt;
 print(1)&lt;br /&gt;
 value = cw1(1)&lt;br /&gt;
 &lt;br /&gt;
 -- In step 12, c1 should have yielded and returned the value 6.&lt;br /&gt;
 -- So now c1 and c2 should both be suspended.&lt;br /&gt;
 -- STEP 13: Check all that.&lt;br /&gt;
 print(13)&lt;br /&gt;
 assert(value == 6)&lt;br /&gt;
 &lt;br /&gt;
 -- STEP 14: Run c2 directly, NOT nested inside c1 this time, passing it the value 7.&lt;br /&gt;
 print(14)&lt;br /&gt;
 value = cw2(7)&lt;br /&gt;
 &lt;br /&gt;
 -- c2 should have exited normally, returning the value 8.&lt;br /&gt;
 -- Therefore c1 should still be suspended, but c2 should be dead.&lt;br /&gt;
 -- STEP 17: Check all that.&lt;br /&gt;
 print(17)&lt;br /&gt;
 assert(value == 8)&lt;br /&gt;
&lt;br /&gt;
== Interaction with Other APIs ==&lt;br /&gt;
The [[OS (API)#pullEvent|os.pullEventRaw]] (and therefore [[os.pullEvent]]) functions are built on top of coroutines: &amp;lt;code&amp;gt;os.pullEventRaw&amp;lt;/code&amp;gt; actually just calls [[coroutine.yield]], passing the event type filter up to the parent coroutine. The parent coroutine is expected to wait until an event of the required type arrives, then use [[coroutine.resume]] to pass the event to the suspended coroutine (where it will be returned from &amp;lt;code&amp;gt;os.pullEventRaw&amp;lt;/code&amp;gt;). If you use the [[Parallel (API)|parallel API]], this is exactly what [[parallel.waitForAny]] and [[parallel.waitForAll]] do: they pull events from the system event queue (or even from a higher invocation of &amp;lt;code&amp;gt;parallel.waitForAny&amp;lt;/code&amp;gt; or &amp;lt;code&amp;gt;parallel.waitForAll&amp;lt;/code&amp;gt;!) and deliver them to all nested coroutines. Therefore, the easiest way to use coroutines is the parallel API, if it works for your situation. However, in the event that you are not able to use the parallel API (e.g. if you need to add and remove coroutines from the executing set dynamically), you can build your own dispatcher that delivers events in the same way as the parallel API—looking at the source code to the parallel API may be useful here.&lt;br /&gt;
&lt;br /&gt;
If you choose to use coroutines in a different way, then &amp;lt;code&amp;gt;os.pullEventRaw&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;os.pullEvent&amp;lt;/code&amp;gt; will not work. This in turn will break any other API function which is written on top of &amp;lt;code&amp;gt;os.pullEvent&amp;lt;/code&amp;gt;. As a guideline, nearly any API function that can possibly take time to complete will fall into this category; some examples are:&lt;br /&gt;
* [[rednet.receive]] blocks until either a [[Rednet message (event)|rednet_message event]] or (if a timeout was requested) a matching [[Timer (event)|timer event]] occurs.&lt;br /&gt;
* [[Gps (API)|gps.locate]] blocks until either a number of [[Modem message (event)|modem_message events]] or (if a timeout was requested) a matching [[Timer (event)|timer event]] occurs.&lt;br /&gt;
* [[http.get]] blocks until an [[Http success (event)|HTTP success event]] or [[Http failure (event)|HTTP failure event]] occurs.&lt;br /&gt;
* [[IO (API)|io.read]] and the built-in [[read]] functions block waiting for, presumably, either [[Char (event)|char events]] or [[Key (event)|key events]].&lt;br /&gt;
* [[os.sleep]] blocks until a matching [[Timer (event)|timer event]] occurs.&lt;br /&gt;
* [[textutils.slowPrint]] calls [[os.sleep]].&lt;br /&gt;
* [[textutils.pagedPrint]] blocks until a [[Key (event)|key event]] occurs for each page.&lt;br /&gt;
* Most of the functions in the [[Turtle (API)|turtle API]] (with the exception of [[turtle.getItemCount]], [[turtle.getItemSpace]], and [[turtle.getFuelLevel]]) block waiting for a [[Turtle response (event)|turtle response event]].&lt;br /&gt;
&lt;br /&gt;
Most of these can be worked around by using non-blocking equivalents that return immediately and then queue an event on completion (such as using [[http.request]]) or that deliver an event unconditionally (such as [[Char_(event)|char]] for keyboard input), then handling events in a way that is suitable for the application. However, if possible, it will often be easier to implement event dispatching instead, remembering that [[os.queueEvent]] can be used for inter-coroutine communication within an application. Another alternative, if you must use a custom protocol between your coroutines and dispatcher, might be to replace &amp;lt;code&amp;gt;os.pullEventRaw&amp;lt;/code&amp;gt; with a new function that uses a mechanism appropriate to the application.&lt;br /&gt;
&lt;br /&gt;
[[Category:APIs]]&lt;/div&gt;</summary>
		<author><name>YoYoYonnY</name></author>	</entry>

	<entry>
		<id>https://www.computercraft.info/wiki/index.php?title=Coroutine_(API)&amp;diff=5770</id>
		<title>Coroutine (API)</title>
		<link rel="alternate" type="text/html" href="https://www.computercraft.info/wiki/index.php?title=Coroutine_(API)&amp;diff=5770"/>
				<updated>2013-07-03T04:28:55Z</updated>
		
		<summary type="html">&lt;p&gt;YoYoYonnY: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{NeedsWork}}&lt;br /&gt;
:{| border=&amp;quot;1&amp;quot; class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
| '''Bug'''&lt;br /&gt;
'''From ComputerCraft 1.3''' this API suffers from the problem of potentially spawning Java threads that live forever therefore, use of coroutines should be minimized. This is '''fixed in ComputerCraft 1.32+''', though.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
''This is for the Coroutine API. For the Coroutine Object, visit [[Coroutine (type)]].''&lt;br /&gt;
&lt;br /&gt;
Coroutine is a default Lua 5.1 API defined [http://www.lua.org/manual/5.1/manual.html#5.2 here]. Please list any non-working functions on this page.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;table style=&amp;quot;width: 100%; border: solid 1px black; margin: 2px; border-spacing: 0px;&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&amp;lt;td colspan=&amp;quot;3&amp;quot; style=&amp;quot;font-weight: bold; font-size: large; padding-bottom: .3em; border-bottom: solid #C9C9C9 1px; background: #D3FFC2; line-height:28px;&amp;quot;&amp;gt;&lt;br /&gt;
[[File:Grid_disk.png|24px]]&amp;amp;nbsp;&amp;amp;nbsp;&lt;br /&gt;
Coroutine (API)&lt;br /&gt;
&amp;lt;/td&amp;gt;&amp;lt;/tr&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tr&amp;gt;&amp;lt;td style=&amp;quot;width: 100px; background: #E0E0E0; padding: .4em; font-weight:bold;&amp;quot;&amp;gt;Return&amp;lt;/td&amp;gt;&amp;lt;td style=&amp;quot;width: 350px; background: #E0E0E0; padding: .4em; font-weight:bold;&amp;quot;&amp;gt;Method Name&amp;lt;/td&amp;gt;&amp;lt;td style=&amp;quot;background: #E0E0E0; padding: .4em; font-weight:bold;&amp;quot;&amp;gt;Description&amp;lt;/td&amp;gt;&amp;lt;/tr&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tr style=&amp;quot;background-color: #FFFFFF;&amp;quot;&amp;gt;&amp;lt;td style=&amp;quot;border-top: solid #C9C9C9 1px; padding: .4em;&amp;quot;&amp;gt;{{Type|coroutine}} coro&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td style=&amp;quot;border-top: solid #C9C9C9 1px; padding: .4em;&amp;quot;&amp;gt;[[coroutine.create]]({{Type|function}} f)&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td style=&amp;quot;border-top: solid #C9C9C9 1px; padding: .4em;&amp;quot;&amp;gt;Creates a new coroutine.&amp;lt;/td&amp;gt;&amp;lt;/tr&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tr style=&amp;quot;background-color: #E8E8E8;&amp;quot;&amp;gt;&amp;lt;td style=&amp;quot;border-top: solid #C9C9C9 1px; padding: .4em;&amp;quot;&amp;gt;{{Type|boolean}} success, …&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td style=&amp;quot;border-top: solid #C9C9C9 1px; padding: .4em;&amp;quot;&amp;gt;[[coroutine.resume]]({{Type|coroutine}} coro, [var1], [var2], ...)&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td style=&amp;quot;border-top: solid #C9C9C9 1px; padding: .4em;&amp;quot;&amp;gt;Starts or resumes an existing coroutine.&amp;lt;/td&amp;gt;&amp;lt;/tr&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tr style=&amp;quot;background-color: #FFFFFF;&amp;quot;&amp;gt;&amp;lt;td style=&amp;quot;border-top: solid #C9C9C9 1px; padding: .4em;&amp;quot;&amp;gt;{{Type|coroutine}} coro&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td style=&amp;quot;border-top: solid #C9C9C9 1px; padding: .4em;&amp;quot;&amp;gt;[[coroutine.running]]()&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td style=&amp;quot;border-top: solid #C9C9C9 1px; padding: .4em;&amp;quot;&amp;gt;Returns the currently executing coroutine.&amp;lt;/td&amp;gt;&amp;lt;/tr&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tr style=&amp;quot;background-color: #E8E8E8;&amp;quot;&amp;gt;&amp;lt;td style=&amp;quot;border-top: solid #C9C9C9 1px; padding: .4em;&amp;quot;&amp;gt;{{Type|string}} status&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td style=&amp;quot;border-top: solid #C9C9C9 1px; padding: .4em;&amp;quot;&amp;gt;[[coroutine.status]]({{type|coroutine}} coroutine)&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td style=&amp;quot;border-top: solid #C9C9C9 1px; padding: .4em;&amp;quot;&amp;gt;Returns the status of the given coroutine.&amp;lt;/td&amp;gt;&amp;lt;/tr&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tr style=&amp;quot;background-color: #FFFFFF;&amp;quot;&amp;gt;&amp;lt;td style=&amp;quot;border-top: solid #C9C9C9 1px; padding: .4em;&amp;quot;&amp;gt;{{Type|function}} coroutine wrapper&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td style=&amp;quot;border-top: solid #C9C9C9 1px; padding: .4em;&amp;quot;&amp;gt;[[coroutine.wrap]]({{type|function}} function)&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td style=&amp;quot;border-top: solid #C9C9C9 1px; padding: .4em;&amp;quot;&amp;gt;Creates a new coroutine and wraps it in a function.&amp;lt;/td&amp;gt;&amp;lt;/tr&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tr style=&amp;quot;background-color: #E8E8E8;&amp;quot;&amp;gt;&amp;lt;td style=&amp;quot;border-top: solid #C9C9C9 1px; padding: .4em;&amp;quot;&amp;gt;[var3], [var4], …&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td style=&amp;quot;border-top: solid #C9C9C9 1px; padding: .4em;&amp;quot;&amp;gt;[[coroutine.yield]]([var1], [var2], …)&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td style=&amp;quot;border-top: solid #C9C9C9 1px; padding: .4em;&amp;quot;&amp;gt;Pauses the currently executing coroutine and passes control to its caller.&amp;lt;/td&amp;gt;&amp;lt;/tr&amp;gt;&lt;br /&gt;
&amp;lt;/table&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Coroutine States and Ancestry ==&lt;br /&gt;
Every coroutine is in one of four states:&lt;br /&gt;
* A ''suspended'' coroutine is one that has not yet been started or that has yielded. A suspended coroutine can become running if it is passed to [[coroutine.resume]].&lt;br /&gt;
* A ''running'' coroutine is one that is currently executing code. Only one coroutine can be running at a time on a particular computer. A running coroutine can become suspended if it [[coroutine.yield]], normal if it calls [[coroutine.resume]] on another coroutine, or dead by if it returns from its body function.&lt;br /&gt;
* A ''normal'' coroutine is one that, while running, resumed another coroutine (the ''child coroutine''). A normal coroutine can become running if its child calls [[coroutine.yield]] or returns from its function body.&lt;br /&gt;
* A ''dead'' coroutine is one that, while running, returned from its function body. A dead coroutine can never change state.&lt;br /&gt;
&lt;br /&gt;
While suspended and dead coroutines simply sit loose with no connections to other coroutines, normal and running coroutines have an ancestry relationship between them. Exactly one coroutine is running at any given time, and the running coroutine has no children. Every running or normal coroutine except the top-level BIOS coroutine has a parent, and this relationship forms a chain with one end (the furthest ancestor) being the top-level BIOS coroutine and the other end (the furthest descendant) being the running coroutine. Remember that only the running coroutine can actually execute code, so any functions invoked must be invoked by that coroutine. Then, calling [[coroutine.resume]] makes the chain longer by taking a previously suspended coroutine, hanging it underneath the current coroutine as a new child, and making the current coroutine normal and the new child running. Meanwhile, calling [[coroutine.yield]] makes the chain shorter by turning the currently executing coroutine into a suspended coroutine, detaching it from the chain, and letting its former parent become running.&lt;br /&gt;
&lt;br /&gt;
It is important not to confuse this coroutine chain with the function call stack. Each individual coroutine contains a complete function call stack of its own, rooted at the coroutine’s body function, whether the coroutine is running, normal, or suspended; the chain described in the previous paragraph refers to how entire coroutines are connected together.&lt;br /&gt;
&lt;br /&gt;
== Examples ==&lt;br /&gt;
As the coroutine API is very tightly coupled and many of its function must be used to get any interesting results, examples are shown here instead of on the individual function pages.&lt;br /&gt;
&lt;br /&gt;
=== Using the Basic Coroutine Functions ===&lt;br /&gt;
This example demonstrates using the basic coroutine functions to pass control and data between coroutines. This example prints the numbers 1 through 17 in order, showing how control flow moves through the main program coroutine and the two created coroutines, while using assertions to show how data flows through the program:&lt;br /&gt;
&lt;br /&gt;
 -- These variables will hold the coroutine objects.&lt;br /&gt;
 local c1 = nil&lt;br /&gt;
 local c2 = nil&lt;br /&gt;
 &lt;br /&gt;
 -- This function will be the body of the first coroutine.&lt;br /&gt;
 local function f1(x)&lt;br /&gt;
   -- The main code, below, starts c1 first, passing 1.&lt;br /&gt;
   -- Thus c1 should be running, c2 should be suspended (not started yet), and x should receive the value from main, 1.&lt;br /&gt;
   -- STEP 2: Check these assumptions.&lt;br /&gt;
   print(2)&lt;br /&gt;
   assert(coroutine.status(c1) == &amp;quot;running&amp;quot;)&lt;br /&gt;
   assert(coroutine.status(c2) == &amp;quot;suspended&amp;quot;)&lt;br /&gt;
   assert(x == 1)&lt;br /&gt;
   -- STEP 3: Run c2 until it yields, start it off with the value 2.&lt;br /&gt;
   print(3)&lt;br /&gt;
   success, value = coroutine.resume(c2, 2)&lt;br /&gt;
   assert(success)&lt;br /&gt;
   -- In step 6, c2 yields and passes back the value 3.&lt;br /&gt;
   -- Then c2, having yielded, should be suspended, and c1 should be running again.&lt;br /&gt;
   -- STEP 7: Check all that.&lt;br /&gt;
   print(7)&lt;br /&gt;
   assert(coroutine.status(c1) == &amp;quot;running&amp;quot;)&lt;br /&gt;
   assert(coroutine.status(c2) == &amp;quot;suspended&amp;quot;)&lt;br /&gt;
   assert(value == 3)&lt;br /&gt;
   -- STEP 8: Run c2 again, passing it the value 4.&lt;br /&gt;
   -- Since c2 has already run before, this time the 4 will come out of the yield() instead of appear as a function parameter.&lt;br /&gt;
   print(8)&lt;br /&gt;
   success, value = coroutine.resume(c2, 4)&lt;br /&gt;
   -- In step 10, c2 yields and passes back the value 5.&lt;br /&gt;
   -- Then c2, having yielded, should be suspended, and c1 should be running again.&lt;br /&gt;
   -- STEP 11: Check all that.&lt;br /&gt;
   print(11)&lt;br /&gt;
   assert(coroutine.status(c1) == &amp;quot;running&amp;quot;)&lt;br /&gt;
   assert(coroutine.status(c2) == &amp;quot;suspended&amp;quot;)&lt;br /&gt;
   assert(value == 5)&lt;br /&gt;
   -- STEP 12: Yield, turning c1 back into a suspended coroutine and continuing execution of the main program, passing back value 6.&lt;br /&gt;
   print(12)&lt;br /&gt;
   value = coroutine.yield(6)&lt;br /&gt;
 end&lt;br /&gt;
 &lt;br /&gt;
 -- This function will be the body of the second coroutine.&lt;br /&gt;
 local function f2(x)&lt;br /&gt;
   -- The first time c2 is run, it is run from f1, which passes 2.&lt;br /&gt;
   -- Thus c1 should be normal (as we are nested inside it), c2 should be running, and x should receive the value from f1, 2.&lt;br /&gt;
   -- STEP 4: Check these assumptions.&lt;br /&gt;
   print(4)&lt;br /&gt;
   assert(coroutine.status(c1) == &amp;quot;normal&amp;quot;)&lt;br /&gt;
   assert(coroutine.status(c2) == &amp;quot;running&amp;quot;)&lt;br /&gt;
   assert(x == 2)&lt;br /&gt;
   -- Because c1 is not suspended, we should not be able to resume it.&lt;br /&gt;
   -- STEP 5: Check this is correct.&lt;br /&gt;
   print(5)&lt;br /&gt;
   success, value = coroutine.resume(c1)&lt;br /&gt;
   assert(not success)&lt;br /&gt;
   assert(value == &amp;quot;cannot resume normal coroutine&amp;quot;)&lt;br /&gt;
   -- STEP 6: Yield, turning c2 back into a suspended coroutine and continuing execution of c1, passing back value 3.&lt;br /&gt;
   print(6)&lt;br /&gt;
   value = coroutine.yield(3)&lt;br /&gt;
   -- In step 8, c1 resumed c2 again and passed the value 4.&lt;br /&gt;
   -- c2 should now be running again, and c1 normal again.&lt;br /&gt;
   -- STEP 9: Check all that.&lt;br /&gt;
   print(9)&lt;br /&gt;
   assert(coroutine.status(c1) == &amp;quot;normal&amp;quot;)&lt;br /&gt;
   assert(coroutine.status(c2) == &amp;quot;running&amp;quot;)&lt;br /&gt;
   assert(value == 4)&lt;br /&gt;
   -- STEP 10: Yield, turning c2 back into a suspended coroutine and continuing execution of c1, passing back value 5.&lt;br /&gt;
   print(10)&lt;br /&gt;
   value = coroutine.yield(5)&lt;br /&gt;
   -- In step 14, the main program resumed c2 directly and passed the value 7, bypassing c1.&lt;br /&gt;
   -- So c2 should be running and c1 should be suspended.&lt;br /&gt;
   -- STEP 15: Check all that.&lt;br /&gt;
   print(15)&lt;br /&gt;
   assert(coroutine.status(c1) == &amp;quot;suspended&amp;quot;)&lt;br /&gt;
   assert(coroutine.status(c2) == &amp;quot;running&amp;quot;)&lt;br /&gt;
   assert(value == 7)&lt;br /&gt;
   -- STEP 16: Now die, returning value 8 to the main program.&lt;br /&gt;
   print(16)&lt;br /&gt;
   return 8&lt;br /&gt;
 end&lt;br /&gt;
 &lt;br /&gt;
 -- Construct the two coroutines.&lt;br /&gt;
 c1 = coroutine.create(f1)&lt;br /&gt;
 c2 = coroutine.create(f2)&lt;br /&gt;
 &lt;br /&gt;
 -- Newly constructed coroutines are always suspended.&lt;br /&gt;
 assert(coroutine.status(c1) == &amp;quot;suspended&amp;quot;)&lt;br /&gt;
 assert(coroutine.status(c2) == &amp;quot;suspended&amp;quot;)&lt;br /&gt;
 &lt;br /&gt;
 -- STEP 1: Run c1 until it yields, starting it off with the value 1.&lt;br /&gt;
 print(1)&lt;br /&gt;
 success, value = coroutine.resume(c1, 1)&lt;br /&gt;
 assert(success)&lt;br /&gt;
 &lt;br /&gt;
 -- In step 12, c1 should have yielded and returned the value 6.&lt;br /&gt;
 -- So now c1 and c2 should both be suspended.&lt;br /&gt;
 -- STEP 13: Check all that.&lt;br /&gt;
 print(13)&lt;br /&gt;
 assert(coroutine.status(c1) == &amp;quot;suspended&amp;quot;)&lt;br /&gt;
 assert(coroutine.status(c2) == &amp;quot;suspended&amp;quot;)&lt;br /&gt;
 assert(value == 6)&lt;br /&gt;
 &lt;br /&gt;
 -- STEP 14: Run c2 directly, NOT nested inside c1 this time, passing it the value 7.&lt;br /&gt;
 print(14)&lt;br /&gt;
 success, value = coroutine.resume(c2, 7)&lt;br /&gt;
 assert(success)&lt;br /&gt;
 &lt;br /&gt;
 -- c2 should have exited normally, returning the value 8.&lt;br /&gt;
 -- Therefore c1 should still be suspended, but c2 should be dead.&lt;br /&gt;
 -- STEP 17: Check all that.&lt;br /&gt;
 print(17)&lt;br /&gt;
 assert(coroutine.status(c1) == &amp;quot;suspended&amp;quot;)&lt;br /&gt;
 assert(coroutine.status(c2) == &amp;quot;dead&amp;quot;)&lt;br /&gt;
 assert(value == 8)&lt;br /&gt;
&lt;br /&gt;
=== Using Coroutine Wrapper Functions ===&lt;br /&gt;
This second example is virtually identical, but shows using [[coroutine.wrap]] and wrapper functions instead of the basic coroutine functions (checks of [[coroutine.status]] have been removed as the raw coroutine objects are not available):&lt;br /&gt;
&lt;br /&gt;
 -- These variables will hold the coroutine wrapper functions.&lt;br /&gt;
 local cw1 = nil&lt;br /&gt;
 local cw2 = nil&lt;br /&gt;
 &lt;br /&gt;
 -- This function will be the body of the first coroutine.&lt;br /&gt;
 local function f1(x)&lt;br /&gt;
   -- The main code, below, starts c1 first, passing 1.&lt;br /&gt;
   -- Thus c1 should be running, c2 should be suspended (not started yet), and x should receive the value from main, 1.&lt;br /&gt;
   -- STEP 2: Check these assumptions.&lt;br /&gt;
   print(2)&lt;br /&gt;
   assert(x == 1)&lt;br /&gt;
   -- STEP 3: Run c2 until it yields, start it off with the value 2.&lt;br /&gt;
   print(3)&lt;br /&gt;
   value = cw2(2)&lt;br /&gt;
   -- In step 6, c2 yields and passes back the value 3.&lt;br /&gt;
   -- Then c2, having yielded, should be suspended, and c1 should be running again.&lt;br /&gt;
   -- STEP 7: Check all that.&lt;br /&gt;
   print(7)&lt;br /&gt;
   assert(value == 3)&lt;br /&gt;
   -- STEP 8: Run c2 again, passing it the value 4.&lt;br /&gt;
   -- Since c2 has already run before, this time the 4 will come out of the yield() instead of appear as a function parameter.&lt;br /&gt;
   print(8)&lt;br /&gt;
   value = cw2(4)&lt;br /&gt;
   -- In step 10, c2 yields and passes back the value 5.&lt;br /&gt;
   -- Then c2, having yielded, should be suspended, and c1 should be running again.&lt;br /&gt;
   -- STEP 11: Check all that.&lt;br /&gt;
   print(11)&lt;br /&gt;
   assert(value == 5)&lt;br /&gt;
   -- STEP 12: Yield, turning c1 back into a suspended coroutine and continuing execution of the main program, passing back value 6.&lt;br /&gt;
   print(12)&lt;br /&gt;
   value = coroutine.yield(6)&lt;br /&gt;
 end&lt;br /&gt;
 &lt;br /&gt;
 -- This function will be the body of the second coroutine.&lt;br /&gt;
 local function f2(x)&lt;br /&gt;
   -- The first time c2 is run, it is run from f1, which passes 2.&lt;br /&gt;
   -- Thus c1 should be normal (as we are nested inside it), c2 should be running, and x should receive the value from f1, 2.&lt;br /&gt;
   -- STEP 4: Check these assumptions.&lt;br /&gt;
   print(4)&lt;br /&gt;
   assert(x == 2)&lt;br /&gt;
   -- Because c1 is not suspended, we should not be able to resume it.&lt;br /&gt;
   -- STEP 5: Check this is correct (we must use pcall because an error will be raised).&lt;br /&gt;
   print(5)&lt;br /&gt;
   success, value = pcall(cw1)&lt;br /&gt;
   assert(not success)&lt;br /&gt;
   -- STEP 6: Yield, turning c2 back into a suspended coroutine and continuing execution of c1, passing back value 3.&lt;br /&gt;
   print(6)&lt;br /&gt;
   value = coroutine.yield(3)&lt;br /&gt;
   -- In step 8, c1 resumed c2 again and passed the value 4.&lt;br /&gt;
   -- c2 should now be running again, and c1 normal again.&lt;br /&gt;
   -- STEP 9: Check all that.&lt;br /&gt;
   print(9)&lt;br /&gt;
   assert(value == 4)&lt;br /&gt;
   -- STEP 10: Yield, turning c2 back into a suspended coroutine and continuing execution of c1, passing back value 5.&lt;br /&gt;
   print(10)&lt;br /&gt;
   value = coroutine.yield(5)&lt;br /&gt;
   -- In step 14, the main program resumed c2 directly and passed the value 7, bypassing c1.&lt;br /&gt;
   -- So c2 should be running and c1 should be suspended.&lt;br /&gt;
   -- STEP 15: Check all that.&lt;br /&gt;
   print(15)&lt;br /&gt;
   assert(value == 7)&lt;br /&gt;
   -- STEP 16: Now die, returning value 8 to the main program.&lt;br /&gt;
   print(16)&lt;br /&gt;
   return 8&lt;br /&gt;
 end&lt;br /&gt;
 &lt;br /&gt;
 -- Construct the two coroutine wrappers.&lt;br /&gt;
 cw1 = coroutine.wrap(f1)&lt;br /&gt;
 cw2 = coroutine.wrap(f2)&lt;br /&gt;
 &lt;br /&gt;
 -- STEP 1: Run cw1 until it yields, starting it off with the value 1.&lt;br /&gt;
 print(1)&lt;br /&gt;
 value = cw1(1)&lt;br /&gt;
 &lt;br /&gt;
 -- In step 12, c1 should have yielded and returned the value 6.&lt;br /&gt;
 -- So now c1 and c2 should both be suspended.&lt;br /&gt;
 -- STEP 13: Check all that.&lt;br /&gt;
 print(13)&lt;br /&gt;
 assert(value == 6)&lt;br /&gt;
 &lt;br /&gt;
 -- STEP 14: Run c2 directly, NOT nested inside c1 this time, passing it the value 7.&lt;br /&gt;
 print(14)&lt;br /&gt;
 value = cw2(7)&lt;br /&gt;
 &lt;br /&gt;
 -- c2 should have exited normally, returning the value 8.&lt;br /&gt;
 -- Therefore c1 should still be suspended, but c2 should be dead.&lt;br /&gt;
 -- STEP 17: Check all that.&lt;br /&gt;
 print(17)&lt;br /&gt;
 assert(value == 8)&lt;br /&gt;
&lt;br /&gt;
== Interaction with Other APIs ==&lt;br /&gt;
The [[OS (API)#pullEvent|os.pullEventRaw]] (and therefore [[os.pullEvent]]) functions are built on top of coroutines: &amp;lt;code&amp;gt;os.pullEventRaw&amp;lt;/code&amp;gt; actually just calls [[coroutine.yield]], passing the event type filter up to the parent coroutine. The parent coroutine is expected to wait until an event of the required type arrives, then use [[coroutine.resume]] to pass the event to the suspended coroutine (where it will be returned from &amp;lt;code&amp;gt;os.pullEventRaw&amp;lt;/code&amp;gt;). If you use the [[Parallel (API)|parallel API]], this is exactly what [[parallel.waitForAny]] and [[parallel.waitForAll]] do: they pull events from the system event queue (or even from a higher invocation of &amp;lt;code&amp;gt;parallel.waitForAny&amp;lt;/code&amp;gt; or &amp;lt;code&amp;gt;parallel.waitForAll&amp;lt;/code&amp;gt;!) and deliver them to all nested coroutines. Therefore, the easiest way to use coroutines is the parallel API, if it works for your situation. However, in the event that you are not able to use the parallel API (e.g. if you need to add and remove coroutines from the executing set dynamically), you can build your own dispatcher that delivers events in the same way as the parallel API—looking at the source code to the parallel API may be useful here.&lt;br /&gt;
&lt;br /&gt;
If you choose to use coroutines in a different way, then &amp;lt;code&amp;gt;os.pullEventRaw&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;os.pullEvent&amp;lt;/code&amp;gt; will not work. This in turn will break any other API function which is written on top of &amp;lt;code&amp;gt;os.pullEvent&amp;lt;/code&amp;gt;. As a guideline, nearly any API function that can possibly take time to complete will fall into this category; some examples are:&lt;br /&gt;
* [[rednet.receive]] blocks until either a [[Rednet message (event)|rednet_message event]] or (if a timeout was requested) a matching [[Timer (event)|timer event]] occurs.&lt;br /&gt;
* [[Gps (API)|gps.locate]] blocks until either a number of [[Modem message (event)|modem_message events]] or (if a timeout was requested) a matching [[Timer (event)|timer event]] occurs.&lt;br /&gt;
* [[http.get]] blocks until an [[Http success (event)|HTTP success event]] or [[Http failure (event)|HTTP failure event]] occurs.&lt;br /&gt;
* [[IO (API)|io.read]] and the built-in [[read]] functions block waiting for, presumably, either [[Char (event)|char events]] or [[Key (event)|key events]].&lt;br /&gt;
* [[os.sleep]] blocks until a matching [[Timer (event)|timer event]] occurs.&lt;br /&gt;
* [[textutils.slowPrint]] calls [[os.sleep]].&lt;br /&gt;
* [[textutils.pagedPrint]] blocks until a [[Key (event)|key event]] occurs for each page.&lt;br /&gt;
* Most of the functions in the [[Turtle (API)|turtle API]] (with the exception of [[turtle.getItemCount]], [[turtle.getItemSpace]], and [[turtle.getFuelLevel]]) block waiting for a [[Turtle response (event)|turtle response event]].&lt;br /&gt;
&lt;br /&gt;
Most of these can be worked around by using non-blocking equivalents that return immediately and then queue an event on completion (such as using [[http.request]]) or that deliver an event unconditionally (such as [[Char_(event)|char]] for keyboard input), then handling events in a way that is suitable for the application. However, if possible, it will often be easier to implement event dispatching instead, remembering that [[os.queueEvent]] can be used for inter-coroutine communication within an application. Another alternative, if you must use a custom protocol between your coroutines and dispatcher, might be to replace &amp;lt;code&amp;gt;os.pullEventRaw&amp;lt;/code&amp;gt; with a new function that uses a mechanism appropriate to the application.&lt;br /&gt;
&lt;br /&gt;
[[Category:APIs]]&lt;/div&gt;</summary>
		<author><name>YoYoYonnY</name></author>	</entry>

	<entry>
		<id>https://www.computercraft.info/wiki/index.php?title=Term.native&amp;diff=5082</id>
		<title>Term.native</title>
		<link rel="alternate" type="text/html" href="https://www.computercraft.info/wiki/index.php?title=Term.native&amp;diff=5082"/>
				<updated>2013-02-17T18:08:02Z</updated>
		
		<summary type="html">&lt;p&gt;YoYoYonnY: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{lowercase}}&lt;br /&gt;
{{Function&lt;br /&gt;
|name=term.native&lt;br /&gt;
|returns=The term table&lt;br /&gt;
|api=term&lt;br /&gt;
|addon=ComputerCraft&lt;br /&gt;
|desc=Equal to the term API table&lt;br /&gt;
|examples=&lt;br /&gt;
{{Example&lt;br /&gt;
|desc=Restores a program to the computer. &lt;br /&gt;
This will only work if the computer was running a program on a monitor&lt;br /&gt;
|code=term.native.write(&amp;quot;term.native.write() = term.write()&amp;quot;)&lt;br /&gt;
}}&lt;br /&gt;
|notes=&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
[[Category:API_Functions]]&lt;/div&gt;</summary>
		<author><name>YoYoYonnY</name></author>	</entry>

	<entry>
		<id>https://www.computercraft.info/wiki/index.php?title=Term.native&amp;diff=5081</id>
		<title>Term.native</title>
		<link rel="alternate" type="text/html" href="https://www.computercraft.info/wiki/index.php?title=Term.native&amp;diff=5081"/>
				<updated>2013-02-17T18:07:31Z</updated>
		
		<summary type="html">&lt;p&gt;YoYoYonnY: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{lowercase}}&lt;br /&gt;
{{Variable&lt;br /&gt;
|name=term.native&lt;br /&gt;
|returns=The term table&lt;br /&gt;
|api=term&lt;br /&gt;
|addon=ComputerCraft&lt;br /&gt;
|desc=Equal to the term API table&lt;br /&gt;
|examples=&lt;br /&gt;
{{Example&lt;br /&gt;
|desc=Restores a program to the computer. &lt;br /&gt;
This will only work if the computer was running a program on a monitor&lt;br /&gt;
|code=term.native.write(&amp;quot;term.native.write() = term.write()&amp;quot;)&lt;br /&gt;
}}&lt;br /&gt;
|notes=&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
[[Category:API_Functions]]&lt;/div&gt;</summary>
		<author><name>YoYoYonnY</name></author>	</entry>

	<entry>
		<id>https://www.computercraft.info/wiki/index.php?title=Term.native&amp;diff=5080</id>
		<title>Term.native</title>
		<link rel="alternate" type="text/html" href="https://www.computercraft.info/wiki/index.php?title=Term.native&amp;diff=5080"/>
				<updated>2013-02-17T18:07:05Z</updated>
		
		<summary type="html">&lt;p&gt;YoYoYonnY: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{lowercase}}&lt;br /&gt;
{{Table&lt;br /&gt;
|name=term.native&lt;br /&gt;
|returns=The term table&lt;br /&gt;
|api=term&lt;br /&gt;
|addon=ComputerCraft&lt;br /&gt;
|desc=Equal to the term API table&lt;br /&gt;
|examples=&lt;br /&gt;
{{Example&lt;br /&gt;
|desc=Restores a program to the computer. &lt;br /&gt;
This will only work if the computer was running a program on a monitor&lt;br /&gt;
|code=term.native.write(&amp;quot;term.native.write() = term.write()&amp;quot;)&lt;br /&gt;
}}&lt;br /&gt;
|notes=&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
[[Category:API_Functions]]&lt;/div&gt;</summary>
		<author><name>YoYoYonnY</name></author>	</entry>

	<entry>
		<id>https://www.computercraft.info/wiki/index.php?title=Term.native&amp;diff=5079</id>
		<title>Term.native</title>
		<link rel="alternate" type="text/html" href="https://www.computercraft.info/wiki/index.php?title=Term.native&amp;diff=5079"/>
				<updated>2013-02-17T18:05:43Z</updated>
		
		<summary type="html">&lt;p&gt;YoYoYonnY: Created page with &amp;quot;{{lowercase}} {{Function |name=term.native |returns=The term table |api=term |addon=ComputerCraft |desc=Equal to the term API table |examples= {{Example |desc=Restores a progr...&amp;quot;&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{lowercase}}&lt;br /&gt;
{{Function&lt;br /&gt;
|name=term.native&lt;br /&gt;
|returns=The term table&lt;br /&gt;
|api=term&lt;br /&gt;
|addon=ComputerCraft&lt;br /&gt;
|desc=Equal to the term API table&lt;br /&gt;
|examples=&lt;br /&gt;
{{Example&lt;br /&gt;
|desc=Restores a program to the computer. &lt;br /&gt;
This will only work if the computer was running a program on a monitor&lt;br /&gt;
|code=term.native.write(&amp;quot;term.native.write() = term.write()&amp;quot;)&lt;br /&gt;
}}&lt;br /&gt;
|notes=&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
[[Category:API_Functions]]&lt;/div&gt;</summary>
		<author><name>YoYoYonnY</name></author>	</entry>

	<entry>
		<id>https://www.computercraft.info/wiki/index.php?title=Diamond_pickaxe&amp;diff=5076</id>
		<title>Diamond pickaxe</title>
		<link rel="alternate" type="text/html" href="https://www.computercraft.info/wiki/index.php?title=Diamond_pickaxe&amp;diff=5076"/>
				<updated>2013-02-13T05:15:07Z</updated>
		
		<summary type="html">&lt;p&gt;YoYoYonnY: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;The diamond pickaxe can be equipped on a turtle. The pickaxe is the best tool for mining that can be equipped on a turtle. Because of the high cost of the pickaxe, it can mine anything and get the resources for it. The turtle can also attack with the pickaxe, and has the same damage output as a [[diamond shovel]] and [[diamond hoe]].&lt;br /&gt;
{{Crafting grid&lt;br /&gt;
 |B2=turtle |C2=diamond_pickaxe&lt;br /&gt;
 |Output=mining_turtle&lt;br /&gt;
 }}&lt;br /&gt;
For more information on the &amp;quot;Diamond Pickaxe&amp;quot;, please go the the Minecraft official wiki.&lt;br /&gt;
&lt;br /&gt;
[http://www.minecraftwiki.net/wiki/Diamond_Pickaxe Diamond Pickaxe]&lt;br /&gt;
&lt;br /&gt;
[[Category:Vanilla_Minecraft]]&lt;/div&gt;</summary>
		<author><name>YoYoYonnY</name></author>	</entry>

	<entry>
		<id>https://www.computercraft.info/wiki/index.php?title=Diamond_shovel&amp;diff=5075</id>
		<title>Diamond shovel</title>
		<link rel="alternate" type="text/html" href="https://www.computercraft.info/wiki/index.php?title=Diamond_shovel&amp;diff=5075"/>
				<updated>2013-02-13T05:13:53Z</updated>
		
		<summary type="html">&lt;p&gt;YoYoYonnY: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;The diamond shovel can be equipped on a turtle. Because of it's low cost it can only mine soft blocks like dirt and sand. The shovel is the only tool that can mine snow and get snowballs from it. The turtle can also attack with the shovel, and has the same damage output as a [[diamond pickaxe]] and [[diamond hoe]].&lt;br /&gt;
{{Crafting grid&lt;br /&gt;
 |B2=turtle |C2=diamond_shovel&lt;br /&gt;
 |Output=Digging_Turtle&lt;br /&gt;
 }}&lt;br /&gt;
For more information on the &amp;quot;Diamond Shovel&amp;quot;, please go the the Minecraft official wiki.&lt;br /&gt;
&lt;br /&gt;
[http://www.minecraftwiki.net/wiki/Diamond_Shovel Diamond Shovel]&lt;br /&gt;
&lt;br /&gt;
[[Category:Vanilla_Minecraft]]&lt;/div&gt;</summary>
		<author><name>YoYoYonnY</name></author>	</entry>

	<entry>
		<id>https://www.computercraft.info/wiki/index.php?title=Diamond_hoe&amp;diff=5074</id>
		<title>Diamond hoe</title>
		<link rel="alternate" type="text/html" href="https://www.computercraft.info/wiki/index.php?title=Diamond_hoe&amp;diff=5074"/>
				<updated>2013-02-13T05:13:26Z</updated>
		
		<summary type="html">&lt;p&gt;YoYoYonnY: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;The diamond hoe can be equipped on a Turtle. The hoe is the only tool that can turn dirt into farmland. The turtle can also attack with the hoe, and has the same damage output as a [[diamond pickaxe]] and [[diamond shovel]].&lt;br /&gt;
{{Crafting grid&lt;br /&gt;
 |B2=turtle |C2=diamond_hoe&lt;br /&gt;
 |Output=Farming_Turtle&lt;br /&gt;
 }}&lt;br /&gt;
For more information on the &amp;quot;Diamond Hoe&amp;quot;, please go the the Minecraft official wiki.&lt;br /&gt;
&lt;br /&gt;
[http://www.minecraftwiki.net/wiki/Diamond_Hoe  Diamond Hoe]&lt;br /&gt;
&lt;br /&gt;
[[Category:Vanilla_Minecraft]]&lt;/div&gt;</summary>
		<author><name>YoYoYonnY</name></author>	</entry>

	<entry>
		<id>https://www.computercraft.info/wiki/index.php?title=Diamond_axe&amp;diff=5073</id>
		<title>Diamond axe</title>
		<link rel="alternate" type="text/html" href="https://www.computercraft.info/wiki/index.php?title=Diamond_axe&amp;diff=5073"/>
				<updated>2013-02-13T05:12:30Z</updated>
		
		<summary type="html">&lt;p&gt;YoYoYonnY: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;The diamond axe can be equipped on a turtle and is a tool that is both effective for mining and attacking. The axe is the second best weapon for the turtle and can also mine blocks. The turtle cannot get the resources for mining ores and stone.&lt;br /&gt;
{{Crafting grid&lt;br /&gt;
 |B2=turtle |C2=diamond_axe&lt;br /&gt;
 |Output=Felling_Turtle&lt;br /&gt;
 }}&lt;br /&gt;
For more information on the &amp;quot;Diamond Axe&amp;quot;, please go the the Minecraft official wiki.&lt;br /&gt;
&lt;br /&gt;
[http://www.minecraftwiki.net/wiki/Diamond_Axe Diamond Axe]&lt;br /&gt;
&lt;br /&gt;
[[Category:Vanilla_Minecraft]]&lt;/div&gt;</summary>
		<author><name>YoYoYonnY</name></author>	</entry>

	<entry>
		<id>https://www.computercraft.info/wiki/index.php?title=Textutils.unserialize&amp;diff=4892</id>
		<title>Textutils.unserialize</title>
		<link rel="alternate" type="text/html" href="https://www.computercraft.info/wiki/index.php?title=Textutils.unserialize&amp;diff=4892"/>
				<updated>2013-01-02T08:42:48Z</updated>
		
		<summary type="html">&lt;p&gt;YoYoYonnY: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{lowercase}}&lt;br /&gt;
{{Function&lt;br /&gt;
|name=textutils.unserialize&lt;br /&gt;
|args= [[string (type)|serialized]]&lt;br /&gt;
|returns=a copy of the original object that was serialized&lt;br /&gt;
|api=textutils&lt;br /&gt;
|addon=ComputerCraft&lt;br /&gt;
|desc=Converts the serialized string back into an object.  The string should have been created using [[Textutils.serialize|serialize]].   Note, the representation used by textutils actually creates Lua syntax, so that [loadstring] will also work to deserialize. See [[textutils.serialize]] for more information&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
[[Category:API_Functions]]&lt;/div&gt;</summary>
		<author><name>YoYoYonnY</name></author>	</entry>

	<entry>
		<id>https://www.computercraft.info/wiki/index.php?title=Printer_(API)&amp;diff=4891</id>
		<title>Printer (API)</title>
		<link rel="alternate" type="text/html" href="https://www.computercraft.info/wiki/index.php?title=Printer_(API)&amp;diff=4891"/>
				<updated>2013-01-02T04:38:13Z</updated>
		
		<summary type="html">&lt;p&gt;YoYoYonnY: /* Note */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;The Printer API allows you to interact with printers.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;table style=&amp;quot;width: 100%; border: solid 1px black; margin: 2px; border-spacing: 0px;&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&amp;lt;td colspan=&amp;quot;2&amp;quot; style=&amp;quot;font-weight: bold; font-size: large; padding-bottom: .3em; border-bottom: solid #C9C9C9 1px; background: #D3FFC2; line-height:28px;&amp;quot;&amp;gt;&lt;br /&gt;
[[File:Grid_disk.png|24px]]&amp;amp;nbsp;&amp;amp;nbsp;&lt;br /&gt;
Printer (API))&lt;br /&gt;
&amp;lt;/td&amp;gt;&amp;lt;/tr&amp;gt;&lt;br /&gt;
&amp;lt;tr style=&amp;quot;background-color: #FFFFFF;&amp;quot;&amp;gt;&amp;lt;td style=&amp;quot;border-top: solid #C9C9C9 1px; padding: .4em;&amp;quot;&amp;gt;[[printer.getPaperLevel]]()&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td style=&amp;quot;border-top: solid #C9C9C9 1px; padding: .4em;&amp;quot;&amp;gt;Returns the amount of paper available in the paper tray.&amp;lt;/td&amp;gt;&amp;lt;/tr&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tr style=&amp;quot;background-color: #E8E8E8;&amp;quot;&amp;gt;&amp;lt;td style=&amp;quot;border-top: solid #C9C9C9 1px; padding: .4em;&amp;quot;&amp;gt;[[printer.newPage]]()&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td style=&amp;quot;border-top: solid #C9C9C9 1px; padding: .4em;&amp;quot;&amp;gt;Starts a new page. Returns true if page got started, false if not.&amp;lt;/td&amp;gt;&amp;lt;/tr&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tr style=&amp;quot;background-color: #FFFFFF;&amp;quot;&amp;gt;&amp;lt;td style=&amp;quot;border-top: solid #C9C9C9 1px; padding: .4em;&amp;quot;&amp;gt;[[printer.endPage]]()&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td style=&amp;quot;border-top: solid #C9C9C9 1px; padding: .4em;&amp;quot;&amp;gt;Ends the page and prints the page to the output tray. Returns true if page was ended, false if not.&amp;lt;/td&amp;gt;&amp;lt;/tr&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tr style=&amp;quot;background-color: #E8E8E8;&amp;quot;&amp;gt;&amp;lt;td style=&amp;quot;border-top: solid #C9C9C9 1px; padding: .4em;&amp;quot;&amp;gt;[[printer.write]]([[string]] text)&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td style=&amp;quot;border-top: solid #C9C9C9 1px; padding: .4em;&amp;quot;&amp;gt;Writes text to the paper, works the same way as [[term.write|term.write()]]&amp;lt;/td&amp;gt;&amp;lt;/tr&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tr style=&amp;quot;background-color: #FFFFFF;&amp;quot;&amp;gt;&amp;lt;td style=&amp;quot;border-top: solid #C9C9C9 1px; padding: .4em;&amp;quot;&amp;gt;[[printer.setPageTitle]]([[string]] title)&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td style=&amp;quot;border-top: solid #C9C9C9 1px; padding: .4em;&amp;quot;&amp;gt;Sets the title of the page.&amp;lt;/td&amp;gt;&amp;lt;/tr&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tr style=&amp;quot;background-color: #E8E8E8;&amp;quot;&amp;gt;&amp;lt;td style=&amp;quot;border-top: solid #C9C9C9 1px; padding: .4em;&amp;quot;&amp;gt;[[printer.getInkLevel]]()&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td style=&amp;quot;border-top: solid #C9C9C9 1px; padding: .4em;&amp;quot;&amp;gt;Returns the amount of ink in the ink slot.&amp;lt;/td&amp;gt;&amp;lt;/tr&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tr style=&amp;quot;background-color: #FFFFFF;&amp;quot;&amp;gt;&amp;lt;td style=&amp;quot;border-top: solid #C9C9C9 1px; padding: .4em;&amp;quot;&amp;gt;[[printer.getCursorPos]]()&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td style=&amp;quot;border-top: solid #C9C9C9 1px; padding: .4em;&amp;quot;&amp;gt;Returns the coordinates of the cursor on the paper, works the same way as [[term.getCursorPos|term.getCursorPos()]]&amp;lt;/td&amp;gt;&amp;lt;/tr&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tr style=&amp;quot;background-color: #E8E8E8;&amp;quot;&amp;gt;&amp;lt;td style=&amp;quot;border-top: solid #C9C9C9 1px; padding: .4em;&amp;quot;&amp;gt;[[printer.setCursorPos]]([[int (type)|int]] x, [[int (type)|int]] y)&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td style=&amp;quot;border-top: solid #C9C9C9 1px; padding: .4em;&amp;quot;&amp;gt;Sets the cursor pos, works the same way as [[term.setCursorPos|term.setCursorPos()]]&amp;lt;/td&amp;gt;&amp;lt;/tr&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tr style=&amp;quot;background-color: #FFFFFF;&amp;quot;&amp;gt;&amp;lt;td style=&amp;quot;border-top: solid #C9C9C9 1px; padding: .4em;&amp;quot;&amp;gt;[[printer.getPageSize]]()&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td style=&amp;quot;border-top: solid #C9C9C9 1px; padding: .4em;&amp;quot;&amp;gt;Returns the size of the paper, works the same way as [[term.getSize|term.getSize()]]&amp;lt;/td&amp;gt;&amp;lt;/tr&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tr style=&amp;quot;background-color: #E8E8E8;&amp;quot;&amp;gt;&amp;lt;td style=&amp;quot;border-top: solid #C9C9C9 1px; padding: .4em;&amp;quot;&amp;gt;&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td style=&amp;quot;border-top: solid #C9C9C9 1px; padding: .4em;&amp;quot;&amp;gt;&amp;lt;/td&amp;gt;&amp;lt;/tr&amp;gt;&lt;br /&gt;
&amp;lt;/table&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Note==&lt;br /&gt;
All printer functions are to be used ''after'' wrapping the printer in a peripheral.&lt;br /&gt;
'''example''': printer = peripheral.wrap(&amp;quot;left&amp;quot;)&lt;br /&gt;
&lt;br /&gt;
[[Category:APIs]]&lt;/div&gt;</summary>
		<author><name>YoYoYonnY</name></author>	</entry>

	<entry>
		<id>https://www.computercraft.info/wiki/index.php?title=Printer_(API)&amp;diff=4890</id>
		<title>Printer (API)</title>
		<link rel="alternate" type="text/html" href="https://www.computercraft.info/wiki/index.php?title=Printer_(API)&amp;diff=4890"/>
				<updated>2013-01-02T04:38:03Z</updated>
		
		<summary type="html">&lt;p&gt;YoYoYonnY: /* Note */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;The Printer API allows you to interact with printers.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;table style=&amp;quot;width: 100%; border: solid 1px black; margin: 2px; border-spacing: 0px;&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&amp;lt;td colspan=&amp;quot;2&amp;quot; style=&amp;quot;font-weight: bold; font-size: large; padding-bottom: .3em; border-bottom: solid #C9C9C9 1px; background: #D3FFC2; line-height:28px;&amp;quot;&amp;gt;&lt;br /&gt;
[[File:Grid_disk.png|24px]]&amp;amp;nbsp;&amp;amp;nbsp;&lt;br /&gt;
Printer (API))&lt;br /&gt;
&amp;lt;/td&amp;gt;&amp;lt;/tr&amp;gt;&lt;br /&gt;
&amp;lt;tr style=&amp;quot;background-color: #FFFFFF;&amp;quot;&amp;gt;&amp;lt;td style=&amp;quot;border-top: solid #C9C9C9 1px; padding: .4em;&amp;quot;&amp;gt;[[printer.getPaperLevel]]()&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td style=&amp;quot;border-top: solid #C9C9C9 1px; padding: .4em;&amp;quot;&amp;gt;Returns the amount of paper available in the paper tray.&amp;lt;/td&amp;gt;&amp;lt;/tr&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tr style=&amp;quot;background-color: #E8E8E8;&amp;quot;&amp;gt;&amp;lt;td style=&amp;quot;border-top: solid #C9C9C9 1px; padding: .4em;&amp;quot;&amp;gt;[[printer.newPage]]()&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td style=&amp;quot;border-top: solid #C9C9C9 1px; padding: .4em;&amp;quot;&amp;gt;Starts a new page. Returns true if page got started, false if not.&amp;lt;/td&amp;gt;&amp;lt;/tr&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tr style=&amp;quot;background-color: #FFFFFF;&amp;quot;&amp;gt;&amp;lt;td style=&amp;quot;border-top: solid #C9C9C9 1px; padding: .4em;&amp;quot;&amp;gt;[[printer.endPage]]()&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td style=&amp;quot;border-top: solid #C9C9C9 1px; padding: .4em;&amp;quot;&amp;gt;Ends the page and prints the page to the output tray. Returns true if page was ended, false if not.&amp;lt;/td&amp;gt;&amp;lt;/tr&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tr style=&amp;quot;background-color: #E8E8E8;&amp;quot;&amp;gt;&amp;lt;td style=&amp;quot;border-top: solid #C9C9C9 1px; padding: .4em;&amp;quot;&amp;gt;[[printer.write]]([[string]] text)&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td style=&amp;quot;border-top: solid #C9C9C9 1px; padding: .4em;&amp;quot;&amp;gt;Writes text to the paper, works the same way as [[term.write|term.write()]]&amp;lt;/td&amp;gt;&amp;lt;/tr&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tr style=&amp;quot;background-color: #FFFFFF;&amp;quot;&amp;gt;&amp;lt;td style=&amp;quot;border-top: solid #C9C9C9 1px; padding: .4em;&amp;quot;&amp;gt;[[printer.setPageTitle]]([[string]] title)&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td style=&amp;quot;border-top: solid #C9C9C9 1px; padding: .4em;&amp;quot;&amp;gt;Sets the title of the page.&amp;lt;/td&amp;gt;&amp;lt;/tr&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tr style=&amp;quot;background-color: #E8E8E8;&amp;quot;&amp;gt;&amp;lt;td style=&amp;quot;border-top: solid #C9C9C9 1px; padding: .4em;&amp;quot;&amp;gt;[[printer.getInkLevel]]()&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td style=&amp;quot;border-top: solid #C9C9C9 1px; padding: .4em;&amp;quot;&amp;gt;Returns the amount of ink in the ink slot.&amp;lt;/td&amp;gt;&amp;lt;/tr&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tr style=&amp;quot;background-color: #FFFFFF;&amp;quot;&amp;gt;&amp;lt;td style=&amp;quot;border-top: solid #C9C9C9 1px; padding: .4em;&amp;quot;&amp;gt;[[printer.getCursorPos]]()&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td style=&amp;quot;border-top: solid #C9C9C9 1px; padding: .4em;&amp;quot;&amp;gt;Returns the coordinates of the cursor on the paper, works the same way as [[term.getCursorPos|term.getCursorPos()]]&amp;lt;/td&amp;gt;&amp;lt;/tr&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tr style=&amp;quot;background-color: #E8E8E8;&amp;quot;&amp;gt;&amp;lt;td style=&amp;quot;border-top: solid #C9C9C9 1px; padding: .4em;&amp;quot;&amp;gt;[[printer.setCursorPos]]([[int (type)|int]] x, [[int (type)|int]] y)&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td style=&amp;quot;border-top: solid #C9C9C9 1px; padding: .4em;&amp;quot;&amp;gt;Sets the cursor pos, works the same way as [[term.setCursorPos|term.setCursorPos()]]&amp;lt;/td&amp;gt;&amp;lt;/tr&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tr style=&amp;quot;background-color: #FFFFFF;&amp;quot;&amp;gt;&amp;lt;td style=&amp;quot;border-top: solid #C9C9C9 1px; padding: .4em;&amp;quot;&amp;gt;[[printer.getPageSize]]()&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td style=&amp;quot;border-top: solid #C9C9C9 1px; padding: .4em;&amp;quot;&amp;gt;Returns the size of the paper, works the same way as [[term.getSize|term.getSize()]]&amp;lt;/td&amp;gt;&amp;lt;/tr&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tr style=&amp;quot;background-color: #E8E8E8;&amp;quot;&amp;gt;&amp;lt;td style=&amp;quot;border-top: solid #C9C9C9 1px; padding: .4em;&amp;quot;&amp;gt;&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td style=&amp;quot;border-top: solid #C9C9C9 1px; padding: .4em;&amp;quot;&amp;gt;&amp;lt;/td&amp;gt;&amp;lt;/tr&amp;gt;&lt;br /&gt;
&amp;lt;/table&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Note==&lt;br /&gt;
All printer functions are to be used ''after'' wrapping the printer in a peripheral.\n&lt;br /&gt;
'''example''': printer = peripheral.wrap(&amp;quot;left&amp;quot;)&lt;br /&gt;
&lt;br /&gt;
[[Category:APIs]]&lt;/div&gt;</summary>
		<author><name>YoYoYonnY</name></author>	</entry>

	<entry>
		<id>https://www.computercraft.info/wiki/index.php?title=Printer_(API)&amp;diff=4889</id>
		<title>Printer (API)</title>
		<link rel="alternate" type="text/html" href="https://www.computercraft.info/wiki/index.php?title=Printer_(API)&amp;diff=4889"/>
				<updated>2013-01-02T04:37:32Z</updated>
		
		<summary type="html">&lt;p&gt;YoYoYonnY: /* Note */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;The Printer API allows you to interact with printers.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;table style=&amp;quot;width: 100%; border: solid 1px black; margin: 2px; border-spacing: 0px;&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&amp;lt;td colspan=&amp;quot;2&amp;quot; style=&amp;quot;font-weight: bold; font-size: large; padding-bottom: .3em; border-bottom: solid #C9C9C9 1px; background: #D3FFC2; line-height:28px;&amp;quot;&amp;gt;&lt;br /&gt;
[[File:Grid_disk.png|24px]]&amp;amp;nbsp;&amp;amp;nbsp;&lt;br /&gt;
Printer (API))&lt;br /&gt;
&amp;lt;/td&amp;gt;&amp;lt;/tr&amp;gt;&lt;br /&gt;
&amp;lt;tr style=&amp;quot;background-color: #FFFFFF;&amp;quot;&amp;gt;&amp;lt;td style=&amp;quot;border-top: solid #C9C9C9 1px; padding: .4em;&amp;quot;&amp;gt;[[printer.getPaperLevel]]()&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td style=&amp;quot;border-top: solid #C9C9C9 1px; padding: .4em;&amp;quot;&amp;gt;Returns the amount of paper available in the paper tray.&amp;lt;/td&amp;gt;&amp;lt;/tr&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tr style=&amp;quot;background-color: #E8E8E8;&amp;quot;&amp;gt;&amp;lt;td style=&amp;quot;border-top: solid #C9C9C9 1px; padding: .4em;&amp;quot;&amp;gt;[[printer.newPage]]()&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td style=&amp;quot;border-top: solid #C9C9C9 1px; padding: .4em;&amp;quot;&amp;gt;Starts a new page. Returns true if page got started, false if not.&amp;lt;/td&amp;gt;&amp;lt;/tr&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tr style=&amp;quot;background-color: #FFFFFF;&amp;quot;&amp;gt;&amp;lt;td style=&amp;quot;border-top: solid #C9C9C9 1px; padding: .4em;&amp;quot;&amp;gt;[[printer.endPage]]()&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td style=&amp;quot;border-top: solid #C9C9C9 1px; padding: .4em;&amp;quot;&amp;gt;Ends the page and prints the page to the output tray. Returns true if page was ended, false if not.&amp;lt;/td&amp;gt;&amp;lt;/tr&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tr style=&amp;quot;background-color: #E8E8E8;&amp;quot;&amp;gt;&amp;lt;td style=&amp;quot;border-top: solid #C9C9C9 1px; padding: .4em;&amp;quot;&amp;gt;[[printer.write]]([[string]] text)&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td style=&amp;quot;border-top: solid #C9C9C9 1px; padding: .4em;&amp;quot;&amp;gt;Writes text to the paper, works the same way as [[term.write|term.write()]]&amp;lt;/td&amp;gt;&amp;lt;/tr&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tr style=&amp;quot;background-color: #FFFFFF;&amp;quot;&amp;gt;&amp;lt;td style=&amp;quot;border-top: solid #C9C9C9 1px; padding: .4em;&amp;quot;&amp;gt;[[printer.setPageTitle]]([[string]] title)&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td style=&amp;quot;border-top: solid #C9C9C9 1px; padding: .4em;&amp;quot;&amp;gt;Sets the title of the page.&amp;lt;/td&amp;gt;&amp;lt;/tr&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tr style=&amp;quot;background-color: #E8E8E8;&amp;quot;&amp;gt;&amp;lt;td style=&amp;quot;border-top: solid #C9C9C9 1px; padding: .4em;&amp;quot;&amp;gt;[[printer.getInkLevel]]()&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td style=&amp;quot;border-top: solid #C9C9C9 1px; padding: .4em;&amp;quot;&amp;gt;Returns the amount of ink in the ink slot.&amp;lt;/td&amp;gt;&amp;lt;/tr&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tr style=&amp;quot;background-color: #FFFFFF;&amp;quot;&amp;gt;&amp;lt;td style=&amp;quot;border-top: solid #C9C9C9 1px; padding: .4em;&amp;quot;&amp;gt;[[printer.getCursorPos]]()&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td style=&amp;quot;border-top: solid #C9C9C9 1px; padding: .4em;&amp;quot;&amp;gt;Returns the coordinates of the cursor on the paper, works the same way as [[term.getCursorPos|term.getCursorPos()]]&amp;lt;/td&amp;gt;&amp;lt;/tr&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tr style=&amp;quot;background-color: #E8E8E8;&amp;quot;&amp;gt;&amp;lt;td style=&amp;quot;border-top: solid #C9C9C9 1px; padding: .4em;&amp;quot;&amp;gt;[[printer.setCursorPos]]([[int (type)|int]] x, [[int (type)|int]] y)&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td style=&amp;quot;border-top: solid #C9C9C9 1px; padding: .4em;&amp;quot;&amp;gt;Sets the cursor pos, works the same way as [[term.setCursorPos|term.setCursorPos()]]&amp;lt;/td&amp;gt;&amp;lt;/tr&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tr style=&amp;quot;background-color: #FFFFFF;&amp;quot;&amp;gt;&amp;lt;td style=&amp;quot;border-top: solid #C9C9C9 1px; padding: .4em;&amp;quot;&amp;gt;[[printer.getPageSize]]()&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td style=&amp;quot;border-top: solid #C9C9C9 1px; padding: .4em;&amp;quot;&amp;gt;Returns the size of the paper, works the same way as [[term.getSize|term.getSize()]]&amp;lt;/td&amp;gt;&amp;lt;/tr&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tr style=&amp;quot;background-color: #E8E8E8;&amp;quot;&amp;gt;&amp;lt;td style=&amp;quot;border-top: solid #C9C9C9 1px; padding: .4em;&amp;quot;&amp;gt;&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td style=&amp;quot;border-top: solid #C9C9C9 1px; padding: .4em;&amp;quot;&amp;gt;&amp;lt;/td&amp;gt;&amp;lt;/tr&amp;gt;&lt;br /&gt;
&amp;lt;/table&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Note==&lt;br /&gt;
All printer functions are to be used ''after'' wrapping the printer in a peripheral.&lt;br /&gt;
example: printer = peripheral.wrap(&amp;quot;left&amp;quot;)&lt;br /&gt;
&lt;br /&gt;
[[Category:APIs]]&lt;/div&gt;</summary>
		<author><name>YoYoYonnY</name></author>	</entry>

	<entry>
		<id>https://www.computercraft.info/wiki/index.php?title=Os.pullEvent&amp;diff=3737</id>
		<title>Os.pullEvent</title>
		<link rel="alternate" type="text/html" href="https://www.computercraft.info/wiki/index.php?title=Os.pullEvent&amp;diff=3737"/>
				<updated>2012-11-14T08:03:33Z</updated>
		
		<summary type="html">&lt;p&gt;YoYoYonnY: /* Event Types */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{lowercase}}&lt;br /&gt;
{{Function&lt;br /&gt;
 |name=os.pullEvent&lt;br /&gt;
 |args=([[string]]) only-event-to-accept&lt;br /&gt;
 |api=os&lt;br /&gt;
 |returns=(string)event, variable parameters(see table below)&lt;br /&gt;
 |addon=ComputerCraft&lt;br /&gt;
 |desc=Yields computer until event occurs&lt;br /&gt;
 |examples=&lt;br /&gt;
{{Example&lt;br /&gt;
|desc=The program requires to wait for a keypress to do something:&lt;br /&gt;
|code=[[function]] clear()&lt;br /&gt;
    [[term.clear]]()&lt;br /&gt;
    [[term.setCursorPos]] (1,1)&lt;br /&gt;
 end&lt;br /&gt;
 while true do&lt;br /&gt;
    clear()&lt;br /&gt;
    [[print]] (&amp;quot;Press E to do something.&amp;quot;)&lt;br /&gt;
    local event, param1 = os.pullEvent (&amp;quot;char&amp;quot;) -- limit os.pullEvent to the char event&lt;br /&gt;
    if param1 == &amp;quot;e&amp;quot; then -- if the returned value was 'e'&lt;br /&gt;
        clear()&lt;br /&gt;
        [[write]] (&amp;quot;Name: &amp;quot;)&lt;br /&gt;
        local name = [[read]]()&lt;br /&gt;
        [[print]] (name)&lt;br /&gt;
        break&lt;br /&gt;
    else&lt;br /&gt;
        clear()&lt;br /&gt;
        [[print]] (&amp;quot;Wrong button!&amp;quot;)&lt;br /&gt;
        [[sleep]] (1.5) -- I don't like a whole 2 seconds but 1 second is too short&lt;br /&gt;
    end&lt;br /&gt;
 end&lt;br /&gt;
}}&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
== How it Works ==&lt;br /&gt;
When os.pullEvent() is called, regardless of whether it has variables to set, the computer is yielded until an event occurs. An event is anything the computer can use as input, such as a button being pushed on the keyboard or a redstone input.&lt;br /&gt;
When said event occurs, the event's name is placed in the first variable (the variable 'event' in the section below). With the event comes returned values, and, depending on the event type, there can be different amounts and different data types of returned values.&lt;br /&gt;
&lt;br /&gt;
For example, the event &amp;quot;char&amp;quot; returns &amp;quot;char&amp;quot; as the event and (let's say E was pressed) the first parameter will be set to &amp;quot;e&amp;quot;, although whether or not Shift was pressed can change that &amp;quot;e&amp;quot; to an &amp;quot;E&amp;quot; as well.&lt;br /&gt;
&lt;br /&gt;
The event &amp;quot;redstone&amp;quot; only returns the event type since any other information needed can be retrieved with [[redstone.getInput]].&lt;br /&gt;
&lt;br /&gt;
=== Common Syntax ===&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
event, param1, param2, param3 = os.pullEvent()&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Event Types==&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; width=&amp;quot;100%&amp;quot;&lt;br /&gt;
! rowspan=&amp;quot;2&amp;quot; | Name&lt;br /&gt;
! rowspan=&amp;quot;2&amp;quot; | Description&lt;br /&gt;
! colspan=&amp;quot;3&amp;quot; | Parameters&lt;br /&gt;
|-&lt;br /&gt;
! 1&lt;br /&gt;
! 2&lt;br /&gt;
! 3&lt;br /&gt;
|-&lt;br /&gt;
![[char]]&lt;br /&gt;
|Fired when text is typed on the keyboard&lt;br /&gt;
|(string)the letter typed&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
![[key]]&lt;br /&gt;
|Fired when a key is pressed on the keyboard&lt;br /&gt;
|(number)numerical keycode&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
![[timer]]&lt;br /&gt;
|Fired when a timeout started by [[os.startTimer]]() completes&lt;br /&gt;
|(number)Value of the timer as returned by os.startTimer()&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
![[alarm]]&lt;br /&gt;
|Fired when a time passed to [[os.setAlarm]]() is reached&lt;br /&gt;
|(number)Value of the alarm as returned by os.setAlarm()&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
![[redstone]]&lt;br /&gt;
|Fired when the state of any of the redstone inputs change&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
![[terminate]]&lt;br /&gt;
|Fired when a combination of keys CTRL and T is pressed and held for three seconds. It is handled by default by os.pullEvent() and causes calling of two other functions: error() - To terminate the program; and print() to inform the user that the program he or she was running has been terminated.&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
![[disk]]&lt;br /&gt;
|Fired when a disk is inserted into an adjacent disk drive&lt;br /&gt;
|(string)side&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
![[disk_eject]]&lt;br /&gt;
|Fired when a disk is removed from an adjacent disk drive&lt;br /&gt;
|(string)side&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
![[peripheral]]&lt;br /&gt;
|Fired when peripheral is attached&lt;br /&gt;
|(string)side&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
![[peripheral_detach]]&lt;br /&gt;
|Fired when peripheral is removed&lt;br /&gt;
|(string)side&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
![[rednet_message]]&lt;br /&gt;
|Fired when a rednet message is received from the [[Rednet_(API)|rednet API]]&lt;br /&gt;
|(number)senderID&lt;br /&gt;
|(string)message&lt;br /&gt;
|(number)distance travelled&lt;br /&gt;
|-&lt;br /&gt;
![[http_success]]&lt;br /&gt;
|Fired when an attempt to receieve text from / post text on a website is successful&lt;br /&gt;
|(string)url of the site&lt;br /&gt;
|(table)text on the site&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
![[http_failure]]&lt;br /&gt;
|Fired when an attempt to receive text from / post text on a website is unsuccessful&lt;br /&gt;
|(string)url of the site&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
![[mouse_click]]&lt;br /&gt;
|Fired when a mouse button is pressed&lt;br /&gt;
|(number)mouse button&lt;br /&gt;
|(number)x coordinate&lt;br /&gt;
|(number)y coordinate&lt;br /&gt;
|-&lt;br /&gt;
![[mouse_scroll]]&lt;br /&gt;
|Fired when a mousewheel is scrolled.&lt;br /&gt;
|(number)scroll direction (-1 for up, 1 for down)&lt;br /&gt;
|(number)x coordinate(in screen chars)&lt;br /&gt;
|(number)y coordinate(in screen chars)&lt;br /&gt;
|-&lt;br /&gt;
![[mouse_drag]]&lt;br /&gt;
|Fired when the mouse is moved after clicking.&lt;br /&gt;
|(number)x coordinate(in screen chars)&lt;br /&gt;
|(number)y coordinate(in screen chars)&lt;br /&gt;
|&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== Guides ==&lt;br /&gt;
[http://www.computercraft.info/forums2/index.php?/topic/1516-ospullevent-what-is-it-and-how-is-it-useful/page__view__findpost__p__11156 ''Onionnion's Guide on os.pullEvent()'']&lt;/div&gt;</summary>
		<author><name>YoYoYonnY</name></author>	</entry>

	<entry>
		<id>https://www.computercraft.info/wiki/index.php?title=Os.pullEvent&amp;diff=3736</id>
		<title>Os.pullEvent</title>
		<link rel="alternate" type="text/html" href="https://www.computercraft.info/wiki/index.php?title=Os.pullEvent&amp;diff=3736"/>
				<updated>2012-11-14T08:02:03Z</updated>
		
		<summary type="html">&lt;p&gt;YoYoYonnY: /* Event Types */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{lowercase}}&lt;br /&gt;
{{Function&lt;br /&gt;
 |name=os.pullEvent&lt;br /&gt;
 |args=([[string]]) only-event-to-accept&lt;br /&gt;
 |api=os&lt;br /&gt;
 |returns=(string)event, variable parameters(see table below)&lt;br /&gt;
 |addon=ComputerCraft&lt;br /&gt;
 |desc=Yields computer until event occurs&lt;br /&gt;
 |examples=&lt;br /&gt;
{{Example&lt;br /&gt;
|desc=The program requires to wait for a keypress to do something:&lt;br /&gt;
|code=[[function]] clear()&lt;br /&gt;
    [[term.clear]]()&lt;br /&gt;
    [[term.setCursorPos]] (1,1)&lt;br /&gt;
 end&lt;br /&gt;
 while true do&lt;br /&gt;
    clear()&lt;br /&gt;
    [[print]] (&amp;quot;Press E to do something.&amp;quot;)&lt;br /&gt;
    local event, param1 = os.pullEvent (&amp;quot;char&amp;quot;) -- limit os.pullEvent to the char event&lt;br /&gt;
    if param1 == &amp;quot;e&amp;quot; then -- if the returned value was 'e'&lt;br /&gt;
        clear()&lt;br /&gt;
        [[write]] (&amp;quot;Name: &amp;quot;)&lt;br /&gt;
        local name = [[read]]()&lt;br /&gt;
        [[print]] (name)&lt;br /&gt;
        break&lt;br /&gt;
    else&lt;br /&gt;
        clear()&lt;br /&gt;
        [[print]] (&amp;quot;Wrong button!&amp;quot;)&lt;br /&gt;
        [[sleep]] (1.5) -- I don't like a whole 2 seconds but 1 second is too short&lt;br /&gt;
    end&lt;br /&gt;
 end&lt;br /&gt;
}}&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
== How it Works ==&lt;br /&gt;
When os.pullEvent() is called, regardless of whether it has variables to set, the computer is yielded until an event occurs. An event is anything the computer can use as input, such as a button being pushed on the keyboard or a redstone input.&lt;br /&gt;
When said event occurs, the event's name is placed in the first variable (the variable 'event' in the section below). With the event comes returned values, and, depending on the event type, there can be different amounts and different data types of returned values.&lt;br /&gt;
&lt;br /&gt;
For example, the event &amp;quot;char&amp;quot; returns &amp;quot;char&amp;quot; as the event and (let's say E was pressed) the first parameter will be set to &amp;quot;e&amp;quot;, although whether or not Shift was pressed can change that &amp;quot;e&amp;quot; to an &amp;quot;E&amp;quot; as well.&lt;br /&gt;
&lt;br /&gt;
The event &amp;quot;redstone&amp;quot; only returns the event type since any other information needed can be retrieved with [[redstone.getInput]].&lt;br /&gt;
&lt;br /&gt;
=== Common Syntax ===&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
event, param1, param2, param3 = os.pullEvent()&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Event Types==&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; width=&amp;quot;100%&amp;quot;&lt;br /&gt;
! rowspan=&amp;quot;2&amp;quot; | Name&lt;br /&gt;
! rowspan=&amp;quot;2&amp;quot; | Description&lt;br /&gt;
! colspan=&amp;quot;3&amp;quot; | Parameters&lt;br /&gt;
|-&lt;br /&gt;
! 1&lt;br /&gt;
! 2&lt;br /&gt;
! 3&lt;br /&gt;
|-&lt;br /&gt;
![[char]]&lt;br /&gt;
|Fired when text is typed on the keyboard&lt;br /&gt;
|(string)the letter typed&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
![[key]]&lt;br /&gt;
|Fired when a key is pressed on the keyboard&lt;br /&gt;
|(number)numerical keycode&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
![[timer]]&lt;br /&gt;
|Fired when a timeout started by [[os.startTimer()]] completes&lt;br /&gt;
|(number)Value of the timer as returned by os.startTimer()&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
![[alarm]]&lt;br /&gt;
|Fired when a time passed to [[os.setAlarm()]] is reached&lt;br /&gt;
|(number)Value of the alarm as returned by os.setAlarm()&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
![[redstone]]&lt;br /&gt;
|Fired when the state of any of the redstone inputs change&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
![[terminate]]&lt;br /&gt;
|Fired when a combination of keys CTRL and T is pressed and held for three seconds. It is handled by default by os.pullEvent() and causes calling of two other functions: error() - To terminate the program; and print() to inform the user that the program he or she was running has been terminated.&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
![[disk]]&lt;br /&gt;
|Fired when a disk is inserted into an adjacent disk drive&lt;br /&gt;
|(string)side&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
![[disk_eject]]&lt;br /&gt;
|Fired when a disk is removed from an adjacent disk drive&lt;br /&gt;
|(string)side&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
![[peripheral]]&lt;br /&gt;
|Fired when peripheral is attached&lt;br /&gt;
|(string)side&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
![[peripheral_detach]]&lt;br /&gt;
|Fired when peripheral is removed&lt;br /&gt;
|(string)side&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
![[rednet_message]]&lt;br /&gt;
|Fired when a rednet message is received from the [[Rednet_(API)|rednet API]]&lt;br /&gt;
|(number)senderID&lt;br /&gt;
|(string)message&lt;br /&gt;
|(number)distance travelled&lt;br /&gt;
|-&lt;br /&gt;
![[http_success]]&lt;br /&gt;
|Fired when an attempt to receieve text from / post text on a website is successful&lt;br /&gt;
|(string)url of the site&lt;br /&gt;
|(table)text on the site&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
![[http_failure]]&lt;br /&gt;
|Fired when an attempt to receive text from / post text on a website is unsuccessful&lt;br /&gt;
|(string)url of the site&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
![[mouse_click]]&lt;br /&gt;
|Fired when a mouse button is pressed&lt;br /&gt;
|(number)mouse button&lt;br /&gt;
|(number)x coordinate&lt;br /&gt;
|(number)y coordinate&lt;br /&gt;
|-&lt;br /&gt;
![[mouse_scroll]]&lt;br /&gt;
|Fired when a mousewheel is scrolled.&lt;br /&gt;
|(number)scroll direction (-1 for up, 1 for down)&lt;br /&gt;
|(number)x coordinate(in screen chars)&lt;br /&gt;
|(number)y coordinate(in screen chars)&lt;br /&gt;
|-&lt;br /&gt;
![[mouse_drag]]&lt;br /&gt;
|Fired when the mouse is moved after clicking.&lt;br /&gt;
|(number)x coordinate(in screen chars)&lt;br /&gt;
|(number)y coordinate(in screen chars)&lt;br /&gt;
|&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== Guides ==&lt;br /&gt;
[http://www.computercraft.info/forums2/index.php?/topic/1516-ospullevent-what-is-it-and-how-is-it-useful/page__view__findpost__p__11156 ''Onionnion's Guide on os.pullEvent()'']&lt;/div&gt;</summary>
		<author><name>YoYoYonnY</name></author>	</entry>

	<entry>
		<id>https://www.computercraft.info/wiki/index.php?title=Os.pullEvent&amp;diff=3591</id>
		<title>Os.pullEvent</title>
		<link rel="alternate" type="text/html" href="https://www.computercraft.info/wiki/index.php?title=Os.pullEvent&amp;diff=3591"/>
				<updated>2012-11-04T04:43:54Z</updated>
		
		<summary type="html">&lt;p&gt;YoYoYonnY: /* Event Types */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{lowercase}}&lt;br /&gt;
{{Function&lt;br /&gt;
 |name=os.pullEvent&lt;br /&gt;
 |args=[[string]] only-event-to-accept&lt;br /&gt;
 |api=os&lt;br /&gt;
 |returns=event, parameters&lt;br /&gt;
 |addon=ComputerCraft&lt;br /&gt;
 |desc=Yields computer until event occurs&lt;br /&gt;
 |examples=&lt;br /&gt;
{{Example&lt;br /&gt;
|desc=The program requires to wait for a keypress to do something:&lt;br /&gt;
|code=[[function]] clear()&lt;br /&gt;
    [[term.clear]]()&lt;br /&gt;
    [[term.setCursorPos]] (1,1)&lt;br /&gt;
 end&lt;br /&gt;
 while true do&lt;br /&gt;
    clear()&lt;br /&gt;
    [[print]] (&amp;quot;Press E to do something.&amp;quot;)&lt;br /&gt;
    local event, param1 = os.pullEvent (&amp;quot;char&amp;quot;) -- limit os.pullEvent to the char event&lt;br /&gt;
    if param1 == &amp;quot;e&amp;quot; then -- if the returned value was 'e'&lt;br /&gt;
        clear()&lt;br /&gt;
        [[write]] (&amp;quot;Name: &amp;quot;)&lt;br /&gt;
        local name = [[read]]()&lt;br /&gt;
        [[print]] (name)&lt;br /&gt;
        break&lt;br /&gt;
    else&lt;br /&gt;
        clear()&lt;br /&gt;
        [[print]] (&amp;quot;Wrong button!&amp;quot;)&lt;br /&gt;
        [[sleep]] (1.5) -- I don't like a whole 2 seconds but 1 second is too short&lt;br /&gt;
    end&lt;br /&gt;
 end&lt;br /&gt;
}}&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
== How it Works ==&lt;br /&gt;
When os.pullEvent() is called, regardless of whether it has variables to set, the computer is yielded until an event occurs. An event is anything the computer can use as input, such as a button being pushed on the keyboard or a redstone input.&lt;br /&gt;
When said event occurs, the event's name is placed in the first variable (the variable 'event' in the section below). With the event comes returned values, and, depending on the event type, there can be different amounts and different data types of returned values.&lt;br /&gt;
&lt;br /&gt;
For example, the event &amp;quot;char&amp;quot; returns &amp;quot;char&amp;quot; as the event and (let's say E was pressed) the first parameter will be set to &amp;quot;e&amp;quot;, although whether or not Shift was pressed can change that &amp;quot;e&amp;quot; to an &amp;quot;E&amp;quot; as well.&lt;br /&gt;
&lt;br /&gt;
The event &amp;quot;redstone&amp;quot; only returns the event type since any other information needed can be retrieved with [[redstone.getInput]].&lt;br /&gt;
&lt;br /&gt;
=== Common Syntax ===&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
event, param1, param2, param3 = os.pullEvent()&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Event Types==&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; width=&amp;quot;100%&amp;quot;&lt;br /&gt;
! rowspan=&amp;quot;2&amp;quot; | Name&lt;br /&gt;
! rowspan=&amp;quot;2&amp;quot; | Description&lt;br /&gt;
! colspan=&amp;quot;6&amp;quot; | Parameters&lt;br /&gt;
|-&lt;br /&gt;
! 1&lt;br /&gt;
! 2&lt;br /&gt;
! 3&lt;br /&gt;
! 4&lt;br /&gt;
! 5&lt;br /&gt;
! 6&lt;br /&gt;
|-&lt;br /&gt;
![[char]]&lt;br /&gt;
|Fired when text is typed on the keyboard&lt;br /&gt;
|the letter typed&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
![[key]]&lt;br /&gt;
|Fired when a key is pressed on the keyboard&lt;br /&gt;
|numerical keycode&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
![[timer]]&lt;br /&gt;
|Fired when a timeout started by os.startTimer() completes&lt;br /&gt;
|Value of the timer as returned by os.startTimer()&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
![[alarm]]&lt;br /&gt;
|Fired when a time passed to os.setAlarm() is reached&lt;br /&gt;
|Value of the alarm as returned by os.setAlarm()&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
![[redstone]]&lt;br /&gt;
|Fired when the state of any of the redstone inputs change&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
![[disk]]&lt;br /&gt;
|Fired when a disk is inserted into an adjacent disk drive&lt;br /&gt;
|side&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
![[disk_eject]]&lt;br /&gt;
|Fired when a disk is removed from an adjacent disk drive&lt;br /&gt;
|side&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
![[peripheral]]&lt;br /&gt;
|Fired when peripheral is attached&lt;br /&gt;
|side&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
![[peripheral_detach]]&lt;br /&gt;
|Fired when peripheral is removed&lt;br /&gt;
|side&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
![[rednet_message]]&lt;br /&gt;
|Fired when a rednet message is received from the [[Rednet_(API)|rednet API]]&lt;br /&gt;
|senderID&lt;br /&gt;
|message&lt;br /&gt;
|distanceTravelled&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
![[http_success]]&lt;br /&gt;
|Fired when an attempt to recieve text from / post text on a website is successful&lt;br /&gt;
|url of the site&lt;br /&gt;
|text on the site&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
![[http_failure]]&lt;br /&gt;
|Fired when an attempt to recieve text from / post text on a website is unsuccessful&lt;br /&gt;
|url of the site&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
![[mouse_click]]&lt;br /&gt;
|Fired when a mouse button is pressed&lt;br /&gt;
|mouse button&lt;br /&gt;
|x coordinate&lt;br /&gt;
|y coordinate&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
![[mouse_scroll]]&lt;br /&gt;
|Fired when a mousewheel is scrolled.&lt;br /&gt;
|scroll direction (-1 for up, 1 for down)&lt;br /&gt;
|x coordinate&lt;br /&gt;
|y coordinate&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
![[mouse_drag]]&lt;br /&gt;
|Fired when the mouse is moved after clicking.&lt;br /&gt;
|x coordinate&lt;br /&gt;
|y coordinate&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== Guides ==&lt;br /&gt;
[http://www.computercraft.info/forums2/index.php?/topic/1516-ospullevent-what-is-it-and-how-is-it-useful/page__view__findpost__p__11156 ''Onionnion's Guide on os.pullEvent()'']&lt;/div&gt;</summary>
		<author><name>YoYoYonnY</name></author>	</entry>

	<entry>
		<id>https://www.computercraft.info/wiki/index.php?title=Os.pullEvent&amp;diff=3590</id>
		<title>Os.pullEvent</title>
		<link rel="alternate" type="text/html" href="https://www.computercraft.info/wiki/index.php?title=Os.pullEvent&amp;diff=3590"/>
				<updated>2012-11-04T04:43:43Z</updated>
		
		<summary type="html">&lt;p&gt;YoYoYonnY: /* Event Types */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{lowercase}}&lt;br /&gt;
{{Function&lt;br /&gt;
 |name=os.pullEvent&lt;br /&gt;
 |args=[[string]] only-event-to-accept&lt;br /&gt;
 |api=os&lt;br /&gt;
 |returns=event, parameters&lt;br /&gt;
 |addon=ComputerCraft&lt;br /&gt;
 |desc=Yields computer until event occurs&lt;br /&gt;
 |examples=&lt;br /&gt;
{{Example&lt;br /&gt;
|desc=The program requires to wait for a keypress to do something:&lt;br /&gt;
|code=[[function]] clear()&lt;br /&gt;
    [[term.clear]]()&lt;br /&gt;
    [[term.setCursorPos]] (1,1)&lt;br /&gt;
 end&lt;br /&gt;
 while true do&lt;br /&gt;
    clear()&lt;br /&gt;
    [[print]] (&amp;quot;Press E to do something.&amp;quot;)&lt;br /&gt;
    local event, param1 = os.pullEvent (&amp;quot;char&amp;quot;) -- limit os.pullEvent to the char event&lt;br /&gt;
    if param1 == &amp;quot;e&amp;quot; then -- if the returned value was 'e'&lt;br /&gt;
        clear()&lt;br /&gt;
        [[write]] (&amp;quot;Name: &amp;quot;)&lt;br /&gt;
        local name = [[read]]()&lt;br /&gt;
        [[print]] (name)&lt;br /&gt;
        break&lt;br /&gt;
    else&lt;br /&gt;
        clear()&lt;br /&gt;
        [[print]] (&amp;quot;Wrong button!&amp;quot;)&lt;br /&gt;
        [[sleep]] (1.5) -- I don't like a whole 2 seconds but 1 second is too short&lt;br /&gt;
    end&lt;br /&gt;
 end&lt;br /&gt;
}}&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
== How it Works ==&lt;br /&gt;
When os.pullEvent() is called, regardless of whether it has variables to set, the computer is yielded until an event occurs. An event is anything the computer can use as input, such as a button being pushed on the keyboard or a redstone input.&lt;br /&gt;
When said event occurs, the event's name is placed in the first variable (the variable 'event' in the section below). With the event comes returned values, and, depending on the event type, there can be different amounts and different data types of returned values.&lt;br /&gt;
&lt;br /&gt;
For example, the event &amp;quot;char&amp;quot; returns &amp;quot;char&amp;quot; as the event and (let's say E was pressed) the first parameter will be set to &amp;quot;e&amp;quot;, although whether or not Shift was pressed can change that &amp;quot;e&amp;quot; to an &amp;quot;E&amp;quot; as well.&lt;br /&gt;
&lt;br /&gt;
The event &amp;quot;redstone&amp;quot; only returns the event type since any other information needed can be retrieved with [[redstone.getInput]].&lt;br /&gt;
&lt;br /&gt;
=== Common Syntax ===&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
event, param1, param2, param3 = os.pullEvent()&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Event Types==&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; width=&amp;quot;100%&amp;quot;&lt;br /&gt;
! rowspan=&amp;quot;2&amp;quot; | Name&lt;br /&gt;
! rowspan=&amp;quot;2&amp;quot; | Description&lt;br /&gt;
! colspan=&amp;quot;6&amp;quot; | Parameters&lt;br /&gt;
|-&lt;br /&gt;
! 1&lt;br /&gt;
! 2&lt;br /&gt;
! 3&lt;br /&gt;
! 4&lt;br /&gt;
! 5&lt;br /&gt;
! 6&lt;br /&gt;
|-&lt;br /&gt;
![[char]] (Event)&lt;br /&gt;
|Fired when text is typed on the keyboard&lt;br /&gt;
|the letter typed&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
![[key]]&lt;br /&gt;
|Fired when a key is pressed on the keyboard&lt;br /&gt;
|numerical keycode&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
![[timer]]&lt;br /&gt;
|Fired when a timeout started by os.startTimer() completes&lt;br /&gt;
|Value of the timer as returned by os.startTimer()&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
![[alarm]]&lt;br /&gt;
|Fired when a time passed to os.setAlarm() is reached&lt;br /&gt;
|Value of the alarm as returned by os.setAlarm()&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
![[redstone]]&lt;br /&gt;
|Fired when the state of any of the redstone inputs change&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
![[disk]]&lt;br /&gt;
|Fired when a disk is inserted into an adjacent disk drive&lt;br /&gt;
|side&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
![[disk_eject]]&lt;br /&gt;
|Fired when a disk is removed from an adjacent disk drive&lt;br /&gt;
|side&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
![[peripheral]]&lt;br /&gt;
|Fired when peripheral is attached&lt;br /&gt;
|side&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
![[peripheral_detach]]&lt;br /&gt;
|Fired when peripheral is removed&lt;br /&gt;
|side&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
![[rednet_message]]&lt;br /&gt;
|Fired when a rednet message is received from the [[Rednet_(API)|rednet API]]&lt;br /&gt;
|senderID&lt;br /&gt;
|message&lt;br /&gt;
|distanceTravelled&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
![[http_success]]&lt;br /&gt;
|Fired when an attempt to recieve text from / post text on a website is successful&lt;br /&gt;
|url of the site&lt;br /&gt;
|text on the site&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
![[http_failure]]&lt;br /&gt;
|Fired when an attempt to recieve text from / post text on a website is unsuccessful&lt;br /&gt;
|url of the site&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
![[mouse_click]]&lt;br /&gt;
|Fired when a mouse button is pressed&lt;br /&gt;
|mouse button&lt;br /&gt;
|x coordinate&lt;br /&gt;
|y coordinate&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
![[mouse_scroll]]&lt;br /&gt;
|Fired when a mousewheel is scrolled.&lt;br /&gt;
|scroll direction (-1 for up, 1 for down)&lt;br /&gt;
|x coordinate&lt;br /&gt;
|y coordinate&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
![[mouse_drag]]&lt;br /&gt;
|Fired when the mouse is moved after clicking.&lt;br /&gt;
|x coordinate&lt;br /&gt;
|y coordinate&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== Guides ==&lt;br /&gt;
[http://www.computercraft.info/forums2/index.php?/topic/1516-ospullevent-what-is-it-and-how-is-it-useful/page__view__findpost__p__11156 ''Onionnion's Guide on os.pullEvent()'']&lt;/div&gt;</summary>
		<author><name>YoYoYonnY</name></author>	</entry>

	<entry>
		<id>https://www.computercraft.info/wiki/index.php?title=Os.pullEvent&amp;diff=3589</id>
		<title>Os.pullEvent</title>
		<link rel="alternate" type="text/html" href="https://www.computercraft.info/wiki/index.php?title=Os.pullEvent&amp;diff=3589"/>
				<updated>2012-11-04T04:43:27Z</updated>
		
		<summary type="html">&lt;p&gt;YoYoYonnY: /* Event Types */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{lowercase}}&lt;br /&gt;
{{Function&lt;br /&gt;
 |name=os.pullEvent&lt;br /&gt;
 |args=[[string]] only-event-to-accept&lt;br /&gt;
 |api=os&lt;br /&gt;
 |returns=event, parameters&lt;br /&gt;
 |addon=ComputerCraft&lt;br /&gt;
 |desc=Yields computer until event occurs&lt;br /&gt;
 |examples=&lt;br /&gt;
{{Example&lt;br /&gt;
|desc=The program requires to wait for a keypress to do something:&lt;br /&gt;
|code=[[function]] clear()&lt;br /&gt;
    [[term.clear]]()&lt;br /&gt;
    [[term.setCursorPos]] (1,1)&lt;br /&gt;
 end&lt;br /&gt;
 while true do&lt;br /&gt;
    clear()&lt;br /&gt;
    [[print]] (&amp;quot;Press E to do something.&amp;quot;)&lt;br /&gt;
    local event, param1 = os.pullEvent (&amp;quot;char&amp;quot;) -- limit os.pullEvent to the char event&lt;br /&gt;
    if param1 == &amp;quot;e&amp;quot; then -- if the returned value was 'e'&lt;br /&gt;
        clear()&lt;br /&gt;
        [[write]] (&amp;quot;Name: &amp;quot;)&lt;br /&gt;
        local name = [[read]]()&lt;br /&gt;
        [[print]] (name)&lt;br /&gt;
        break&lt;br /&gt;
    else&lt;br /&gt;
        clear()&lt;br /&gt;
        [[print]] (&amp;quot;Wrong button!&amp;quot;)&lt;br /&gt;
        [[sleep]] (1.5) -- I don't like a whole 2 seconds but 1 second is too short&lt;br /&gt;
    end&lt;br /&gt;
 end&lt;br /&gt;
}}&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
== How it Works ==&lt;br /&gt;
When os.pullEvent() is called, regardless of whether it has variables to set, the computer is yielded until an event occurs. An event is anything the computer can use as input, such as a button being pushed on the keyboard or a redstone input.&lt;br /&gt;
When said event occurs, the event's name is placed in the first variable (the variable 'event' in the section below). With the event comes returned values, and, depending on the event type, there can be different amounts and different data types of returned values.&lt;br /&gt;
&lt;br /&gt;
For example, the event &amp;quot;char&amp;quot; returns &amp;quot;char&amp;quot; as the event and (let's say E was pressed) the first parameter will be set to &amp;quot;e&amp;quot;, although whether or not Shift was pressed can change that &amp;quot;e&amp;quot; to an &amp;quot;E&amp;quot; as well.&lt;br /&gt;
&lt;br /&gt;
The event &amp;quot;redstone&amp;quot; only returns the event type since any other information needed can be retrieved with [[redstone.getInput]].&lt;br /&gt;
&lt;br /&gt;
=== Common Syntax ===&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
event, param1, param2, param3 = os.pullEvent()&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Event Types==&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; width=&amp;quot;100%&amp;quot;&lt;br /&gt;
! rowspan=&amp;quot;2&amp;quot; | Name&lt;br /&gt;
! rowspan=&amp;quot;2&amp;quot; | Description&lt;br /&gt;
! colspan=&amp;quot;6&amp;quot; | Parameters&lt;br /&gt;
|-&lt;br /&gt;
! 1&lt;br /&gt;
! 2&lt;br /&gt;
! 3&lt;br /&gt;
! 4&lt;br /&gt;
! 5&lt;br /&gt;
! 6&lt;br /&gt;
|-&lt;br /&gt;
![[char](Event)]&lt;br /&gt;
|Fired when text is typed on the keyboard&lt;br /&gt;
|the letter typed&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
![[key]]&lt;br /&gt;
|Fired when a key is pressed on the keyboard&lt;br /&gt;
|numerical keycode&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
![[timer]]&lt;br /&gt;
|Fired when a timeout started by os.startTimer() completes&lt;br /&gt;
|Value of the timer as returned by os.startTimer()&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
![[alarm]]&lt;br /&gt;
|Fired when a time passed to os.setAlarm() is reached&lt;br /&gt;
|Value of the alarm as returned by os.setAlarm()&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
![[redstone]]&lt;br /&gt;
|Fired when the state of any of the redstone inputs change&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
![[disk]]&lt;br /&gt;
|Fired when a disk is inserted into an adjacent disk drive&lt;br /&gt;
|side&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
![[disk_eject]]&lt;br /&gt;
|Fired when a disk is removed from an adjacent disk drive&lt;br /&gt;
|side&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
![[peripheral]]&lt;br /&gt;
|Fired when peripheral is attached&lt;br /&gt;
|side&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
![[peripheral_detach]]&lt;br /&gt;
|Fired when peripheral is removed&lt;br /&gt;
|side&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
![[rednet_message]]&lt;br /&gt;
|Fired when a rednet message is received from the [[Rednet_(API)|rednet API]]&lt;br /&gt;
|senderID&lt;br /&gt;
|message&lt;br /&gt;
|distanceTravelled&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
![[http_success]]&lt;br /&gt;
|Fired when an attempt to recieve text from / post text on a website is successful&lt;br /&gt;
|url of the site&lt;br /&gt;
|text on the site&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
![[http_failure]]&lt;br /&gt;
|Fired when an attempt to recieve text from / post text on a website is unsuccessful&lt;br /&gt;
|url of the site&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
![[mouse_click]]&lt;br /&gt;
|Fired when a mouse button is pressed&lt;br /&gt;
|mouse button&lt;br /&gt;
|x coordinate&lt;br /&gt;
|y coordinate&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
![[mouse_scroll]]&lt;br /&gt;
|Fired when a mousewheel is scrolled.&lt;br /&gt;
|scroll direction (-1 for up, 1 for down)&lt;br /&gt;
|x coordinate&lt;br /&gt;
|y coordinate&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
![[mouse_drag]]&lt;br /&gt;
|Fired when the mouse is moved after clicking.&lt;br /&gt;
|x coordinate&lt;br /&gt;
|y coordinate&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== Guides ==&lt;br /&gt;
[http://www.computercraft.info/forums2/index.php?/topic/1516-ospullevent-what-is-it-and-how-is-it-useful/page__view__findpost__p__11156 ''Onionnion's Guide on os.pullEvent()'']&lt;/div&gt;</summary>
		<author><name>YoYoYonnY</name></author>	</entry>

	<entry>
		<id>https://www.computercraft.info/wiki/index.php?title=Os.pullEvent&amp;diff=3588</id>
		<title>Os.pullEvent</title>
		<link rel="alternate" type="text/html" href="https://www.computercraft.info/wiki/index.php?title=Os.pullEvent&amp;diff=3588"/>
				<updated>2012-11-04T04:42:36Z</updated>
		
		<summary type="html">&lt;p&gt;YoYoYonnY: /* Event Types */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{lowercase}}&lt;br /&gt;
{{Function&lt;br /&gt;
 |name=os.pullEvent&lt;br /&gt;
 |args=[[string]] only-event-to-accept&lt;br /&gt;
 |api=os&lt;br /&gt;
 |returns=event, parameters&lt;br /&gt;
 |addon=ComputerCraft&lt;br /&gt;
 |desc=Yields computer until event occurs&lt;br /&gt;
 |examples=&lt;br /&gt;
{{Example&lt;br /&gt;
|desc=The program requires to wait for a keypress to do something:&lt;br /&gt;
|code=[[function]] clear()&lt;br /&gt;
    [[term.clear]]()&lt;br /&gt;
    [[term.setCursorPos]] (1,1)&lt;br /&gt;
 end&lt;br /&gt;
 while true do&lt;br /&gt;
    clear()&lt;br /&gt;
    [[print]] (&amp;quot;Press E to do something.&amp;quot;)&lt;br /&gt;
    local event, param1 = os.pullEvent (&amp;quot;char&amp;quot;) -- limit os.pullEvent to the char event&lt;br /&gt;
    if param1 == &amp;quot;e&amp;quot; then -- if the returned value was 'e'&lt;br /&gt;
        clear()&lt;br /&gt;
        [[write]] (&amp;quot;Name: &amp;quot;)&lt;br /&gt;
        local name = [[read]]()&lt;br /&gt;
        [[print]] (name)&lt;br /&gt;
        break&lt;br /&gt;
    else&lt;br /&gt;
        clear()&lt;br /&gt;
        [[print]] (&amp;quot;Wrong button!&amp;quot;)&lt;br /&gt;
        [[sleep]] (1.5) -- I don't like a whole 2 seconds but 1 second is too short&lt;br /&gt;
    end&lt;br /&gt;
 end&lt;br /&gt;
}}&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
== How it Works ==&lt;br /&gt;
When os.pullEvent() is called, regardless of whether it has variables to set, the computer is yielded until an event occurs. An event is anything the computer can use as input, such as a button being pushed on the keyboard or a redstone input.&lt;br /&gt;
When said event occurs, the event's name is placed in the first variable (the variable 'event' in the section below). With the event comes returned values, and, depending on the event type, there can be different amounts and different data types of returned values.&lt;br /&gt;
&lt;br /&gt;
For example, the event &amp;quot;char&amp;quot; returns &amp;quot;char&amp;quot; as the event and (let's say E was pressed) the first parameter will be set to &amp;quot;e&amp;quot;, although whether or not Shift was pressed can change that &amp;quot;e&amp;quot; to an &amp;quot;E&amp;quot; as well.&lt;br /&gt;
&lt;br /&gt;
The event &amp;quot;redstone&amp;quot; only returns the event type since any other information needed can be retrieved with [[redstone.getInput]].&lt;br /&gt;
&lt;br /&gt;
=== Common Syntax ===&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
event, param1, param2, param3 = os.pullEvent()&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Event Types==&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; width=&amp;quot;100%&amp;quot;&lt;br /&gt;
! rowspan=&amp;quot;2&amp;quot; | Name&lt;br /&gt;
! rowspan=&amp;quot;2&amp;quot; | Description&lt;br /&gt;
! colspan=&amp;quot;6&amp;quot; | Parameters&lt;br /&gt;
|-&lt;br /&gt;
! 1&lt;br /&gt;
! 2&lt;br /&gt;
! 3&lt;br /&gt;
! 4&lt;br /&gt;
! 5&lt;br /&gt;
! 6&lt;br /&gt;
|-&lt;br /&gt;
![[char]]&lt;br /&gt;
|Fired when text is typed on the keyboard&lt;br /&gt;
|the letter typed&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
![[key]]&lt;br /&gt;
|Fired when a key is pressed on the keyboard&lt;br /&gt;
|numerical keycode&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
![[timer]]&lt;br /&gt;
|Fired when a timeout started by os.startTimer() completes&lt;br /&gt;
|Value of the timer as returned by os.startTimer()&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
![[alarm]]&lt;br /&gt;
|Fired when a time passed to os.setAlarm() is reached&lt;br /&gt;
|Value of the alarm as returned by os.setAlarm()&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
![[redstone]]&lt;br /&gt;
|Fired when the state of any of the redstone inputs change&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
![[disk]]&lt;br /&gt;
|Fired when a disk is inserted into an adjacent disk drive&lt;br /&gt;
|side&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
![[disk_eject]]&lt;br /&gt;
|Fired when a disk is removed from an adjacent disk drive&lt;br /&gt;
|side&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
![[peripheral]]&lt;br /&gt;
|Fired when peripheral is attached&lt;br /&gt;
|side&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
![[peripheral_detach]]&lt;br /&gt;
|Fired when peripheral is removed&lt;br /&gt;
|side&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
![[rednet_message]]&lt;br /&gt;
|Fired when a rednet message is received from the [[Rednet_(API)|rednet API]]&lt;br /&gt;
|senderID&lt;br /&gt;
|message&lt;br /&gt;
|distanceTravelled&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
![[http_success]]&lt;br /&gt;
|Fired when an attempt to recieve text from / post text on a website is successful&lt;br /&gt;
|url of the site&lt;br /&gt;
|text on the site&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
![[http_failure]]&lt;br /&gt;
|Fired when an attempt to recieve text from / post text on a website is unsuccessful&lt;br /&gt;
|url of the site&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
![[mouse_click]]&lt;br /&gt;
|Fired when a mouse button is pressed&lt;br /&gt;
|mouse button&lt;br /&gt;
|x coordinate&lt;br /&gt;
|y coordinate&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
![[mouse_scroll]]&lt;br /&gt;
|Fired when a mousewheel is scrolled.&lt;br /&gt;
|scroll direction (-1 for up, 1 for down)&lt;br /&gt;
|x coordinate&lt;br /&gt;
|y coordinate&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
![[mouse_drag]]&lt;br /&gt;
|Fired when the mouse is moved after clicking.&lt;br /&gt;
|x coordinate&lt;br /&gt;
|y coordinate&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== Guides ==&lt;br /&gt;
[http://www.computercraft.info/forums2/index.php?/topic/1516-ospullevent-what-is-it-and-how-is-it-useful/page__view__findpost__p__11156 ''Onionnion's Guide on os.pullEvent()'']&lt;/div&gt;</summary>
		<author><name>YoYoYonnY</name></author>	</entry>

	<entry>
		<id>https://www.computercraft.info/wiki/index.php?title=Turtle.getFuelLevel&amp;diff=2817</id>
		<title>Turtle.getFuelLevel</title>
		<link rel="alternate" type="text/html" href="https://www.computercraft.info/wiki/index.php?title=Turtle.getFuelLevel&amp;diff=2817"/>
				<updated>2012-09-05T19:06:43Z</updated>
		
		<summary type="html">&lt;p&gt;YoYoYonnY: Created page with &amp;quot;&amp;lt;table style=&amp;quot;width: 70%; border: solid 2px black; margin: 2px; padding: .3em; border-spacing: 0px;&amp;quot;&amp;gt; &amp;lt;tr&amp;gt;&amp;lt;td colspan=&amp;quot;2&amp;quot; style=&amp;quot;font-weight: bold; font-size: large; padding-b...&amp;quot;&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&amp;lt;table style=&amp;quot;width: 70%; border: solid 2px black; margin: 2px; padding: .3em; border-spacing: 0px;&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&amp;lt;td colspan=&amp;quot;2&amp;quot; style=&amp;quot;font-weight: bold; font-size: large; padding-bottom: .3em; border-bottom: solid black 1px;&amp;quot;&amp;gt;Function turtle.getFuelLevel&amp;lt;/td&amp;gt;&amp;lt;/tr&amp;gt;&lt;br /&gt;
&amp;lt;tr style=&amp;quot;background-color: #E8E8E8;&amp;quot;&amp;gt;&amp;lt;td style=&amp;quot;border-right: solid black 1px; padding: .2em; width: 10%; font-weight: bold;&amp;quot;&amp;gt;Syntax&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td style=&amp;quot;border-color: black; padding: .2em; padding-left: .4em;&amp;quot;&amp;gt;turtle.getFuelLevel()&amp;lt;/td&amp;gt;&amp;lt;/tr&amp;gt;&lt;br /&gt;
&amp;lt;tr style=&amp;quot;background-color: #FFFFFF;&amp;quot;&amp;gt;&amp;lt;td style=&amp;quot;border-right: solid black 1px; padding: .2em; width: 10%; font-weight: bold;&amp;quot;&amp;gt;Returns&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td style=&amp;quot;border-color: black; padding: .2em; padding-left: .4em;&amp;quot;&amp;gt; &amp;quot;unlimited&amp;quot; if [[disabled fuel]], else the fuel level.&amp;lt;/td&amp;gt;&amp;lt;/tr&amp;gt;&lt;br /&gt;
&amp;lt;tr style=&amp;quot;background-color: #E8E8E8;&amp;quot;&amp;gt;&amp;lt;td style=&amp;quot;border-right: solid black 1px; padding: .2em; width: 10%; font-weight: bold;&amp;quot;&amp;gt;Part of&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td style=&amp;quot;border-color: black; padding: .2em; padding-left: .4em;&amp;quot;&amp;gt;[[ComputerCraft]]&amp;lt;/td&amp;gt;&amp;lt;/tr&amp;gt;&lt;br /&gt;
&amp;lt;tr style=&amp;quot;background-color: #FFFFFF;&amp;quot;&amp;gt;&amp;lt;td style=&amp;quot;border-right: solid black 1px; padding: .2em; width: 10%; font-weight: bold;&amp;quot;&amp;gt;API&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td style=&amp;quot;border-color: black; padding: .2em; padding-left: .4em;&amp;quot;&amp;gt;[[turtle]]&amp;lt;/td&amp;gt;&amp;lt;/tr&amp;gt;&lt;br /&gt;
&amp;lt;tr style=&amp;quot;background-color: #E8E8E8;&amp;quot;&amp;gt;&amp;lt;td style=&amp;quot;border-right: solid black 1px; padding: .2em; width: 10%; font-weight: bold;&amp;quot;&amp;gt;Description&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td style=&amp;quot;border-color: black; padding: .2em; padding-left: .4em;&amp;quot;&amp;gt;Returns the fuel level.&amp;lt;/td&amp;gt;&amp;lt;/tr&amp;gt;&lt;br /&gt;
&amp;lt;/table&amp;gt;&lt;br /&gt;
&amp;lt;h2&amp;gt; &amp;lt;span class=&amp;quot;mw-headline&amp;quot; id=&amp;quot;Examples&amp;quot;&amp;gt; Examples &amp;lt;/span&amp;gt;&amp;lt;/h2&amp;gt;&lt;br /&gt;
&amp;lt;table style=&amp;quot;border-spacing: 0px;&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&lt;br /&gt;
&amp;lt;td style=&amp;quot;padding-right: .5em; border-right: solid #DDD 1px; border-bottom: solid #DDD 1px;&amp;quot;&amp;gt;&amp;lt;b&amp;gt;Description&amp;lt;/b&amp;gt;&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td style=&amp;quot;padding-left: .5em; border-bottom: solid #DDD 1px;&amp;quot;&amp;gt;Fills the turtle with fuel if the fuel tank is empty&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;/tr&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&lt;br /&gt;
&amp;lt;td style=&amp;quot;padding-right: .5em; border-right: solid #DDD 1px;&amp;quot;&amp;gt;&amp;lt;b&amp;gt;Code&amp;lt;/b&amp;gt;&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td style=&amp;quot;padding-left: .5em;&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;pre&amp;gt;if turtle.getFuelLevel() &amp;lt; 1&lt;br /&gt;
 turtle.refuel()&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;/tr&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&lt;br /&gt;
&amp;lt;td style=&amp;quot;padding-right: .5em; border-right: solid #DDD 1px;&amp;quot;&amp;gt;&amp;lt;b&amp;gt;Output&amp;lt;/b&amp;gt;&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td style=&amp;quot;padding-left: .5em;&amp;quot;&amp;gt;Checks if the fuel tank is empty, if it is, it will fill the tank, else it wont do anything.&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;/tr&amp;gt;&lt;br /&gt;
&amp;lt;/table&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Uses ==&lt;br /&gt;
&lt;br /&gt;
Turtle.getFuelLevel is usefull for [http://computercraft.info/wiki/index.php?title=Turtle_Lumberjack_(tutorial) Turtle Lumberjacks]&lt;br /&gt;
Lets say you don't want to use more fuel than you need.&lt;br /&gt;
 if turtle.getFuelLevel &amp;lt; 1&lt;br /&gt;
  turtle.refuel(1)&lt;br /&gt;
 end&lt;br /&gt;
&lt;br /&gt;
'''Output'''&lt;br /&gt;
&lt;br /&gt;
if the fuel tank is empty, i will give myself new fuel.&lt;br /&gt;
&lt;br /&gt;
a verry simple code.&lt;br /&gt;
&lt;br /&gt;
there are plenty kinds of uses.&lt;br /&gt;
try it yourself!&lt;/div&gt;</summary>
		<author><name>YoYoYonnY</name></author>	</entry>

	<entry>
		<id>https://www.computercraft.info/wiki/index.php?title=Clear&amp;diff=2792</id>
		<title>Clear</title>
		<link rel="alternate" type="text/html" href="https://www.computercraft.info/wiki/index.php?title=Clear&amp;diff=2792"/>
				<updated>2012-09-02T16:51:17Z</updated>
		
		<summary type="html">&lt;p&gt;YoYoYonnY: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;br /&gt;
== Clear ==&lt;br /&gt;
&lt;br /&gt;
Clear is a program in computercraft.&lt;br /&gt;
You may want to use it in a script like:&lt;br /&gt;
  shell.run('clear')&lt;br /&gt;
  print 'Your screen is emtpy new!'&lt;br /&gt;
This clears the screen so you can write a text&lt;br /&gt;
&lt;br /&gt;
Clear is usefull becaus you don't have to enter a code like:&lt;br /&gt;
  if turtle then&lt;br /&gt;
   a = 11&lt;br /&gt;
  else&lt;br /&gt;
   a = 17&lt;br /&gt;
  end&lt;br /&gt;
  print 'Your screen is emtpy new!'&lt;br /&gt;
  i = 0&lt;br /&gt;
  repeat&lt;br /&gt;
   print ' '&lt;br /&gt;
   i = i + 1&lt;br /&gt;
  until i == a&lt;br /&gt;
You see, a huge code!&lt;br /&gt;
New lets use a api that generate like clear:&lt;br /&gt;
  term.setCursorPos(term.getSize)&lt;br /&gt;
  term.clear()&lt;br /&gt;
  term.setCursorPos(1,1)&lt;br /&gt;
a smaller code and it works for Turtle '''AND''' CraftOS&lt;br /&gt;
&lt;br /&gt;
== term.clear() ==&lt;br /&gt;
&lt;br /&gt;
New lets look to the api.&lt;br /&gt;
How does it work?&lt;br /&gt;
Can it clear the whole screen if the cursor is in the midle?&lt;br /&gt;
&lt;br /&gt;
No it cant!&lt;br /&gt;
&lt;br /&gt;
If you place it in the midle, anything behind the cursor would not be deleted!&lt;br /&gt;
&lt;br /&gt;
Thats where getSize comes in.&lt;br /&gt;
It checks how grand the screen is(default 50,18).&lt;br /&gt;
&lt;br /&gt;
So it always clears the exact screen and not less or more!&lt;/div&gt;</summary>
		<author><name>YoYoYonnY</name></author>	</entry>

	<entry>
		<id>https://www.computercraft.info/wiki/index.php?title=Clear&amp;diff=2791</id>
		<title>Clear</title>
		<link rel="alternate" type="text/html" href="https://www.computercraft.info/wiki/index.php?title=Clear&amp;diff=2791"/>
				<updated>2012-09-02T16:50:36Z</updated>
		
		<summary type="html">&lt;p&gt;YoYoYonnY: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;br /&gt;
== Clear ==&lt;br /&gt;
&lt;br /&gt;
Clear is a program in computercraft.&lt;br /&gt;
You may want to use it in a script like:&lt;br /&gt;
  shell.run('clear')&lt;br /&gt;
  print 'Your screen is emtpy new!'&lt;br /&gt;
This clears the screen so you can write a text&lt;br /&gt;
&lt;br /&gt;
Clear is usefull becaus you don't have to enter a code like:&lt;br /&gt;
  if turtle then&lt;br /&gt;
   a = 11&lt;br /&gt;
  else&lt;br /&gt;
   a = 17&lt;br /&gt;
  end&lt;br /&gt;
  print 'Your screen is emtpy new!'&lt;br /&gt;
  i = 0&lt;br /&gt;
  repeat&lt;br /&gt;
   print ' '&lt;br /&gt;
   i = i + 1&lt;br /&gt;
  until i == a&lt;br /&gt;
You see, a huge code!&lt;br /&gt;
New lets use a api that generate like clear:&lt;br /&gt;
  term.setCursorPos(term.getSize)&lt;br /&gt;
  term.clear()&lt;br /&gt;
  term.setCursorPos(1,1)&lt;br /&gt;
a smaller code and it works for Turtle '''AND''' CraftOS&lt;br /&gt;
&lt;br /&gt;
== term.clear() ==&lt;br /&gt;
&lt;br /&gt;
New lets look to the api.&lt;br /&gt;
&lt;br /&gt;
How does it work?&lt;br /&gt;
&lt;br /&gt;
Can it clear the whole screen if the cursor is in the midle?&lt;br /&gt;
&lt;br /&gt;
No it cant!&lt;br /&gt;
&lt;br /&gt;
If you place it in the midle, anything behind the cursor would not be deleted!&lt;br /&gt;
&lt;br /&gt;
Thats where getSize comes in.&lt;br /&gt;
&lt;br /&gt;
It checks how grand the screen is(default 50,18)&lt;br /&gt;
&lt;br /&gt;
So it always clears the exact screen and not less or more!&lt;/div&gt;</summary>
		<author><name>YoYoYonnY</name></author>	</entry>

	<entry>
		<id>https://www.computercraft.info/wiki/index.php?title=Clear&amp;diff=2790</id>
		<title>Clear</title>
		<link rel="alternate" type="text/html" href="https://www.computercraft.info/wiki/index.php?title=Clear&amp;diff=2790"/>
				<updated>2012-09-02T16:50:00Z</updated>
		
		<summary type="html">&lt;p&gt;YoYoYonnY: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;br /&gt;
== Clear ==&lt;br /&gt;
&lt;br /&gt;
Clear is a program in computercraft.&lt;br /&gt;
You may want to use it in a script like:&lt;br /&gt;
  shell.run('clear')&lt;br /&gt;
  print 'Your screen is emtpy new!'&lt;br /&gt;
This clears the screen so you can write a text&lt;br /&gt;
&lt;br /&gt;
Clear is usefull becaus you don't have to enter a code like:&lt;br /&gt;
  if turtle then&lt;br /&gt;
   a = 11&lt;br /&gt;
  else&lt;br /&gt;
   a = 17&lt;br /&gt;
  end&lt;br /&gt;
  print 'Your screen is emtpy new!'&lt;br /&gt;
  i = 0&lt;br /&gt;
  repeat&lt;br /&gt;
   print ' '&lt;br /&gt;
   i = i + 1&lt;br /&gt;
  until i == a&lt;br /&gt;
You see, a huge code!&lt;br /&gt;
New lets use a api that generate like clear:&lt;br /&gt;
  term.setCursorPos(term.getSize)&lt;br /&gt;
  term.clear()&lt;br /&gt;
  term.setCursorPos(1,1)&lt;br /&gt;
a smaller code and it works for Turtle '''AND''' CraftOS&lt;br /&gt;
&lt;br /&gt;
== term.clear() ==&lt;br /&gt;
&lt;br /&gt;
New lets look to the api.&lt;br /&gt;
How does it work?&lt;br /&gt;
Can it clear the whole screen if the cursor is in the midle?&lt;br /&gt;
No it cant!&lt;br /&gt;
If you place it in the midle, anything behind the cursor would not be deleted!&lt;br /&gt;
Thats where getSize comes in.&lt;br /&gt;
It checks how grand the screen is(default 50,18)&lt;br /&gt;
So it always clears the exact screen and not less or more!&lt;/div&gt;</summary>
		<author><name>YoYoYonnY</name></author>	</entry>

	<entry>
		<id>https://www.computercraft.info/wiki/index.php?title=Clear&amp;diff=2789</id>
		<title>Clear</title>
		<link rel="alternate" type="text/html" href="https://www.computercraft.info/wiki/index.php?title=Clear&amp;diff=2789"/>
				<updated>2012-09-02T16:45:16Z</updated>
		
		<summary type="html">&lt;p&gt;YoYoYonnY: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;br /&gt;
== Clear ==&lt;br /&gt;
&lt;br /&gt;
Clear is a program in computercraft.&lt;br /&gt;
You may want to use it in a script like:&lt;br /&gt;
  shell.run('clear')&lt;br /&gt;
  print 'Your screen is emtpy new!'&lt;br /&gt;
This clears the screen so you can write a text&lt;br /&gt;
&lt;br /&gt;
Clear is usefull becaus you don't have to enter a code like:&lt;br /&gt;
  if turtle then&lt;br /&gt;
   a = 11&lt;br /&gt;
  else&lt;br /&gt;
   a = 17&lt;br /&gt;
  end&lt;br /&gt;
  print 'Your screen is emtpy new!'&lt;br /&gt;
  i = 0&lt;br /&gt;
  repeat&lt;br /&gt;
   print ' '&lt;br /&gt;
   i = i + 1&lt;br /&gt;
  until i == a&lt;br /&gt;
You see, a huge code!&lt;br /&gt;
New lets use a api that generate like clear:&lt;br /&gt;
  term.setCursorPos(term.getCursorPos)&lt;br /&gt;
  term.clear()&lt;br /&gt;
  term.setCursorPos(1,1)&lt;br /&gt;
a smaller code and it works for Turtle '''AND''' CraftOS&lt;/div&gt;</summary>
		<author><name>YoYoYonnY</name></author>	</entry>

	<entry>
		<id>https://www.computercraft.info/wiki/index.php?title=Clear&amp;diff=2788</id>
		<title>Clear</title>
		<link rel="alternate" type="text/html" href="https://www.computercraft.info/wiki/index.php?title=Clear&amp;diff=2788"/>
				<updated>2012-09-02T16:44:14Z</updated>
		
		<summary type="html">&lt;p&gt;YoYoYonnY: Created page with &amp;quot; == Clear ==  Clear is a program in computercraft. You may want to use it in a script like:   shell.run('clear')   print 'Your screen is emtpy new!' This clears the screen so ...&amp;quot;&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;br /&gt;
== Clear ==&lt;br /&gt;
&lt;br /&gt;
Clear is a program in computercraft.&lt;br /&gt;
You may want to use it in a script like:&lt;br /&gt;
  shell.run('clear')&lt;br /&gt;
  print 'Your screen is emtpy new!'&lt;br /&gt;
This clears the screen so you can write a text&lt;br /&gt;
&lt;br /&gt;
Clear is usefull becaus you don't have to enter a code like:&lt;br /&gt;
  if turtle then&lt;br /&gt;
   print 'Your screen is emtpy new!'&lt;br /&gt;
   i = 0&lt;br /&gt;
   repeat&lt;br /&gt;
    print ' '&lt;br /&gt;
    i = i + 1&lt;br /&gt;
   until i == 11&lt;br /&gt;
  else&lt;br /&gt;
   print 'Your screen is emtpy new!'&lt;br /&gt;
   i = 0&lt;br /&gt;
   repeat&lt;br /&gt;
    print ' '&lt;br /&gt;
    i = i + 1&lt;br /&gt;
   until i == 17&lt;br /&gt;
  end&lt;br /&gt;
You see, a huge code!&lt;br /&gt;
New lets use a api that generate like clear:&lt;br /&gt;
  term.setCursorPos(term.getCursorPos)&lt;br /&gt;
  term.clear()&lt;br /&gt;
  term.setCursorPos(1,1)&lt;br /&gt;
a smaller code and it works for Turtle '''AND''' CraftOS&lt;/div&gt;</summary>
		<author><name>YoYoYonnY</name></author>	</entry>

	<entry>
		<id>https://www.computercraft.info/wiki/index.php?title=Shell.run&amp;diff=2787</id>
		<title>Shell.run</title>
		<link rel="alternate" type="text/html" href="https://www.computercraft.info/wiki/index.php?title=Shell.run&amp;diff=2787"/>
				<updated>2012-09-02T15:49:54Z</updated>
		
		<summary type="html">&lt;p&gt;YoYoYonnY: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;while true do&lt;br /&gt;
print 'Hello!'&lt;br /&gt;
end&lt;/div&gt;</summary>
		<author><name>YoYoYonnY</name></author>	</entry>

	<entry>
		<id>https://www.computercraft.info/wiki/index.php?title=Shell.run&amp;diff=2786</id>
		<title>Shell.run</title>
		<link rel="alternate" type="text/html" href="https://www.computercraft.info/wiki/index.php?title=Shell.run&amp;diff=2786"/>
				<updated>2012-09-02T15:48:44Z</updated>
		
		<summary type="html">&lt;p&gt;YoYoYonnY: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;-- while true do&lt;br /&gt;
-- print 'Hello!'&lt;br /&gt;
-- end&lt;/div&gt;</summary>
		<author><name>YoYoYonnY</name></author>	</entry>

	<entry>
		<id>https://www.computercraft.info/wiki/index.php?title=Shell.run&amp;diff=2785</id>
		<title>Shell.run</title>
		<link rel="alternate" type="text/html" href="https://www.computercraft.info/wiki/index.php?title=Shell.run&amp;diff=2785"/>
				<updated>2012-09-02T15:47:43Z</updated>
		
		<summary type="html">&lt;p&gt;YoYoYonnY: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;if true do&lt;br /&gt;
 --code here&lt;br /&gt;
end&lt;/div&gt;</summary>
		<author><name>YoYoYonnY</name></author>	</entry>

	<entry>
		<id>https://www.computercraft.info/wiki/index.php?title=Shell.run&amp;diff=2784</id>
		<title>Shell.run</title>
		<link rel="alternate" type="text/html" href="https://www.computercraft.info/wiki/index.php?title=Shell.run&amp;diff=2784"/>
				<updated>2012-09-02T15:47:00Z</updated>
		
		<summary type="html">&lt;p&gt;YoYoYonnY: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;br /&gt;
== Shell.run ==&lt;/div&gt;</summary>
		<author><name>YoYoYonnY</name></author>	</entry>

	<entry>
		<id>https://www.computercraft.info/wiki/index.php?title=Shell.run&amp;diff=2783</id>
		<title>Shell.run</title>
		<link rel="alternate" type="text/html" href="https://www.computercraft.info/wiki/index.php?title=Shell.run&amp;diff=2783"/>
				<updated>2012-09-02T15:45:30Z</updated>
		
		<summary type="html">&lt;p&gt;YoYoYonnY: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[Link title]]&lt;/div&gt;</summary>
		<author><name>YoYoYonnY</name></author>	</entry>

	<entry>
		<id>https://www.computercraft.info/wiki/index.php?title=Shell.run&amp;diff=2782</id>
		<title>Shell.run</title>
		<link rel="alternate" type="text/html" href="https://www.computercraft.info/wiki/index.php?title=Shell.run&amp;diff=2782"/>
				<updated>2012-09-02T15:44:43Z</updated>
		
		<summary type="html">&lt;p&gt;YoYoYonnY: Created page with &amp;quot; == Headline text ==&amp;quot;&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;br /&gt;
== Headline text ==&lt;/div&gt;</summary>
		<author><name>YoYoYonnY</name></author>	</entry>

	<entry>
		<id>https://www.computercraft.info/wiki/index.php?title=Shell.programs&amp;diff=2761</id>
		<title>Shell.programs</title>
		<link rel="alternate" type="text/html" href="https://www.computercraft.info/wiki/index.php?title=Shell.programs&amp;diff=2761"/>
				<updated>2012-09-01T10:29:37Z</updated>
		
		<summary type="html">&lt;p&gt;YoYoYonnY: Blanked the page&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;/div&gt;</summary>
		<author><name>YoYoYonnY</name></author>	</entry>

	<entry>
		<id>https://www.computercraft.info/wiki/index.php?title=Shell.programs&amp;diff=2760</id>
		<title>Shell.programs</title>
		<link rel="alternate" type="text/html" href="https://www.computercraft.info/wiki/index.php?title=Shell.programs&amp;diff=2760"/>
				<updated>2012-09-01T10:28:31Z</updated>
		
		<summary type="html">&lt;p&gt;YoYoYonnY: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;br /&gt;
== Help! ==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;nowiki&amp;gt;Help!&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
Help!&lt;/div&gt;</summary>
		<author><name>YoYoYonnY</name></author>	</entry>

	<entry>
		<id>https://www.computercraft.info/wiki/index.php?title=Shell.programs&amp;diff=2759</id>
		<title>Shell.programs</title>
		<link rel="alternate" type="text/html" href="https://www.computercraft.info/wiki/index.php?title=Shell.programs&amp;diff=2759"/>
				<updated>2012-09-01T10:27:57Z</updated>
		
		<summary type="html">&lt;p&gt;YoYoYonnY: Created page with &amp;quot;Help!&amp;quot;&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Help!&lt;/div&gt;</summary>
		<author><name>YoYoYonnY</name></author>	</entry>

	</feed>