Skip to content

Commit

Permalink
Finished LiveWindow implementation
Browse files Browse the repository at this point in the history
  • Loading branch information
retrodaredevil committed Nov 28, 2019
1 parent f46e5be commit 62db5b1
Show file tree
Hide file tree
Showing 20 changed files with 149 additions and 58 deletions.
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,4 +2,4 @@
An abstraction of NetworkTables, Shuffleboard, SmartDashboard, and LiveWindow

### TODO
* Have master object to hold instances of important stuff
* Nothing right now!

This file was deleted.

Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,13 @@ import com.first1444.dashboard.ActiveComponent
import com.first1444.dashboard.BasicDashboard
import com.first1444.dashboard.enable.EnabledProvider

class ActuatorSendable(
class ActuatorSendable
/**
* @param sendable The [Sendable] that will be used
* @param enabledProvider The [EnabledProvider] that that enables or disabled [sendable]
* @param reportActuator true to set `.actuator` to true, false to leave unspecified.
*/
constructor(
private val sendable: Sendable<*>,
private val enabledProvider: EnabledProvider,
private val reportActuator: Boolean
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -25,9 +25,9 @@ class BasicAdvancedDashboard(
while(iterator.hasNext()){
val (name, component) = iterator.next()
if(component == activeComponent){
basicDashboard.delete(name)
activeComponent.onRemove()
iterator.remove()
basicDashboard.delete(name) // deletes the dashboard that activeComponent was using
iterator.remove() // removes from componentMap
return true
}
}
Expand Down

This file was deleted.

Original file line number Diff line number Diff line change
Expand Up @@ -19,12 +19,12 @@ open class SendableHelper(
* Sets the dashboard type. AKA the SmartDashboard type
*/
@set:JvmSynthetic
var dashboardType: String
var type: String
get() = dashboard[".type"].getter.getString("")
set(value) { dashboard[".type"].strictSetter.setString(value) }

fun setDashboardType(value: String): SendableHelper {
dashboardType = value
fun setType(value: String): SendableHelper {
type = value
return this
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ constructor(

override fun init(title: String, dashboard: BasicDashboard): ActiveComponent {
SendableHelper(dashboard)
.setDashboardType("String Chooser")
.setType("String Chooser")
dashboard[INSTANCE].strictSetter.setDouble(instanceNumber.toDouble())

return ActiveComponentMultiplexer(title, listOf(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,14 +4,12 @@ import com.first1444.dashboard.BasicDashboard
import com.first1444.dashboard.advanced.AdvancedDashboard
import com.first1444.dashboard.livewindow.LiveWindow
import com.first1444.dashboard.shuffleboard.Shuffleboard
import com.first1444.dashboard.smartdashboard.SmartDashboard

interface DashboardBundle {
val rootDashboard: BasicDashboard

val shuffleboard: Shuffleboard

val smartDashboard: AdvancedDashboard
val smartDashboardBasic: BasicDashboard

val smartDashboard: SmartDashboard
val liveWindow: LiveWindow
}
Original file line number Diff line number Diff line change
Expand Up @@ -6,26 +6,27 @@ import com.first1444.dashboard.advanced.BasicAdvancedDashboard
import com.first1444.dashboard.livewindow.DefaultLiveWindow
import com.first1444.dashboard.livewindow.LiveWindow
import com.first1444.dashboard.shuffleboard.implementations.DefaultShuffleboard
import com.first1444.dashboard.smartdashboard.DefaultSmartDashboard
import com.first1444.dashboard.smartdashboard.SmartDashboard

class DefaultDashboardBundle(
override val rootDashboard: BasicDashboard
) : ActiveDashboardBundle {
override val title: String = "Default Dashboard Bundle"

override val shuffleboard = DefaultShuffleboard(rootDashboard)

override val smartDashboardBasic: BasicDashboard = rootDashboard.getSubDashboard("SmartDashboard")
override val smartDashboard = BasicAdvancedDashboard("Smart Dashboard", smartDashboardBasic)

override val liveWindow: LiveWindow = DefaultLiveWindow(rootDashboard)
override val smartDashboard = DefaultSmartDashboard(rootDashboard)
override val liveWindow = DefaultLiveWindow(rootDashboard)

override fun update() {
shuffleboard.update()
smartDashboard.update()
liveWindow.update()
}

override fun onRemove() {
shuffleboard.onRemove()
smartDashboard.onRemove()
liveWindow.onRemove()
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -2,4 +2,12 @@ package com.first1444.dashboard.enable

interface EnabledProvider {
val isEnabled: Boolean

companion object {
@JvmSynthetic
operator fun invoke(lambda: () -> Boolean) = object : EnabledProvider {
override val isEnabled: Boolean
get() = lambda()
}
}
}
Original file line number Diff line number Diff line change
@@ -1,7 +1,12 @@
package com.first1444.dashboard.livewindow

import com.first1444.dashboard.ActiveComponent
import com.first1444.dashboard.BasicDashboard
import com.first1444.dashboard.advanced.SendableDashboard
import com.first1444.dashboard.advanced.ActuatorSendable
import com.first1444.dashboard.advanced.Sendable
import com.first1444.dashboard.enable.EnabledProvider
import com.first1444.dashboard.enable.MutableEnabledProvider
import com.first1444.dashboard.enable.SimpleEnabledProvider

class DefaultLiveWindow(
rootDashboard: BasicDashboard
Expand All @@ -10,20 +15,70 @@ class DefaultLiveWindow(
private val statusDashboard = dashboard.getSubDashboard(".status")
private val enabledEntry = statusDashboard["LW Enabled"]

private val map = HashMap<Sendable<*>, Pair<ActiveComponent, MutableEnabledProvider>>()

override val title: String = "Live Window"
override var isEnabled: Boolean = false
set(value) {
field = value
enabledEntry.strictSetter.setBoolean(value)
}
override val sendableDashboard: SendableDashboard
get() = TODO("not implemented") //To change initializer of created properties use File | Settings | File Templates.
override fun delete(key: String): Boolean {
val iterator = map.iterator()
while(iterator.hasNext()){
val (_, pair) = iterator.next()
val (activeComponent, _) = pair
if(activeComponent.title == key){
iterator.remove()
doRemove(activeComponent)
return true
}
}
return false
}

override fun delete(sendable: Sendable<*>): Boolean {
val (activeComponent, _) = map.remove(sendable) ?: return false
doRemove(activeComponent)
return true
}
private fun doRemove(activeComponent: ActiveComponent){
activeComponent.onRemove()
dashboard.delete(activeComponent.title)
}

override fun add(key: String, data: Sendable<*>): Boolean {
if(data in map){
return false
}
val sendableDashboard = dashboard.getSubDashboard(key)
val telemetryProvider = SimpleEnabledProvider(false)
val sendable = ActuatorSendable(data, EnabledProvider { isEnabled || telemetryProvider.isEnabled }, false)
val activeComponent = sendable.init(key, sendableDashboard)
map[data] = Pair(activeComponent, telemetryProvider)
return true
}

override fun setTelemetryEnabled(sendable: Sendable<*>, enabled: Boolean) {
val (_, telemetryProvider) = map[sendable] ?: throw NoSuchElementException("No element found with sendable=$sendable")
telemetryProvider.isEnabled = enabled
}

override val title: String = "Live Window"

override fun update() {
for((activeComponent, _) in map.values){
activeComponent.update()
}
}

override fun onRemove() {
try {
for((activeComponent, _) in map.values){
activeComponent.onRemove()
}
} finally {
map.clear()
}
}

}
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
package com.first1444.dashboard.livewindow

import com.first1444.dashboard.advanced.SendableDashboard
import com.first1444.dashboard.advanced.Sendable
import com.first1444.dashboard.enable.MutableEnabledProvider

interface LiveWindow : MutableEnabledProvider {
Expand All @@ -10,5 +10,18 @@ interface LiveWindow : MutableEnabledProvider {
telemetry can override this for certain Sendable objects.
*/

val sendableDashboard: SendableDashboard
fun delete(key: String): Boolean
fun delete(sendable: Sendable<*>): Boolean

/**
* @return true if it was added, false otherwise
*/
fun add(key: String, data: Sendable<*>): Boolean

/**
* When set to true, [sendable] will still update even if [isEnabled] is false.
* @param sendable The [Sendable] to enable or disable
* @param enabled true to enable telemetry, false to disable telemetry
*/
fun setTelemetryEnabled(sendable: Sendable<*>, enabled: Boolean)
}
Original file line number Diff line number Diff line change
Expand Up @@ -45,27 +45,17 @@ class DefaultShuffleboardContainer(

override fun remove(title: String): Boolean {
checkRemoved()
val component = componentMap[title] ?: return false
val component = componentMap.remove(title) ?: return false
component.onRemove()
componentMap.remove(title)
dashboard.delete(title) // may be removing an entry or removes a sub dashboard
metadataDashboard.delete(title) // removes the sub dashboard that contains the metadata
return true
}

override fun remove(component: ActiveComponent): Boolean {
checkRemoved()
val iterator = componentMap.iterator()
while(iterator.hasNext()){
val (_, iteratorComponent) = iterator.next()
if(iteratorComponent == component){
iteratorComponent.onRemove()
iterator.remove()
return true
}
}
return false
return remove(component.title)
}


override fun update() {
checkRemoved()
for(component in componentMap.values){
Expand All @@ -88,6 +78,7 @@ class DefaultShuffleboardContainer(
val componentMetadata = metadataDashboard.getSubDashboard(title)
metadataEditor.editMetadata(componentMetadata)
val r = component.init(title, dashboard, componentMetadata)
check(r.title == title) { "The title of the ActiveComponent must be the same as the passed title!" }
componentMap[title] = r
return r
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ class ShuffleboardLayoutComponent(
override fun init(title: String, parentDashboard: BasicDashboard, metadataDashboard: BasicDashboard): ActiveShuffleboardContainer {
val dashboard = parentDashboard.getSubDashboard(title)
SendableHelper(dashboard)
.setDashboardType("ShuffleboardLayout")
.setType("ShuffleboardLayout")
ComponentMetadataHelper(metadataDashboard)
.setPreferredComponent(layoutName)

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ import com.first1444.dashboard.shuffleboard.ShuffleboardComponent
object ShuffleboardTabComponent : ShuffleboardComponent<ActiveShuffleboardContainer> {
override fun init(title: String, parentDashboard: BasicDashboard, metadataDashboard: BasicDashboard): ActiveShuffleboardContainer {
val dashboard = parentDashboard.getSubDashboard(title)
SendableHelper(dashboard).setDashboardType("ShuffleboardTab")
SendableHelper(dashboard).setType("ShuffleboardTab")
return DefaultShuffleboardContainer(title, dashboard, metadataDashboard)
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
package com.first1444.dashboard.smartdashboard

import com.first1444.dashboard.ActiveComponent

interface ActiveSmartDashboard : SmartDashboard, ActiveComponent
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
package com.first1444.dashboard.smartdashboard

import com.first1444.dashboard.BasicDashboard
import com.first1444.dashboard.advanced.BasicAdvancedDashboard

class DefaultSmartDashboard(
rootDashboard: BasicDashboard
) : ActiveSmartDashboard {
override val title: String = "SmartDashboard"

override val basicDashboard: BasicDashboard = rootDashboard.getSubDashboard("SmartDashboard")
override val dashboard = BasicAdvancedDashboard("SmartDashboard", basicDashboard)

override fun update() {
dashboard.update()
}

override fun onRemove() {
dashboard.onRemove()
}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
package com.first1444.dashboard.smartdashboard

import com.first1444.dashboard.BasicDashboard
import com.first1444.dashboard.advanced.AdvancedDashboard

interface SmartDashboard {
val dashboard: AdvancedDashboard
val basicDashboard: BasicDashboard
}
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ class PropertyActiveComponent(

private val listener: EntryListener? = if(property.supportsSetting){
EntryListener {
property.setValue(it.value!!) // TODO think about handling nulls
property.setValue(it.value!!) // value shouldn't be null because we don't expect the property to be removed // We may change this in the future
}
} else null

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ val NetworkTableValue.asBasicValue: BasicValue?
return null
}
return BasicValue(when (type) {
NetworkTableType.kUnassigned -> throw AssertionError()
NetworkTableType.kUnassigned -> throw AssertionError("We just checked this above!")
NetworkTableType.kBoolean -> BasicValueType.BOOLEAN
NetworkTableType.kDouble -> BasicValueType.DOUBLE
NetworkTableType.kString -> BasicValueType.STRING
Expand Down

0 comments on commit 62db5b1

Please sign in to comment.