@@ -36,6 +36,8 @@ public class HomekitRoot {
36
36
private final SubscriptionManager subscriptions = new SubscriptionManager ();
37
37
private boolean started = false ;
38
38
private int configurationIndex = 1 ;
39
+ private int nestedBatches = 0 ;
40
+ private boolean madeChanges = false ;
39
41
40
42
HomekitRoot (
41
43
String label , HomekitWebHandler webHandler , InetAddress host , HomekitAuthInfo authInfo )
@@ -65,7 +67,7 @@ public class HomekitRoot {
65
67
this .authInfo = authInfo ;
66
68
this .label = label ;
67
69
this .category = category ;
68
- this .registry = new HomekitRegistry (label );
70
+ this .registry = new HomekitRegistry (label , subscriptions );
69
71
}
70
72
71
73
HomekitRoot (
@@ -83,11 +85,19 @@ public class HomekitRoot {
83
85
this (
84
86
label , DEFAULT_ACCESSORY_CATEGORY , webHandler , authInfo , new JmdnsHomekitAdvertiser (jmdns ));
85
87
}
88
+
89
+ public synchronized void batchUpdate () {
90
+ if (this .nestedBatches == 0 ) madeChanges = false ;
91
+ ++this .nestedBatches ;
92
+ }
93
+
94
+ public synchronized void completeUpdateBatch () {
95
+ if (--this .nestedBatches == 0 && madeChanges ) registry .reset ();
96
+ }
97
+
86
98
/**
87
- * Add an accessory to be handled and advertised by this root. Any existing HomeKit connections
88
- * will be terminated to allow the clients to reconnect and see the updated accessory list. When
89
- * using this for a bridge, the ID of the accessory must be greater than 1, as that ID is reserved
90
- * for the Bridge itself.
99
+ * Add an accessory to be handled and advertised by this root. When using this for a bridge, the
100
+ * ID of the accessory must be greater than 1, as that ID is reserved for the Bridge itself.
91
101
*
92
102
* @param accessory to advertise and handle.
93
103
*/
@@ -110,25 +120,28 @@ void addAccessorySkipRangeCheck(HomekitAccessory accessory) {
110
120
if (logger .isTraceEnabled ()) {
111
121
accessory .getName ().thenAccept (name -> logger .trace ("Added accessory {}" , name ));
112
122
}
113
- if (started ) {
123
+ madeChanges = true ;
124
+ if (started && nestedBatches == 0 ) {
114
125
registry .reset ();
115
126
}
116
127
}
117
128
118
129
/**
119
- * Removes an accessory from being handled or advertised by this root. Any existing HomeKit
120
- * connections will be terminated to allow the clients to reconnect and see the updated accessory
121
- * list.
130
+ * Removes an accessory from being handled or advertised by this root.
122
131
*
123
132
* @param accessory accessory to cease advertising and handling
124
133
*/
125
134
public void removeAccessory (HomekitAccessory accessory ) {
126
- this .registry .remove (accessory );
127
- if (logger .isTraceEnabled ()) {
128
- accessory .getName ().thenAccept (name -> logger .trace ("Removed accessory {}" , name ));
129
- }
130
- if (started ) {
131
- registry .reset ();
135
+ if (this .registry .remove (accessory )) {
136
+ if (logger .isTraceEnabled ()) {
137
+ accessory .getName ().thenAccept (name -> logger .trace ("Removed accessory {}" , name ));
138
+ }
139
+ madeChanges = true ;
140
+ if (started && nestedBatches == 0 ) {
141
+ registry .reset ();
142
+ }
143
+ } else {
144
+ accessory .getName ().thenAccept (name -> logger .warn ("Could not remove accessory {}" , name ));
132
145
}
133
146
}
134
147
@@ -140,6 +153,7 @@ public void removeAccessory(HomekitAccessory accessory) {
140
153
*/
141
154
public void start () {
142
155
started = true ;
156
+ madeChanges = false ;
143
157
registry .reset ();
144
158
webHandler
145
159
.start (
0 commit comments