Search Unity

Trying eliminating statics

Discussion in 'Entity Component System' started by Antypodish, Oct 20, 2020.

  1. Antypodish

    Antypodish

    Joined:
    Apr 29, 2014
    Posts:
    10,769
    So here is my little problem, which I would like resolve.
    I want to eliminate static in fields (not for methods), to be able utilize Entrer Play Mode Settings



    Mind, it all works at the current state, but using statics.

    I got following:
    • Monobehaviour inspector, in which I can adjust properties at runtime, to generate and modify my hex planet.
    • DOTS systems and jobs, which are responsible for generating planet.
    • And some static data, which are common for both MB and Systems.

    upload_2020-10-20_17-34-54.png

    So in terms of eliminating static fields, as my next goal, I started using singleton entities.
    The thing is, I have also UnityEngine.Collection List, which I set in MB inspector, and read in the system on main thread. Of course it is none blitable. And I can not store list in singleton, as far I am aware.

    But I could convert that lists into Dynamic buffer in MB script. And I think that could resolve that part of the problem, as I could read settings data, across different systems. Can I actually use IBufferElementData in singleton entity? I assume that I can (haven't tested yet).
    Whether this is most appropriate solution, I am uncertain.

    However, I have also NativeHasMap. And my question is, what is the current most appropriate approach, to read for example NativeHashMap across multiple systems, without using static?

    Any though?
    How should I bite this problem?
     
  2. Enzi

    Enzi

    Joined:
    Jan 28, 2013
    Posts:
    962
    Yes. You can attach pretty much anything you like to a singleton entity. (comps, buffers)

    var cachedSystem = World.GetExistingSystem<SystemA>();
    var hashMap = cachedSystem.hashMap;
     
    Antypodish likes this.
  3. Antypodish

    Antypodish

    Joined:
    Apr 29, 2014
    Posts:
    10,769
    Right, I shall do that then.

    Ah, this is simpler than I thought :)
     
    CPlusSharp22 likes this.
  4. eizenhorn

    eizenhorn

    Joined:
    Oct 17, 2016
    Posts:
    2,683
    class
    IComponentData 
    can store managed things and it can be singleton entity without problems - lists, native containers etc. Of course with only main thread usage limitation, but as you told you will use it on the main thread. And in case of native containers, you just get singleton entity in system and just pass native container from this singleton to job.
    (but for class singletons use extension methods on systems -
    this.GetSingleton<t> this.SetSingleton<T>
    instead of just
    GetSingleton<t> SetSingleton<T>
    because last one has struct restriction and extension hasn't)
     
  5. Antypodish

    Antypodish

    Joined:
    Apr 29, 2014
    Posts:
    10,769
    @eizenhorn this is really nice info.
    This just reminds me, I have seen somewhere very recently the discussion, which was mentioning class IComponentData.
     
  6. Lieene-Guo

    Lieene-Guo

    Joined:
    Aug 20, 2013
    Posts:
    547
    Even weirder. you can use any class derived from UnityEngine.Object as ComponentObject (without IComponentData).
    Code (CSharp):
    1.         public struct SingletonTag : IComponentData { }
    2.         public class MyClassComponent : IComponentData
    3.         {
    4.             public NativeList<int> Data = new NativeList<int>(Allocator.Persistent);
    5.         }
    6.         public class MyObjectComponent : UnityEngine.Object
    7.         {
    8.             public NativeList<int> Data = new NativeList<int>(Allocator.Persistent);
    9.             private void OnDestroy()
    10.             {
    11.                 Data.Dispose();
    12.             }
    13.         }
    14.         protected override void OnCreate()
    15.         {
    16.             var entity = EntityManager.CreateEntity();
    17.  
    18.             EntityManager.AddComponentObject(entity, new MyObjectComponent());
    19.             EntityManager.AddComponentObject(entity, new MyClassComponent());
    20.             EntityManager.AddComponent<SingletonTag>(entity);
    21.         }
    22.         protected override void OnUpdate()
    23.         {
    24.  
    25.             var objComp = GetSingleton<MyObjectComponent>();//not working
    26.             var clsComp = GetSingleton<MyClassComponent>();//not working
    27.             var objComp2 = this.GetSingleton<MyObjectComponent>();//not working
    28.             var clsComp2 = this.GetSingleton<MyClassComponent>();//working
    29.             //but this works
    30.             var e = GetSingletonEntity<SingletonTag>();
    31.             EntityManager.GetComponentObject<MyObjectComponent>(e);
    32.             EntityManager.GetComponentObject<MyClassComponent>(e);
    33.         }
    34.  
     
    Last edited: Oct 21, 2020
    Antypodish likes this.
  7. Antypodish

    Antypodish

    Joined:
    Apr 29, 2014
    Posts:
    10,769
    Oh these are indeed clever. How did you even come up with that? :D

    But on other hand, it make me think, is it right to use classes in Dots?
    Are this approaches not invalidate dots principles, or some sort things like that?
    I am probably wrong, but I feel, these are like kind of hacks / work arounds :rolleyes:
    Shouldn't we be avoiding mixing entities and classes as components together, as the principle?
     
  8. Lieene-Guo

    Lieene-Guo

    Joined:
    Aug 20, 2013
    Posts:
    547
    UnityEngine.Object support is for HybridComponent.
    It's there and will be there as long as GameObject exists.
    It's part of DOTS principle.
    Say you have a UnityEngine. Object designed for GameObject.
    But you also want to use it in ECS.
    You can either choose to simply add it to entity as ObjectComponent or shared component if you want.
    or convert it to unmanaged IComponentData or BlobAsset.
     
  9. Antypodish

    Antypodish

    Joined:
    Apr 29, 2014
    Posts:
    10,769
    Thank you guys for assistance, I think I got decent results so far.
    Here is my outcome.
    Sorry for quotations from other thread.

    Any further thoughts, are more than welcome.
     
  10. CPlusSharp22

    CPlusSharp22

    Joined:
    Dec 1, 2012
    Posts:
    111
    You could also have an editor play mode changed event hook that kills/resets/shutdown any singletons or static data manually.

    So, if for some reason your singleton entities are not being killed on ECS shutdown, you can always tap into ECS directly and murder them yourself.
     
  11. Enzi

    Enzi

    Joined:
    Jan 28, 2013
    Posts:
    962
    bobbaluba likes this.