Skip to content

Commit

Permalink
Requests
Browse files Browse the repository at this point in the history
  • Loading branch information
vanifatovvlad committed Sep 26, 2023
1 parent 47552e9 commit aee324c
Show file tree
Hide file tree
Showing 13 changed files with 354 additions and 12 deletions.
34 changes: 22 additions & 12 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,41 +8,51 @@ using System;
using Scellecs.Morpeh;
using Scellecs.Morpeh.Systems;

[Serializable]
public struct DamageRequest : IEventData {
public struct DamageRequest : IRequestData {
public EntityId targetEntityId;
}

[Serializable]
public struct DamagedEvent : IEventData {
public EntityId targetEntityId;
}

public class DamageSystem : UpdateSystem {
private Event<DamageRequest> damageRequest;
private Request<DamageRequest> damageRequest;
private Event<DamagedEvent> damagedEvent;

public override void OnAwake() {
damageRequest = World.GetEvent<DamageRequest>();
damageRequest = World.GetRequest<DamageRequest>();
damagedEvent = World.GetEvent<DamagedEvent>();
}

public override void OnUpdate(float deltaTime) {
if (!damageRequest.IsPublished) {
return;
}

foreach (var evt in damageRequest.BatchedChanges) {
ApplyDamage(evt.targetEntityId);
foreach (var request in damageRequest.Consume()) {
ApplyDamage(request.targetEntityId);

damagedEvent.NextFrame(new DamagedEvent {
targetEntityId = evt.targetEntityId,
targetEntityId = request.targetEntityId,
});
}
}

private void ApplyDamage(EntityId target) { }
}

public class PlaySoundOnDamageSystem : UpdateSystem {
private Event<DamagedEvent> damagedEvent;

public override void OnAwake() {
damagedEvent = World.GetEvent<DamagedEvent>();
}

public override void OnUpdate(float deltaTime) {
foreach (var evt in damagedEvent.publishedChanges) {
PlaySound(evt.targetEntityId);
}
}

private void PlaySound(EntityId target) { }
}
```

## License
Expand Down
1 change: 1 addition & 0 deletions Scellecs.Morpeh/EventWorldPlugin.cs
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ public static void RuntimeInitialize()
public void Initialize(World world)
{
world.CodeWriterEventsRegistry = new EventRegistry();
world.CodeWriterRequestsRegistry = new RequestRegistry();

var eventSystemGroup = world.CreateSystemsGroup();
eventSystemGroup.AddSystem(new ProcessEventsSystem(world.CodeWriterEventsRegistry));
Expand Down
6 changes: 6 additions & 0 deletions Scellecs.Morpeh/IRequestData.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
namespace Scellecs.Morpeh
{
public interface IRequestData
{
}
}
3 changes: 3 additions & 0 deletions Scellecs.Morpeh/IRequestData.cs.meta

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

121 changes: 121 additions & 0 deletions Scellecs.Morpeh/Request.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,121 @@
#if UNITY_EDITOR
#define MORPEH_DEBUG
#endif

using System;
using System.Runtime.CompilerServices;
using JetBrains.Annotations;
using Scellecs.Morpeh.Collections;
using Unity.IL2CPP.CompilerServices;
using UnityEngine;

namespace Scellecs.Morpeh
{
[Il2CppSetOption(Option.NullChecks, false)]
[Il2CppSetOption(Option.ArrayBoundsChecks, false)]
[Il2CppSetOption(Option.DivideByZeroChecks, false)]
public class Request<TData> : RequestBase where TData : struct, IRequestData
{
internal readonly FastList<TData> changes = new FastList<TData>();

#if MORPEH_DEBUG
internal int lastConsumeFrame;
#endif
internal int lastConsumedIndex;

[PublicAPI]
public void Publish(in TData request, bool allowNextFrame = false)
{
#if MORPEH_DEBUG
if (!allowNextFrame && lastConsumeFrame == Time.frameCount)
{
MLogger.LogError(
"The request was already consumed in the current frame. " +
"Reorder systems or set allowNextFrame parameter");
}
#endif

changes.Add(request);
}

[PublicAPI]
public Consumer Consume()
{
#if MORPEH_DEBUG
lastConsumeFrame = Time.frameCount;
#endif

if (lastConsumedIndex > 0)
{
Cleanup();
}

Consumer consumer;
consumer.request = this;
return consumer;
}

internal void Cleanup()
{
if (lastConsumedIndex >= changes.length)
{
changes.Clear();
lastConsumedIndex = 0;
return;
}

Array.Copy(changes.data, lastConsumedIndex, changes.data, 0, changes.length - lastConsumedIndex);

changes.length -= lastConsumedIndex;
changes.lastSwappedIndex = -1;

for (var i = 0; i < lastConsumedIndex; i++)
{
changes.data[i + changes.length] = default;
}

lastConsumedIndex = 0;
}

public struct Consumer
{
public Request<TData> request;

public Enumerator GetEnumerator()
{
Enumerator e;
e.request = request;
e.current = default;
return e;
}
}

public struct Enumerator
{
public Request<TData> request;
public TData current;

public bool MoveNext()
{
if (request.lastConsumedIndex >= request.changes.length)
{
return false;
}

current = request.changes.data[request.lastConsumedIndex++];
return true;
}

public TData Current
{
[MethodImpl(MethodImplOptions.AggressiveInlining)]
get => this.current;
}
}
}

public abstract class RequestBase
{
internal RequestRegistry registry;
}
}
3 changes: 3 additions & 0 deletions Scellecs.Morpeh/Request.cs.meta

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

10 changes: 10 additions & 0 deletions Scellecs.Morpeh/RequestRegistry.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
using System;
using System.Collections.Generic;

namespace Scellecs.Morpeh
{
internal class RequestRegistry
{
internal readonly Dictionary<Type, RequestBase> RegisteredRequests = new Dictionary<Type, RequestBase>();
}
}
3 changes: 3 additions & 0 deletions Scellecs.Morpeh/RequestRegistry.cs.meta

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

47 changes: 47 additions & 0 deletions Scellecs.Morpeh/RequestWorldExtensions.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
using System;
using JetBrains.Annotations;

namespace Scellecs.Morpeh
{
public static class RequestWorldExtensions
{
[PublicAPI]
public static Request<TData> GetRequest<TData>(this World world)
where TData : struct, IRequestData
{
var type = typeof(TData);
var registry = world.CodeWriterRequestsRegistry;

if (registry.RegisteredRequests.TryGetValue(type, out var registeredRequest))
{
return (Request<TData>) registeredRequest;
}

registeredRequest = new Request<TData>();
registeredRequest.registry = registry;

registry.RegisteredRequests.Add(type, registeredRequest);

return (Request<TData>) registeredRequest;
}

[PublicAPI]
public static RequestBase GetReflectionRequest(this World world, Type type)
{
var registry = world.CodeWriterRequestsRegistry;

if (registry.RegisteredRequests.TryGetValue(type, out var registeredRequest))
{
return registeredRequest;
}

var constructedType = typeof(Request<>).MakeGenericType(type);
registeredRequest = (RequestBase) Activator.CreateInstance(constructedType, true);
registeredRequest.registry = registry;

registry.RegisteredRequests.Add(type, registeredRequest);

return registeredRequest;
}
}
}
3 changes: 3 additions & 0 deletions Scellecs.Morpeh/RequestWorldExtensions.cs.meta

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions Scellecs.Morpeh/World.Events.cs
Original file line number Diff line number Diff line change
Expand Up @@ -3,5 +3,6 @@ namespace Scellecs.Morpeh
public partial class World
{
internal EventRegistry CodeWriterEventsRegistry;
internal RequestRegistry CodeWriterRequestsRegistry;
}
}
Loading

0 comments on commit aee324c

Please sign in to comment.