-
Notifications
You must be signed in to change notification settings - Fork 41
System
jiepengtan edited this page Nov 20, 2019
·
7 revisions
- 需要在文件 __DllSourceFiles/Tools.UnsafeECS.ECDefine/Src/Unsafe/System.cs 中进行定义,
- 同时需要继承自 ISystem 相应的接口的说明可以在 __DllSourceFiles/Tools.UnsafeECS.ECDefine/Src/BuildIn/BuildIn_Interfaces.cs 中找到
- 生成的代码的主体可以在 __DllSourceFiles/Game.Model/Src/__UnsafeECS/Generated/CodeGen_System.cs 看到
- 抱歉,为了可以在 游戏逻辑代码 有编译错误的情况下依旧能够生成代码,需要将相应的system 在 ECDefine.dll 中进行声明
- 比如声明了相应的System
- Overview
-
System Define
- IJobSystem
- IPureSystem
-
System Implement
- GameJobSystem
- GameExecuteSystem
-
其中以Job开头的定义,在UNING_UNITY_BURST_JOB 定义了的情况下,会使用Unity 的Burst 进行编译,且会交由Unity 的JobSystem 进行调度,否则会在主线程中调度,所以这类System,不能修改全局的状态,只能访问相关的属性
-
而 IPureSystem 一定会被主线程调用,适合处理涉及全局状态的改变的任务
public abstract unsafe class BaseExecuteSystem : BaseSystem, IExecuteSystem {
public void Execute(IContext context){
if (BeforeSchedule()) { DoSchedule(context); }
AfterSchedule(isSucc);
}
protected virtual bool BeforeSchedule(){ return true;}
protected virtual void DoSchedule(IContext context){ context.Schedule(this); }
protected virtual void AfterSchedule(bool isSucc){ }
}
public partial class GameExecuteSystem :BaseExecuteSystem{ }
- 你可以Override BeforeSchedule 在正式调度前去设置一下状态,方便在Execute 中访问
- 你可以Override AfterSchedule 在调度完成后去清理一下状态
- 更多的描述
//Input
public class InputSystem : IPureSystem {
public PlayerData PlayerData;
public MoveData MoveData;
}
- 相应的在Game.Model.dll 中你需要定义相应的System
public unsafe partial class InputSystem : GameExecuteSystem {
public void Execute(
ref PlayerData playerData,
ref MoveData moveData
){
//... other codes
}
//... other codes
}
- 1.如果该System 继承自 ISystemWithIdx,则相应的System 的定义需要添加 int Index 参数,该参数意思是在本次调度中第多少次调用该函数
- eg:
//Input
public class InputSystem : IPureSystem, ISystemWithIdx {
public PlayerData PlayerData;
public MoveData MoveData;
}
public unsafe partial class InputSystem : GameExecuteSystem {
public void Execute(
int index,//代码在这里
ref PlayerData playerData,
ref MoveData moveData
){
//... other codes
}
//... other codes
}
- 2.如果该System 继承自 ISystemWithEntity 的定义需要添加 Entity ptr*参数,该参数代表这次调用的 Entity 对象的指针
//Input
public class InputSystem : IPureSystem, ISystemWithEntity {
public PlayerData PlayerData;
public MoveData MoveData;
}
public unsafe partial class InputSystem : GameExecuteSystem {
public void Execute(
Entity* ptr,//代码在这里
ref PlayerData playerData,
ref MoveData moveData
){
//... other codes
}
//... other codes
}
-
3.如果该System 继承自 IJobSystem
- 如果定义了宏 UNING_UNITY_BURST_JOB 该系统将会使用 Unity's Burst compiler 进行编辑并被 Unity's JobSystem 调度(多线程)
- 如果没有定义 UNING_UNITY_BURST_JOB ,则会在主线程中调度,
- 所以为了可以使用Unity Burst,请保证在 该System中是线程安全的,比如不能修改全局变量,或着调用会修改全局变量的函数eg:_DestroyEntity
- 如果不能保证线程安全,请使用 IPureSystem
-
eg: 在ECDefine.dll 中进行声明
public class SinkSystem : IJobSystem {
public Transform3D Transform;
public BoidState BoidState;
}
- 需要以内部Struct的形式定义相应的JobDefine
- 注意 不要添加 [Unity.Burst.BurstCompile] ,也不要 继承自 Unity.Jobs.IJob,方便后续框架使用条件宏开关相应的调度,以及运行在服务器中
- 相应的JobDefine 中的成员的初始化,可以在 BeforeSchedule 进行赋值(在主线程中调用)
public unsafe partial class SinkSystem : GameJobSystem {
public unsafe partial struct JobDefine {
[ReadOnly] public LVector3 SinkOffset;
[ReadOnly] public LFloat DeltaTime;
public void Execute(ref Transform3D transform3D, ref BoidState boidState){
if (!boidState.IsDied) return;
boidState.SinkTimer -= DeltaTime;
transform3D.Position += SinkOffset;
}
}
// 相应的需要在BeforeSchedule 中给相应的 JobDefine
protected override bool BeforeSchedule(){
//assign jobData info
JobData.DeltaTime = _globalStateService.DeltaTime;
JobData.SinkOffset = new LVector3(0,_gameConfigService.BoidSettting.SinkSpd * JobData.DeltaTime,0) ;
return true;
}
}
- 下面是相应的System Interface的定义
/// should declare a Method like:
/// public void Execute(.....)
public interface ISystem { }
/// should declare a Method like:
/// public void Execute(int index, .....)
public interface ISystemWithIdx { }
/// should declare a Method like:
/// public void Execute(Entity* ptr, .....)
public interface ISystemWithEntity { }
/// this system would always be scheduled in main thread
/// should declare a Method like:
/// public void Execute(.....)
public interface IPureSystem : ISystem { }
/// this system would always be scheduled in main thread
/// should declare a Method like:
/// public void Execute(Entity* ptr, .....)
public interface IPureSystemWithEntity : IPureSystem, ISystemWithEntity { }
/// If macro UNING_UNITY_BURST_JOB was defined
/// this system will be complied by Unity's Burst compiler and scheduled by Unity's JobSystem,Otherwise it will be scheduled call in MainThread
/// should declare a Method like:
/// public void Execute(.....)
public interface IJobSystem : ISystem { }
/// If macro UNING_UNITY_BURST_JOB was defined
/// this system will be complied by Unity's Burst compiler and scheduled by Unity's JobSystem,Otherwise it will be scheduled call in MainThread
/// should declare a Method like:
/// public void Execute(Entity* ptr, .....)
public interface IJobSystemWithEntity : IJobSystem, ISystemWithEntity { }
/// If macro UNING_UNITY_BURST_JOB was defined
/// this system will be complied by Unity's Burst compiler and scheduled by Unity's JobSystem,Otherwise it will be scheduled call in MainThread
/// should declare a Method like:
/// public void Execute(int index, .....)
public interface IJobForEachSystem : IJobSystem { }
/// If macro UNING_UNITY_BURST_JOB was defined
/// this system will be complied by Unity's Burst compiler and scheduled by Unity's JobSystem,Otherwise it will be scheduled call in MainThread
/// should declare a Method like:
/// public void Execute(Entity* ptr,int index, .....)
public interface IJobForEachSystemWithEntity : IJobForEachSystem, ISystemWithEntity { }
/// If macro UNING_UNITY_BURST_JOB was defined
/// this system will be complied by Unity's Burst compiler and scheduled by Unity's JobSystem,Otherwise it will be scheduled call in MainThread
/// should declare as if it was inherited from : Unity.Collections.IJobNativeMultiHashMapMergedSharedKeyIndices
public interface IJobHashMapSystem : ISystem { }