Skip to content

Commit

Permalink
[Wrapper] Updated wrappers and implemented Canvas event listeners in …
Browse files Browse the repository at this point in the history
…C99 wrapper.

- Moved event listener wrapper logic into EventListenerContainer template.
- Added wrapper callback types and functions for new Canvas event listener interface.
- Implemented canvas event handling in C99 wrapper.
- Updated auto-generated C# and Go wrappers.
  • Loading branch information
LukasBanana committed Aug 8, 2024
1 parent bc8dc02 commit 2dca042
Show file tree
Hide file tree
Showing 7 changed files with 265 additions and 52 deletions.
30 changes: 28 additions & 2 deletions include/LLGL-C/Canvas.h
Original file line number Diff line number Diff line change
Expand Up @@ -15,25 +15,51 @@


typedef void (*LLGL_PFN_OnCanvasProcessEvents)(LLGLCanvas sender);
typedef void (*LLGL_PFN_OnCanvasQuit)(LLGLCanvas sender, bool* veto);
typedef void (*LLGL_PFN_OnCanvasQuit)(LLGLCanvas sender, bool* veto); //LLGL_DEPRECATED("LLGL_PFN_OnCanvasQuit is deprecated since 0.04b; Use custom state instead!")
typedef void (*LLGL_PFN_OnCanvasInit)(LLGLCanvas sender);
typedef void (*LLGL_PFN_OnCanvasDestroy)(LLGLCanvas sender);
typedef void (*LLGL_PFN_OnCanvasDraw)(LLGLCanvas sender);
typedef void (*LLGL_PFN_OnCanvasResize)(LLGLCanvas sender, const LLGLExtent2D* clientAreaSize);
typedef void (*LLGL_PFN_OnCanvasTapGesture)(LLGLCanvas sender, const LLGLOffset2D* position, uint32_t numTouches);
typedef void (*LLGL_PFN_OnCanvasPanGesture)(LLGLCanvas sender, const LLGLOffset2D* position, uint32_t numTouches, float dx, float dy, LLGLEventAction action);
typedef void (*LLGL_PFN_OnCanvasKeyDown)(LLGLCanvas sender, LLGLKey keyCode);
typedef void (*LLGL_PFN_OnCanvasKeyUp)(LLGLCanvas sender, LLGLKey keyCode);

typedef struct LLGLCanvasEventListener
{
LLGL_PFN_OnCanvasProcessEvents onProcessEvents;
LLGL_PFN_OnCanvasQuit onQuit;
LLGL_PFN_OnCanvasQuit onQuit; //LLGL_DEPRECATED("onQuit is deprecated since 0.04b; Use custom state instead!")
LLGL_PFN_OnCanvasInit onInit;
LLGL_PFN_OnCanvasDestroy onDestroy;
LLGL_PFN_OnCanvasDraw onDraw;
LLGL_PFN_OnCanvasResize onResize;
LLGL_PFN_OnCanvasTapGesture onTapGesture;
LLGL_PFN_OnCanvasPanGesture onPanGesture;
LLGL_PFN_OnCanvasKeyDown onKeyDown;
LLGL_PFN_OnCanvasKeyUp onKeyUp;
}
LLGLCanvasEventListener;

