Skip to content

Defaults for Add Fixture #50

Open
Open
@Firionus

Description

When adding a fixture, the UI should have good defaults:

  • Fixture Type: last one in that field (if not submitted) or fixture type last added
  • DMX Mode: last one with which this fixture was added
  • Name: Fixture Type Name (Numbering with space if multiple Qty, but not in text field, only in preview)
  • Quantity: 1
  • FID: highest FID + 1
  • Universe/Address: lowest free with enough space for selected above

A first draft for the API is still in hackmd, but we may still want to decide whether HTTP or WS is the better approach here.

Also, Form validation for adding fixtures needs to be added and we should report errors from the server to the user.

Kotlin Algorithm for Finding Free Address

When adding new fixtures, the client needs to assign their DMX Addresses. By default it makes sense to put these in the "next free gap" of the approriate size. I wrote an algorithm in Kotlin to find these gaps:

/**
 * Finds the first gap in [inputList] at or after [target]. The minimum size of the gap can be specified by [gapSize].
 *
 * [inputList] does not have to be sorted.
 */
fun nextGap(inputList: List<Int>, target: Int, gapSize: Int = 1): Int {
    val list = inputList.sorted()
    var firstCandidate = list.binarySearch(target)

    if (firstCandidate < 0) {
        // negative returned index means the targetFid does not exist in Patch yet
        firstCandidate = -firstCandidate-1
    }

    var last: Int = target-1
    var current: Int

    for (i in firstCandidate..list.lastIndex) {
        current = list[i]
        if (current > last + gapSize) {
            return last + 1
        }
        last = current
    }

    return last + 1
}

Note this algorithm does not consider the upper limit of 512 on DMX Addresses, so that needs to be added in an outer layer.

The associated unit test:

    @Test
    fun testFindGapAtOrAfter() {
        val exampleArray = arrayOf(10,11,12,20,21,23)
        exampleArray.shuffle(kotlin.random.Random(42))
        val exampleList = exampleArray.asList()

        // gapSize 1
        assertEquals(1, nextGap(exampleList, 1))
        assertEquals(3, nextGap(exampleList, 3))
        assertEquals(13, nextGap(exampleList, 10))
        assertEquals(13, nextGap(exampleList, 12))
        assertEquals(19, nextGap(exampleList, 19))
        assertEquals(22, nextGap(exampleList, 20))
        assertEquals(22, nextGap(exampleList, 21))
        assertEquals(22, nextGap(exampleList, 22))
        assertEquals(24, nextGap(exampleList, 23))
        assertEquals(24, nextGap(exampleList, 24))

        // bigger gapSize
        assertEquals(1, nextGap(exampleList, 1, 9))
        assertEquals(24, nextGap(exampleList, 1, 10))
        assertEquals(13, nextGap(exampleList, 12, 7))
        assertEquals(24, nextGap(exampleList, 12, 8))
        assertEquals(18, nextGap(exampleList, 18, 2))
        assertEquals(24, nextGap(exampleList, 18, 3))
        assertEquals(24, nextGap(exampleList, 23, 9))
        assertEquals(24, nextGap(exampleList, 24, 9))
    }

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions