Skip to content
FlameyosFlow edited this page Sep 14, 2023 · 5 revisions

Woody - Performance

On average, Woody (theoretically triumph-gui fork) is 2.31x faster than triumph-gui on average (when setting up a menu, such as adding, etc etc)

Without benchmarks, I'm basically typing BS.

With THESE benchmarks, you'll believe me (Calculated with System.nanoTime())

(Wallahi (Islamic equivalent to "I swear to god") there was no purposeful cheating)

The following benchmarks was calculated on:

  • AMD Athlon X2 64 Dual Core 3800+ Processor
  • 3GB DDR2 677MHz Ram (or exactly 2.8gb ram)

(If you aren't a computer nerd, what that means is that if you have any newer CPU than 2005 or have 800MHz+ ram, it'll only get faster than these benchmarks, if you somehow have worse specs, you probably can't even run minecraft 🙏) woodymoment triumphL

Those are just 2 benchmarks of some of my best benchmarks executing:

Woody:

Menu exampleMenu = new Menu(3, "Example Menu");
exampleMenu.getFiller().fillBorders(new ItemStack(Material.STAINED_GLASS_PANE, 1, (short) 7));
exampleMenu.setCloseAction((event, result) -> event.getPlayer().sendMessage("You closed the menu!")); // notice result
exampleMenu.addAllModifiers();

MenuItem item = ItemBuilder.of(Material.IRON_SWORD).buildItem(event -> {
    event.getWhoClicked().sendMessage("You clicked the iron sword!");
});

MenuItem itemTwo = ItemBuilder.of(Material.DIAMOND_SWORD).buildItem(event -> {
    event.getWhoClicked().sendMessage("You clicked the diamond sword!");
});
exampleMenu.addItem(item, itemTwo);
exampleMenu.get(10)
           .filter(itemOne -> itemOne.getType() == Material.IRON_SWORD)
           .map(MenuItem::getUniqueId)
           .ifPresent(uuid -> Bukkit.getLogger().info(uuid.toString()));
return exampleMenu;

triumph-gui:

Gui gui = new Gui(3, "Example Menu", EnumSet.noneOf(InteractionModifier.class));
gui.getFiller().fillBorder(ItemBuilder.from(new ItemStack(Material.STAINED_GLASS_PANE, 1, (short) 7)).asGuiItem());
gui.setCloseGuiAction(event -> event.getPlayer().sendMessage("You closed the menu!"));
gui.disableAllInteractions();

GuiItem item = ItemBuilder.from(Material.IRON_SWORD).asGuiItem(event -> {
    event.getWhoClicked().sendMessage("You clicked the iron sword!");
});

GuiItem itemTwo = ItemBuilder.from(Material.DIAMOND_SWORD).asGuiItem(event -> {
    event.getWhoClicked().sendMessage("You clicked the diamond sword!");
});
gui.addItem(item, itemTwo);

// no access to UUID except reflection
Optional.ofNullable(gui.getGuiItem(10))
        .filter(itemOne -> itemOne.getItemStack().getType() == Material.IRON_SWORD)
        .ifPresent(itemOne -> Bukkit.getLogger().info(itemOne.getItemStack().toString()));
return gui;

Notice that they're very similar syntax-wise except for a few method names

Woody - Specialty Features

MenuItem ease-of-editing:

MenuItem item = ...;
item.editor().emptyLore().setName("&aCool Right?").done(); // item will be changed without need for a set or update.

MenuLayoutBuilder menu building: (Experimental)

Map<Character, MenuItem> charAsItem = ImmutableMaps.of(
    'X', ItemBuilder.of(Material.STONE).buildItem()
);
Menu menu = MenuLayoutBuilder.bind(charAsItem)
                      .row("XXXXXXXXX")
                      .row("X       X")
                      .row("X       X")
                      .row("X       X")
                      .row("XXXXXXXXX")
                      .createMenu("&aSICKK");

Custom, and Fast Iteration: (Thanks to Mqzen's Collaboration)

// Without "Iterable<MenuItem>" magic
MenuIterator<MenuItem> iterator = menu.iterator();
while (iterator.hasNext()) {
    MenuItem item = iterator.next();
    // ...
}

// you have the ability to use the custom .iterator() methods like: (one example)
MenuIterator<MenuItem> iterator = menu.iterator(MenuIterator.IterationDirection.VERTICAL); // now it searches from up to down and when it's max row and not max column, column is updated and row is 1.
while (iterator.hasNext()) {
    MenuItem item = iterator.next();
    // ...
}

// With "Iterable<MenuItem>" magic
for (MenuItem item : menu) { // how nice of you java
    // ...
}

Slot-based getting and setting:

Slot slot = new Slot(1, 1); // slot = 0
Slot slotTwo = new Slot(6, 1); // slot = 45

Optional<MenuItem> item = menu.get(slot);
MenuItem itemTwo = menu.getItem(slotTwo);

non-close-able menus: (just use it wisely or you'll probably have a plugin everyone hates)

menu.setCloseAction((event, result) -> { // both are mandatory
    // ...
    boolean shouldRemove = shouldRemove(event); // not a real method
    if (shouldRemove) result.set(Result.denied());
    // ...
});

And much more!

Clone this wiki locally