Giter VIP home page Giter VIP logo

Comments (6)

RomanNiki avatar RomanNiki commented on May 27, 2024 1

My Bootstrap

using System;
using System.Linq;
using Core.Extensions;
using Core.Extensions.Views;
using Core.Movement;
using Cysharp.Threading.Tasks;
using Engine.Factories.SystemsFactories;
using Scellecs.Morpeh;
using TriInspector;
using UnityEngine;
using Zenject;
using EntityProvider = Engine.Providers.EntityProvider;

public sealed class GameplayStartup : BaseInstaller
{
    [ReadOnly]
    [SerializeReference] private BaseMorpehFeature[] _activeFeatures = Array.Empty<BaseMorpehFeature>();
    private IFeaturesFactory _featuresesFactory;
    private IMoveLoopService _moveLoopService;
    private SystemFactoryArgs _systemFactoryArgs;

    [Inject]
    public void Constructor(World world, IFeaturesFactory featuresesFactory, SystemFactoryArgs systemFactoryArgs)
    {
        _systemFactoryArgs = systemFactoryArgs;
        World = world;
        World.UpdateByUnity = true;
        _featuresesFactory = featuresesFactory;

        CreateFeatures();
    }

    protected override async void OnEnable()
    {
        await EnableFeatures();
    }

    protected override void OnDisable()
    {
        DisableFeatures();
    }

    private async UniTask EnableFeatures()
    {
        var order = 0;
        for (var i = 0; i < _activeFeatures.Length; i++, order++)
            await World.AddFeatureAsync(order, _activeFeatures[i]);
    }

    private void DisableFeatures()
    {
        for (var i = 0; i < _activeFeatures.Length; i++)
            World.RemoveFeature(_activeFeatures[i]);
    }

    private void Start()
    {
        foreach (var entity in FindObjectsOfType<EntityProvider>())
        {
            entity.Init(World);
        }
    }

    private void OnDestroy()
    {
        World?.Dispose();
    }

    private void CreateFeatures()
    {
        _activeFeatures = _featuresesFactory.CreateFeatures(_systemFactoryArgs).ToArray();
    }
}

from morpeh.

RomanNiki avatar RomanNiki commented on May 27, 2024 1

The problem is in EntityEnumerator, because when calling GetEnumerator in a filter with the number of archtypes = 0, default is returned and there the world is null. And when foreach tried to call Dispose(), NullReferenceException was thrown.

from morpeh.

RomanNiki avatar RomanNiki commented on May 27, 2024

After the rollback, everything was fixed.

from morpeh.

olegmrzv avatar olegmrzv commented on May 27, 2024

Thanks for the contribution.
Can you attach a minimal reproduction case? Or maybe attach exception message with code line?

In my example everything works, I can’t find what’s broken.

using Scellecs.Morpeh;
using UnityEngine;

public class Bootstrap : MonoBehaviour {
    private void Start() {
        World.Default.UpdateByUnity = false;
        var sg = World.Default.CreateSystemsGroup();
        sg.AddSystem(new FooSystem());
        World.Default.AddSystemsGroup(0, sg);
    }

    private void Update() {
        World.Default.Update(Time.deltaTime);
    }

    private void FixedUpdate() {
        World.Default.FixedUpdate(Time.fixedDeltaTime);
    }

    private void LateUpdate() {
        World.Default.LateUpdate(Time.deltaTime);
    }
}

public struct TestComponent0 : IComponent {
    public int test;
}

public class FooSystem : ISystem {
    public World World { get; set; }

    private Filter filter;
    private Stash<TestComponent0> stash;

    public void OnAwake() {
        this.filter = this.World.Filter.With<TestComponent0>().Build();
        this.stash = this.World.GetStash<TestComponent0>();
        
        for (int i = 0, length = 1000; i < length; i++) {
            var e = this.World.CreateEntity();
            e.AddComponent<TestComponent0>();
        }
    }
    public void OnUpdate(float deltaTime) {
        foreach (var entity in this.filter) {
            this.stash.Get(entity).test++;
        }
        
    }
    
    public void Dispose() {
    }
}

from morpeh.

RomanNiki avatar RomanNiki commented on May 27, 2024

