Giter Club home page Giter Club logo

Comments (6)

pjueon avatar pjueon commented on July 28, 2024

If JetsonGPIO could use lambda objects or custom callable objects as callback,
the problem would be very easy and clean.

But unfortunately current version of JetsonGPIO can only use function pointers as callback,
so I think global object or singleton pattern is the only option for now.

for example, something like this

static MyGPIO* pGpio = nullptr;

static void Snap(int iPin)
{
    if(pGpio == nullptr)
        return;
    //...
};

//---------------------------------------------------------------------------
bool MyGPIO::LoadGPIO()
{
    pGpio = this;
    int iPin = 18;
    GPIO::setup(iPin, GPIO::IN);
    GPIO::add_event_detect(iPin, GPIO::Edge::RISING, Snap, 50);
}

In the future, I want to make JetsonGPIO supports std::function as callback type,
so that we can use all kinds of callable types (ex> lambda, function pointer, std::bind, user-defined callable class),
but there is a technical issue.

I don't know how to implement remove_event_callback function with std::function,
because you cannot compare 2 std::function objects for equality in general.
(https://stackoverflow.com/questions/20833453/comparing-stdfunctions-for-equality)

If somebody has any idea for this issue, please let me know.

from jetsongpio.

pjueon avatar pjueon commented on July 28, 2024

Ok, I came up with an idea to support custom type callback!
And I've just updated the master branch. Pull the master branch and re-build the library first.

Now any object that satisfies the following requirements can be used as callback functions.

  • Callable (argument type: int, return type: void)
  • Copy-constructible
  • Equality-comparable with same type (ex> func0 == func1)

So you don't need to use ugly global variables for this!
All you need to do is just define your custom callback class.

For example:

// define callback object
class MyCallback
{
public:
   explicit MyCallback(MyGPIO& myGPIO) : myGPIO(myGPIO) {}
   MyCallback(const MyCallback&) = default; // Copy-constructible

   void operator()(int channel) // Callable
   {
       // do something with myGPIO
   }

   bool operator==(const MyCallback& other) const // Equality-comparable
   {
       // equality compare example:
       return myGPIO == other.myGPIO;
   }

private:
   MyGPIO& myGPIO;
};

//------
bool MyGPIO::LoadGPIO()
{
   // create callback object
   MyCallback my_callback(*this);
   int iPin = 18;
   GPIO::setup(iPin, GPIO::IN);
   GPIO::add_event_detect(iPin, GPIO::Edge::RISING, my_callback, 50);
}

Or you can also make MyGPIO class into callback itself if you want.

from jetsongpio.

yassiezar avatar yassiezar commented on July 28, 2024

I'm having some trouble implementing the custom type callback class you posted. Here's my code:

#include <functional>

class GpioCallback {
 public:
  using CallbackType = std::string;
  using Callback = std::function<void(const CallbackType&)>;

  explicit GpioCallback() {}
  GpioCallback(const GpioCallback&) = default;

  void operator()(const CallbackType& channel) { callback_(channel); }
  bool operator==(const GpioCallback& other) const { 
    /* placeholder for now */
    return true; 
  }

  void setCallback(Callback callback) { callback_ = callback; }

 private:
  Callback callback_;
};

I'm not passing in the GPIO controller object for now to avoid a circular include issue I've been having and using placeholders instead. However, when I change CallbackType from std::string to e.g. int, I get a compile error:

error: no matching function for call to β€˜std::function<void(const std::__cxx11::basic_string<char>&)>::function(GpioCallback&)’
         comparer([](const func_t& A, const func_t& B) { return comparer_impl<std::decay_t<T>>(A, B); })

Is this the expected behaviour? Am I doing something silly? I've tried it on the latest release and master branches

from jetsongpio.

pjueon avatar pjueon commented on July 28, 2024

@yassiezar

However, when I change CallbackType from std::string to e.g. int, I get a compile error:

In the earlier version of the library(at the moment I posted this example), the channel type in the callback was int.
But in the latest version, it changed to const std::string& from int (related to #39, #40).
So the callback object MUST be callable with const std::string& argument now, not int.

So in your code, the GpioCallback::CallbackType must be std::string. If you want to use callbacks with int type channel,
you can change your code like this:

class GpioCallback {
  using CallbackType = int;
  using Callback = std::function<void(const CallbackType&)>;
  
  /*...*/
  
  // the argument type of the operator() MUST be const std::string& 
  void operator()(const std::string& channel) 
  { 
     // cast the channel to int by std::stoi
    callback_(std::stoi(channel)); 
  }
  
  /*...*/
};

The support for callbacks with int argument might be added in the future, not sure.

from jetsongpio.

yassiezar avatar yassiezar commented on July 28, 2024

Thanks for the quick response. Your suggestions worked and we can use callbacks with different signatures, but still using std::string for the channel names. Using intfor the channel isn't really that crucial, I just wanted to use different signatures for the callbacks themselves

from jetsongpio.

pjueon avatar pjueon commented on July 28, 2024

@yassiezar
You mean you want to use your callback without those wrapper?

from jetsongpio.

Related Issues (20)

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.