Skip to main content
edited title
Link

Daily events Assigning action typewithout creating closure

added 132 characters in body
Source Link

I am trying to create a system for daily events in Unity, but I am facing an obstacle where performance and memory are very sensitive for me, and I cannot choose betweenThe ActionDailyEvent orconsists of a list of delegateDailyEventAction, noting thatwhich hold the function willdata of the actions to be called withinvoked, such as the name, time, and a parameterreference to the action function.

1- Which one is better for performance, consumes less memory, and does not consume additional memory during execution? Or is there a better option than both of them?I am using Action for each DailyEventAction as the reference for the procedure to be followed to execute the desired event when its time comes.

2- Is this the correctWhat I want is a way to createassign the actionAction and pass the function parameter ExecuteEvent(NightLightsEvent eventData) without creating a (Lambda expression)closure.

Because the list may contain a large number of DailyEventAction, and is therethus more memory will be consumed when creating a better way?closure for each DailyEventAction in the list.

 

I am trying to create a system for daily events in Unity, but I am facing an obstacle where performance and memory are very sensitive for me, and I cannot choose between Action or delegate, noting that the function will be called with a parameter.

1- Which one is better for performance, consumes less memory, and does not consume additional memory during execution? Or is there a better option than both of them?

2- Is this the correct way to create the action (Lambda expression), and is there a better way?

I am trying to create a system for daily events in Unity, but I am facing an obstacle where performance and memory are very sensitive for me,The DailyEvent consists of a list of DailyEventAction, which hold the data of the actions to be invoked, such as the name, time, and a reference to the action function.

and I am using Action for each DailyEventAction as the reference for the procedure to be followed to execute the desired event when its time comes.

What I want is a way to assign the Action and pass the function parameter ExecuteEvent(NightLightsEvent eventData) without creating a closure.

Because the list may contain a large number of DailyEventAction, thus more memory will be consumed when creating a closure for each DailyEventAction in the list.

 
Post Undeleted by Ahmed Dyaa
Post Deleted by Ahmed Dyaa
added 1149 characters in body
Source Link
using System.Collections.Generic;
using UnityEngine;

public class NightLightsManager : DailyEvent
{
    public override List<DailyEventAction> DailyEventActions { get; protected set; } = new List<DailyEventAction>();
    DailyEventAction _dailyEventActionToAdd = new DailyEventAction();

    [SerializeField] private List<NightLightsEvent> _nightLightsEvents;

    [SerializeField] private Light[] _streetLights;
    void Init()
    {
        if (_nightLightsEvents.Count < 1)
            return;

#if UNITY_EDITOR
       NightLightsEvent _nightLightsEvents.SortnightLightsEvent = new NightLightsEvent();
#endif

        NightLightsEvent nightLightsEvent = new NightLightsEvent_nightLightsEvents.Sort();
 
        for (int i = 0; i < _nightLightsEvents.Count; i++)
        {
            if (DailyEventActions.FindIndex(localDailyEvntAction => localDailyEvntAction.Name == _nightLightsEvents[i].Name) < 0)
            {
                int currentIndex = i;

                _dailyEventActionToAdd.DailyEvent = this;
                _dailyEventActionToAdd.Name = _nightLightsEvents[i].Name;

                nightLightsEvent = _nightLightsEvents[currentIndex];
                _dailyEventActionToAdd.Action = () => ExecuteEvent(nightLightsEvent);
                _dailyEventActionToAdd.TimeInMinutes = _nightLightsEvents[i].Hour * 60 + _nightLightsEvents[i].Minute;

                DailyEventActions.Add(_dailyEventActionToAdd);
            }
        }
    }

    void ExecuteEvent(NightLightsEvent eventData)
    {
        for (int i = 0; i < _streetLights.Length; i++)
        {
            _streetLights[i].enabled = eventData.IsLightsOn;
        }

        Debug.Log($"Invoking {eventData.Name} | {eventData.IsLightsOn} lights at: {TimeManager.Instance.CurrentTotalMinutes}");
    }
}
using UnityEngine;
using System;

[Serializable]
public struct DailyEventAction : IComparable<DailyEventAction>
{
    public DailyEvent DailyEvent;
    public string Name;
    public Action Action;

    [SerializeField, Range(0, 1439)] private int _timeInMinutes;
    public int TimeInMinutes
    {
        get => _timeInMinutes;
        set => _timeInMinutes = Mathf.Clamp(value, 0, 1439);
    }

