Skip to content

Simplify single-member component access #926

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

Open
ianeinman opened this issue Nov 23, 2019 · 4 comments
Open

Simplify single-member component access #926

ianeinman opened this issue Nov 23, 2019 · 4 comments

Comments

@ianeinman
Copy link

I have a suggestion to simplify access to components that have only a single member. Let's say I have an entity that looks like this:

[Game]
public struct InterstellarPosition : IComponent {
   public double3 Position;

I need to access this value as follows:

entity.interstellarPosition.Position = newPosition;

But if the component only has one member, it would be nice if I could just do this:

entity.interstellarPosition = newPosition;

My suggestion is to add an optional attribute to the component which enables it to do this. Note that in this case, I think that the component is never actually created, it functions only as a template which describes what type the component is. So you could define a generic class and perhaps all they need to do is something like this:

[Game]
public struct InterstellarPosition : SingleMemberComponent<double3> {}
@Arpple
Copy link

Arpple commented Nov 23, 2019

there is workaround by using c# implicit keyword
#88

@ianeinman
Copy link
Author

Excellent, thanks for the prompt response.

I do think an attribute would still be good though. The workaround just makes it less code I have to type, which is good. But underneath, there's still a component being created, and that operator is also being called.

The attribute would enable you to optimize the code generation to be more like the Atom proposal, where in this case the component is not actually created at all, but only the raw inner value is created.

@ribbanya
Copy link

ribbanya commented Nov 26, 2019

I wrote this for my game, does something similar.

public abstract class ValueComponent<T> : Entitas.IComponent {
  public T value;

  public override string ToString() {
    return this.value.ToString();
  }

  // Allows "var (x) = (entity.xComponent)",
  // although you can also just do "T x = entity.xComponent"
  public void Deconstruct(out T value) {
    value = this.value;
  }

  public static implicit operator T(ValueComponent<T> component) {
    return component.value;
  }
}

I'll see if I can work up a code generator for something like this, when I have time.

@ianeinman
Copy link
Author

Yes, the issue isn't too hard to work around, but I think it would be more performant if Entitas supported it directly. Let me show an example:

[Game]
public class HealthComponent : IComponent
{
   public int Health;
}

// Access as follows:
GameEntity entity = <from wherever>
string myName = entity.healthComponent.Health;

The workarounds mentioned above make it easier to access the value, by not needing to type Health. This is fine, but does not improve the performance. Underneath, as far as I know, there is still an array of "HealthComponent" references.

But if Entitas knows that this component has only a single value, it can instead make it reference an array of that type (in this case, an "int"). Particularly when the single type is a value type it would be fast since it would be a contiguous memory block. This is one of the performance benefits of Unity's ECS system, and I think it was at the core of the "Atom" prototype that @sschmid was talking about a few months ago.

I prefer Entitas over Unity's ECS for several reasons (it is more flexible). I like the fact that a component can contain anything and does not have to be value types. But it would be great if there was a performance benefit when you were using only value types and I think this is one way to do it.

Now, I could be wrong about how things are currently working underneath and maybe this suggestion wouldn't be of benefit, but I still wanted to put it out there because I thought it could be useful.

@sschmid sschmid added this to Entitas Sep 6, 2022
@sschmid sschmid moved this to New in Entitas Jul 3, 2023
@sschmid sschmid removed the status in Entitas Jul 3, 2023
@sschmid sschmid moved this to New in Entitas Jul 3, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
Status: New
Development

No branches or pull requests

3 participants