Skip to content

Commit e7bbf58

Browse files
authored
Merge pull request #17 from yahoo/sal/0_11_2
Don't use forced unwrapping
2 parents db3258f + 1c21da6 commit e7bbf58

File tree

7 files changed

+71
-64
lines changed

7 files changed

+71
-64
lines changed

behavior-graph/build.gradle

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -42,7 +42,7 @@ import com.vanniktech.maven.publish.SonatypeHost
4242
mavenPublishing {
4343
configure(new KotlinJvm(new JavadocJar.Dokka("dokkaHtml"), true))
4444
publishToMavenCentral(SonatypeHost.CENTRAL_PORTAL)
45-
coordinates("com.yahoo.behaviorgraph", "bgjvm", "0.11.1")
45+
coordinates("com.yahoo.behaviorgraph", "bgjvm", "0.11.2")
4646
pom {
4747
name = 'Behavior Graph'
4848
description = 'Behavior Graph lets you build your programs out of small, easily understood pieces in a way that lets the computer do more of the work for you.'

behavior-graph/src/main/kotlin/behaviorgraph/BehaviorBuilder.kt

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -163,13 +163,13 @@ class BehaviorBuilder<T: Any>(
163163
val demands: MutableList<Demandable> = mutableListOf()
164164
dynamicDemandSwitches?.let { demands.addAll(it) }
165165
if (dynamicDemandRelinkingOrder == RelinkingOrder.RelinkingOrderPrior) {
166-
supplies = listOf(dynamicDemandResource!!)
166+
dynamicDemandResource?.let { supplies = listOf(it) }
167167
} else {
168-
demands.add(dynamicDemandResource!!)
168+
dynamicDemandResource?.let { demands.add(it) }
169169
}
170170
Behavior(extent, demands, supplies) {
171171
val mutableListOfDemands = mutableListOf<Demandable?>()
172-
dynamicDemandLinks!!.invoke(it, mutableListOfDemands)
172+
dynamicDemandLinks?.invoke(it, mutableListOfDemands)
173173
mainBehavior.setDynamicDemands(mutableListOfDemands)
174174
}
175175
}
@@ -179,13 +179,13 @@ class BehaviorBuilder<T: Any>(
179179
val demands: MutableList<Demandable> = mutableListOf()
180180
dynamicSupplySwitches?.let { demands.addAll(it) }
181181
if (dynamicSupplyRelinkingOrder == RelinkingOrder.RelinkingOrderPrior) {
182-
supplies = listOf(dynamicSupplyResource!!)
182+
dynamicSupplyResource?.let { supplies = listOf(dynamicSupplyResource) }
183183
} else {
184-
demands.add(dynamicSupplyResource!!)
184+
dynamicSupplyResource?.let { demands.add(dynamicSupplyResource) }
185185
}
186186
Behavior(extent, demands, supplies) {
187187
val mutableListOfSupplies = mutableListOf<Resource?>()
188-
dynamicSupplyLinks!!.invoke(it, mutableListOfSupplies)
188+
dynamicSupplyLinks?.invoke(it, mutableListOfSupplies)
189189
mainBehavior.setDynamicSupplies(mutableListOfSupplies)
190190
}
191191
}

behavior-graph/src/main/kotlin/behaviorgraph/Extent.kt

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -61,7 +61,7 @@ open class Extent<ExtentContext: Any> @JvmOverloads constructor(val graph: Graph
6161
if (lifetime == null) {
6262
lifetime = ExtentLifetime(this)
6363
}
64-
lifetime!!.unify(extent)
64+
lifetime?.unify(extent)
6565
}
6666

6767
/**
@@ -71,14 +71,14 @@ open class Extent<ExtentContext: Any> @JvmOverloads constructor(val graph: Graph
7171
if (this.lifetime == null) {
7272
lifetime = ExtentLifetime(this)
7373
}
74-
lifetime!!.addChild(extent)
74+
lifetime?.addChild(extent)
7575
}
7676

7777
internal fun hasCompatibleLifetime(extent: Extent<*>): Boolean {
7878
if (this == extent) {
7979
return true
8080
} else if (lifetime != null) {
81-
return lifetime!!.hasCompatibleLifetime(extent.lifetime)
81+
return lifetime?.hasCompatibleLifetime(extent.lifetime) ?: false
8282
} else {
8383
return false
8484
}

behavior-graph/src/main/kotlin/behaviorgraph/ExtentLifetime.kt

Lines changed: 8 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -31,11 +31,11 @@ internal class ExtentLifetime(
3131
if (extent.lifetime != null) {
3232
// merge existing lifetimes and children into one lifetime heirarchy
3333
// move children first
34-
extent.lifetime!!.children?.forEach {(lifetime, _) ->
34+
extent.lifetime?.children?.forEach {(lifetime, _) ->
3535
addChildLifetime(lifetime)
3636
}
3737
// then make any extents in other lifetime part of this one
38-
extent.lifetime!!.extents.forEach { (it, _) ->
38+
extent.lifetime?.extents?.forEach { (it, _) ->
3939
it.lifetime = this
4040
extents[it] = true
4141
}
@@ -49,7 +49,9 @@ internal class ExtentLifetime(
4949
if (extent.lifetime == null) {
5050
extent.lifetime = ExtentLifetime(extent)
5151
}
52-
addChildLifetime(extent.lifetime!!)
52+
extent.lifetime?.let {
53+
addChildLifetime(it)
54+
}
5355
}
5456

5557
fun addChildLifetime(lifetime: ExtentLifetime) {
@@ -77,9 +79,10 @@ internal class ExtentLifetime(
7779
return true
7880
} else if (lifetime != null) {
7981
// parents
80-
if (parent != null) {
82+
val thisParent = parent
83+
if (thisParent != null) {
8184
// parent is a weak reference so we get it here
82-
val refParent = parent!!.get()
85+
val refParent = thisParent.get()
8386
if (refParent != null) {
8487
return refParent.hasCompatibleLifetime(lifetime)
8588
}

behavior-graph/src/main/kotlin/behaviorgraph/Graph.kt

Lines changed: 45 additions & 45 deletions
Original file line numberDiff line numberDiff line change
@@ -139,12 +139,13 @@ class Graph @JvmOverloads constructor(private val dateProvider: DateProvider? =
139139
// Check that an action wasn't created from inside another action or behavior.
140140
// It is easy to accidentally do an updateWithAction inside a behavior or action
141141
// We want to alert the programmer to that mistake.
142-
val wrongAction = eventLoopState != null &&
143-
eventLoopState!!.thread == Thread.currentThread() &&
144-
(eventLoopState!!.phase == EventLoopPhase.Action || eventLoopState!!.phase == EventLoopPhase.Updates)
145-
assert(
146-
!wrongAction,
147-
{ "Action cannot be created directly inside another action or behavior. Consider wrapping it in a side effect block." })
142+
eventLoopState?.let {
143+
val wrongAction = it.thread == Thread.currentThread() &&
144+
(it.phase == EventLoopPhase.Action || it.phase == EventLoopPhase.Updates)
145+
assert(
146+
!wrongAction,
147+
{ "Action cannot be created directly inside another action or behavior. Consider wrapping it in a side effect block." })
148+
}
148149
// queue up the action and start the event loop if one isn't already running
149150
actions.addLast(action)
150151
if (currentEvent == null) {
@@ -180,8 +181,8 @@ class Graph @JvmOverloads constructor(private val dateProvider: DateProvider? =
180181
modifiedSupplyBehaviors.size > 0 ||
181182
needsOrdering.size > 0
182183
) {
183-
eventLoopState!!.phase = EventLoopPhase.Updates
184-
val sequence = this.currentEvent!!.sequence
184+
eventLoopState?.phase = EventLoopPhase.Updates
185+
val sequence: Long = this.currentEvent?.sequence ?: 0
185186
addUntrackedBehaviors()
186187
addUntrackedSupplies()
187188
addUntrackedDemands(sequence)
@@ -203,9 +204,9 @@ class Graph @JvmOverloads constructor(private val dateProvider: DateProvider? =
203204
}
204205
if (effects.isNotEmpty()) {
205206
val effect = this.effects.removeFirst()
206-
eventLoopState!!.phase = EventLoopPhase.SideEffects
207-
eventLoopState!!.currentSideEffect = effect
208-
sideEffectExecutor!!.execute(effect)
207+
eventLoopState?.phase = EventLoopPhase.SideEffects
208+
eventLoopState?.currentSideEffect = effect
209+
sideEffectExecutor.execute(effect)
209210
if (eventLoopState != null) {
210211
// side effect could create a synchronous action which would create a nested event loop
211212
// which would clear out any existing event loop states
@@ -215,13 +216,13 @@ class Graph @JvmOverloads constructor(private val dateProvider: DateProvider? =
215216
}
216217

217218
currentEvent?.let { aCurrentEvent ->
218-
val eventAction = eventLoopState!!.action
219+
val eventAction = eventLoopState?.action
219220
clearTransients()
220221
lastEvent = aCurrentEvent
221222
currentEvent = null
222223
eventLoopState = null
223224
currentBehavior = null
224-
eventAction.complete()
225+
eventAction?.complete()
225226
}
226227

227228
if (actions.isNotEmpty()) {
@@ -231,7 +232,7 @@ class Graph @JvmOverloads constructor(private val dateProvider: DateProvider? =
231232
)
232233
this.currentEvent = newEvent
233234
eventLoopState = EventLoopState(action)
234-
eventLoopState!!.phase = EventLoopPhase.Action
235+
eventLoopState?.phase = EventLoopPhase.Action
235236
action.runAction()
236237
continue
237238
}
@@ -262,7 +263,7 @@ class Graph @JvmOverloads constructor(private val dateProvider: DateProvider? =
262263
val needAdding: MutableSet<Extent<*>> = mutableSetOf()
263264
for (added in extentsAdded) {
264265
if (added.lifetime != null) {
265-
for (ext in added.lifetime!!.getAllContainingExtents()) {
266+
for (ext in added.lifetime?.getAllContainingExtents() ?: listOf()) {
266267
if (ext.addedToGraphWhen == null) {
267268
needAdding.add(ext)
268269
}
@@ -279,7 +280,7 @@ class Graph @JvmOverloads constructor(private val dateProvider: DateProvider? =
279280
val needRemoving: MutableSet<Extent<*>> = mutableSetOf()
280281
for (removed in extentsRemoved) {
281282
if (removed.lifetime != null) {
282-
for (ext in removed.lifetime!!.getAllContainedExtents()) {
283+
for (ext in removed.lifetime?.getAllContainedExtents() ?: listOf()) {
283284
if (ext.addedToGraphWhen != null) {
284285
needRemoving.add(ext)
285286
}
@@ -300,7 +301,7 @@ class Graph @JvmOverloads constructor(private val dateProvider: DateProvider? =
300301
}
301302
}
302303
}
303-
if (resource.suppliedBy != null && resource.suppliedBy!!.extent.addedToGraphWhen != null) {
304+
if (resource.suppliedBy != null && resource.suppliedBy?.extent?.addedToGraphWhen != null) {
304305
assert(false) {
305306
"Remaining behaviors should remove dynamicSupplies to removed resources. \nRemaining Behavior=${resource.suppliedBy} \nRemoved resource=$resource"
306307
}
@@ -322,12 +323,12 @@ class Graph @JvmOverloads constructor(private val dateProvider: DateProvider? =
322323

323324
internal fun resourceTouched(resource: Resource) {
324325
this.currentEvent?.let { aCurrentEvent ->
325-
if (eventLoopState != null && eventLoopState!!.phase == EventLoopPhase.Action) {
326-
eventLoopState!!.actionUpdates.add(resource)
326+
if (eventLoopState != null && eventLoopState?.phase == EventLoopPhase.Action) {
327+
eventLoopState?.actionUpdates?.add(resource)
327328
}
328329
for (subsequent in resource.subsequents) {
329330
val isOrderingDemand =
330-
subsequent.orderingDemands != null && subsequent.orderingDemands!!.contains(resource)
331+
subsequent.orderingDemands != null && subsequent.orderingDemands?.contains(resource) ?: false
331332
if (!isOrderingDemand) {
332333
activateBehavior(subsequent, aCurrentEvent.sequence)
333334
}
@@ -336,7 +337,7 @@ class Graph @JvmOverloads constructor(private val dateProvider: DateProvider? =
336337
}
337338

338339
private fun activateBehavior(behavior: Behavior<*>, sequence: Long) {
339-
if (behavior.enqueuedWhen == null || behavior.enqueuedWhen!! < sequence) {
340+
if (behavior.enqueuedWhen == null || (behavior.enqueuedWhen ?: 0) < sequence) {
340341
behavior.enqueuedWhen = sequence
341342
activatedBehaviors.add(behavior)
342343
}
@@ -370,7 +371,7 @@ class Graph @JvmOverloads constructor(private val dateProvider: DateProvider? =
370371
assert(false) {
371372
"You've created a side effect from an alternate thread while another is running. Side effects should be created inside behaviors only."
372373
}
373-
} else if (eventLoopState!!.phase == EventLoopPhase.SideEffects) {
374+
} else if (eventLoopState?.phase == EventLoopPhase.SideEffects) {
374375
assert(false) {
375376
"You've created a side effect inside another side effect. Side effects should be created inside behaviors. Is this a mistake?"
376377
}
@@ -401,13 +402,12 @@ class Graph @JvmOverloads constructor(private val dateProvider: DateProvider? =
401402
}
402403

403404
val allUntrackedSupplies: MutableSet<Resource> = mutableSetOf()
404-
if (behavior.untrackedSupplies != null) {
405-
allUntrackedSupplies.addAll(behavior.untrackedSupplies!!)
405+
behavior.untrackedSupplies?.let {
406+
allUntrackedSupplies.addAll(it)
406407
}
407-
if (behavior.untrackedDynamicSupplies != null) {
408-
allUntrackedSupplies.addAll(behavior.untrackedDynamicSupplies!!)
408+
behavior.untrackedDynamicSupplies?.let {
409+
allUntrackedSupplies.addAll(it)
409410
}
410-
411411
behavior.supplies?.forEach { it.suppliedBy = null }
412412

413413
behavior.supplies = allUntrackedSupplies
@@ -446,11 +446,11 @@ class Graph @JvmOverloads constructor(private val dateProvider: DateProvider? =
446446
}
447447

448448
val allUntrackedDemands: MutableSet<Demandable> = mutableSetOf()
449-
if (behavior.untrackedDemands != null) {
450-
allUntrackedDemands.addAll(behavior.untrackedDemands!!)
449+
behavior.untrackedDemands?.let {
450+
allUntrackedDemands.addAll(it)
451451
}
452-
if (behavior.untrackedDynamicDemands != null) {
453-
allUntrackedDemands.addAll(behavior.untrackedDynamicDemands!!)
452+
behavior.untrackedDynamicDemands?.let {
453+
allUntrackedDemands.addAll(it)
454454
}
455455

456456
var removedDemands: MutableList<Resource>? = null
@@ -459,7 +459,7 @@ class Graph @JvmOverloads constructor(private val dateProvider: DateProvider? =
459459
if (removedDemands == null) {
460460
removedDemands = mutableListOf()
461461
}
462-
removedDemands!!.add(demand)
462+
removedDemands?.add(demand)
463463
}
464464
}
465465

@@ -471,7 +471,7 @@ class Graph @JvmOverloads constructor(private val dateProvider: DateProvider? =
471471
"Cannot demand a resource that hasn't been added to the graph. Demanding behavior=$behavior \nDemand=$untrackedDemand"
472472
}
473473
}
474-
if (behavior.demands == null || !behavior.demands!!.contains(untrackedDemand)) {
474+
if (behavior.demands == null || !(behavior.demands?.contains(untrackedDemand) ?: false)) {
475475
if (addedDemands == null) {
476476
addedDemands = mutableListOf()
477477
}
@@ -502,12 +502,12 @@ class Graph @JvmOverloads constructor(private val dateProvider: DateProvider? =
502502
if (newDemands == null) {
503503
newDemands = mutableSetOf()
504504
}
505-
newDemands!!.add(link.resource)
505+
newDemands?.add(link.resource)
506506
if (link.type == LinkType.Order) {
507507
if (orderingDemands == null) {
508508
orderingDemands = mutableSetOf()
509509
}
510-
orderingDemands!!.add(link.resource)
510+
orderingDemands?.add(link.resource)
511511
}
512512
}
513513
behavior.demands = newDemands
@@ -721,8 +721,8 @@ class Graph @JvmOverloads constructor(private val dateProvider: DateProvider? =
721721

722722
if (validateLifetimes) {
723723
if (extent.lifetime != null) {
724-
if (extent.lifetime!!.addedToGraphWhen == null) {
725-
extent.lifetime!!.addedToGraphWhen = currentEvent!!.sequence
724+
if (extent.lifetime?.addedToGraphWhen == null) {
725+
extent.lifetime?.addedToGraphWhen = currentEvent?.sequence
726726
}
727727
}
728728
val refParent = extent.lifetime?.parent?.get()
@@ -734,9 +734,9 @@ class Graph @JvmOverloads constructor(private val dateProvider: DateProvider? =
734734
}
735735
}
736736

737-
extent.addedToGraphWhen = currentEvent!!.sequence
737+
extent.addedToGraphWhen = currentEvent?.sequence
738738
extentsAdded.add(extent)
739-
activateBehavior(extent.didAddBehavior, currentEvent!!.sequence)
739+
activateBehavior(extent.didAddBehavior, currentEvent?.sequence ?: 0)
740740
for (behavior in extent.behaviors) {
741741
addBehavior(behavior)
742742
}
@@ -751,24 +751,24 @@ class Graph @JvmOverloads constructor(private val dateProvider: DateProvider? =
751751
}
752752
extentsRemoved.add(extent)
753753
for (behavior in extent.behaviors) {
754-
removeBehavior(behavior, currentEvent!!.sequence)
754+
removeBehavior(behavior, currentEvent?.sequence ?: 0)
755755
}
756756
extent.addedToGraphWhen = null
757757
}
758758

759759
override fun toString(): String {
760760
return buildString {
761761
if (currentEvent != null) {
762-
append(String.format("Current Event: %d\n", currentEvent!!.sequence))
762+
append(String.format("Current Event: %d\n", currentEvent?.sequence ?: 0))
763763
} else {
764764
append("No current event")
765765
}
766-
if (eventLoopState != null) {
767-
append(eventLoopState!!.toString())
766+
eventLoopState?.let {
767+
append(it.toString())
768768
append("\n")
769769
}
770-
if (currentBehavior != null) {
771-
append(currentBehavior!!.toString())
770+
currentBehavior?.let {
771+
append(it.toString())
772772
}
773773
}
774774
}

behavior-graph/src/main/kotlin/behaviorgraph/Resource.kt

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -53,7 +53,8 @@ open class Resource @JvmOverloads constructor(val extent: Extent<*>, var debugNa
5353
internal fun assertValidAccessor() {
5454
if (!graph.validateDependencies) { return }
5555
// allow access to state from alternate threads while running
56-
if (graph.eventLoopState != null && graph.eventLoopState!!.thread != Thread.currentThread()) { return }
56+
val eventLoopThread = graph.eventLoopState?.thread
57+
if (graph.eventLoopState != null && eventLoopThread != Thread.currentThread()) { return }
5758
val currentBehavior = graph.currentBehavior
5859
if (currentBehavior != null && currentBehavior != suppliedBy && !(currentBehavior.demands?.contains(this) ?: false)) {
5960
assert(false) {

behavior-graph/src/main/kotlin/behaviorgraph/State.kt

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -88,12 +88,15 @@ class State<T> @JvmOverloads constructor(extent: Extent<*>, initialState: T, deb
8888
*/
8989
fun updateForce(newValue: T) {
9090
assertValidUpdater()
91-
if (graph.currentEvent != null && currentState.event.sequence < graph.currentEvent!!.sequence) {
91+
val thisSequence = graph.currentEvent?.sequence ?: 0
92+
if (graph.currentEvent != null && currentState.event.sequence < thisSequence) {
9293
// this check prevents updating priorState if we are updated multiple times in same behavior
9394
priorStateDuringEvent = currentState
9495
}
9596

96-
currentState = StateHistory(newValue, this.graph.currentEvent!!)
97+
this.graph.currentEvent?.let {
98+
currentState = StateHistory(newValue, it)
99+
}
97100
this.graph.resourceTouched(this)
98101
this.graph.trackTransient(this)
99102
}
@@ -124,7 +127,7 @@ class State<T> @JvmOverloads constructor(extent: Extent<*>, initialState: T, deb
124127
*/
125128
fun justUpdatedFrom(fromValue: T): Boolean {
126129
return justUpdated &&
127-
(priorStateDuringEvent!!.value == fromValue)
130+
(priorStateDuringEvent?.value == fromValue)
128131
}
129132

130133
/**

0 commit comments

Comments
 (0)