1- using System . Collections . Generic ;
1+ using System ;
2+ using System . Collections . Generic ;
23using System . Diagnostics ;
34using System . Linq ;
45
56using CodeBlaze . Vloxy . Engine . Components ;
67using CodeBlaze . Vloxy . Engine . Data ;
78using CodeBlaze . Vloxy . Engine . Noise ;
89using CodeBlaze . Vloxy . Engine . Settings ;
10+ using CodeBlaze . Vloxy . Engine . Utils . Extensions ;
911using CodeBlaze . Vloxy . Engine . Utils . Logger ;
1012
1113using Unity . Collections ;
@@ -27,7 +29,10 @@ public class ChunkDataScheduler {
2729 private JobHandle _Handle ;
2830
2931 private NativeList < int3 > _Jobs ;
30- private Queue < int3 > _Queue ;
32+ private NativeParallelHashMap < int3 , Chunk > _Results ;
33+ private Queue < VloxyBatch < int3 > > _Batches ;
34+ private VloxyBatch < int3 > _CurrentBatch ;
35+
3136 private bool _Scheduled ;
3237 private int _BatchSize ;
3338
@@ -49,8 +54,10 @@ BurstFunctionPointers burstFunctionPointers
4954 _NoiseProfile = noiseProfile ;
5055 _BurstFunctionPointers = burstFunctionPointers ;
5156
52- _Queue = new Queue < int3 > ( ) ;
57+ _Batches = new Queue < VloxyBatch < int3 > > ( ) ;
58+
5359 _Jobs = new NativeList < int3 > ( Allocator . Persistent ) ;
60+ _Results = new NativeParallelHashMap < int3 , Chunk > ( settings . Chunk . LoadDistance . CubedSize ( ) , Allocator . Persistent ) ;
5461
5562#if VLOXY_LOGGING
5663 _Watch = new Stopwatch ( ) ;
@@ -59,7 +66,7 @@ BurstFunctionPointers burstFunctionPointers
5966 }
6067
6168 internal bool Update ( ) {
62- if ( _Scheduled || _Queue . Count <= 0 ) return false ;
69+ if ( _Scheduled || ! Processing ) return false ;
6370
6471 Process ( ) ;
6572
@@ -69,8 +76,17 @@ internal bool Update() {
6976 internal bool LateUpdate ( ) {
7077 return _Scheduled && Complete ( ) ;
7178 }
79+
80+ internal void Dispose ( ) {
81+ _Jobs . Dispose ( ) ;
82+ _Results . Dispose ( ) ;
83+ }
7284
73- public void GenerateChunks ( NativeArray < int3 > jobs ) {
85+ /// <summary>
86+ /// Initial Generation
87+ /// </summary>
88+ /// <param name="jobs"></param>
89+ internal void GenerateChunks ( NativeArray < int3 > jobs ) {
7490 var job = new ChunkDataJob {
7591 Jobs = jobs ,
7692 ChunkSize = _ChunkSize ,
@@ -80,12 +96,12 @@ public void GenerateChunks(NativeArray<int3> jobs) {
8096 } ;
8197
8298 var handle = job . Schedule ( jobs . Length , 4 ) ;
83-
99+
84100 handle . Complete ( ) ;
85-
101+
86102 for ( var index = 0 ; index < jobs . Length ; index ++ ) {
87103 var position = jobs [ index ] ;
88-
104+
89105 if ( _ChunkState . GetState ( position ) == ChunkState . State . STREAMING ) {
90106 _ChunkState . SetState ( position , ChunkState . State . LOADED ) ;
91107 } else { // This is unnecessary, how can we avoid this ?
@@ -94,23 +110,87 @@ public void GenerateChunks(NativeArray<int3> jobs) {
94110#endif
95111 }
96112 }
97-
113+
98114 jobs . Dispose ( ) ;
99115 }
116+
117+ internal void Reclaim ( List < int3 > positions ) {
118+ for ( int i = 0 ; i < positions . Count ; i ++ ) {
119+ var position = positions [ i ] ;
120+ var state = _ChunkState . GetState ( position ) ;
121+
122+ switch ( state ) {
123+ case ChunkState . State . UNLOADED :
124+ #if VLOXY_LOGGING
125+ VloxyLogger . Warn < ChunkDataScheduler > ( $ "Invalid state : { state } for : { position } ") ;
126+ #endif
127+ break ;
128+ case ChunkState . State . STREAMING :
129+ _ChunkState . RemoveState ( position ) ;
130+ break ;
131+ case ChunkState . State . LOADED :
132+ _ChunkStore . RemoveChunk ( position ) ;
133+ _ChunkState . RemoveState ( position ) ;
134+ break ;
135+ case ChunkState . State . MESHING :
136+ _ChunkStore . RemoveChunk ( position ) ;
137+ _ChunkState . RemoveState ( position ) ;
138+ break ;
139+ case ChunkState . State . ACTIVE :
140+ _ChunkStore . RemoveChunk ( position ) ;
141+ _ChunkState . RemoveState ( position ) ;
142+ break ;
143+ default :
144+ throw new ArgumentOutOfRangeException ( ) ;
145+ }
146+ }
147+ }
100148
101- public void Schedule ( List < int3 > jobs ) {
149+ internal void Schedule ( List < int3 > jobs ) {
150+ var batch = new VloxyBatch < int3 > ( jobs . Count ) ;
151+
102152 for ( int i = 0 ; i < jobs . Count ; i ++ ) {
103- _Queue . Enqueue ( jobs [ i ] ) ;
153+ var position = jobs [ i ] ;
154+ var state = _ChunkState . GetState ( position ) ;
155+
156+ switch ( state ) {
157+ case ChunkState . State . UNLOADED :
158+ batch . Enqueue ( position ) ;
159+ _ChunkState . SetState ( position , ChunkState . State . STREAMING ) ;
160+ break ;
161+ case ChunkState . State . STREAMING :
162+ #if VLOXY_LOGGING
163+ VloxyLogger . Warn < ChunkDataScheduler > ( $ "Waiting streaming for : { position } ") ;
164+ #endif
165+ break ;
166+ case ChunkState . State . LOADED :
167+ case ChunkState . State . MESHING :
168+ case ChunkState . State . ACTIVE :
169+ #if VLOXY_LOGGING
170+ VloxyLogger . Warn < ChunkDataScheduler > ( $ "Invalid state : { state } for : { position } ") ;
171+ #endif
172+ break ;
173+ default :
174+ throw new ArgumentOutOfRangeException ( ) ;
175+ }
104176 }
105177
106- Processing = _Queue . Count > 0 ;
178+ _Batches . Enqueue ( batch ) ;
179+
180+ Processing = _Batches . Count > 0 ;
107181 }
108182
109183 private void Process ( ) {
184+ _CurrentBatch ??= _Batches . Dequeue ( ) ;
185+
110186 var count = _BatchSize ;
111-
112- while ( count > 0 && _Queue . Count > 0 ) {
113- _Jobs . Add ( _Queue . Dequeue ( ) ) ;
187+
188+ while ( count > 0 && _CurrentBatch . Count > 0 ) {
189+ var position = _CurrentBatch . Dequeue ( ) ;
190+
191+ if ( _ChunkState . GetState ( position ) != ChunkState . State . STREAMING ) continue ;
192+
193+ _Jobs . Add ( position ) ;
114194 count -- ;
115195 }
116196
@@ -122,7 +202,7 @@ private void Process() {
122202 Jobs = _Jobs ,
123203 ChunkSize = _ChunkSize ,
124204 NoiseProfile = _NoiseProfile ,
125- Results = _ChunkStore . Chunks . AsParallelWriter ( ) ,
205+ Results = _Results . AsParallelWriter ( ) ,
126206 BurstFunctionPointers = _BurstFunctionPointers ,
127207 } ;
128208
@@ -140,6 +220,8 @@ private bool Complete() {
140220 var position = _Jobs [ index ] ;
141221
142222 if ( _ChunkState . GetState ( position ) == ChunkState . State . STREAMING ) {
223+ var chunk = _Results [ position ] ;
224+ _ChunkStore . Chunks . Add ( position , chunk ) ;
143225 _ChunkState . SetState ( position , ChunkState . State . LOADED ) ;
144226 } else { // This is unnecessary, how can we avoid this ?
145227#if VLOXY_LOGGING
@@ -149,9 +231,13 @@ private bool Complete() {
149231 }
150232
151233 _Jobs . Clear ( ) ;
234+ _Results . Clear ( ) ;
235+
152236 _Scheduled = false ;
153237
154- Processing = _Queue . Count > 0 ;
238+ if ( _CurrentBatch . Count == 0 ) _CurrentBatch = null ;
239+
240+ Processing = _Batches . Count > 0 || _CurrentBatch != null ;
155241
156242#if VLOXY_LOGGING
157243 _Watch . Stop ( ) ;
@@ -160,10 +246,6 @@ private bool Complete() {
160246 return true ;
161247 }
162248
163- public void Dispose ( ) {
164- _Jobs . Dispose ( ) ;
165- }
166-
167249#if VLOXY_LOGGING
168250 public float AvgTime => ( float ) _Timings . Sum ( ) / 10 ;
169251
0 commit comments