Giter Site home page Giter Site logo

inventory-framework's People

Contributors

dependabot[bot] avatar devnatan avatar devwckd avatar eokasta avatar fossabot avatar georgev220 avatar luiz-otavio avatar mattnicee7 avatar renovate[bot] avatar saiintbrisson avatar sasuked avatar srgaabriel avatar stooneg0mes avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar

inventory-framework's Issues

Slot context not updateable when running on a Paginated View

How to reproduce:

// onPaginationItemRender
item.withItem(x).onClick(slot -> slot.updateSlot());

Expected behavior:
Slot updated

Stacktrace:

Caused by: java.lang.ClassCastException: me.saiintbrisson.minecraft.DelegatedViewContext cannot be cast to me.saiintbrisson.minecraft.PaginatedViewContext
        at me.saiintbrisson.minecraft.PaginatedView.update(PaginatedView.java:354) ~[?:?]
        at me.saiintbrisson.minecraft.ViewSlotContext.updateSlot(ViewSlotContext.java:79) ~[?:?]
        at me.saiintbrisson.minecraft.ViewListener.onViewClick(ViewListener.java:184) ~[?:?]
        at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) ~[?:1.8.0_292]
        at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) ~[?:1.8.0_292]
        at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) ~[?:1.8.0_292]
        at java.lang.reflect.Method.invoke(Method.java:498) ~[?:1.8.0_292]
        at org.bukkit.plugin.java.JavaPluginLoader$1.execute(JavaPluginLoader.java:300) ~[PaperSpigot.jar:git-PaperSpigot-"4347b01"]

Context history

This will allow for a "return" mechanic with preserved data.
Useful for paged views that, if returned, your page is preserved.

Possible API design
Creating two forward and backward functions

context.back();
context.advance();
History

It will be necessary to keep a history of context but with a low level of amount of transitions, how deep the context will hold a previous context

// will save only one context per transition
useHistory(1);

A public API will be needed for the developer to handle the history freely implemented on VirtualView.

Lack of documentation

There is currently no documentation on how to use some functions with onItemHold and onItemRelease and there is not much documentation in the code itself because the code was ported from another repository.

Fix item handler call order

Paginated & non-paginated onRender being called after onUpdate, cancelling update handler setItem slot change.

Lazy pagination source

Currently IF paging only supports one-time set data, ie you have a large amount of data taken in one go and stored entirely in a data list that will later be rendered in the inventory.

List<...> hugeAmountOfData;

setSource(hugeAmountOfData);

This becomes a problem when there is an indeterminate amount of data, a large amount of data, or you don't necessarily have access to all that data at once, which is the case with calls to a backend that are paginated and only get results of specific pages. IF does not support this.

List<...> getHugeAmountOfData(int page);

setSource(/* how ??? */)

There are workarounds currently to get around these problems like the page switching handler that you can use to get the current page that is in the inventory, and thus update the items accordingly but this doesn't work properly besides breaking all the flow of rendering and updating a paginated inventory.

The idea here is that the developer can determine the data that will be rendered according to the page, providing a data factory instead of the data itself. Something like this.

List<...> getData(int page);

setSource(ctx -> getData(ctx.getPage()));

That way:

  • It will not be necessary to have all the data at once;
  • It is now possible to have conditional data without necessarily having to put it in onRender even if it is not dynamic;
  • Error handling will work correctly if you define the data in the View's constructor.

Custom "on click outside" handler

There is currently an option that when the player clicks outside the inventory while it is open, the inventory is closed to the player, this is the closeOnClickOutside option.

The idea is to create a custom handler so that the developer can decide what to do when this happens. This custom handler can be used for example as a return function, which when clicked on the outside returns to the previous inventory instead of closing it.

Auto slot fill

Currently the layout only works in paginated views whose item position is defined according to a layout if it is defined.

The idea is that the layout also works for non-paged views and that adding items through an item definition function in the View that does not specify a slot for it to go to a position according to the layout.

These two functions will either add items that will adapt to the layout if any or one will be added to the first available inventory slot.

slot(ItemStack);
slot().withItem(ItemStack);

