using SadnessMonday.DiscIndustries.Fluids;
using Unity.Collections;
using UnityEngine;
using UnityEngine.Jobs;
using Unity.Jobs;
using System.Collections.Generic;
#if UNITY_EDITOR
using UnityEditor;
#endif
namespace SadnessMonday.DiscIndustries.Components{
public class FluidJobTester : MonoBehaviour {
public NativeList<FluidBuffer> buffers;
[SerializeField]
int bufferCount = 10;
[SerializeField]
bool DrainEnabled = true;
[SerializeField]
bool FillEnabled = true;
private void OnEnable() {
//buffers = new NativeArray<FluidBuffer>(bufferCount, Allocator.Persistent);
buffers = new NativeList<FluidBuffer>(Allocator.Persistent);
buffers.ResizeUninitialized(bufferCount);
PopulateTestBuffers();
#if UNITY_EDITOR
SetupGizmos();
#endif
}
int[] sinks = new int[] { 9, 5 };
int[] sources = new int[] { 0 };
private void PopulateTestBuffers() {
buffers[0] = new FluidBuffer(0, 200) { Right = 1 };
buffers[1] = new FluidBuffer(0, 200) { Left = 0, Right = 2 };
buffers[2] = new FluidBuffer(0, 200) { Left = 1, Right = 3, Bottom = 4 };
buffers[3] = new FluidBuffer(0, 200) { Left = 2, Right = 5 };
buffers[5] = new FluidBuffer(0, 200) { Left = 3 };
buffers[4] = new FluidBuffer(0, 200) { Top = 2, Bottom = 6 };
buffers[6] = new FluidBuffer(0, 200) { Top = 4, Bottom = 7 };
buffers[7] = new FluidBuffer(0, 200) { Top = 6, Bottom = 8 };
buffers[8] = new FluidBuffer(0, 200) { Top = 7, Bottom = 9 };
buffers[9] = new FluidBuffer(0, 200) { Top = 8 };
//for (int i = 0; i < bufferCount; i++) {
// FluidBuffer buffer = new FluidBuffer(i, 200);
// if (i > 0) {
// buffer.Left = i - 1;
// }
// if (i < bufferCount - 1) {
// buffer.Right = i + 1;
// }
// buffers[i] = buffer;
//}
}
private void OnDisable() {
buffers.Dispose();
}
float timer = 0;
float timestep = 1f / TimeManager.TicksPerSecond;
private void Update() {
timer += Time.deltaTime;
while (timer > timestep) {
timer -= timestep;
Simulate();
}
}
private void Simulate() {
if (DrainEnabled) {
foreach (var sink in sinks) {
// Remove some fluid from the last buffer
var s = buffers[sink];
s.Content = s.Content / 2;
buffers[sink] = s;
}
}
if (FillEnabled) {
foreach (var source in sources) {
// Remove some fluid from the last buffer
var s = buffers[source];
s.Content = s.Content + 20;
s.Content = Mathf.Clamp(s.Content, 0, s.Capacity);
buffers[source] = s;
}
}
// Schedule Jobs
UpdateFlow flowJob = new UpdateFlow(buffers.AsArray());
var flowHandle = flowJob.Schedule(buffers.Length, 1);
UpdateContent contentJob = new UpdateContent(buffers.AsArray());
var contentJobHandle = contentJob.Schedule(buffers.Length, 1, flowHandle);
contentJobHandle.Complete();
int total = 0;
for (int i = 0; i < buffers.Length; i++) {
total += buffers[i].Content;
}
print($"Total system fluid content = {total}");
}
#if UNITY_EDITOR
Dictionary<int, Vector3> positions = new Dictionary<int, Vector3>();
Bounds gizmoBounds;
void SetupGizmos() {
gizmoBounds = new Bounds(Vector3.zero, Vector3.one);
HashSet<int> visited = new HashSet<int>();
Stack<(int, Vector3)> stack = new Stack<(int, Vector3)>();
stack.Push((0, Vector3.zero));
while (stack.Count > 0) {
var current = stack.Pop();
var currentIdx = current.Item1;
if (!visited.Add(currentIdx)) continue;
var currentPos = current.Item2;
var currentBuffer = buffers[currentIdx];
positions[currentIdx] = currentPos;
gizmoBounds.Encapsulate(currentPos);
if (currentBuffer.Left >= 0) stack.Push((currentBuffer.Left, currentPos + Vector3.left));
if (currentBuffer.Right >= 0) stack.Push((currentBuffer.Right, currentPos + Vector3.right));
if (currentBuffer.Top >= 0) stack.Push((currentBuffer.Top, currentPos + Vector3.up));
if (currentBuffer.Bottom >= 0) stack.Push((currentBuffer.Bottom, currentPos + Vector3.down));
}
}
void OnDrawGizmos() {
if (!Application.isPlaying) return;
Gizmos.color = Color.red;
for (int i = 0; i < buffers.Length; i++) {
var buffer = buffers[i];
Gizmos.DrawSphere(positions[i] * 3, buffer.NormalizedContent + .1f);
}
}
#endif
}
}