How it works...

Let's start by introducing the structures that participate in this example:

  • PlayerStatus is an enumerator for maintaining a global state on the player's instance. The variants are:
    • Loading, which is the initial state
    • Default, which is applied after we are done loading the player's stats
    • Jumping is a special state that won't allow us to add points to the player's scoreboard due to the rules of the game
  • Player holds our player's main attributes, along with a special attribute called ticks that stores the amount of cycles that we want to run through with poll() before assigning the player's status from Loading to Default.

Now, onto our implementations:

  • Jumping down to the fn set_status(&mut self, status: PlayerStatus) -> FutureResult<&mut Self, Never> function on our Player structure, we will notice a return value of FutureResult, which tells futures that this function will immediately return a computed value from the result(), ok(), or err() functions from futures::futures.  This is useful for quickly prototyping our application while being able to utilize our executors and futures combinators.
  • At the fn add_points(&mut self, points: u32) -> Async<&mut Self> function we return our Async value immediately, since we currently do not have a server to use, but we would implement the Async<T> value over FutureResult for functions that require computations asynchronously.
  • We mimic the time it takes for a network request using our player's ticks attribute. Poll<I, E> will keep executing as long as we are returning Async::Pending (line [x]).  The executor needs to know whether or not a task needs to be polled again. The task's Waker trait is what handles these notifications, and we can manually invoke it using cx.waker().wake() on line 83 . Once our player's ticks attribute reaches zero we send an Async::Ready(self) signal, which tells the executor to no longer poll this function.

For our async_add_points() helper method:

  • We return Box<Future<Item = Player, Error = Never> + Send, which tells futures that this function will eventually return a value of Player (since we Never return an error).
  • The + Send part of the return is not necessary for our current code base, but in the future, we may want to offload some of these tasks onto other threads which executors require. Spawning across threads requires us to return the futures::prelude::Never type as an error and a 'static variable as well. 
  • When calling future functions with combinators (such as then and and_then), we will need to return a Never error type or the same error type as every other future function that is being called within the same combinator flow.

Finally, onto our main block:

  • We use the futures::future::join_all function, which accepts any IntoIterator that contains all InfoFuture trait elements (which should be all future functions). This either collects and returns Vec<T> sorted FIFO, or cancels executing as soon as the first error returns from any of the future functions within the collection, which becomes the returning value for the join_all() call.
  • then() and and_then() are combinators that internally use future::Chain and return a Future trait value, which allows us to add more combinators if we wanted. See the Using combinators and utilities section for more information on combinators.
  • block_on() is an executor method that handles any future function or value as its input and returns a Result<Future::Item, Future::Error>. When running this method, the function containing the method will block until the future(s) have been completed. Spawned tasks will execute on the default executor, but they may not be completed before block_on finishes its task(s). If block_on() finishes before the spawned tasks, then those spawned tasks will be dropped.
  • We can also use block_on() as a quick way to run our cycles/ticks and execute task(s), which invokes our poll() functions. We used this method on line 124 for initially loading players onto the game.
..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
18.220.237.24