lvgl / lv_binding_cpp

[WIP] C++ binding for LVGL
MIT License
44 stars 20 forks source link

Initial planning #1

Closed kisvegabor closed 2 years ago

kisvegabor commented 3 years ago

Continue https://github.com/lvgl/lvgl/issues/2303

It seems there is a consensus about some parts should be autogenerated and others are written manually. I suggest clarifying it first. If we see a list of tasks we can start to work on the tasks in parallel.

fstuff-dev commented 3 years ago

IMO we have to:

If i say wrong let me know !

fstuff-dev commented 3 years ago

For example LvObj i think should look like this:

namespace lvglpp {

class LvObj {
protected:
    LvPointer<lv_obj_t, lv_obj_del> cObj;
public:

    /* Creation and deletion */
    LvObj();
    LvObj(LvObj *Parent);
    virtual ~LvObj();

    /* Methods */
    lv_obj_t* raw();
        ....
};

}

LvPointer<lv_obj_t, lv_obj_del> cObj is the smart pointer constructed as we talked in the prev issue:

namespace lvglpp {

/* Template for custom deleter function */
template <auto DeleterFunction>
using CustomDeleter = std::integral_constant<decltype(DeleterFunction), DeleterFunction>;

/* Used for create a smart_pointer with custom deleter */
template <typename ManagedType, auto Functor>
using LvPointer = std::unique_ptr<ManagedType, CustomDeleter<Functor>>;

/* Sleep for milliseconds */
static void LvSleep(unsigned int ms) {
#ifdef __linux__
    usleep(ms * 1000);
#endif
}

.Cpp;


namespace lvglpp {

LvObj::LvObj() {
    cObj.reset(lv_obj_create(lv_scr_act()));
}

LvObj::LvObj(LvObj* Parent) {
    cObj.reset(lv_obj_create(Parent->raw()));
}

lv_obj_t* LvObj::raw() {
    return cObj.get();
}

LvObj::~LvObj() {

}

} /* namespace lvglpp */

So we have tho implement all LvObj method that works with cObj smart pointer.

kisvegabor commented 3 years ago

I'm ok with this approach, but I think the binding shouldn't implement functions like LvSleep. These are platform-specific and part of the C LVGL either.

I think it'd be great to auto-generate the C++ code of at least one widget. With this, we'd have something concrete to discuss.

fstuff-dev commented 3 years ago

I'm ok with this approach, but I think the binding shouldn't implement functions like LvSleep. These are platform-specific and part of the C LVGL either.

I think it'd be great to auto-generate the C++ code of at least one widget. With this, we'd have something concrete to discuss.

That’s ok it’s only a copy and paste … i use LvSleep for testing purpouse in Linux …

fstuff-dev commented 3 years ago

I think it'd be great to auto-generate the C++ code of at least one widget. With this, we'd have something concrete to discuss.

Ok i'm ready with auto-generated widget. i will upload tomorrow !!

kisvegabor commented 3 years ago

Cool, looking forward to it!

fstuff-dev commented 3 years ago

Hi you can find First autogenerated widgets on my personal repo https://github.com/fstuff-dev/lvglpp/tree/main/lv_cpp . Let me know. I have some doubts about it !

kisvegabor commented 3 years ago

I like it! Simple and elegant.

cc: @scottandrew @puzrin @ropg @liebman @zapta @ShenRen @ValentiWorkLearning @embeddedt

ValentiWorkLearning commented 3 years ago

We have to somehow define the range of supported standards for the wrapper. The generated code seems ok for C++98 like, but I don't know how has it been generated.

fstuff-dev commented 3 years ago

Ok … how can i improve the code ?! The code is autogenerated with personal python script that use pycparser library !

kisvegabor commented 3 years ago

The code is autogenerated with personal python script that use pycparser library !

Could you share the script too?

fstuff-dev commented 3 years ago

I'm not a python expert so my script can be very ugly and bad programmed. I'll make a clean up of the script and then i will upload it.

fstuff-dev commented 3 years ago

i've uploaded the script..... Please be gentle !!!! This really sucks !!!

kisvegabor commented 3 years ago

Great! I'm also not a Python developer so I can't judge it. (I write much more chaotic Python scripts :smile: )

ValentiWorkLearning commented 3 years ago

@fstuff-dev

void addStyle(lv_style_t *style, lv_style_selector_t selector);

It's better to return the reference to corresponding object. For instance, it can be useful to apply chainable methods here.

LvObj rectangle{};
rectangle
.addStyle(redColor,selector)
.addStyle(greenColor,selector);

I guess, almost all of the set methods should have a signature like:

LvCorrespondingType& setSomething(params);

where LvCorrespondingType is a LVGL type like a LvObj or LvButton

fstuff-dev commented 3 years ago

@fstuff-dev

void addStyle(lv_style_t *style, lv_style_selector_t selector);

It's better to return the reference to corresponding object. For instance, it can be useful to apply chainable methods here.

LvObj rectangle{};
rectangle
.addStyle(redColor,selector)
.addStyle(greenColor,selector);

I guess, almost all of the set methods should have a signature like:

LvCorrespondingType& setSomething(params);

where LvCorrespondingType is a LVGL type like a LvObj or LvButton

I Think that is a good idea ! I will work in it in my return from my holidays !!! 👍

fstuff-dev commented 3 years ago

Hi what about to return object reference for each void methods ? @ValentiWorkLearning

fstuff-dev commented 3 years ago

Hi what about to return object reference for each void methods ? @ValentiWorkLearning

done in my repo !

ValentiWorkLearning commented 3 years ago

@fstuff-dev Seems much better.