stack trace NullReferenceException: Object reference not set to an instance of an object Scellecs.Morpeh.Filter+EntityEnumerator.Dispose () (at ./Library/PackageCache/com.scellecs.morpeh@b4983589c5/Core/Filter.cs:182) Core.Characteristics.EnergyLimits.Systems.ChargeSystem.OnUpdate (System.Single deltaTime) (at Assets/Scripts/Core/Characteristics/EnergyLimits/Systems/ChargeSystem.cs:32) Scellecs.Morpeh.SystemsGroupExtensions.TryCatchUpdate (Scellecs.Morpeh.ISystem system, Scellecs.Morpeh.SystemsGroup systemsGroup, System.Single deltaTime) (at ./Library/PackageCache/com.scellecs.morpeh@b4983589c5/Core/SystemsGroupExtensions.cs:187) UnityEngine.Debug:LogException(Exception) Scellecs.Morpeh.Logging.MorpehUnityLogger:Scellecs.Morpeh.Logging.IMorpehLogger.LogException(Exception) (at ./Library/PackageCache/com.scellecs.morpeh@b4983589c5/Core/Logging/MorpehUnityLogger.cs:11) Scellecs.Morpeh.MLogger:LogException(Exception) (at ./Library/PackageCache/com.scellecs.morpeh@b4983589c5/Core/MLogger.cs:39) Scellecs.Morpeh.SystemsGroupExtensions:SystemThrowException(SystemsGroup, ISystem, Exception) (at ./Library/PackageCache/com.scellecs.morpeh@b4983589c5/Core/SystemsGroupExtensions.cs:175) Scellecs.Morpeh.SystemsGroupExtensions:TryCatchUpdate(ISystem, SystemsGroup, Single) (at ./Library/PackageCache/com.scellecs.morpeh@b4983589c5/Core/SystemsGroupExtensions.cs:193) Scellecs.Morpeh.SystemsGroupExtensions:Update(SystemsGroup, Single) (at ./Library/PackageCache/com.scellecs.morpeh@b4983589c5/Core/SystemsGroupExtensions.cs:74) Scellecs.Morpeh.WorldExtensions:Update(World, Single) (at ./Library/PackageCache/com.scellecs.morpeh@b4983589c5/Core/WorldExtensions.cs:218) Scellecs.Morpeh.WorldExtensions:GlobalUpdate(Single) (at ./Library/PackageCache/com.scellecs.morpeh@b4983589c5/Core/WorldExtensions.cs:185) Scellecs.Morpeh.UnityRuntimeHelper:Update() (at ./Library/PackageCache/com.scellecs.morpeh@b4983589c5/Unity/UnityRuntimeHelper.cs:70)
the System:

using Core.Characteristics.EnergyLimits.Components;
using Core.Extensions;
using Scellecs.Morpeh;
using UnityEngine;

namespace Core.Characteristics.EnergyLimits.Systems
{
#if ENABLE_IL2CPP
    using Unity.IL2CPP.CompilerServices;
  
    [Il2CppSetOption(Option.NullChecks, false)]
    [Il2CppSetOption(Option.ArrayBoundsChecks, false)]
#endif
    
    public sealed class ChargeSystem : ISystem
    {
        private Filter _filter;
        private Stash<Energy> _energyPool;
        private Stash<ChargeRequest> _chargeRequestPool;

        public World World { get; set; }

        public void OnAwake()
        {
            _filter = World.Filter.With<ChargeRequest>().Build();
            _energyPool = World.GetStash<Energy>();
            _chargeRequestPool = World.GetStash<ChargeRequest>();
        }

        public void OnUpdate(float deltaTime)
        {
            foreach (var requestEntity in _filter)
            {
                ref var chargeRequest = ref _chargeRequestPool.Get(requestEntity);
                ref var chargeRequestEntity = ref chargeRequest.Entity;
                ref var energy = ref _energyPool.Get(chargeRequestEntity);
                var chargeAmount = chargeRequest.Value;
                energy.Value = Mathf.Min(energy.MaxValue, energy.Value + chargeAmount);

                World.SendMessage(new EnergyChangedEvent { Entity = chargeRequestEntity });

                World.RemoveEntity(requestEntity);
            }
        }

        public void Dispose()
        {
        }
    }
}

filter is not initialized in all systems. In debug mode awake is called and is called before update (as it should be) but for some reason the filter has null reference already in update

from morpeh.

olegmrzv avatar olegmrzv commented on May 27, 2024

Thanks for your investigation.
Fix is already in stage 2023.

from morpeh.

Related Issues (20)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.