Skip to content

Commit 236a6de

Browse files
committed
Add ImGuiStorage
1 parent 136cdce commit 236a6de

File tree

3 files changed

+147
-3
lines changed

3 files changed

+147
-3
lines changed

imgui-binding/src/main/java/imgui/ImDrawList.java

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -12,8 +12,6 @@
1212
* Important: Primitives are always added to the list and not culled (culling is done at higher-level by ImGui:: functions), if you use this API a lot consider coarse culling your drawn objects.
1313
*/
1414
public final class ImDrawList {
15-
// BINDING NOTICE:
16-
// For proper usage in getWindowDrawList(), getBackgroundDrawList(), getForegroundDrawList() we should be able to change object pointer.
1715
long ptr;
1816

1917
ImDrawList(final long ptr) {

imgui-binding/src/main/java/imgui/ImGui.java

Lines changed: 33 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@ public final class ImGui {
2727
private static final ImDrawList WINDOW_DRAW_LIST;
2828
private static final ImDrawList BACKGROUND_DRAW_LIST;
2929
private static final ImDrawList FOREGROUND_DRAW_LIST;
30+
private static final ImGuiStorage IMGUI_STORAGE;
3031

3132
private static ImDrawData drawData;
3233
private static ImFont font;
@@ -51,6 +52,7 @@ public final class ImGui {
5152
WINDOW_DRAW_LIST = new ImDrawList(0);
5253
BACKGROUND_DRAW_LIST = new ImDrawList(0);
5354
FOREGROUND_DRAW_LIST = new ImDrawList(0);
55+
IMGUI_STORAGE = new ImGuiStorage(0);
5456

5557
nInitJni();
5658
ImDrawList.nInit();
@@ -61,6 +63,7 @@ public final class ImGui {
6163
ImFont.nInit();
6264
ImGuiStyle.nInit();
6365
ImGuiWindowClass.nInit();
66+
ImGuiStorage.nInit();
6467
nInitInputTextData();
6568
}
6669

@@ -4616,7 +4619,36 @@ public static ImDrawList getForegroundDrawListNew() {
46164619
return env->NewStringUTF(ImGui::GetStyleColorName(imGuiCol));
46174620
*/
46184621

4619-
// TODO SetStateStorage, GetStateStorage
4622+
/**
4623+
* Replace current window storage with our own (if you want to manipulate it yourself, typically clear subsection of it).
4624+
*/
4625+
public static void setStateStorage(final ImGuiStorage storage) {
4626+
nSetStateStorage(storage.ptr);
4627+
}
4628+
4629+
private static native void nSetStateStorage(long imGuiStoragePtr); /*
4630+
ImGui::SetStateStorage((ImGuiStorage*)imGuiStoragePtr);
4631+
*/
4632+
4633+
/**
4634+
* BINDING NOTICE: to minimize overhead, method ALWAYS returns the same object, but changes its underlying pointer.
4635+
* If you need to get an object with constant pointer (which will point to the same window all the time) use {@link #getStateStorageNew()}.
4636+
*/
4637+
public static ImGuiStorage getStateStorage() {
4638+
IMGUI_STORAGE.ptr = nGetStateStorage();
4639+
return IMGUI_STORAGE;
4640+
}
4641+
4642+
/**
4643+
* BINDING NOTICE: returns {@link ImGuiStorage} for current window with constant pointer to it. Prefer to use {@link #getStateStorage()}.
4644+
*/
4645+
public static ImGuiStorage getStateStorageNew() {
4646+
return new ImGuiStorage(nGetStateStorage());
4647+
}
4648+
4649+
private static native long nGetStateStorage(); /*
4650+
return (intptr_t)ImGui::GetStateStorage();
4651+
*/
46204652

46214653
/**
46224654
* Calculate coarse clipping for large list of evenly sized items. Prefer using the ImGuiListClipper higher-level helper if you can.
Lines changed: 114 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,114 @@
1+
package imgui;
2+
3+
/**
4+
* Helper: Key-Value storage
5+
* Typically you don't have to worry about this since a storage is held within each Window.
6+
* We use it to e.g. store collapse state for a tree (Int 0/1)
7+
* This is optimized for efficient lookup (dichotomy into a contiguous buffer) and rare insertion (typically tied to user interactions aka max once a frame)
8+
* You can use it as custom user storage for temporary values. Declare your own storage if, for example:
9+
* - You want to manipulate the open/close state of a particular sub-tree in your interface (tree node uses Int 0/1 to store their state).
10+
* - You want to store custom debug data easily without adding or editing structures in your code (probably not efficient, but convenient)
11+
* Types are NOT stored, so it is up to you to make sure your Key don't collide with different types.
12+
*/
13+
public final class ImGuiStorage implements ImGuiDestroyableStruct {
14+
long ptr;
15+
16+
/**
17+
* This class will create a native structure.
18+
* Call {@link #destroy()} method to manually free used memory.
19+
*/
20+
public ImGuiStorage() {
21+
ImGui.touch();
22+
ptr = nCreate();
23+
}
24+
25+
ImGuiStorage(final long ptr) {
26+
this.ptr = ptr;
27+
}
28+
29+
@Override
30+
public void destroy() {
31+
nDestroy(ptr);
32+
}
33+
34+
/*JNI
35+
#include <stdint.h>
36+
#include <imgui.h>
37+
38+
jfieldID imGuiStoragePtrID;
39+
40+
#define IMGUI_STORAGE ((ImGuiStorage*)env->GetLongField(object, imGuiStoragePtrID))
41+
*/
42+
43+
static native void nInit(); /*
44+
jclass jImGuiStorageClass = env->FindClass("imgui/ImGuiStorage");
45+
imGuiStoragePtrID = env->GetFieldID(jImGuiStorageClass, "ptr", "J");
46+
*/
47+
48+
private native long nCreate(); /*
49+
ImGuiStorage* imGuiStorage = new ImGuiStorage();
50+
return (intptr_t)imGuiStorage;
51+
*/
52+
53+
private native void nDestroy(long ptr); /*
54+
delete (ImGuiStorage*)ptr;
55+
*/
56+
57+
// - Get***() functions find pair, never add/allocate. Pairs are sorted so a query is O(log N)
58+
// - Set***() functions find pair, insertion on demand if missing.
59+
// - Sorted insertion is costly, paid once. A typical frame shouldn't need to insert any new pair.
60+
61+
public native void clear(); /*
62+
IMGUI_STORAGE->Clear();
63+
*/
64+
65+
public native int getInt(int imGuiID); /*
66+
return IMGUI_STORAGE->GetInt(imGuiID);
67+
*/
68+
69+
public native int getInt(int imGuiID, int defaultVal); /*
70+
return IMGUI_STORAGE->GetInt(imGuiID, defaultVal);
71+
*/
72+
73+
public native void setInt(int imGuiID, int val); /*
74+
IMGUI_STORAGE->SetInt(imGuiID, val);
75+
*/
76+
77+
public native boolean getBool(int imGuiID); /*
78+
return IMGUI_STORAGE->GetBool(imGuiID);
79+
*/
80+
81+
public native boolean getBool(int imGuiID, boolean defaultVal); /*
82+
return IMGUI_STORAGE->GetBool(imGuiID, defaultVal);
83+
*/
84+
85+
public native void setBool(int imGuiID, boolean val); /*
86+
IMGUI_STORAGE->SetBool(imGuiID, val);
87+
*/
88+
89+
public native float getFloat(int imGuiID); /*
90+
return IMGUI_STORAGE->GetFloat(imGuiID);
91+
*/
92+
93+
public native float getFloat(int imGuiID, float defaultVal); /*
94+
return IMGUI_STORAGE->GetFloat(imGuiID, defaultVal);
95+
*/
96+
97+
public native void setFloat(int imGuiID, float val); /*
98+
IMGUI_STORAGE->SetFloat(imGuiID, val);
99+
*/
100+
101+
/**
102+
* Use on your own storage if you know only integer are being stored (open/close all tree nodes)
103+
*/
104+
public native void setAllInt(int val); /*
105+
IMGUI_STORAGE->SetAllInt(val);
106+
*/
107+
108+
/**
109+
* For quicker full rebuild of a storage (instead of an incremental one), you may add all your contents and then sort once.
110+
*/
111+
public native void buildSortByKey(); /*
112+
IMGUI_STORAGE->BuildSortByKey();
113+
*/
114+
}

0 commit comments

Comments
 (0)