  1. virtual ~LvLed(); let's mark all of the child d-tors with the override specifier.
  2. LvTable& LvTable::setCellValueFmt(uint16_t row, uint16_t col, const char *fmt, ...) { - it's better to use the variadic templates here.

int32_t LvSlider::getLeftValue() { return lv_slider_get_left_value(cObj.get()); } int32_t LvSlider::getMinValue() { return lv_slider_get_min_value(cObj.get()); } int32_t LvSlider::getMaxValue() {


It would be better to have getter methods with const-cvalified modifier, like this
```cpp
int32_t LvSlider::getLeftValue() const noexcept {
     return lv_slider_get_left_value(cObj.get());
}
int32_t LvSlider::getMinValue() const noexcept{
     return lv_slider_get_min_value(cObj.get());
}
int32_t LvSlider::getMaxValue() const noexcept{

It's necessary to add noexcept for a slightly optimized code.

fstuff-dev commented 3 years ago

@ValentiWorkLearning Ok , Now it's time to talk about Events and C++ Calback. What method should we use for that:

Let me know !

zapta commented 3 years ago

Can you provide code snippets that demonstrate how each of the options will be used (from user's perspective)? I would give high weight for code simplicity.

On Thu, Aug 5, 2021 at 4:50 AM fstuff-dev @.***> wrote:

@ValentiWorkLearning https://github.com/ValentiWorkLearning Ok , Now it's time to talk about Events and C++ Calback. What method should we use for that:

  • std::function and lambdas
  • Custom static method "EventDispatcher"
  • Custom LvEvent template class (That's what i use for callbacks)
  • other methods

Let me know !

— You are receiving this because you were mentioned. Reply to this email directly, view it on GitHub https://github.com/lvgl/lv_binding_cpp/issues/1#issuecomment-893395585, or unsubscribe https://github.com/notifications/unsubscribe-auth/AAQVMQLM3WKHGIBUS6OEHWDT3J3HVANCNFSM47QCYHFA . Triage notifications on the go with GitHub Mobile for iOS https://apps.apple.com/app/apple-store/id1477376905?ct=notification-email&mt=8&pt=524675 or Android https://play.google.com/store/apps/details?id=com.github.android&utm_campaign=notification-email .

fstuff-dev commented 3 years ago

@zapta I have upload some examples. This use my Event management system. it use a EventDispatcher that sacrify the user_data for store LvObj pointer. The Calsses in "lv_cpp/core" are only for explain the concepts that i want to implement. There'are used only for debug pourpose on a linux machine. If the ideas of how i'd like to implement the LvApp and other stuff are good i will spend some time and effort to make it better and portable.

if you like the example let me know !

fstuff-dev commented 3 years ago

Any updates or comments ?!

ValentiWorkLearning commented 3 years ago

@fstuff-dev I've looked through your examples implementation. Try to use LvPointerWrapper instead of the raw new/delete things.

ValentiWorkLearning commented 3 years ago

I guess, we can try to set-up CI build for this.

fstuff-dev commented 3 years ago

I guess, we can try to set-up CI build for this.

That,s a good idea ! But what do you Think about working on official repo !? @kisvegabor

kisvegabor commented 3 years ago

I'd love to work here because it makes the more more visible.

@fstuff-dev If you wish I can add write access for you on this repo to make development easier.

fstuff-dev commented 3 years ago

That's what i'm talking about 👍 maybe @ValentiWorkLearning need access to the repo ?!🤔

fstuff-dev commented 3 years ago

if you prefer we can continue to work on my personal repo and when we have something more stable we'll release to lv_cpp_binding repo !

kisvegabor commented 3 years ago

@fstuff-dev I've sent an invitation.

The description of this repo has "[WIP]" tag, so it's fine to make the development here.

ValentiWorkLearning commented 3 years ago

@fstuff-dev it would be great to have wrote access to the development repo. I'll participate as soon as possible 😉

kisvegabor commented 3 years ago

@ValentiWorkLearning Invitation sent.

fstuff-dev commented 3 years ago

I'm working on other autogenerated Cpp Object. I will upload it soon. @kisvegabor

kisvegabor commented 3 years ago

What do you exactly mean by " Cpp Object"?

fstuff-dev commented 3 years ago

What do you exactly mean by " Cpp Object"?

For example for style or Themes. you can create and add style in this way:

    btnStyle = Make<LvStyle>();
    btnStyle->setBgColor(lv_palette_main(LV_PALETTE_RED)).
            setBgGradColor(lv_palette_lighten(LV_PALETTE_RED, 3));

    /* Button */
    btn = Make<LvBtn>();
    btn->addStyle(btnStyle->raw(), 0);

or Timers:

    timer = Make<LvTimer>();
    timer->setPeriod(1000).
            setCb(TimerCb).
            ready();

do you think that can be useful ?!

kisvegabor commented 3 years ago

These might be slightly out of scope

fstuff-dev commented 3 years ago

These might be slightly out of scope

  • is it safe to use such a generic name like Make?

We can choose another one !

  • would it be possible to eliminate the use of ->raw in btn->addStyle(btnStyle->raw(), 0);?

Yes i will pass the cpp object reference as method parameter ! So you can call it as:

btn->addStyle(btnStyle,0); 
kisvegabor commented 3 years ago

is it safe to use such a generic name like Make?

We can choose another one !

Could you remind me what was the problem with simple constructors, such as lv::Btn(parent)

would it be possible to eliminate the use of ->raw in btn->addStyle(btnStyle->raw(), 0);?

Yes i will pass the cpp object reference as method parameter !

Great, I think it'd be more intuitive.

fstuff-dev commented 3 years ago

is it safe to use such a generic name like Make?

We can choose another one !

Could you remind me what was the problem with simple constructors, such as lv::Btn(parent)

In my opinion there's no problem in using standard contructor !!! You can use both, std::unique_pointer with the use of Make and standard contructor with new Lvxxx(parent) . Using smart pointer is safer for memory garbage but the developer can use it or not !!! They are both implemented !!!

would it be possible to eliminate the use of ->raw in btn->addStyle(btnStyle->raw(), 0);?

Yes i will pass the cpp object reference as method parameter !

Great, I think it'd be more intuitive.

kisvegabor commented 3 years ago

In my opinion there's no problem in using standard contructor !!! ...

Great! :+1: What is the next step?

fstuff-dev commented 2 years ago

Moving on new issue ! #4