How to set a non-lambda button callback?

Hey everyone. I was wondering how to set a button callback without using a lambda expression, and instead using a variant of CC_CALLBACK.
I do not know where to find how to do this though, so I would appreciate if someone could tell me :>)

std::bind would be the right choice for C++11, but there is no reason for it if you’re using C++14. It’s better to just keep using lambdas, but call the method you actually want from within it. Some info here as to the reasons why.

For example, for an EventListenerTouchOneByOne:

auto* eventListener = EventListenerTouchOneByOne::create();
eventListener ->onTouchBegan = [this](cocos2d::Touch* touch, cocos2d::Event* e) -> bool {
    return this->GetSomeBoolFromClassMethod();
};

Alternatively, if you’re set on using std::bind:

eventListener ->onTouchBegan = std::bind(&ClassName::GetSomeBoolFromClassMethod, this, std::placeholders::_1, std::placeholders::_2);

// or 
using namespace std::placeholders;
eventListener ->onTouchBegan = std::bind(&ClassName::GetSomeBoolFromClassMethod, this, _1, _2);
1 Like

What I am trying to do is set a button callback.
And also there is a reason why I do not want to use lambdas.
I mentioned it in one of my previous posts, but I cannot seem to edit any variable declared outside the lambda scope, even if I put it in the capture list. I constantly get errors like “access violation writing location”.
Look into that post and tell me a way I could fix that.
Basically what I am trying to do is make a custom level editor for myself, similar to the one seen in geometry dash:

The problem is that I do not know how the creator of geometry dash made the buttons work, I am making my buttons so when they are pressed they change a string value which is used to determine what texture a block will use when placed. And I am generating buttons by looping through a dictionary which has the key as a string that represents the texture and the value the block type.

You probably shouldn’t have created a new post, since it’s still about the same issue as your other post.

Your issue has nothing to do with any limitation of lambdas, but rather your usage of them. You would have the same problem whether you used lambda, std::bind or anything else. You should brush up on C++ and lambda captures: https://en.cppreference.com/w/cpp/language/lambda. Scroll down to the Lambda capture section on that page.

If the information there doesn’t make sense, then it’s perhaps advantageous to brush up on C++ and certain concepts related to what you’re trying to achieve.

1 Like

Alright, I will brush up on C++ since I did not in a significant amount of time, but as for the concepts related to what I am trying to do, there is no information I can find about how to make custom level editors in cocos2d-x like I mentioned with Geometry Dash.

If only there was a step-by-step guide for everything in life. :wink:

You seem to be diving into the deep end without first learning how to stay afloat, let alone swim.

The developers of something like Geometry Dash would have put a lot of time, effort and thought into creating the level editor; it didn’t happen overnight, and it is quite unlikely they had a step-by-step guide on how to create it.

Break down the problem into smaller and smaller pieces until what you have in front of you is something you can understand and work on. If you run into problems like what you’ve faced with lambdas, then look into why, and don’t just instantly blame the programming language constructs. It is most likely indicating a gap in your knowledge, so address that first, and as things become clearer, they also become easier. It’s the only way to improve as a developer.

4 Likes

I already broke the problem of how to create the editor into pieces, and it was all going alright and how I expected it to until the point it started throwing me errors while I was making the system that would generate and separate the buttons in pages.
Those errors made me question if I am even doing this the right way :thinking:

Anyways I am sorry if I sound incredibly annoying and entitled but it is bugging me that I cannot get a simple feature to work just because of my lack of knowledge about lambda expression capture lists.
Especially since Geometry Dash took the developer 4 months to make!

How long they took to make that game is only a reflection of their knowledge and abilities, so you can’t apply that to how long it will take you to create something similar.

To point you in the right direction, as another user here has already pointed out in the other thread, the issue is related to the scope of the data you’re working with. The reason you’re getting the crashes is because you’re working with temporary variables that either disappear off the stack when they are no longer in scope, or they change value.

When you capture a variable in the lambda, you either capture it by reference or by value. If you capture it by reference, then just remember that at the future point when the lambda is entered into, the lambda will act on the current state of the value in the reference. The reference would be pointing to data that either may no longer exist, or different data altogether.

If you capture by value, then that means you’ve taken a snapshot of those variables, and when the lambda is entered into then it will be operating on those values as they are. There is no way those values can change.

A simple solution would be to store whatever data you want access to in your class, and access the data of that instance of the class via the this pointer. Capture this in your lambda, and go from there.

[this]() {
    this->_memberVariable = 1234;
    this->getData();
    this->setData();
}
2 Likes

I’m currently building a level editor for a game I’ve spent 5 years on. I don’t need the editor. I’m happy to build me levels on graph paper and put my level data into a txt file and read it in on demand.

However, users of my unreleased game think it’s cool enough to contribute their own levels. So why not.

@r101 has given you defacto information. Read it and absorb it.

As far as building your own level editor. It’s simple to get started. Put a few blocks on the screen. Click and drag them around and have the editor write out the new values into a text file. Have a clear screen button. Clear all objects. Have a load button. Click it and have it load back in the file you just wrote. Once you have this working. Go to town. Add more stuff like pallets. A property editor, physics boundaries, etc etc etc etc etc. this task will take you months at the very least depending upon skill level. It’s not trivial but rather time consuming to catch every detail.

I already started making a level editor and I finished a lot of features up until now. I made a DrawNode to automatically draw a grid of 64x64 tiles, and when you place a block it automatically snaps it to that grid. Now, I am testing around with making buttons that would allow users(and me, since I will be using this editor to make the levels as well) to change the block texture (so for example if they wanted to add a spike, they click on the spike button and they will be placing spike objects). I have added a system that runs through each object in the map, and writes it to a .plist file.
So I already have some stuff done, but these weird bugs stopped me from continuing. Fortunately @R101 answered my question and things seem to be working okay.
So we will see and I might post my progress on the forum if I feel like it.

What weird bugs?

Well it is not weird actually because I learnt how lambda expressions actually work, but when I tried changing a variable in a lambda I kept getting writing location violations inside that lambdaimage

That’s not a bug though. I re-read this thread and I don’t see any bugs for us to fix.

This topic was automatically closed 24 hours after the last reply. New replies are no longer allowed.