Skip to content

Conversation

@amownyy
Copy link
Contributor

@amownyy amownyy commented Jun 23, 2025

This PR removes redundant calls to adapter.onX() methods in AdapterListener. Previously, each event handler was iterating over plugin.getListenerAdapters() twice—once using a forEach lambda and again using a traditional for-each loop—which caused each adapter to process the same event twice.

Changes:

  • Removed the redundant for loops following each forEach invocation.
  • Ensured each adapter is only called once per event.

This cleanup improves performance and prevents potential side effects due to double event handling.

@alwyn974 alwyn974 requested a review from Copilot June 23, 2025 13:49
Copy link
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull Request Overview

This PR refactors event and button dispatch to ensure each adapter or button callback is invoked exactly once, replacing redundant lambda-based loops with single enhanced for-loops.

  • Replaced forEach lambdas in AdapterListener with explicit for-each loops to prevent double invocation.
  • Applied the same loop style in InventoryDefault to handle button callbacks consistently.
  • Removed any duplicated iterations over adapters and buttons.

Reviewed Changes

Copilot reviewed 2 out of 2 changed files in this pull request and generated 3 comments.

File Description
src/main/java/fr/maxlego08/menu/listener/AdapterListener.java Replaced plugin.getListenerAdapters().forEach calls with single for-each loops
src/main/java/fr/maxlego08/menu/inventory/inventories/InventoryDefault.java Replaced buttons.forEach calls with enhanced for-loops for inventory opening/building

Comment on lines +39 to +57
for (ListenerAdapter adapter : this.plugin.getListenerAdapters()) {
adapter.onInventoryClick(event, (Player) event.getWhoClicked());
}
}

@EventHandler
public void onDrag(InventoryDragEvent event) {
if (event.getWhoClicked() instanceof Player) {
this.plugin.getListenerAdapters().forEach(adapter -> adapter.onInventoryDrag(event, (Player) event.getWhoClicked()));
for (ListenerAdapter adapter : this.plugin.getListenerAdapters()) {
adapter.onInventoryDrag(event, (Player) event.getWhoClicked());
}
}
}

@EventHandler
public void onClose(InventoryCloseEvent event) {
if (event.getPlayer() instanceof Player) {
this.plugin.getListenerAdapters().forEach(adapter -> adapter.onInventoryClose(event, (Player) event.getPlayer()));
for (ListenerAdapter adapter : this.plugin.getListenerAdapters()) {
adapter.onInventoryClose(event, (Player) event.getPlayer());
Copy link

Copilot AI Jun 23, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You’re repeatedly casting event.getWhoClicked() to Player inside the loop; consider extracting it to a local Player variable before the loop to improve readability and avoid redundant casts.

Copilot uses AI. Check for mistakes.
Comment on lines 23 to +67
@EventHandler
public void onConnect(PlayerJoinEvent event) {
this.plugin.getListenerAdapters().forEach(adapter -> adapter.onConnect(event, event.getPlayer()));
for (ListenerAdapter adapter : this.plugin.getListenerAdapters()) {
adapter.onConnect(event, event.getPlayer());
}
}

@EventHandler
public void onQuit(PlayerQuitEvent event) {
this.plugin.getListenerAdapters().forEach(adapter -> adapter.onQuit(event, event.getPlayer()));
for (ListenerAdapter adapter : this.plugin.getListenerAdapters()) {
adapter.onQuit(event, event.getPlayer());
}
}

@EventHandler
public void onInventoryClick(InventoryClickEvent event) {
this.plugin.getListenerAdapters().forEach(adapter -> adapter.onInventoryClick(event, (Player) event.getWhoClicked()));
for (ListenerAdapter adapter : this.plugin.getListenerAdapters()) {
adapter.onInventoryClick(event, (Player) event.getWhoClicked());
}
}

@EventHandler
public void onDrag(InventoryDragEvent event) {
if (event.getWhoClicked() instanceof Player) {
this.plugin.getListenerAdapters().forEach(adapter -> adapter.onInventoryDrag(event, (Player) event.getWhoClicked()));
for (ListenerAdapter adapter : this.plugin.getListenerAdapters()) {
adapter.onInventoryDrag(event, (Player) event.getWhoClicked());
}
}
}

@EventHandler
public void onClose(InventoryCloseEvent event) {
if (event.getPlayer() instanceof Player) {
this.plugin.getListenerAdapters().forEach(adapter -> adapter.onInventoryClose(event, (Player) event.getPlayer()));
for (ListenerAdapter adapter : this.plugin.getListenerAdapters()) {
adapter.onInventoryClose(event, (Player) event.getPlayer());
}
}
}

@EventHandler
public void onPick(EntityPickupItemEvent event) {
if (event.getEntity() instanceof Player player) {
this.plugin.getListenerAdapters().forEach(adapter -> adapter.onPickUp(event, player));
for (ListenerAdapter adapter : this.plugin.getListenerAdapters()) {
adapter.onPickUp(event, player);
}
Copy link

Copilot AI Jun 23, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

All event handlers follow the same iteration pattern; consider extracting this loop into a helper method (e.g., dispatchEvent) to reduce duplicated code and improve maintainability.

Copilot uses AI. Check for mistakes.
Comment on lines +78 to +80
for (Button button : this.buttons) {
button.onInventoryOpen(player, this, placeholders);
}
Copy link

Copilot AI Jun 23, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[nitpick] This manual loop over buttons appears multiple times; consider abstracting button processing into a reusable helper or using concise method references for cleaner code.

Suggested change
for (Button button : this.buttons) {
button.onInventoryOpen(player, this, placeholders);
}
processButtons(button -> button.onInventoryOpen(player, this, placeholders));

Copilot uses AI. Check for mistakes.
@Maxlego08
Copy link
Owner

I don’t really understand your pull request, what is the goal? Because here the changes do not seem relevant to me

@amownyy
Copy link
Contributor Author

amownyy commented Jun 23, 2025

The goal is to replace lambdas with regular for loops because lambdas can be less performant when dealing with large data sets and high-frequency events. On a server with 500+ players, this small difference adds up — as seen in the attached usage snapshot from zMenu.

Screenshot 2025-06-23 at 17 01 30

@Maxlego08
Copy link
Owner

Have you more concrete details about the effect of this modification? any stats or else

@amownyy
Copy link
Contributor Author

amownyy commented Jun 23, 2025

I haven't tested for zmenu yet, but I solve every plugin that is open source and uses lambda like this and has high usage, and their usage solves incredibly, I can give an example of the duel plugin right now, the pr I opened for duel is below

dumbo-the-developer/Duels#126

after:
Screenshot 2025-06-23 at 17 15 04

@amownyy
Copy link
Contributor Author

amownyy commented Jun 24, 2025

after:
Screenshot 2025-06-25 at 01 02 34

@Maxlego08 Maxlego08 merged commit c4933ff into Maxlego08:main Jun 25, 2025
2 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants