Note that there are some explanatory texts on larger screens.

plurals
  1. PO
    text
    copied!<p>Here's a sample of some code I've been working on that uses the approach of returning a copy rather than mutating state directly. The nice thing about this kind of approach, on the server side at least, is that it enables me to easily implement transaction-type semantics. If something goes wrong while doing an update, it's trivial for me to still have everything that was updated in a consistent state.</p> <p>The code below is from a game server I'm working on, which does something similar to what you're doing, it's for tracking objects that are moving around in time slices. This approach isn't as spectacular as what Dave Griffith suggests, but it may be of some use to you for contemplation.</p> <pre><code>case class PosController( pos: Vector3 = Vector3.zero, maxSpeed: Int = 90, velocity: Vector3 = Vector3.zero, target: Vector3 = Vector3.zero ) { def moving = !velocity.isZero def update(elapsed: Double) = { if (!moving) this else { val proposedMove = velocity * elapsed // If we're about to overshoot, then stop at the exact position. if (proposedMove.mag2 &gt; pos.dist2(target)) copy(velocity = Vector3.zero, pos = target) else copy(pos = pos + proposedMove) } } def setTarget(p: Vector3) = { if (p == pos) this else { // For now, go immediately to max velocity in the correct direction. val direction = (p - pos).norm val newVel = direction * maxSpeed copy(velocity = direction * maxSpeed, target = p) } } def setTargetRange(p: Vector3, range: Double) = { val delta = p - pos // Already in range? if (delta.mag2 &lt; range * range) this else { // We're not in range. Select a spot on a line between them and us, at max range. val d = delta.norm * range setTarget(p - d) } } def eta = if (!moving) 0.0 else pos.dist(target) / maxSpeed } </code></pre> <p>One nice thing about case classes in Scala is that they create the copy() method for you-- you just pass in which parameters have changed, and the others retain the same value. You can code this by hand if you're not using case classes, but you need to remember to update the copy method whenever you change what values are present in the class.</p> <p>Regarding resources, what really made a difference for me was spending some time doing things in Erlang, where there is basically no choice but to use immutable state. I have two Erlang books I worked through and studied every example carefully. That, plus forcing myself to get some things done in Erlang made me a lot more comfortable with working with immutable data.</p>
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload