axmolengine / axmol

Axmol Engine – A Multi-platform Engine for Desktop, XBOX (UWP) and Mobile games. (A fork of Cocos2d-x-4.0)
https://axmol.dev
MIT License
922 stars 205 forks source link

Crash in TextFieldTTF::update line #478 #1889

Closed TyelorD closed 6 months ago

TyelorD commented 6 months ago

Steps to Reproduce:

  1. In the MainScene::init function, create, setup, and add a TextField object to the scene, e.g.:
    static auto textField = axmol::ui::UICCTextField::create("Custom", "fonts/arial.ttf", 24);
    textField->setPosition(Vec2(origin.x + visibleSize.width / 2, origin.y + visibleSize.height - textField->getContentSize().height));
    this->addChild(textField, 1);
  2. Add a way to open and close the IME, e.g.:

    auto mouseListener = EventListenerMouse::create();
    mouseListener->onMouseUp = [this] (ax::Event* event) {
    textField->setPlaceHolder("Enter Text...");
    
    isOpen = !isOpen;
    if (isOpen) {
        textField->openIME();
    } else {
        textField->closeIME();
    }
    };
    _eventDispatcher->addEventListenerWithFixedPriority(mouseListener, 11);
  3. In the Config.h file, enable the AX_LABEL_DEBUG_DRAW preprocessor macro definition to enable the debug outlines around labels.
  4. Run the game, open the IME for that created textField object, and observe the crash that occurs on line #​1754 of Label.cpp, specifically when attempting to draw the polygon bounding box for the textField's label object, and line #​365 in DrawNode.cpp

If I manage to fix this crash I'll report back here, and likely post a pull request later for it too, but maybe someone here will beat me to fixing it 😅

Edit: A little more information, it looks like if I debug it line by line the crash doesn't occur and the TextField appears to work properly. When the crash does occur, V2F_C4B_T2F* point is still NULL after line #​359.

TyelorD commented 6 months ago

Alright, I've submitted PR #1890 with a fix for this bug. Feel free to pull my change in and then close this issue 🙂

rh101 commented 6 months ago

static auto textField = axmol::ui::UICCTextField::create("Custom", "fonts/arial.ttf", 24);

Is the static a typo?

TyelorD commented 6 months ago

static auto textField = axmol::ui::UICCTextField::create("Custom", "fonts/arial.ttf", 24);

Is the static a typo?

No, it was so that the reference to the textField pointer wasn't lost upon finishing the MainScene::init call, since the listener I wrote in step 2 uses that pointer reference in it's logic. This was just to avoid needing to have the textField declared in the header file, which would've been an additional file that needed changing for these repro steps.

(It probably wasn't needed here, since adding a Node as a child stops that pointer from being cleaned up. But I was just trying to be thorough here really. There is no harm in making textField a member field of MainScene either.)

rh101 commented 6 months ago

No, it was so that the reference to the textField pointer wasn't lost upon finishing the MainScene::init call, since the listener I wrote in step 2 uses that pointer reference in it's logic.

I understand. Another option would have been to capture it by value in the lambda, so you wouldn't need the static:

mouseListener->onMouseUp = [textField] (ax::Event* event) {

TyelorD commented 6 months ago

I understand. Another option would have been to capture it by value in the lambda, so you wouldn't need the static:

mouseListener->onMouseUp = [textField] (ax::Event* event) {

Ah, that's a good point: I hadn't considered that. Thank you for pointing that out!