GithubHelp home page GithubHelp logo

bitbuttercore.v2's Introduction

BitButter C.O.R.E V2

小黄油框架轻量版,采用工厂模式与事件驱动。

对象工厂

继承自BaseObject的游戏对象类可以被ObjectFactory工厂进行全生命周期管理,开发者不需要对其进行额外维护。

例如,我们定义游戏的角色类Character:

public class Character : BaseObject<Character>
{
    // 确保构造函数为public
    public Character(uint id)
        : base(id)
    {
    }
}

我们便可以通过ObjectFactory实例化Character类的对象:

var character = ObjectFactory.Instance.Create<Character>();

变量character是指向Character对象的ObjectReference,通过其Object属性可访问Character对象:

var characterObject = character.Object;

注意,继承自BaseObject的类无法通过new关键字实例化:

var characterObject = new Character(newID); // 将抛出InvalidOperationException

使用ObjectReference作为参数,可以删除工厂中的对象:

var character = ObjectFactory.Instance.Create<Character>();
ObjectFactory.Instance.Remove(character); // 删除character指向的对象

删除对象后,ObjectReference.IsValid将返回False,且ObjectReference.Object将返回null。

对象查询

我们定义以下游戏对象类:

// 角色抽象基类
public abstract class Character : BaseObject<Character>
{
    public Character(uint id)
        : base(id)
    {
    }

    public abstract string Name { get; }
}

// 英雄类,继承自角色基类
public class Hero : Character
{
    public Hero(uint id)
        : base(id)
    {
    }

    public override string Name => "Hero";
}

// 怪物类,继承自角色基类
public class Monster : Character
{
    public Monster(uint id, int attack)
        : base(id)
    {
        Attack = attack;
    }

    public override string Name => "Monster";
    
    public int Attack { get; }
}

可以通过ObjectFactory的Query方法进行对象查询,示例如下:

// 实例化游戏对象
ObjectFactory.Instance.Create<Hero>();
ObjectFactory.Instance.Create<Monster>(1);
ObjectFactory.Instance.Create<Monster>(3);

// 按类型查询
var allObjects = ObjectFactory.Instance.Query<IBaseObject>(); // 返回工厂中所有对象实例的ObjectReference,注意这里需要使用接口IBaseObject进行查询
var allCharacters = ObjectFactory.Instance.Query<Character>(); // 返回工厂中所有角色类实例的ObjectReference,在这个例子中查询结果与上一条查询相同
var allHeros = ObjectFactory.Instance.Query<Hero>(); // 返回工厂中所有英雄类实例的ObjectReference

// 条件查询
var validMonsters = ObjectFactory.Instance.Query<Monster>(monster => monster.Attack >= 3); // 返回工厂中所有攻击力大于等于3的怪物类实例的ObjectReference

抛出事件

使用EventManager的RaiseEvent方法抛出事件,示例如下:

EventManager.Instance.RaiseEvent("TestEventName");

所有事件均通过字符串进行唯一标识,可以使用字符串常量存储事件标识,确保不会因拼写错误导致事件处理出错。

抛出事件时可以提供参数,示例如下:

EventManager.Instance.RaiseEvent("TestEventName", 1, "abc", new[] { 0, 1 });

参数数量及类型均没有限制。对于同一个事件,也可以在多次抛出时传入不同数量及类型的参数。

注册事件Handler

使用EventManager的AddHandler方法注册事件Handler,示例如下:

EventManager.Instance.AddHandler("TestEventName", (args) =>
{
    // Handle event
});

上例中使用lambda表达式定义了Handler方法,也可以使用带有可变参数的方法,示例如下:

EventManager.Instance.AddHandler("TestEventName", HandleEvent);

void HandleEvent(params object[] args)
{
    // Handle event
}

在事件Handler中,可以使用args参数获取事件数据,但开发者必须确保访问args参数时不会造成下标越界。

如果事件Handler不会使用args参数,可以使用"_"忽略事件参数。

EventManager.Instance.AddHandler("TestEventName", (_) =>
{
    // Handle event without parameters
});

另外,不仅在框架提供的BaseObject子类中可以注册事件Handler,在一般C#类中也可以注册事件Handler,即框架的事件模块可以单独使用。

不过需要注意的是,如果要在一般C#类中注册事件Handler,该类必须实现IEventHandler接口。

性能

访问ObjectReference的任何成员都不会分配堆内存。

但目前访问ObjectFactory及EventManager的成员仍会产生堆内存垃圾,导致GC耗时增加。 因此不建议在画面绘制及逻辑更新等频繁调用的代码中(例如GameObject.Update())使用ObjectFactory进行数据查询,或使用EventManager抛出事件。

推荐的做法是仅在游戏数据发生改变时抛出事件,通知绘制代码进行画面状态更新。

后续计划进一步优化框架性能,减少ObjectFactory及EventManager的堆内存分配。

bitbuttercore.v2's People

Contributors

ypzhou avatar

Stargazers

 avatar

Watchers

 avatar  avatar

bitbuttercore.v2's Issues

Import data from excel

Support define data schema and import data row from excel.
Match class constructor with data row value types.

Consider how to report data import error when value type mismatched.

Heap allocation optimization

Reduce heap memory allocation for ObjectFactory and EventManager.

Currently these 2 classes generate quite a lot heap garbage, which cause GC time increase in games that require real time interaction.

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.