Skip to content

Releases: team5499/forest

Startup time

08 Mar 03:48
79102e1
Compare
Choose a tag to compare

This update cuts the startup time by 300%. The cause of the long startup time was the use of reflection to initialize class properties. As reflection is an expensive set of operations, the better way to approach this issue is with the use of the provideDelegate function inside DashboardDelegate.

To use this update, instead of calling DashboardVar.initClassProps(this::class), just make sure that the classes with dashboard properties get initialized. A simple example:

object Constants {
    fun initProps() {
        println("init Constants")
        First.initProps()
        Nested.initProps()
    }
    public var PROP by DashboardVar(0.0)
    object First {
        fun initProps() {
            println("init First")
        }
        public var PROP by DashboardVar(1.0)
    }
    object Nested {
        fun initProps() {
            println("init Nested")
            Inner.initProps()
        }
        public var PROP by DashboardVar(2.0)
        object Inner {
            fun initProps() {
                println("init Inner")
            }
            public var PROP by DashboardVar(3.0)
        }
    }
}

Typed callbacks

07 Mar 04:10
10ed8ef
Compare
Choose a tag to compare

This update changes the callbacks so that the value can be any type. Also, the callback IDs are now Longs. Finally, some minor concurrency errors are addressed.

Example usage of typed callbacks:

Dashboard.addInlineListener("SOME_STRING") {
    key: String, value: String? ->
    println("$key : $value")
}

Dashboard.addInlineListener("SOME_DOUBLE") {
    key: String, value: Double? ->
    println("$key : $value")
}

Dashboard.addConcurrentListener("SOME_INT") {
    key: String, value: Int? ->
    println("$key : $value")
}

Dashboard.runIfUpdate("SOME_BOOLEAN") {
    key: String, value: Boolean? ->
    println("$key : $value")
}

Dashboard.addInlineListener("SOME_VARIABLE") {
    key: String, value: Any? ->
    println("$key : $value")
}

Reload page when robot program restarts

02 Mar 06:09
5ac7185
Compare
Choose a tag to compare

Automatically reloads the page when robot program restarts. Temporary hack for reconnection.

Startup time minor fix

02 Mar 06:08
e38ab66
Compare
Choose a tag to compare

Should decrease startup time by at least a little bit.

Add auto selector widget

02 Mar 06:07
f5ffed3
Compare
Choose a tag to compare

This update adds a selector widget and corresponding Kotlin API. Example:

Robot.kt

import org.team5499.dashboard.StringChooser

class Robot : TimedRobot(0.005) {
    val chooser: StringChooser
    var inlineId: Int
    var concurrentId: Int
    
    init {
        chooser = StringChooser("SOME_VARIABLE", "default option", "first option",
                                                                   "second option",
                                                                   "default option",
                                                                   "another option")
        inlineId = chooser.addInlineListener() {
            key: String, value: Any? ->
            println("$key: $value")
        }

        concurrentId = chooser.addVarListener() {
            key: String, value: Any? ->
            println("$key: $value")
        }
    }

    fun robotPeriodic() {
        Dashboard.update()
        chooser.runIfUpdate() {
            key: String, value: Any? ->
            println("$key: $value")
        }
    }
}

Camera Widget

01 Mar 08:28
547f4e9
Compare
Choose a tag to compare

This release adds a camera widget, which can be configured to crop the input stream. This feature is useful for the limelight, which streams a side-by-side view of the vision pipeline and the driver camera. With cropping, the camera widget will just display the driver feed without the vision feed, or vice versa.

Inline callbacks with one-time set function

01 Mar 03:55
e6401c7
Compare
Choose a tag to compare

This release adds functionality that allows the programmer to add a lambda function as a callback just once. Then, it is called whenever Dashboard.update() is called, and a variable change is present.
Example:

...
class Robot : TimedRobot(0.005) {
    ...
    fun robotInit() {
        ...
        Dashboard.addInlineListener("SOME_VARIABLE") {
            key: String, value: Any? ->
            println("$key : $value")
        }
        ...
    }
    ...
    fun robotPeriodic() {
        Dashboard.update() // Any callbacks will be called at this time
        ...
    }
    ...
}

Inline Callbacks

28 Feb 05:40
b5d4057
Compare
Choose a tag to compare

This update adds support for inline callbacks. These are really useful for streamlining dashboard integration. See the usage examples below:

Robot.kt

...
class Robot : TimedRobot(0.005) {
    ...
    fun robotPeriodic() {
        Dashboard.update()
        ...
    }
    ...
    fun teleopPeriodic() {
        ...
        Dashboard.runIfUpdate("SOME_VARIABLE") {
            key: String, value: Any? ->
            println("$key : $value")
        }
        ...
    }
    ...
}

Even though the function runIfUpdate is being called periodically, the lambda only gets called whenever SOME_VARIABLE is updated on the dashboard web page. This functionality only works if the Dashboard.update() function is called inside the robotPeriodic function.

Webdriver

28 Feb 05:39
17b4bca
Compare
Choose a tag to compare

No API changes

Change Widget Names

18 Feb 02:48
Compare
Choose a tag to compare

Change the name of a widget by clicking on the title.