Skip to content
FlameyosFlow edited this page Sep 5, 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())

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 = item.editor().emptyLore().setName("&aCool Right?").done();

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());
    // ...
});

Much more!

Clone this wiki locally