Entt: component const and non const are generating different ctype/family

Created on 10 Feb 2019  Β·  28Comments  Β·  Source: skypjack/entt

Hello,
thanks a lot for sharing this lib!

I just started to use it, and there is a behavior which i found confusing, so i'm curious if it's expected.
here is what i did:
auto entity = registry_.create();
registry_.assign(entity, Position2D(100, 100));
and then in a process
registry_.view().each({ ... });

From what i read in the doc, I was assuming that it would just access the position, read-only.
Instead the view is empty, because the constness actually generates a different family/ctype, which pool is empty.

Is there anything I'm doing/getting wrong?

thanks a lot in advance,
best regards,
Ju

enhancement

Most helpful comment

@skypjack Sure. I'll do what I can

All 28 comments

Dealing with shared libraries?

@skypjack The ASSERT_TRUEs in the call to each aren’t reached in SingleComponentView, ConstNonConstAndAllInBetween because the view is empty. Those really should be static_asserts anyway.

no, all static.

On Sun, Feb 10, 2019 at 12:44 PM Michele Caini notifications@github.com
wrote:

Dealing with shared libraries?

β€”
You are receiving this because you authored the thread.
Reply to this email directly, view it on GitHub
https://github.com/skypjack/entt/issues/182#issuecomment-462125375, or mute
the thread
https://github.com/notifications/unsubscribe-auth/AIvaVmr9X5dPFI9M_lyKhoImbWb11IUmks5vMAYdgaJpZM4azAz0
.

@Kerndog73 do you mean this?

@skypjack Yes. Inside the lambda that is passed to each

I see, the same applies here. It seems I forgot a few assigns. :smile:

Ok, tests fixed. No bug detected btw.
@trashuj what you're doing looks a lot like what this test does and it seems to work as expected. In other terms:

entt::registry<> registry;
auto view = registry.view<const my_type>();

registry.assign<my_type>(registry.create());

cview.each([](auto, const auto &instance) {
    // ...
});

The test checks the _size_ of the view (that is correctly returned as 1) and iterates components.

One thing I don't understand in your example is this:

registry_.view().each([](auto entity, auto const & pos){ ... });

Did you mean this instead?

registry_.view<const Position2D>().each([](auto entity, auto const & pos){ ... });

Otherwise, can you copy and paste the actual code, so that I can tell you what's wrong there? Thanks.

Also, I cannot understand why you're saying this:

component const and non const are generating different ctype/family

Almost all the tests would break if this was true. The only way that came to my mind for that is if you create a view as:

registry.view<const my_type &>();

Instead of:

registry.view<const my_type>();

I didn't test it, so I'm not even sure it would compile actually.

