Skip to content

Commit c2d350e

Browse files
authored
feat: impl JindongApplier that manages the haptic node tree for Compose Runtime (#13)
* feat: impl JindongApplier that manages node trees * fix: apply spotless check * fix: apply spotless check and use beforeEach to create applier * fix: apply spotless check * test: test target index is out of bounds * fix: remove unnecessary applier.up() * fix: apply spotless check
1 parent 1cb1534 commit c2d350e

2 files changed

Lines changed: 428 additions & 0 deletions

File tree

Lines changed: 62 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,62 @@
1+
/*
2+
* Copyright (C) 2026 compose-jindong
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* http://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
package io.github.jindong.compose
17+
18+
import androidx.compose.runtime.AbstractApplier
19+
import io.github.jindong.node.HapticNode
20+
21+
/**
22+
* Applier that manages the haptic node tree for Compose Runtime.
23+
*
24+
* This applier is responsible for:
25+
* - Adding nodes to the tree ([insertTopDown], [insertBottomUp])
26+
* - Removing nodes from the tree ([remove])
27+
* - Moving nodes within the tree ([move])
28+
* - Clearing the tree ([onClear])
29+
*
30+
* The applier maintains a tree of [io.github.jindong.node.HapticNode]s which will be traversed
31+
* to collect [ScheduledHapticEvent]s for playback.
32+
*
33+
* @param root The root node of the composition tree
34+
*/
35+
internal class JindongApplier(
36+
root: HapticNode,
37+
) : AbstractApplier<HapticNode>(root) {
38+
39+
override fun insertTopDown(index: Int, instance: HapticNode) {
40+
current.children.add(index, instance)
41+
}
42+
43+
override fun insertBottomUp(index: Int, instance: HapticNode) {
44+
// Insertion is already handled in insertTopDown
45+
}
46+
47+
override fun remove(index: Int, count: Int) {
48+
current.children.subList(index, index + count).clear()
49+
}
50+
51+
override fun move(from: Int, to: Int, count: Int) {
52+
if (from == to) return
53+
54+
val items = current.children.subList(from, from + count).toList()
55+
current.children.subList(from, from + count).clear()
56+
current.children.addAll(to, items)
57+
}
58+
59+
override fun onClear() {
60+
root.children.clear()
61+
}
62+
}

0 commit comments

Comments
 (0)