Files
wren/doc/site/modules/core/fiber.markdown
T

182 lines
4.2 KiB
Markdown
Raw Normal View History

2015-01-18 15:36:36 -08:00
^title Fiber Class
2015-11-07 11:09:04 -08:00
A lightweight coroutine. [Here][fibers] is a gentle introduction.
[fibers]: ../../concurrency.html
2015-01-18 15:36:36 -08:00
2016-08-04 06:28:41 -07:00
## Static Methods
2017-09-16 21:38:35 -07:00
### Fiber.**abort**(message)
2017-10-05 06:50:45 -07:00
Raises a runtime error with the provided message:
2017-09-16 21:38:35 -07:00
:::wren
2017-10-05 06:50:45 -07:00
Fiber.abort("Something bad happened.")
2017-09-16 21:38:35 -07:00
2017-10-05 06:50:45 -07:00
If the message is `null`, does nothing.
2017-09-16 21:38:35 -07:00
2016-08-04 06:28:41 -07:00
### Fiber.**current**
The currently executing fiber.
2015-07-10 09:18:22 -07:00
### Fiber.**new**(function)
2015-01-18 15:36:36 -08:00
Creates a new fiber that executes `function` in a separate coroutine when the
fiber is run. Does not immediately start running the fiber.
:::wren
2015-07-10 09:18:22 -07:00
var fiber = Fiber.new {
2015-09-15 07:46:09 -07:00
System.print("I won't get printed")
2015-01-18 15:36:36 -08:00
}
### Fiber.**suspend**()
Pauses the current fiber, and stops the interpreter. Control returns to the
host application.
2016-05-16 08:09:14 -07:00
Typically, you store a reference to the fiber using `Fiber.current` before
calling this. The fiber can be resumed later by calling or transferring to that
reference. If there are no references to it, it is eventually garbage collected.
Much like `yield()`, returns the value passed to `call()` or `transfer()` when
the fiber is resumed.
2015-02-26 23:08:36 -08:00
### Fiber.**yield**()
2015-01-18 15:36:36 -08:00
Pauses the current fiber and transfers control to the parent fiber. "Parent"
2016-05-16 08:09:14 -07:00
here means the last fiber that was started using `call` and not `transfer`.
2015-01-18 15:36:36 -08:00
:::wren
2015-07-10 09:18:22 -07:00
var fiber = Fiber.new {
2015-09-15 07:46:09 -07:00
System.print("Before yield")
2015-02-26 23:08:36 -08:00
Fiber.yield()
2015-09-15 07:46:09 -07:00
System.print("After yield")
2015-01-18 15:36:36 -08:00
}
fiber.call() //> Before yield
System.print("After call") //> After call
fiber.call() //> After yield
2015-01-18 15:36:36 -08:00
2015-02-26 23:08:36 -08:00
When resumed, the parent fiber's `call()` method returns `null`.
2015-01-18 15:36:36 -08:00
2016-05-16 08:09:14 -07:00
If a yielded fiber is resumed by calling `call()` or `transfer()` with an
argument, `yield()` returns that value.
2015-01-18 15:36:36 -08:00
:::wren
2015-07-10 09:18:22 -07:00
var fiber = Fiber.new {
System.print(Fiber.yield()) //> value
2015-01-18 15:36:36 -08:00
}
2015-02-26 23:08:36 -08:00
fiber.call() // Run until the first yield.
2015-01-18 15:36:36 -08:00
fiber.call("value") // Resume the fiber.
2016-05-16 08:09:14 -07:00
If it was resumed by calling `call()` or `transfer()` with no argument, it
returns `null`.
2015-01-18 15:36:36 -08:00
If there is no parent fiber to return to, this exits the interpreter. This can
be useful to pause execution until the host application wants to resume it
later.
2015-01-18 15:36:36 -08:00
:::wren
Fiber.yield()
2015-09-15 07:46:09 -07:00
System.print("this does not get reached")
2015-01-18 15:36:36 -08:00
### Fiber.**yield**(value)
Similar to `Fiber.yield` but provides a value to return to the parent fiber's
`call`.
:::wren
2015-07-10 09:18:22 -07:00
var fiber = Fiber.new {
2015-01-18 15:36:36 -08:00
Fiber.yield("value")
}
System.print(fiber.call()) //> value
2015-01-18 15:36:36 -08:00
2015-03-27 07:43:36 -07:00
## Methods
2015-02-26 23:08:36 -08:00
### **call**()
2015-01-18 15:36:36 -08:00
2015-04-22 07:45:20 -07:00
Starts or resumes the fiber if it is in a paused state.
2015-04-04 16:50:40 -07:00
:::wren
2015-07-10 09:18:22 -07:00
var fiber = Fiber.new {
2015-09-15 07:46:09 -07:00
System.print("Fiber called")
2015-04-04 16:50:40 -07:00
Fiber.yield()
2015-09-15 07:46:09 -07:00
System.print("Fiber called again")
2015-04-04 16:50:40 -07:00
}
2015-04-22 07:45:20 -07:00
fiber.call() // Start it.
fiber.call() // Resume after the yield() call.
When the called fiber yields, control is transferred back to the fiber that
called it.
If the called fiber is resuming from a yield, the `yield()` method returns
`null` in the called fiber.
:::wren
2015-07-10 09:18:22 -07:00
var fiber = Fiber.new {
2015-09-15 07:46:09 -07:00
System.print(Fiber.yield())
2015-04-22 07:45:20 -07:00
}
2015-04-04 16:50:40 -07:00
fiber.call()
fiber.call() //> null
2015-01-18 15:36:36 -08:00
### **call**(value)
2015-04-04 16:50:40 -07:00
Invokes the fiber or resumes the fiber if it is in a paused state and sets
`value` as the returned value of the fiber's call to `yield`.
:::wren
2015-07-10 09:18:22 -07:00
var fiber = Fiber.new {
2015-09-15 07:46:09 -07:00
System.print(Fiber.yield())
2015-04-04 16:50:40 -07:00
}
2015-04-22 07:45:20 -07:00
2015-04-04 16:50:40 -07:00
fiber.call()
fiber.call("value") //> value
2015-01-18 15:36:36 -08:00
2017-09-16 21:38:35 -07:00
### **error***
2017-10-05 06:50:45 -07:00
The error message that was passed when aborting the fiber, or `null` if the
fiber has not been aborted.
2017-09-16 21:38:35 -07:00
:::wren
var fiber = Fiber.new {
123.badMethod
}
fiber.try()
System.print(fiber.error) //> Num does not implement method 'badMethod'.
2015-01-18 15:36:36 -08:00
### **isDone**
Whether the fiber's main function has completed and the fiber can no longer be
run. This returns `false` if the fiber is currently running or has yielded.
### **transfer**()
2015-01-18 15:36:36 -08:00
2017-09-16 21:38:35 -07:00
### **try**()
Tries to run the fiber. If a runtime error occurs
in the called fiber, the error is captured and is returned as a string.
:::wren
var fiber = Fiber.new {
123.badMethod
}
var error = fiber.try()
System.print("Caught error: " + error)
If the called fiber raises an error, it can no longer be used.
2015-01-18 15:36:36 -08:00
**TODO**
### **transfer**(value)
2015-01-18 15:36:36 -08:00
**TODO**
### **transferError**(error)
**TODO**