Allow transitive data context while transitioning to another view

When transitioning to another view using ViewContext's open fn, user must can choose if it will transfer the data from the current view to the next view

Example:

final class A extends View {}
final class B extends View {}

Opens A view with some data

open(player, A.class, ImmutableMap.of("donnut", "chocolate"));

Inside A handler

Current Behavior

B view opens with no data

...onClick(click -> click.open(B.class));
New Behavior

B view opens with no data but user can transfer data from A to B

...onClick(click -> click.open(B.class, true /* inherit context data */));
Workaround while this is not implemented
...onClick(click -> click.open(B.class, click.getData()));

Expose ViewContext current title

The current title of the inventory is not being exposed for the user to use it as he wants (ViewContext#getTitle), currently a workaround for this is to get the current title of the player's inventory that is open.

Paginated View "update all" is calling the rendering function twice

This issue is related to handlers call order issue (#7).

When we call the update function (ViewContext#update() or ViewSlotContext#updateSlot)
in any handler of an item that is not a page item for example:

final class Example extends PaginatedView<...> {

    public Example() {
        firstSlot(item).onRender($ -> {
            // when updated, this will be called a thousand times for some reason
        }).onClick(ViewContext::update);
    }

    @Override
    public void onPaginationItemRender(PaginatedViewContext<...> ctx, ViewItem item, ... value) {
        item.onRender($ -> {
            // if we click here or on the `firstSlot` item, it will be called once
        }).onClick(iewContext::updateSlot);
    }

}

`onItemRelease` not working with PaginatedView

The check is only being applied to View items, which have been statically defined so it'll not work with items set in context.

for (final ViewItem holdingItem : view.getItems()) {

Reproducible code:

slot(1, new ItemStack(Material.REDSTONE));
context.slot(2, new ItemStack(Material.DIAMOND));

...

@Override
protected void onItemRelease(ViewSlotContext from, ViewSlotContext to) {
    from.getPlayer().sendMessage("Item released");
}

Hold and release the REDSTONE, will work fine, prints "Item released".
Hold and release the DIAMOND, nothing happens.

Also, it won't work with PaginatedViewContext as these contexts don't store item information.

Inline Views

Introduce a "contextless"-like inlined View type to create views that'll be used only for simple interactions like a confirmation menu. The difference between a menu with context and one without context is that many things will no longer be handled, reducing the overhead of the View, making it much faster and simpler.

Design proposals

private void confirm(Player player);
private void cancel(Player player);

// ...
View confirmationView = View.create("Confirmation", 3, view -> {
    view.slot(1, item).onClick(ctx -> confirm(ctx.getPlayer()));
    view.slot(2, item).onClick(ctx -> cancel(ctx.getPlayer()));
});

confirmationView.open(player);

Or

private void confirm(Player player);
private void cancel(Player player);

// ...
ViewItem confirmItem = item(...).onClick(ctx -> confirm(ctx.getPlayer());
ViewItem cancelItem = item(...).onClick(ctx -> cancel(ctx.getPlayer());

createView("Confirmation", 3)
    .with(slot(1, confirmItem))
    .with(slot(2, cancelItem))
    .build()
    .open(player);

This View must use a definitely smaller amount of memory, it must probably be limited in terms of functionality and must be discarded if the player closes it.

Kotlin DSL

Provide an easy way to use IF in Kotlin code by creating a DSL.

Animations

For now it is possible to make animations in the inventories but not in a simple way, it is necessary to change a lot to make a minimally simple animation.

The implementation of a facility for the creation of animations in inventories as well as own and free implementations (from the developer and not from the IF developers) is in the plans.

Why does this project need to build in Java 11?

Most of projects that are built in Gradle > 7.0 need to change their JDK version to Java 11 due to compatibility with inventory-framework.
I mean, all code from inventory-framework doesn't use anything from Java 11, so why is this being built into Java 11?

I think this is happening from that workflow.

Shared context

Allow multiple players to share the same inventory and context.

Dependency Dashboard

This issue lists Renovate updates and detected dependencies. Read the Dependency Dashboard docs to learn more.

Repository problems

These problems occurred while renovating this repository.

  • WARN: Preventing access to file outside the base directory
  • WARN: Failed to process Gradle file

Open

These updates have all been created already. Click a checkbox below to force a retry/rebase of any.

Ignored or Blocked

These are blocked by an existing closed PR and will not be recreated unless you click a checkbox below.

Detected dependencies

github-actions
.github/workflows/build.yml
  • actions/checkout v3
  • actions/setup-java v3
  • gradle/gradle-build-action cd3cedc781988c804f626f4cd2dc51d0bdf02a12
  • actions/checkout v3
  • actions/setup-java v3
  • gradle/gradle-build-action 64a1064eca4dce12f511de38c4afb06707e4e7fc
.github/workflows/codeql-analysis.yml
  • actions/checkout v3
  • github/codeql-action v2
  • github/codeql-action v2
  • github/codeql-action v2
.github/workflows/generate-artifacts.yml
  • actions/checkout v2
  • gradle/wrapper-validation-action v1
  • actions/setup-java v2
  • ASzc/change-string-case-action v2
  • burrunan/gradle-cache-action v1
  • actions/upload-artifact v3
.github/workflows/publish.yml
  • actions/checkout v3
  • actions/setup-java v3
  • gradle/gradle-build-action cd3cedc781988c804f626f4cd2dc51d0bdf02a12
  • gradle/gradle-build-action cd3cedc781988c804f626f4cd2dc51d0bdf02a12
gradle
publish.gradle
settings.gradle
build.gradle
  • com.diffplug.spotless 6.9.1
bom/build.gradle
bukkit-api/build.gradle
bukkit-plugin/build.gradle
feature-move-io/build.gradle
gradle/libs.versions.toml
  • org.spigotmc:spigot-api 1.16.5-R0.1-SNAPSHOT
  • org.jetbrains:annotations 23.0.0
  • org.junit.jupiter:junit-jupiter-api 5.9.0
  • org.junit.jupiter:junit-jupiter-engine 5.9.0
  • org.projectlombok:lombok 1.18.24
  • org.jetbrains.kotlin:kotlin-stdlib-jdk8 1.7.10
  • org.mockito:mockito-core 4.7.0
  • org.mockito:mockito-junit-jupiter 4.7.0
  • com.github.johnrengelman.shadow 7.1.2
  • org.jetbrains.kotlin.jvm 1.7.10
  • org.jmailen.kotlinter 3.11.1
kotlin-dsl/build.gradle.kts
shared/build.gradle
gradle-wrapper
gradle/wrapper/gradle-wrapper.properties
  • gradle 7.5.1

  • Check this box to trigger a request for Renovate to run again on this repository

Cannot render item

Is there an existing issue for this?

  • I have searched the existing issues

🐛 Describe the bug

In the docs on the readme it says to use

render.withItem()

however that item doesn't exist. What am I supposed to use?

✔️ Expected behavior

No response

👣 Steps to Reproduce

No response

💻 Platform

  • Bukkit
  • Sponge
  • Other

⭐ Version

2.5

✍️ Additional context

No response

Improve the performance of inventory updates

The inventory update happens without any conditions. This causes inventories that update constantly to have a "poor performance" (not noticeable for anyone who uses it, but notable for me who develops the library).

My goal is for there to be a way of detecting update and for it to happen intelligently, which, for example, ignores updating of static items – without a explicit rendering function, like constructor defined items via slot(n, ItemStack).

Error handler is not working in paginated inventory

Interacting with PaginatedContext on PaginatedViews, onItemRender, getPreviousPageItem, getNextPageItem, layout resolution, dynamic layout update and such other things related to PaginatedView is not being handled.

Resolve page layout before player views inventory

It is currently not possible to get the limit amount of items for a page without first solving the layout. The problem is that the rendering function is called before the layout is resolved, so it is not possible to get the limit amount of items inside it.

This should be possible:

public void onRender(final ViewContext context) {
    final int maxItems = context.paginated().getPageSize();
}

The error that gets thrown when trying to do this:

Caused by: java.lang.IllegalArgumentException: No pagination source was provided.
at me.saiintbrisson.minecraft.PaginatedViewContext.getPaginator(PaginatedViewContext.java:132) ~[?:?]
at me.saiintbrisson.minecraft.PaginatedViewContext.getPageSize(PaginatedViewContext.java:62) ~[?:?]
at co.outplay.palaze.arcade.bedwars.map.island.store.inventory.IslandStoreInventory.updateCategory(IslandStoreInventory.java:168) ~[?:?]
at co.outplay.palaze.arcade.bedwars.map.island.store.inventory.IslandStoreInventory.onRender(IslandStoreInventory.java:226) ~[?:?]
at me.saiintbrisson.minecraft.View.open(View.java:106) ~[?:?]
at me.saiintbrisson.minecraft.ViewFrame.open(ViewFrame.java:103) ~[?:?]
at me.saiintbrisson.minecraft.ViewFrame.open(ViewFrame.java:95) ~[?:?]
at co.outplay.palaze.arcade.bedwars.state.play.listener.IslandStoreVillagerInteractListener.onVillagerInteract(IslandStoreVillagerInteractListener.java:38) ~[?:?]
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) ~[?:1.8.0_302]
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) ~[?:1.8.0_302]
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) ~[?:1.8.0_302]
at java.lang.reflect.Method.invoke(Method.java:498) ~[?:1.8.0_302]
at org.bukkit.plugin.java.JavaPluginLoader$1.execute(JavaPluginLoader.java:300) ~[PaperSpigot.jar:]
... 16 more

This is because the layout is only resolved after the page source is resolved, due to optimizations, this can be resolved by solving the layout before the rendering function using as a content basis the layout characters and not the pagination source themself.

Temporary workaround:
Force inventory resolution even if content is empty

public void onRender(final ViewContext context) {
    // force layout resolve
    context.paginated().setSource(Collections.emptyList());
    
    final int maxItems = context.paginated().getPageSize();
}

Allow user fill layout with it's own items

Allow players to define items that will place as placeholders in the position of paginated items when the amount of paginated values does not match the total pagination display size.

Example 1

All Xs in the layout will be replaced by a stained glass pane.

setLayout(
    "XXXXXXXXX",
    "XOOOOOOOX
    "XXXXXXXXX
)

setPlaceholder("X", ctx -> ctx.withItem(item(Material.STAINED_GLASS_PANE)))
Example 2

All Xs in the layout will be replaced by a stained glass pane.

setLayout(
    "XXXXXXXXX",
    "XOOOOOOOX
    "XXXXXXXXX
)

@Override
public void onItemRender(
    PaginatedViewContext<?> ctx,
    ViewItem item,
    ? value
) {
    item.withItem(ctx.isFilled() ? <item with value> : <placeholder>)
}

Dependência

A nova versão (2.3.2) pelo jitpack não está baixando.

Timeable out item render

Allow user to render an item only for a duration.
Currently it is possible to use a workaround with context data to do this but it is very complex, it must be implemented in the IF itself.

With duration as parameter of setItem combined with onUpdate

By default the rendered item will be the fallback item PAPER,
when updated it will set to the item DIAMOND for 3 seconds and return to PAPER.

slot(10, new ItemStack(Material.PAPER))
    .onUpdate(update -> update.setItem(new ItemStack(Material.DIAMOND, Duration.ofSeconds(3)))
    .onClick(ViewSlotContext::updateSlot);

It will also be possible to do conditional rendering together with onRender

slot(10)
    .onRender(render -> render.setItem(new ItemStack(Material.PAPER)))
    .onUpdate(update -> update.setItem(new ItemStack(Material.DIAMOND, 10L /* ticks */))
    .onClick(ViewSlotContext::updateSlot);

The item rendering chain will continue to work.
As soon as the render duration of the timeout item update expires,
the render function will be called and if null returns to fallback. As it is now.

slot(10, /* fallback */)
    .onRender(render -> render.setItem(true ? null : new ItemStack(Material.PAPER)))
    .onUpdate(update -> update.setItem(new ItemStack(Material.DIAMOND, 10L /* ticks */))
    .onClick(ViewSlotContext::updateSlot);

Item references

Lately some IF users have been trying to do things that are impossible without using indeterministic magic codes when it comes to slot position, that is, the user tries to find an item in the inventory that he expects to be in a specific slot by looking in that slot, however, the IF has several features that allow a player to move the item within the inventory and the reference to that item remains intact, thus causing the user code to fail.

The idea here is to make an item reference system, this idea was taken from Vue Template Refs that ran into the same problem we have here.

The problem

As I said before, the user may want to make the player be able to move items within the inventory but keep track of these items regardless of where they are, this is already possible using handlers, however, this is internal to the item itself and only in its scope, so, for example, it's not possible to make an item that updates another specific item, like this:

boolean goldRush = true;
firstSlot().onRender(render -> new ItemStack(goldRush ? Material.GOLD_INGOT : Material.IRON_INGOT));

// we we want this item to upgrade gold bar to iron bar and vice versa
lastSlot(new ItemStack(Material.ARROW)).onClick(click -> { /* how??? */ });

A possible workaround for this is to update the entire inventory.
The problem is that we don't want to update the entire inventory, because we don't need to.

lastSlot(new ItemStack(Material.ARROW)).onClick(ViewContext::update);

Maybe we can take the item slot and update ourselves
But that doesn't work either, as we allow the player to move the item in the inventory, once they move, this code will no longer work.

lastSlot(new ItemStack(Material.ARROW)).onClick(click -> click.update(getFirstSlot()));

API Design

As inspired by Vue's template references, it will be possible to reference an item and take that item later and use it however we want.

  1. We will add a reference to an item using a referencedBy or ref.

    private static final String GOLD_REF_KEY = "gold";
    
    firstSlot(new ItemStack(Material.GOLD_INGOT))
        .referencedBy(GOLD_REF_KEY);
  2. And take the reference and use it however you want later.
    The method for getting the reference will return a ViewSlotContext that can be manipulated freely.

    private static final String GOLD_REF_KEY = "gold";
    private boolean goldRush = true;
    
    firstSlot()
        .referencedBy(GOLD_REF_KEY);
        .onUpdate($ -> goldRush = !goldRush)
        .onRender(render -> 
            render.setItem(new ItemStack(goldRush ? Material.GOLD_INGOT : Material.IRON_INGOT))
        );
        
    // ... and then ...
    lastSlot(new ItemStack(Material.ARROW)).onClick(click -> {
        ViewSlotContext gold = click.ref(GOLD_REF_KEY);
        
        // update the gold item
        gold.updateSlot();
    });

You will even be able to know where the item is positioned through ViewSlotContext#getSlot.
Paginated contexts will also work, so you will be able to get the current paging index and value of that item even if it is in another slot.

Smooth scrolling and vertical scrolling

Currently if there are 100 sub data units split over two pages having 50 for each, in IF page switching will render those two pages at once.

Smooth scrolling

Smooth scrolling will make the next batch of items to be rendered not the current amount of items in the inventory for the next page, i.e. if there are 100 data units sub split over two pages having 50 for each, on the next attempt to switch to the next page, only X items from the next page, determined by the developer, will be rendered, not all.

Vertical scrolling

Vertical scrolling causes items from the next inventory update for pagination to be redirected to the end of the inventory, the last slot, going left to right, bottom to top (LRBT), currently in horizontal scrolling, items go from the right to the left, top to bottom (RLTB).

Dúvida em relação a paginação

Olá, estou com uma dúvida em relação ao setar o item de ir para a próxima página e voltar usando o inventário paginado, como faço para definir eles?

View `getRows` not updated in dynamic inventories

It is possible to change the size of the pre-render initial opening handler inventory, if the size is changed in this handler the View#getRows() method returns the rows value defined in the constructor and not the actual inventory value.

How to reproduce:

public final class Ìnventory extends View {

    public Inventory() {
        super(0);
    }
    
    @Override
    protected void onOpen(final OpenViewContext open) {
        open.setInventorySize(36);
    }
    
    @Override
    protected void onRender(final ViewContext render) {
        render.getPlayer().sendMessage(render.getView().getRows() + " rows");
    }

}

Expected output:

4 rows

Actual output:

0 rows

How to fix:
Modify this to adapt to menus with dynamic inventory sizes

public int getRows() {
return rows;
}

Split the project into modules

There are features in the inventory-framework that are very rare to use, for example: the detection of movement of items from the player's inventory to the View, paging, among others.

It is ideal that the default functionality of the project, the core, is a dependency required for use but that these features are moved to specific modules that will be published and that whoever wants to use them can add to the project whenever they want, this will make:

  • The final project jar size gets smaller and smaller;
  • Each module will have its own responsibility, better organizing the project;
  • Feature modifications will not influence the main functionality of the code.

Pagination item overrides already set item on re-render

The render priority of a paginated and a non-paged item is not being applied correctly.

When a paginated item is not available and a non-paged item is in the position that a paginated item can be rendered, the non-paged item is being cleaned up by the IF.

It is expected that if there is a manually defined item in the layout at the position of a non-paged item, and if this paginated item is not present, the non-paged item should be rendered.

Reproducible code
When the inventory refreshes, the non-paged item (IRON_INGOT) should render as there is nothing to page, but in game, the non-paged item (IRON_INGOT) simply does not appear.

public final class A extends PaginatedView<Integer> {


    public A() {
        super(1, "Golden Shower");
        setLayout("OOXXXXXXX");

        slot(0, new ItemStack(Material.IRON_INGOT));
	setSource(Collections.emptyList());
    }

    @Override
    protected void onItemRender(PaginatedViewSlotContext<Integer> render, ViewItem item, Integer value) {
        item.withItem(new ItemStack(Material.GOLD_INGOT));
     }
}

Missing paginated last item

Paged View with Layout is rendering the layout with one item less than the full layout capacity.

This code
It should render five gold bars.

// in constructor
setLayout("OOOOOXXXX");
setSource(IntStream.rangeClosed(1, 5).boxed().collect(Collectors.toList()));

@Override
protected void onItemRender(PaginatedViewSlotContext<Integer> render, ViewItem item, Integer value) {
    item.withItem(new ItemStack(Material.GOLD_INGOT));
}

IN-GAME result
It forgets to render the last item.
Screenshot from 2022-04-25 18-12-49

Asynchronous opening

The central point of opening the View's inventory is from the onOpen opening handler, there, the conditions that will determine whether the inventory will be opened or not must be handled.

However, it is a synchronous handler, in cases where asynchronous calls are necessary, which, from their result, the opening condition will be defined and the inventory will finally be opened to the player, it is not functional and the developer is obliged to wrap the function of opening the inventory to the completion function of this asynchronous call like this:

CompletableFuture<...> fetch();

// somewhere there is an attempt to open the inventory for the player
fetch().whenComplete((result, $) -> viewFrame.open(A.class, player));

And there's also a problem with that, if an error occurs while opening this inventory, the View's error will be propagated to the completion function of this asynchronous method in case this function propagates or does anything with errors inside it, which is bad because the Error handling is done from the View's own error handler and the developer himself determines if it will be propagated or not when it happens.

CompletableFuture<...> fetch();

final class A extends View {

    @Override
    public void onOpen(final OpenViewContext context) {
        throw new RuntimeException("bad"):
    }

}

// somewhere there is an attempt to open the inventory for the player
fetch().whenComplete(($, $$) -> viewFrame.open(A.class, player))
    .exceptionally($ -> { /* bad */ });

The idea of this issue is to create a way to make opening the inventory blocked in case an asynchronous function needs to be terminated first for that.

CompletableFuture<...> fetch();

final class A extends View {

    @Override
    public void onOpen(final OpenViewContext context) {
        CompletableFuture<...> call = fetch();
        // the inventory will not open until `call` is complete somehow
    }

}

// the developer can calmly open the inventory and expect correct encapsulation of errors and correct late opening
viewFrame.open(A.class, player);

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.