当前位置:网站首页>How to handle different types of data

How to handle different types of data

2022-06-13 00:50:00 Small fish game development

demand : Different props need different treatment , Such as props 1 The hook can be released , The props 2 Summon the dog
For these different effects , If you inherit directly, override the function , For heat change . Post maintenance is very unfriendly
In fact, different props are actually the processing of different data
We just need to write the data class first , Then deal with the data class

demo:

Write the data class first

public struct Move
{
    
    public float from;
    public float to;
}

Then process the data

public interface IEvent
{
    
    void Handle();
    void Handle(object a);
}

public abstract class AEvent : IEvent
{
    
    void IEvent.Handle()
    {
    
        Run();
    }
    protected abstract void Run();

    void IEvent.Handle(object a)
    {
    
        throw new NotImplementedException();
    }
}
public abstract class AEvent<T> : IEvent where T : struct
{
    
    void IEvent.Handle()
    {
    
        throw new NotImplementedException();
    }
    void IEvent.Handle(object a)
    {
    
        Run((T)a);
    }
    protected abstract void Run(T a);
}

public class Log2Event : AEvent<Move>
{
    
    protected override void Run(Move a)
    {
    
        System.Console.WriteLine($"from:{
      a.from} to:{
      a.to}");
    }
}

Just test it

class Program
{
    
    static void Main(string[] args)
    {
    
        (new Log2Event() as IEvent).Handle(new Move {
    from=0,to=1 });
    }
}

 Insert picture description here
without doubt , The rewrite handler has nothing to do with the original data class .
It is obvious from the above that , The life cycle of the handler should be from the beginning of the application to the end of the application
So we just need to create a handler when initializing the game , Suppose you want to update the handler , Just replace it directly

class Program
{
    
    static void Main(string[] args)
    {
    
        Dictionary<Type, IEvent> dict = new Dictionary<Type, IEvent>();
        dict.Add(typeof(Move), new Log2Event());

        var move = new Move {
     from = 0,to=1 };
        dict[move.GetType()].Handle(move);
    }
}

At first glance, there seems to be no problem . In case we have 100 Data classes , Do you want to write 100 individual Add?
At this time, it should be reflected , Reflect the entire assembly , Add the traversal handler to the dictionary .

Definition dictionary Key, Any type , As long as it is a unique value, there is no problem

[AttributeUsage(AttributeTargets.Class, AllowMultiple = false)]
public class EventAttribute : Attribute
{
    
    public string eventId;
    public EventAttribute(string eventId)
    {
    
        this.eventId = eventId;
    }
}

Traverse the assembly all added key Processing function of , Add to dictionary

public class EventSystem
{
    
    readonly Dictionary<string, List<IEvent>> dict = new Dictionary<string, List<IEvent>>();
    public EventSystem(System.Reflection.Assembly assembly)
    {
    
        var eventAttribute = typeof(EventAttribute);
        foreach (var type in assembly.GetTypes())
        {
    
            if (type.IsAbstract||type.IsInterface)
                continue;
            var attr = type.GetCustomAttributes(eventAttribute, false);
            if (attr.Length == 0)
                continue;
            var obj = Activator.CreateInstance(type) as IEvent;
            if (obj == null)
                continue;

            var e = attr[0] as EventAttribute;
            if (!dict.ContainsKey(e.eventId))
                dict.Add(e.eventId, new List<IEvent>());

            dict[e.eventId].Add(obj);
        }
    }
    public void Run(string eventId)
    {
    
        List<IEvent> list;
        if (!dict.TryGetValue(eventId, out list))
            return;
        foreach (var e in list)
        {
    
            try
            {
    
                e.Handle();
            }
            catch (Exception ex)
            {
    
                throw ex;
            }
        }
    }
    public void Run<T>(string eventId,T a)where T : struct
    {
    
        List<IEvent> list;
        if(!dict.TryGetValue(eventId, out list))
            return;
        foreach (var e in list)
        {
    
            try
            {
    
                e.Handle(a);
            }
            catch (Exception ex)
            {
    
                throw ex;
            }
        }
    }
}

Examples of use :

[Event("test")]
public class LogEvent : AEvent
{
    
    protected override void Run()
    {
    
        System.Console.WriteLine("test");
    }
}

class Program
{
    
    static void Main(string[] args)
    {
    

        var eventSystem = new EventSystem(typeof(Program).Assembly);
        eventSystem.Run("test");
        eventSystem.Run("test2", new Move {
     from = 0, to = 1 });
    }
}
原网站

版权声明
本文为[Small fish game development]所创,转载请带上原文链接,感谢
https://yzsam.com/2022/02/202202280557591740.html