SanderMertens / flecs

A fast entity component system (ECS) for C & C++

Home Page:https://www.flecs.dev

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Crash when using a component that is movable with no default constructor

Thinkofname opened this issue · comments

Describe the bug
When adding components to entities that are movable but have no default constructor, you'll hit an error in grow_column when attempting to add the 3rd component due to the type having no default constructor.

To Reproduce
Test case:

#include <gtest/gtest.h>
#include "flecs.h"

struct A
{
	int mVal = 0;

	A(int val) : mVal(val){};

	A(A &&other)
	{
		mVal = other.mVal;
	}
	A &operator=(A &&other) noexcept
	{
		mVal = other.mVal;
		return *this;
	}
};

TEST(FlecsTest, Issue)
{
	flecs::world world;

	world.entity().emplace<A>(1);
	world.entity().emplace<A>(2);
	world.entity().emplace<A>(3);
}

Expected behavior

It seems like it should be possible for the resizing to work without a default constructor. Currently the resize is implemented as constructing via the default types constructor the new memory followed by moving the old types into it. I believe it should be possible to instead use the move constructor to do this in one go, assuming the type supports it.

I believe it should be possible to instead use the move constructor to do this in one go, assuming the type supports it.

The challenge is that since the component arrays are not increased with a single component but double in size, more than one element can be added in a grow action. For the elements that are not emplaced I don't have anything to move from (e.g. a valid constructed value), which means I can't initialize them.

What I could try is to not call the default constructor for elements that are allocated but not assigned. As long as I can ensure that they either will be constructed when used or emplaced/moved into, that should still work.

Re-adding the bug label, as this makes emplace a lot less usable.

Fixed!