    public DailyEventAction(DailyEvent dailyEvent, string name, Action action, int hour, int minute)
    {
        DailyEvent = dailyEvent;
        Name = name;
        Action = action;
        _timeInMinutes = Mathf.Clamp(hour, 0, 23) * 60 + Mathf.Clamp(minute, 0, 59);
    }

    public DailyEventAction(DailyEvent dailyEvent, string name, Action action, int timeInMinutes)
    {
        DailyEvent = dailyEvent;
        Name = name;
        Action = action;
        _timeInMinutes = timeInMinutes;
    }

    public int CompareTo(DailyEventAction other)
    {
        return TimeInMinutes - other.TimeInMinutes;
    }
}

NightLightsEvent script: It holds the data that will be used as a parameter in the function and executes the function based on it.

using UnityEngine;
using System;

[Serializable]
public struct NightLightsEvent : IComparable<NightLightsEvent>
{
    public string Name;

    [SerializeField, Range(0, 23)]
    private int _hour;
    public int Hour
    {
        get => _hour;
        set => _hour = Mathf.Clamp(value, 0, 23);
    }

    [SerializeField, Range(0, 59)]
    private int _minute;
    public int Minute
    {
        get => _minute;
        set => _minute = Mathf.Clamp(value, 0, 59);
    }

    public bool IsLightsOn;

    public NightLightsEvent(string name, int hour, int minute, bool isLightsOn)
    {
        Name = name;
        _hour = Mathf.Clamp(hour, 0, 23);
        _minute = Mathf.Clamp(minute, 0, 59);

        IsLightsOn = isLightsOn;
    }

    public int CompareTo(NightLightsEvent other)
    {
        return (Hour * 60 + Minute) - (other.Hour * 60 + other.Minute);
    }
}
using System.Collections.Generic;
using UnityEngine;

public class NightLightsManager : DailyEvent
{
    public override List<DailyEventAction> DailyEventActions { get; protected set; } = new List<DailyEventAction>();
    DailyEventAction _dailyEventActionToAdd = new DailyEventAction();

    [SerializeField] private List<NightLightsEvent> _nightLightsEvents;

    [SerializeField] private Light[] _streetLights;
    void Init()
    {
        if (_nightLightsEvents.Count < 1)
            return;

#if UNITY_EDITOR
        _nightLightsEvents.Sort();
#endif

        NightLightsEvent nightLightsEvent = new NightLightsEvent();
 
        for (int i = 0; i < _nightLightsEvents.Count; i++)
        {
            if (DailyEventActions.FindIndex(localDailyEvntAction => localDailyEvntAction.Name == _nightLightsEvents[i].Name) < 0)
            {
                int currentIndex = i;

                _dailyEventActionToAdd.DailyEvent = this;
                _dailyEventActionToAdd.Name = _nightLightsEvents[i].Name;

                nightLightsEvent = _nightLightsEvents[currentIndex];
                _dailyEventActionToAdd.Action = () => ExecuteEvent(nightLightsEvent);
                _dailyEventActionToAdd.TimeInMinutes = _nightLightsEvents[i].Hour * 60 + _nightLightsEvents[i].Minute;

                DailyEventActions.Add(_dailyEventActionToAdd);
            }
        }
    }

    void ExecuteEvent(NightLightsEvent eventData)
    {
        for (int i = 0; i < _streetLights.Length; i++)
        {
            _streetLights[i].enabled = eventData.IsLightsOn;
        }

        Debug.Log($"Invoking {eventData.Name} | {eventData.IsLightsOn} lights at: {TimeManager.Instance.CurrentTotalMinutes}");
    }
}
using UnityEngine;
using System;

[Serializable]
public struct DailyEventAction : IComparable<DailyEventAction>
{
    public DailyEvent DailyEvent;
    public string Name;
    public Action Action;

    [SerializeField, Range(0, 1439)] private int _timeInMinutes;
    public int TimeInMinutes
    {
        get => _timeInMinutes;
        set => _timeInMinutes = Mathf.Clamp(value, 0, 1439);
    }

    public DailyEventAction(DailyEvent dailyEvent, string name, Action action, int hour, int minute)
    {
        DailyEvent = dailyEvent;
        Name = name;
        Action = action;
        _timeInMinutes = Mathf.Clamp(hour, 0, 23) * 60 + Mathf.Clamp(minute, 0, 59);
    }

