1818
1919import java .util .List ;
2020import java .util .concurrent .CompletableFuture ;
21+ import java .util .concurrent .atomic .AtomicReference ;
2122import java .util .function .*;
2223
2324class CustomBoundItem <G extends Gui > extends AbstractBoundItem {
@@ -26,17 +27,20 @@ class CustomBoundItem<G extends Gui> extends AbstractBoundItem {
2627 private final QuadConsumer <? super Item , ? super G , ? super Player , ? super Integer > selectHandler ;
2728 private volatile BiFunction <? super Player , ? super G , ? extends ItemProvider > itemProvider ;
2829 private final BiConsumer <? super Item , ? super G > bindHandler ;
30+ private final BiConsumer <? super Item , ? super G > unbindHandler ;
2931 private final int updatePeriod ;
3032 private @ Nullable BukkitTask updateTask ;
3133
3234 public CustomBoundItem (
3335 BiConsumer <? super Item , ? super G > bindHandler ,
36+ BiConsumer <? super Item , ? super G > unbindHandler ,
3437 TriConsumer <? super Item , ? super G , ? super Click > clickHandler ,
3538 QuadConsumer <? super Item , ? super G , ? super Player , ? super Integer > selectHandler ,
3639 BiFunction <? super Player , ? super G , ? extends ItemProvider > itemProvider ,
3740 int updatePeriod
3841 ) {
3942 this .bindHandler = bindHandler ;
43+ this .unbindHandler = unbindHandler ;
4044 this .clickHandler = clickHandler ;
4145 this .selectHandler = selectHandler ;
4246 this .itemProvider = itemProvider ;
@@ -61,6 +65,12 @@ public void bind(Gui gui) {
6165 super .bind (gui );
6266 }
6367
68+ @ Override
69+ public void unbind () {
70+ unbindHandler .accept (this , getGui ());
71+ super .unbind ();
72+ }
73+
6474 @ Override
6575 public void handleClick (ClickType clickType , Player player , Click click ) {
6676 clickHandler .accept (this , getGui (), click );
@@ -96,6 +106,7 @@ public void removeViewer(AbstractWindow<?> who, int how) {
96106 non-sealed static class Builder <G extends Gui > implements BoundItem .Builder <G > {
97107
98108 protected BiConsumer <Item , G > bindHandler = (item , gui ) -> {};
109+ protected BiConsumer <Item , G > unbindHandler = (item , gui ) -> {};
99110 private TriConsumer <Item , G , Click > clickHandler = (item , gui , click ) -> {};
100111 private QuadConsumer <Item , G , Player , Integer > selectHandler = (item , gui , player , slot ) -> {};
101112 private @ Nullable BiFunction <? super Player , ? super G , ? extends ItemProvider > itemProviderFn ;
@@ -197,6 +208,12 @@ public Builder<G> addBindHandler(BiConsumer<? super Item, ? super G> handler) {
197208 return this ;
198209 }
199210
211+ @ Override
212+ public BoundItem .Builder <G > addUnbindHandler (BiConsumer <? super Item , ? super G > handler ) {
213+ unbindHandler = unbindHandler .andThen (handler );
214+ return this ;
215+ }
216+
200217 @ Override
201218 public Builder <G > addModifier (Consumer <? super Item > modifier ) {
202219 this .modifier = this .modifier .andThen (modifier );
@@ -213,6 +230,7 @@ public BoundItem build() {
213230 if (asyncPlaceholder != null && itemProviderFn != null ) {
214231 customItem = new CustomBoundItem <>(
215232 bindHandler ,
233+ unbindHandler ,
216234 clickHandler ,
217235 selectHandler ,
218236 (viewer , gui ) -> asyncPlaceholder ,
@@ -237,6 +255,7 @@ public BoundItem build() {
237255 } else {
238256 customItem = new CustomBoundItem <>(
239257 bindHandler ,
258+ unbindHandler ,
240259 clickHandler ,
241260 selectHandler ,
242261 itemProviderFn != null ? itemProviderFn : (viewer , gui ) -> ItemProvider .EMPTY ,
@@ -252,9 +271,19 @@ public BoundItem build() {
252271 static class Paged extends Builder <PagedGui <?>> {
253272
254273 Paged () {
274+ var pageChangeHandler = new AtomicReference <BiConsumer <Integer , Integer >>();
275+ var pageCountChangeHandler = new AtomicReference <BiConsumer <Integer , Integer >>();
276+
255277 bindHandler = bindHandler .andThen ((item , gui ) -> {
256- gui .addPageChangeHandler ((oldPage , newPage ) -> item .notifyWindows ());
257- gui .addPageCountChangeHandler ((oldCount , newCount ) -> item .notifyWindows ());
278+ pageChangeHandler .set ((oldPage , newPage ) -> item .notifyWindows ());
279+ pageCountChangeHandler .set ((oldCount , newCount ) -> item .notifyWindows ());
280+ gui .addPageChangeHandler (pageChangeHandler .get ());
281+ gui .addPageCountChangeHandler (pageCountChangeHandler .get ());
282+ });
283+
284+ unbindHandler = unbindHandler .andThen ((item , gui ) -> {
285+ gui .removePageChangeHandler (pageChangeHandler .get ());
286+ gui .removePageCountChangeHandler (pageCountChangeHandler .get ());
258287 });
259288 }
260289
@@ -263,9 +292,20 @@ static class Paged extends Builder<PagedGui<?>> {
263292 static class Scroll extends Builder <ScrollGui <?>> {
264293
265294 Scroll () {
295+ var scrollHandler = new AtomicReference <BiConsumer <Integer , Integer >>();
296+ var lineCountChangeHandler = new AtomicReference <BiConsumer <Integer , Integer >>();
297+
266298 bindHandler = bindHandler .andThen ((item , gui ) -> {
267- gui .addScrollHandler ((oldScroll , newScroll ) -> item .notifyWindows ());
268- gui .addLineCountChangeHandler ((oldCount , newCount ) -> item .notifyWindows ());
299+ scrollHandler .set ((oldScroll , newScroll ) -> item .notifyWindows ());
300+ lineCountChangeHandler .set ((oldCount , newCount ) -> item .notifyWindows ());
301+
302+ gui .addScrollHandler (scrollHandler .get ());
303+ gui .addLineCountChangeHandler (lineCountChangeHandler .get ());
304+ });
305+
306+ unbindHandler = unbindHandler .andThen ((item , gui ) -> {
307+ gui .removeScrollHandler (scrollHandler .get ());
308+ gui .removeLineCountChangeHandler (lineCountChangeHandler .get ());
269309 });
270310 }
271311
@@ -274,9 +314,16 @@ static class Scroll extends Builder<ScrollGui<?>> {
274314 static class Tab extends Builder <TabGui > {
275315
276316 Tab () {
277- bindHandler = bindHandler .andThen ((item , gui ) ->
278- gui .addTabChangeHandler ((oldTab , newTab ) -> item .notifyWindows ())
279- );
317+ var tabChangeHandler = new AtomicReference <BiConsumer <Integer , Integer >>();
318+
319+ bindHandler = bindHandler .andThen ((item , gui ) -> {
320+ tabChangeHandler .set ((oldTab , newTab ) -> item .notifyWindows ());
321+ gui .addTabChangeHandler (tabChangeHandler .get ());
322+ });
323+
324+ unbindHandler = unbindHandler .andThen ((item , gui ) -> {
325+ gui .removeTabChangeHandler (tabChangeHandler .get ());
326+ });
280327 }
281328
282329 }
0 commit comments