yes sorry, bad copy/paste.
I actually created a quick example, and it works fine...
I'm trying to figure out what's wrong in my actual code :(
but removing or adding const gets different results:
auto viewPosConst = registry_.view(); // size 0
auto viewPos = registry_.view(); // size 1

On Sun, Feb 10, 2019 at 1:36 PM Michele Caini notifications@github.com
wrote:

Also, I cannot understand why you're saying this:

component const and non const are generating different ctype/family

Almost all the tests would break if this was true. The only way that came
to my mind for that is if you create a view as:

registry.view

Instead of:

registry.view();

I didn't test it, so I'm not even sure it would compile actually.

β€”
You are receiving this because you were mentioned.
Reply to this email directly, view it on GitHub
https://github.com/skypjack/entt/issues/182#issuecomment-462129116, or mute
the thread
https://github.com/notifications/unsubscribe-auth/AIvaVtN2b6tVdw6NTUbeLLRYPHdl5Jq7ks5vMBJagaJpZM4azAz0
.

@skypjack That gives me an idea. What if you could do this:

reg.each([](A a, B b) {
  // ...
});

Use the signature of the lambda to construct a standard view and then call each on the view.

Really nothing more than syntax sugar but it's some sweet, sweet sugar don't you think? πŸ˜‹

@trashuj

but removing or adding const gets different results:

auto viewPosConst = registry_.view<const Position2D>(); // size 0
auto viewPos = registry_.view<Position2D>(); // size 1

Can you provide a full example for this?
The test I linked does exactly the same (creates and entity with a component and creates two views, a non-const one and a const one: both have the same size, 1). The two lines above don't help and I don't manage to reproduce the problem, really.

@Kerndog73

You know you'll ask the same for groups, don't you? :smile:

@trashuj any news on this?
I tried a couple of things but I cannot reproduce the issue and thus I must consider it invalid if you don't come up with a reproducible example.
I'm sorry.

Hi all,
here are my findings so far.

I striped down my project to the minimum (find sources attached).
Here is what i print (in display.cpp)
size_t t = registry_.type();
size_t t2 = registry_.type();

printf("out %u %u\n", t, t2);

size_t tb = registry_.type();
size_t tb2 = registry_.type();

printf("out %u %u\n", tb, tb2);

I tested it on ubuntu/ninja/clang, it works fine (and returns 0 0, 1 1)
but on windows, using Windows10/visual studio 2017 (MSVC 19.16.27024.1), it
prints 0 3, 1 2

Now, couple of things to note.
clang seems to give the proper result (ie 0 and 1).
on windows though, I copy pasted the code above in different modules to see
the results, and the values change.
if i print from game.cpp, it gives me 2 2, 3 3 (and then display.cpp also
prints 2 2, 3 3).
if I comment out the code in game.cpp and print only from display like
above, I get 0 3, 1 2

Also, if I change the lib order in main properties > C++ > input, and link
game lib before the others (and rebuild), I also get 2 2, 3 3.
So I guess I have 2 issues here:

  • static init order makes a difference
  • msvc increments both const and non-const identifier in family.hpp, but
    "may" end up with consistent results (ie eventually type<> returns the same
    value for const and non const)

if any kind soul could give it a try and tell me what the output is, that
would be very helpful.
to build i'm using cmake 3.13.0

  • copy entt in ext folder
  • mkdir build
  • cd build
  • cmake ..

thanks a lot in advance!

On Mon, Feb 11, 2019 at 7:55 AM Michele Caini notifications@github.com
wrote:

@trashuj https://github.com/trashuj any news on this?
I tried a couple of things but I cannot reproduce the issue and thus I
must consider it invalid if you don't come up with a reproducible example.
I'm sorry.

β€”
You are receiving this because you were mentioned.
Reply to this email directly, view it on GitHub
https://github.com/skypjack/entt/issues/182#issuecomment-462232741, or mute
the thread
https://github.com/notifications/unsubscribe-auth/AIvaVtxlcf8CY6IPnRjWZbnBVoNbqvw7ks5vMRPmgaJpZM4azAz0
.

I know I've already asked this, but:

Also, if I change the lib order in main properties

Are you working with multiple libs? Shared ones or whatever? Can you give more details on this?

This is a know problem on Windows that doesn't guarantee inline variables are uniquely identified when linking to shared libraries.
This is also likely the _next big step_ of EnTT, the full support for use with shared libraries on systems where shared libraries are just shitty things that work differently from all the other systems. :smile:
In other terms, support for use across boundaries with dlls. Nothing more, nothing less.

I use only static libs.
main is exe, linking with static libs engine, display and game.

On Mon, Feb 11, 2019 at 10:49 AM Michele Caini notifications@github.com
wrote:

I know I've already asked this, but:

Also, if I change the lib order in main properties

Are you working with multiple libs? Shared ones or whatever? Can you give
more details on this?

This is a know problem on Windows that doesn't guarantee inline variables
are uniquely identified when linking to shared libraries.
This is also likely the next big step of EnTT, the full support for use
with shared libraries on systems where shared libraries are just shitty
things that work differently from all the other systems. πŸ˜„
In other terms, support for use across boundaries with dlls. Nothing more,
nothing less.

β€”
You are receiving this because you were mentioned.
Reply to this email directly, view it on GitHub
https://github.com/skypjack/entt/issues/182#issuecomment-462268741, or mute
the thread
https://github.com/notifications/unsubscribe-auth/AIvaVmlfguuegsC3DXB4Ys8wcZmkJ9IPks5vMTy-gaJpZM4azAz0
.

Never tested it but probably the same problem shows up also with static libs, even though I didn't expect it.

Yeah, I reproduced your error with static (and shared) libraries on Windows.
This is a known problem that shows up only on Windows, something to face yet. There are several discussions around if you look at closed issues. :+1:

Can i get away with it by using only non const components for now, or
should i expect more trouble?
Next i'm gonna start using signals and events.

On Mon, Feb 11, 2019, 15:17 Michele Caini <[email protected] wrote:

Yeah, I reproduced your error
https://ci.appveyor.com/project/skypjack/entt with static (and shared)
libraries on Windows.
This is a known problem that shows up only on Windows, something to face
yet. There are several discussions around if you look at closed issues. πŸ‘

β€”
You are receiving this because you were mentioned.
Reply to this email directly, view it on GitHub
https://github.com/skypjack/entt/issues/182#issuecomment-462342843, or mute
the thread
https://github.com/notifications/unsubscribe-auth/AIvaVvsp2tLnmc_b7djP4g_szCogpINEks5vMXuTgaJpZM4azAz0
.

It's not a problem of const and non const, that's just how you observe it.
The fact is that inline variables aren't guaranteed to be unique across all TU on Windows (and only on Windows apparently) as the standard would mandate instead. Therefore unique identifiers are incorrectly reassigned across boundaries and only across boundaries.

We are discussing a solution these days on gitter (feel free to join us if you want to participate).
The idea is to assign a stable identifier based on compile-time strings, something like this:

struct my_type: shared<"foobar"_hs> { ... }

Of course, there will be a macro available to reduce the boilerplate and use the name of the class as an identifier.
This way, the registry has a direct and indirect access to a component and it can use the latter when you are on the _wrong side_ of a boundary.

Unfortunately I cannot give you a deadline. EnTT is a free time project backed by patrons and donations that so far doesn't allow me to work full-time on it. I'm sorry.

Do you mind if I edit the title of your issue, so that to leave it open and use it to track progresses on this front?
Otherwise I can open another issue if you prefer.

Please go ahead!
Thanks a lot for sharing this lib again, i think it's promising!

On Mon, Feb 11, 2019, 23:26 Michele Caini <[email protected] wrote:

Do you mind if I edit the title of your issue, so that to leave it open
and use it to track progresses on this front?
Otherwise I can open another issue if you prefer.

β€”
You are receiving this because you were mentioned.
Reply to this email directly, view it on GitHub
https://github.com/skypjack/entt/issues/182#issuecomment-462520072, or mute
the thread
https://github.com/notifications/unsubscribe-auth/AIvaVrFGjKfiS_XTXXRNeNesDzBTKt85ks5vMe4egaJpZM4azAz0
.

In the meantime, you can look at the closed issues. Someone already faced the problem and somehow solved it a while ago, but I don't remember how.
Also stay tuned, I'm actively working on it, so I don't think it will take much to have it up and running across boundaries. :+1:

@Kerndog73 it's time to make EnTT the greatest library on all platforms. Can I count you in for help and for a review? :-)

@skypjack Sure. I'll do what I can

This one?
https://github.com/skypjack/entt/issues/113

On Mon, Feb 11, 2019, 23:39 Michele Caini <[email protected] wrote:

In the meantime, you can look at the closed issues. Someone already faced
the problem and somehow solved it a while ago, but I don't remember how.
Also stay tuned, I'm actively working on it, so I don't think it will take
much to have it up and running across boundaries. πŸ‘

β€”
You are receiving this because you were mentioned.
Reply to this email directly, view it on GitHub
https://github.com/skypjack/entt/issues/182#issuecomment-462523537, or mute
the thread
https://github.com/notifications/unsubscribe-auth/AIvaVqK1ObV1h7-aEiHnxo95c8sAkIFbks5vMfEGgaJpZM4azAz0
.

Yeah, that's one of them. The issue popped out more than once in two years. :-)

I'll close this issue and open a new one dedicated to the problem. There are too many messages here already.

See #186 and feel free to participate. :+1:

Was this page helpful?
0 / 5 - 0 ratings