    public DailyEventAction(DailyEvent dailyEvent, string name, Action action, int timeInMinutes)
    {
        DailyEvent = dailyEvent;
        Name = name;
        Action = action;
        _timeInMinutes = timeInMinutes;
    }

    public int CompareTo(DailyEventAction other)
    {
        return TimeInMinutes - other.TimeInMinutes;
    }
}
using System.Collections.Generic;
using UnityEngine;

public class NightLightsManager : DailyEvent
{
    public override List<DailyEventAction> DailyEventActions { get; protected set; } = new List<DailyEventAction>();
    DailyEventAction _dailyEventActionToAdd = new DailyEventAction();

    [SerializeField] private List<NightLightsEvent> _nightLightsEvents;

    [SerializeField] private Light[] _streetLights;
    void Init()
    {
        if (_nightLightsEvents.Count < 1)
            return;

        NightLightsEvent nightLightsEvent = new NightLightsEvent();

        _nightLightsEvents.Sort();
        for (int i = 0; i < _nightLightsEvents.Count; i++)
        {
            if (DailyEventActions.FindIndex(localDailyEvntAction => localDailyEvntAction.Name == _nightLightsEvents[i].Name) < 0)
            {
                int currentIndex = i;

                _dailyEventActionToAdd.DailyEvent = this;
                _dailyEventActionToAdd.Name = _nightLightsEvents[i].Name;

                nightLightsEvent = _nightLightsEvents[currentIndex];
                _dailyEventActionToAdd.Action = () => ExecuteEvent(nightLightsEvent);
                _dailyEventActionToAdd.TimeInMinutes = _nightLightsEvents[i].Hour * 60 + _nightLightsEvents[i].Minute;

                DailyEventActions.Add(_dailyEventActionToAdd);
            }
        }
    }

    void ExecuteEvent(NightLightsEvent eventData)
    {
        for (int i = 0; i < _streetLights.Length; i++)
        {
            _streetLights[i].enabled = eventData.IsLightsOn;
        }

        Debug.Log($"Invoking {eventData.Name} | {eventData.IsLightsOn} lights at: {TimeManager.Instance.CurrentTotalMinutes}");
    }
}
using UnityEngine;
using System;

[Serializable]
public struct DailyEventAction : IComparable<DailyEventAction>
{
    public DailyEvent DailyEvent;
    public string Name;
    public Action Action;

    [SerializeField, Range(0, 1439)] private int _timeInMinutes;
    public int TimeInMinutes
    {
        get => _timeInMinutes;
        set => _timeInMinutes = Mathf.Clamp(value, 0, 1439);
    }

    public DailyEventAction(DailyEvent dailyEvent, string name, Action action, int hour, int minute)
    {
        DailyEvent = dailyEvent;
        Name = name;
        Action = action;
        _timeInMinutes = Mathf.Clamp(hour, 0, 23) * 60 + Mathf.Clamp(minute, 0, 59);
    }

    public DailyEventAction(DailyEvent dailyEvent, string name, Action action, int timeInMinutes)
    {
        DailyEvent = dailyEvent;
        Name = name;
        Action = action;
        _timeInMinutes = timeInMinutes;
    }

    public int CompareTo(DailyEventAction other)
    {
        return TimeInMinutes - other.TimeInMinutes;
    }
}

NightLightsEvent script: It holds the data that will be used as a parameter in the function and executes the function based on it.

using UnityEngine;
using System;

[Serializable]
public struct NightLightsEvent : IComparable<NightLightsEvent>
{
    public string Name;

    [SerializeField, Range(0, 23)]
    private int _hour;
    public int Hour
    {
        get => _hour;
        set => _hour = Mathf.Clamp(value, 0, 23);
    }

    [SerializeField, Range(0, 59)]
    private int _minute;
    public int Minute
    {
        get => _minute;
        set => _minute = Mathf.Clamp(value, 0, 59);
    }

    public bool IsLightsOn;

    public NightLightsEvent(string name, int hour, int minute, bool isLightsOn)
    {
        Name = name;
        _hour = Mathf.Clamp(hour, 0, 23);
        _minute = Mathf.Clamp(minute, 0, 59);

        IsLightsOn = isLightsOn;
    }

    public int CompareTo(NightLightsEvent other)
    {
        return (Hour * 60 + Minute) - (other.Hour * 60 + other.Minute);
    }
}
Source Link
Loading