nefarius / ViGEmClient

ViGEm Client SDK for feeder development.
https://docs.nefarius.at/projects/ViGEm/
MIT License
134 stars 65 forks source link

Extra data to callback #8

Closed ya-isakov closed 4 years ago

ya-isakov commented 4 years ago

Is your feature request related to a problem? Please describe. It looks like there are cases, where notification callback functions will need extra data, for example, if they need to store some state between runs.

Describe the solution you'd like Usual way in C is to add void *user_data parameter in register function, store it somewhere, and pass to every callback run.

Describe alternatives you've considered I've tried to find other ways, but all solutions are saying that user_data is the best and only way to keep some external state between callback runs.

Additional context One example of such approach in Go

ya-isakov commented 4 years ago

Please, add it, maybe as additional function, as I'm blocked by it right now - I need my callback function to have access to UDP socket, which is opened in my program and somehow should be passed to every run of callback function

nefarius commented 4 years ago

Hold your horses, buddy ☺️ I get your suggestion and it makes sense to allow passing custom context data along, had that suggestion thrown my way before. I welcome anybody to make a high quality PR or wait until 2020 when I'm - hopefully - back in business. Cheers! 😘

ttsuki commented 4 years ago

Hi.

I think void *user_data is a best approach, too.

By the way, if you are in a hurry, for your information, you can also achieve it with the static instance of the callback table like as in following pseudocode:


// (pClient, pTarget) -> UserData*
static thread_safe_map<std::pair<PVIGEM_CLIENT, PVIGEM_TARGET>, UserData*> callbackTable_;

static void __stdcall X360NotificationCallbackHandler(
    PVIGEM_CLIENT Client, PVIGEM_TARGET Target,
    UCHAR LargeMotor, UCHAR SmallMotor, UCHAR LedNumber)
{
    if (UserData* p = callbackTable_.get({Client, Target}))
        p->Notify(LargeMotor, SmallMotor, LedNumber)
}
// ...
auto client_ = vigem_alloc();
auto target_ = vigem_target_x360_alloc();
callbackTable_.insert({client_, target_}, this);
vigem_target_add(client_, target_);
vigem_target_x360_register_notification(client_, target_, &X360NotificationCallbackHandler);

This may not be the best way, but it is enough for me.

My implementation is available following link. https://github.com/ttsuki/ProconXInputTE/tree/master/ViGEmClient

FYI, thanks,

jpflouret commented 4 years ago

@nefarius - I believe you can close this issue now.

nefarius commented 4 years ago

Let's do it then 😎