1 
2 //          Copyright Marcelo S. N. Mancini(Hipreme) 2020.
3 // Distributed under the Boost Software License, Version 1.0.
4 //    (See accompanying file LICENSE_1_0.txt or copy at
5 //          http://www.boost.org/LICENSE_1_0.txt)
6 
7 module bindbc.cimgui.additional;
8 import bindbc.cimgui.types : ImDrawCallback;
9 import bindbc.cimgui.funcs : igMemAlloc, igMemFree;
10 import core.stdc.string : memcpy;
11 //This file is non auto generated, it may be better creating one file which will contain every manually added change
12 
13 extern(C) enum ImDrawCallback_ResetRenderState = cast(ImDrawCallback)(-1);
14 enum IM_OFFSETOF(alias member) = member.offsetof;
15 enum IM_FREE(T)(ref T* ptr){igMemFree(cast(void*)ptr);}
16 enum IM_ALLOC(size_t size){return igMemAlloc(size);}
17 int IM_ARRAYSIZE(T)(ref T var)
18 {
19     return cast(int)((var.sizeof)/((*(var).ptr).sizeof)); //Same as var.sizeof/(*var).sizeof
20 }
21 void IM_ASSERT()(auto ref bool exp,  string msg = "")
22 {
23     assert(exp, msg);
24 }
25 void IM_DELETE(T)(ref T* p){if(p)destroy(p); igMemFree(p);}
26 
27 @nogc T* IM_NEW(T)()
28 {
29     import core.lifetime : emplace, forward;
30     import core.stdc.string:memset;
31     T* ptr = cast(T*)igMemAlloc(T.sizeof);
32     //*ptr = T.init;
33     return cast(T*)ptr;
34 }
35 
36 //Now the more specifics one that should not be used extensively
37 /**
38 * ImVector_reserve dependency
39 */
40 static int _grow_capacity(T)(ref T imvec, int size)
41 {
42     int new_capacity = imvec.Capacity ? (imvec.Capacity + imvec.Capacity / 2) : 8;
43     return new_capacity > size ? new_capacity : size;
44 }
45 
46 /**
47 *   ImVector_resize dependency
48 */
49 static void _reserve(T)(ref T imvec, int new_capacity)
50 {
51     if (new_capacity <= imvec.Capacity)
52         return; 
53     alias vecDataType = typeof(T.Data);
54 
55     vecDataType new_data = cast(vecDataType)IM_ALLOC(cast(size_t)new_capacity * T.sizeof);
56     if (imvec.Data) 
57     { 
58         memcpy(new_data, imvec.Data, cast(size_t)imvec.Size * T.sizeof);
59         IM_FREE(imvec.Data); 
60     }
61     imvec.Data = new_data;
62     imvec.Capacity = new_capacity;
63 }
64 
65 /**
66 *   Reserved for using on ImVector_
67 *   Required on Impl_SDL
68 */
69 void ImVector_resize(T)(ref T imvec, int new_size)
70 {
71     if (new_size > imvec.Capacity)
72     {
73         _reserve!T(imvec, _grow_capacity!T(imvec, new_size));
74         imvec.Size = new_size;
75     }
76 }
77 
78 /**
79 *   Reserver for using on ImVector_
80 *   Required on Impl_SDL
81 *    //As the data is a C array, it should be the *T.Data
82 */
83 void ImVector_push_back(T)(ref T vec, const ref typeof(*T.Data) v)
84 { 
85     if (vec.Size == vec.Capacity) 
86         _reserve!T(vec, _grow_capacity!T(vec, vec.Size + 1));
87     memcpy(&vec.Data[vec.Size], &v, v.sizeof);
88     vec.Size++; 
89 }
90 
91 //NOT AUTO-GENERATED, CIMGUI SPECIFIC:
92 
93 version(CIMGUI_VIEWPORT_BRANCH)
94 {
95     // NOTE: Some function pointers in the ImGuiPlatformIO structure are not C-compatible because of their
96     // use of a complex return type. To work around this, we store a custom CimguiStorage object inside
97     // ImGuiIO::BackendLanguageUserData, which contains C-compatible function pointer variants for these
98     // functions. When a user function pointer is provided, we hook up the underlying ImGuiPlatformIO
99     // function pointer to a thunk which accesses the user function pointer through CimguiStorage.
100     import bindbc.cimgui.types;
101 
102     extern(C) struct CimguiStorage
103     {
104         void function (ImGuiViewport* vp, ImVec2* out_pos) Platform_GetWindowPos;
105         void function (ImGuiViewport* vp, ImVec2* out_pos) Platform_GetWindowSize;
106     }
107     extern(C) @nogc nothrow
108     {
109         alias pImGuiPlatformIO_Set_Platform_GetWindowPos = void function(ImGuiPlatformIO* platform_io, void function (ImGuiViewport* vp, ImVec2* out_pos) user_callback);
110         alias pImGuiPlatformIO_Set_Platform_GetWindowSize = void function(ImGuiPlatformIO* platform_io, void function(ImGuiViewport* vp, ImVec2* out_size) user_callback);
111     } 
112     __gshared
113     {
114         pImGuiPlatformIO_Set_Platform_GetWindowPos ImGuiPlatformIO_Set_Platform_GetWindowPos;
115         pImGuiPlatformIO_Set_Platform_GetWindowSize ImGuiPlatformIO_Set_Platform_GetWindowSize;
116     }
117     import bindbc.loader:SharedLib, bindSymbol;
118     package void bindCimguiStorage(SharedLib lib)
119     {
120         lib.bindSymbol(cast(void**)&ImGuiPlatformIO_Set_Platform_GetWindowPos, "ImGuiPlatformIO_Set_Platform_GetWindowPos");
121         lib.bindSymbol(cast(void**)&ImGuiPlatformIO_Set_Platform_GetWindowSize, "ImGuiPlatformIO_Set_Platform_GetWindowSize");
122     }
123 }