LLGL_C_EXPORT LLGLCanvas llglCreateCanvas(const LLGLCanvasDescriptor* canvasDesc);
LLGL_C_EXPORT void llglReleaseCanvas(LLGLCanvas canvas);
LLGL_C_EXPORT void llglSetCanvasTitle(LLGLCanvas canvas, const wchar_t* title);
LLGL_C_EXPORT size_t llglGetCanvasTitle(LLGLCanvas canvas, size_t outTitleLength, wchar_t* outTitle LLGL_ANNOTATE(NULL));
//LLGL_DEPRECATED("llglHasCanvasQuit is deprecated since 0.04b; Use custom state instead!")
LLGL_C_EXPORT bool llglHasCanvasQuit(LLGLCanvas canvas);
LLGL_C_EXPORT void llglSetCanvasUserData(LLGLCanvas canvas, void* userData);
LLGL_C_EXPORT void* llglGetCanvasUserData(LLGLCanvas canvas);
LLGL_C_EXPORT int llglAddCanvasEventListener(LLGLCanvas canvas, const LLGLCanvasEventListener* eventListener);
LLGL_C_EXPORT void llglRemoveCanvasEventListener(LLGLCanvas canvas, int eventListenerID);
//LLGL_DEPRECATED("llglPostCanvasQuit is deprecated since 0.04b; Use custom state instead!")
LLGL_C_EXPORT void llglPostCanvasQuit(LLGLCanvas canvas);
LLGL_C_EXPORT void llglPostCanvasInit(LLGLCanvas sender);
LLGL_C_EXPORT void llglPostCanvasDestroy(LLGLCanvas sender);
LLGL_C_EXPORT void llglPostCanvasDraw(LLGLCanvas sender);
LLGL_C_EXPORT void llglPostCanvasResize(LLGLCanvas sender, const LLGLExtent2D* clientAreaSize);
LLGL_C_EXPORT void llglPostCanvasTapGesture(LLGLCanvas sender, const LLGLOffset2D* position, uint32_t numTouches);
LLGL_C_EXPORT void llglPostCanvasPanGesture(LLGLCanvas sender, const LLGLOffset2D* position, uint32_t numTouches, float dx, float dy, LLGLEventAction action);
LLGL_C_EXPORT void llglPostCanvasKeyDown(LLGLCanvas sender, LLGLKey keyCode);
LLGL_C_EXPORT void llglPostCanvasKeyUp(LLGLCanvas sender, LLGLKey keyCode);


#endif
Expand Down
8 changes: 8 additions & 0 deletions include/LLGL-C/LLGLWrapper.h
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,14 @@

/* ----- Enumerations ----- */

typedef enum LLGLEventAction
{
LLGLEventActionBegan,
LLGLEventActionChanged,
LLGLEventActionEnded,
}
LLGLEventAction;

typedef enum LLGLRenderConditionMode
{
LLGLRenderConditionModeWait,
Expand Down
96 changes: 90 additions & 6 deletions wrapper/C99/C99Canvas.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
#include <LLGL/Canvas.h>
#include <LLGL-C/Canvas.h>
#include "C99Internal.h"
#include "C99EventListenerContainer.h"
#include "../sources/Core/CoreUtils.h"
#include "../sources/Core/Exception.h"
#include <vector>
Expand Down Expand Up @@ -35,16 +36,55 @@ class InternalCanvasEventListener final : public Canvas::EventListener
memcpy(&callbacks_, callbacks, sizeof(LLGLCanvasEventListener));
}

void OnQuit(Canvas& sender, bool& veto) override
void OnInit(Canvas& sender) override
{
LLGL_CALLBACK_WRAPPER(onQuit, &veto);
LLGL_CALLBACK_WRAPPER(onInit);
}

void OnDestroy(Canvas& sender) override
{
LLGL_CALLBACK_WRAPPER(onDestroy);
}

void OnDraw(Canvas& sender) override
{
LLGL_CALLBACK_WRAPPER(onDraw);
}

void OnResize(Canvas& sender, const Extent2D& clientAreaSize) override
{
LLGL_CALLBACK_WRAPPER(onResize, (const LLGLExtent2D*)&clientAreaSize);
}

void OnTapGesture(Canvas& sender, const Offset2D& position, std::uint32_t numTouches) override
{
LLGL_CALLBACK_WRAPPER(onTapGesture, (const LLGLOffset2D*)&position, numTouches);
}

void OnPanGesture(Canvas& sender, const Offset2D& position, std::uint32_t numTouches, float dx, float dy, EventAction action) override
{
LLGL_CALLBACK_WRAPPER(onPanGesture, (const LLGLOffset2D*)&position, numTouches, dx, dy, (LLGLEventAction)action);
}

void OnKeyDown(Canvas& sender, Key keyCode) override
{
LLGL_CALLBACK_WRAPPER(onKeyDown, (LLGLKey)keyCode);
}

void OnKeyUp(Canvas& sender, Key keyCode) override
{
LLGL_CALLBACK_WRAPPER(onKeyUp, (LLGLKey)keyCode);
}


};

