Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix memory leak on luaPlayerShowTextDialog - double ref #3752

Merged
merged 3 commits into from
Oct 31, 2021
Merged

Fix memory leak on luaPlayerShowTextDialog - double ref #3752

merged 3 commits into from
Oct 31, 2021

Conversation

ramon-bernardo
Copy link
Contributor

@ramon-bernardo ramon-bernardo commented Oct 20, 2021

Pull Request Prelude

Changes Proposed

  • Fix memory leak on luaPlayerShowTextDialog - double ref

  • Player::setWriteItem and Item::CreateItem will add reference so we'll end up with 2 references and since we'll have 2 references the memory allocated will never be destroyed.

@Zbizu
Copy link
Contributor

Zbizu commented Oct 21, 2021

wasn't there some way to check if item is virtual? Could save effort setting all those variables.

@MillhioreBT
Copy link
Contributor

MillhioreBT commented Oct 22, 2021

I agree, however those booleans look a bit ugly, you should find some more beautiful way to fix that problem, maybe smart pointers.

Maybe add a new argument to the method setWriteItem
Example:

void Player::setWriteItem(Item* item, uint16_t maxWriteLen /*= 0*/, bool addRef /*= true*/)

Then:

Example
int LuaScriptInterface::luaPlayerShowTextDialog(lua_State* L)
{
	// player:showTextDialog(id or name or userdata[, text[, canWrite[, length]]])
	Player* player = getUserdata<Player>(L, 1);
	if (!player) {
		lua_pushnil(L);
		return 1;
	}

	int32_t length = getNumber<int32_t>(L, 5, -1);
	bool canWrite = getBoolean(L, 4, false);
	std::string text;

	int parameters = lua_gettop(L);
	if (parameters >= 3) {
		text = getString(L, 3);
	}
      
	Item* item;
        bool addRef = true;
	if (isNumber(L, 2)) {
		item = Item::CreateItem(getNumber<uint16_t>(L, 2));
	} else if (isString(L, 2)) {
		item = Item::CreateItem(Item::items.getItemIdByName(getString(L, 2)));
	} else if (isUserdata(L, 2)) {
		if (getUserdataType(L, 2) != LuaData_Item) {
			pushBoolean(L, false);
			return 1;
		}

		item = getUserdata<Item>(L, 2);
                addRef = false;
	} else {
		item = nullptr;
	}

	if (!item) {
		reportErrorFunc(L, getErrorDesc(LUA_ERROR_ITEM_NOT_FOUND));
		pushBoolean(L, false);
		return 1;
	}

	if (length < 0) {
		length = Item::items[item->getID()].maxTextLen;
	}

	if (!text.empty()) {
		item->setText(text);
		length = std::max<int32_t>(text.size(), length);
	}

	item->setParent(player);
	player->setWriteItem(item, length, addRef);
	player->sendTextWindow(item, length, canWrite);
	pushBoolean(L, true);
	return 1;
}

The idea is of @nekiro but I like it

src/luascript.cpp Outdated Show resolved Hide resolved
@DSpeichert DSpeichert merged commit 246d4d1 into otland:master Oct 31, 2021
@ramon-bernardo ramon-bernardo deleted the double-ref-mem-leak branch October 31, 2021 17:32
@Znote Znote mentioned this pull request Nov 1, 2021
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

6 participants