using CanvasEventListenerContainer = EventListenerContainer<InternalCanvasEventListener, LLGLCanvasEventListener>;

#undef LLGL_CALLBACK_WRAPPER

static std::vector<std::unique_ptr<Canvas>> g_Canvases;
static CanvasEventListenerContainer g_CanvasEventListenerContainer;

static void ConvertCanvasDesc(CanvasDescriptor& dst, const LLGLCanvasDescriptor& src)
{
Expand Down Expand Up @@ -91,7 +131,7 @@ LLGL_C_EXPORT size_t llglGetCanvasTitle(LLGLCanvas canvas, size_t outTitleLength

LLGL_C_EXPORT bool llglHasCanvasQuit(LLGLCanvas canvas)
{
return LLGL_PTR(Canvas, canvas)->HasQuit();
return false; // deprecated
}

LLGL_C_EXPORT void llglSetCanvasUserData(LLGLCanvas canvas, void* userData)
Expand All @@ -106,20 +146,64 @@ LLGL_C_EXPORT void* llglGetCanvasUserData(LLGLCanvas canvas)

LLGL_C_EXPORT int llglAddCanvasEventListener(LLGLCanvas canvas, const LLGLCanvasEventListener* eventListener)
{
return 0; //todo
auto eventListenerWrapper = g_CanvasEventListenerContainer.Create(eventListener);
LLGL_PTR(Canvas, canvas)->AddEventListener(eventListenerWrapper.second);
return eventListenerWrapper.first;
}

LLGL_C_EXPORT void llglRemoveCanvasEventListener(LLGLCanvas canvas, int eventListenerID)
{
//todo
if (auto eventListener = g_CanvasEventListenerContainer.Release(eventListenerID))
LLGL_PTR(Canvas, canvas)->RemoveEventListener(eventListener.get());
}

LLGL_C_EXPORT void llglPostCanvasQuit(LLGLCanvas canvas)
{
LLGL_PTR(Canvas, canvas)->PostQuit();
// deprecated
}

LLGL_C_EXPORT void llglPostCanvasInit(LLGLCanvas sender)
{
LLGL_PTR(Canvas, sender)->PostInit();
}

LLGL_C_EXPORT void llglPostCanvasDestroy(LLGLCanvas sender)
{
LLGL_PTR(Canvas, sender)->PostDestroy();
}

LLGL_C_EXPORT void llglPostCanvasDraw(LLGLCanvas sender)
{
LLGL_PTR(Canvas, sender)->PostDraw();
}

LLGL_C_EXPORT void llglPostCanvasResize(LLGLCanvas sender, const LLGLExtent2D* clientAreaSize)
{
LLGL_PTR(Canvas, sender)->PostResize(*(const Extent2D*)clientAreaSize);
}

LLGL_C_EXPORT void llglPostCanvasTapGesture(LLGLCanvas sender, const LLGLOffset2D* position, uint32_t numTouches)
{
LLGL_PTR(Canvas, sender)->PostTapGesture(*(const Offset2D*)position, numTouches);
}

LLGL_C_EXPORT void llglPostCanvasPanGesture(LLGLCanvas sender, const LLGLOffset2D* position, uint32_t numTouches, float dx, float dy, LLGLEventAction action)
{
LLGL_PTR(Canvas, sender)->PostPanGesture(*(const Offset2D*)position, numTouches, dx, dy, (EventAction)action);
}

LLGL_C_EXPORT void llglPostCanvasKeyDown(LLGLCanvas sender, LLGLKey keyCode)
{
LLGL_PTR(Canvas, sender)->PostKeyDown((Key)keyCode);
}

LLGL_C_EXPORT void llglPostCanvasKeyUp(LLGLCanvas sender, LLGLKey keyCode)
{
LLGL_PTR(Canvas, sender)->PostKeyUp((Key)keyCode);
}



// } /namespace LLGL


Expand Down
63 changes: 63 additions & 0 deletions wrapper/C99/C99EventListenerContainer.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
/*
* C99EventListenerContainer.h
*
* Copyright (c) 2015 Lukas Hermanns. All rights reserved.
* Licensed under the terms of the BSD 3-Clause license (see LICENSE.txt).
*/

#ifndef LLGL_C99_EVENT_LISTENER_CONTAINER_H
#define LLGL_C99_EVENT_LISTENER_CONTAINER_H


#include "../../sources/Core/Assertion.h"
#include <unordered_map>
#include <mutex>
#include <memory>
#include <limits.h>


template <typename TEventListener, typename TWrapperCallbacks>
class EventListenerContainer
{

public:

using TEventListenerSPtr = std::shared_ptr<TEventListener>;

std::pair<int, TEventListenerSPtr> Create(const TWrapperCallbacks* callbacks)
{
std::lock_guard<std::mutex> guard{ mutex_ };
LLGL_ASSERT(idCounter_ < INT_MAX);
const int id = ++idCounter_;
std::pair<int, TEventListenerSPtr> result{ id, std::make_shared<TEventListener>(callbacks) };
eventListeners_.insert(result);
return result;
}

TEventListenerSPtr Release(int id)
{
std::lock_guard<std::mutex> guard{ mutex_ };
auto it = eventListeners_.find(id);
if (it != eventListeners_.end())
{
TEventListenerSPtr result = std::move(it->second);
eventListeners_.erase(it);
return result;
}
return nullptr;
}

private:

int idCounter_ = 0;
std::unordered_map<int, TEventListenerSPtr> eventListeners_;
std::mutex mutex_;

};


#endif



// ================================================================================
44 changes: 3 additions & 41 deletions wrapper/C99/C99Window.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -8,15 +8,13 @@
#include <LLGL/Window.h>
#include <LLGL-C/Window.h>
#include "C99Internal.h"
#include "C99EventListenerContainer.h"
#include "../sources/Core/CoreUtils.h"
#include "../sources/Core/Exception.h"
#include <vector>
#include <string>
#include <string.h>
#include <algorithm>
#include <unordered_map>
#include <mutex>
#include <limits.h>


// namespace LLGL {
Expand Down Expand Up @@ -101,43 +99,7 @@ class InternalWindowEventListener final : public Window::EventListener

};

using InternalWindowEventListenerSPtr = std::shared_ptr<InternalWindowEventListener>;

class WindowEventListenerContainer
{

public:

std::pair<int, InternalWindowEventListenerSPtr> Create(const LLGLWindowEventListener* callbacks)
{
std::lock_guard<std::mutex> guard{ mutex_ };
LLGL_ASSERT(idCounter_ < INT_MAX);
const int id = ++idCounter_;
std::pair<int, InternalWindowEventListenerSPtr> result{ id, std::make_shared<InternalWindowEventListener>(callbacks) };
eventListeners_.insert(result);
return result;
}

InternalWindowEventListenerSPtr Release(int id)
{
std::lock_guard<std::mutex> guard{ mutex_ };
auto it = eventListeners_.find(id);
if (it != eventListeners_.end())
{
InternalWindowEventListenerSPtr result = std::move(it->second);
eventListeners_.erase(it);
return result;
}
return nullptr;
}

private:

int idCounter_ = 0;
std::unordered_map<int, InternalWindowEventListenerSPtr> eventListeners_;
std::mutex mutex_;

};
using WindowEventListenerContainer = EventListenerContainer<InternalWindowEventListener, LLGLWindowEventListener>;

#undef LLGL_CALLBACK_WRAPPER

Expand Down Expand Up @@ -297,7 +259,7 @@ LLGL_C_EXPORT int llglAddWindowEventListener(LLGLWindow window, const LLGLWindow

LLGL_C_EXPORT void llglRemoveWindowEventListener(LLGLWindow window, int eventListenerID)
{
if (InternalWindowEventListenerSPtr eventListener = g_WindowEventListenerContainer.Release(eventListenerID))
if (auto eventListener = g_WindowEventListenerContainer.Release(eventListenerID))
LLGL_PTR(Window, window)->RemoveEventListener(eventListener.get());
}

Expand Down
Loading

0 comments on commit 2dca042

Please sign in to comment.