protected override void OnDestroy() { GridDataInitialization.MyDestroy(); GridData.GetInstance().MyDestroy(); base.OnDestroy(); }
protected override void OnUpdate() { EntityManager entityManager = World.EntityManager; entityManager.CompleteAllJobs(); // now do special stuff that can't be done in parallel! // // ALL COMMAND BUFFER CHANGES // // Drone Task System: while (DroneTaskSystem.addRemoveTags.Count > 0) { TagInfo tagInfo = DroneTaskSystem.addRemoveTags.Dequeue(); if (tagInfo.shouldRemove == 1) { switch (tagInfo.type) { case Tags.Moving: entityManager.RemoveComponent(tagInfo.entity, typeof(MovingTag)); break; case Tags.NeedsTask: entityManager.RemoveComponent(tagInfo.entity, typeof(NeedsTaskTag)); break; case Tags.PerformTask: entityManager.RemoveComponent(tagInfo.entity, typeof(PerformTaskTag)); break; case Tags.Disable: entityManager.RemoveComponent(tagInfo.entity, typeof(Disabled)); break; default: break; } } else { switch (tagInfo.type) { case Tags.Moving: entityManager.AddComponent(tagInfo.entity, typeof(MovingTag)); break; case Tags.NeedsTask: entityManager.AddComponent(tagInfo.entity, typeof(NeedsTaskTag)); break; case Tags.PerformTask: entityManager.AddComponent(tagInfo.entity, typeof(PerformTaskTag)); break; case Tags.Disable: entityManager.AddComponent(tagInfo.entity, typeof(Disabled)); break; default: break; } } } while (DroneTaskSystem.componentSetInfo.Count > 0) { ComponentSetInfo setInfo = DroneTaskSystem.componentSetInfo.Dequeue(); entityManager.SetComponentData(setInfo.entity, setInfo.plantComponent); } // farmer Task System: while (FarmerTaskSystem.addRemoveTags.Count > 0) { TagInfo tagInfo = FarmerTaskSystem.addRemoveTags.Dequeue(); if (tagInfo.shouldRemove == 1) { switch (tagInfo.type) { case Tags.Moving: entityManager.RemoveComponent(tagInfo.entity, typeof(MovingTag)); break; case Tags.NeedsTask: entityManager.RemoveComponent(tagInfo.entity, typeof(NeedsTaskTag)); break; case Tags.PerformTask: entityManager.RemoveComponent(tagInfo.entity, typeof(PerformTaskTag)); break; case Tags.Disable: entityManager.RemoveComponent(tagInfo.entity, typeof(Disabled)); break; default: break; } } else { switch (tagInfo.type) { case Tags.Moving: entityManager.AddComponent(tagInfo.entity, typeof(MovingTag)); break; case Tags.NeedsTask: entityManager.AddComponent(tagInfo.entity, typeof(NeedsTaskTag)); break; case Tags.PerformTask: entityManager.AddComponent(tagInfo.entity, typeof(PerformTaskTag)); break; case Tags.Disable: entityManager.AddComponent(tagInfo.entity, typeof(Disabled)); break; default: break; } } } while ( FarmerTaskSystem.componentSetInfo.Count > 0) { ComponentSetInfo setInfo = FarmerTaskSystem.componentSetInfo.Dequeue(); entityManager.SetComponentData(setInfo.entity, setInfo.plantComponent); } // movement system: while (MovementSystem.addRemoveTags.Count > 0) { TagInfo tagInfo = MovementSystem.addRemoveTags.Dequeue(); if (tagInfo.shouldRemove == 1) { switch (tagInfo.type) { case Tags.Moving: entityManager.RemoveComponent(tagInfo.entity, typeof(MovingTag)); break; case Tags.NeedsTask: entityManager.RemoveComponent(tagInfo.entity, typeof(NeedsTaskTag)); break; case Tags.PerformTask: entityManager.RemoveComponent(tagInfo.entity, typeof(PerformTaskTag)); break; case Tags.Disable: entityManager.RemoveComponent(tagInfo.entity, typeof(Disabled)); break; default: break; } } else { switch (tagInfo.type) { case Tags.Moving: entityManager.AddComponent(tagInfo.entity, typeof(MovingTag)); break; case Tags.NeedsTask: entityManager.AddComponent(tagInfo.entity, typeof(NeedsTaskTag)); break; case Tags.PerformTask: entityManager.AddComponent(tagInfo.entity, typeof(PerformTaskTag)); break; case Tags.Disable: entityManager.AddComponent(tagInfo.entity, typeof(Disabled)); break; default: break; } } } // perform tasks system: while ( PerformTaskSystem.addRemoveTags.Count > 0) { TagInfo tagInfo = PerformTaskSystem.addRemoveTags.Dequeue(); if (tagInfo.shouldRemove == 1) { switch (tagInfo.type) { case Tags.Moving: entityManager.RemoveComponent(tagInfo.entity, typeof(MovingTag)); break; case Tags.NeedsTask: entityManager.RemoveComponent(tagInfo.entity, typeof(NeedsTaskTag)); break; case Tags.PerformTask: entityManager.RemoveComponent(tagInfo.entity, typeof(PerformTaskTag)); break; case Tags.Disable: entityManager.RemoveComponent(tagInfo.entity, typeof(Disabled)); break; default: break; } } else { switch (tagInfo.type) { case Tags.Moving: entityManager.AddComponent(tagInfo.entity, typeof(MovingTag)); break; case Tags.NeedsTask: entityManager.AddComponent(tagInfo.entity, typeof(NeedsTaskTag)); break; case Tags.PerformTask: entityManager.AddComponent(tagInfo.entity, typeof(PerformTaskTag)); break; case Tags.Disable: entityManager.AddComponent(tagInfo.entity, typeof(Disabled)); break; default: break; } } } while (PerformTaskSystem.componentSetInfo.Count > 0) { ComponentSetInfo setInfo = PerformTaskSystem.componentSetInfo.Dequeue(); entityManager.SetComponentData(setInfo.entity, setInfo.plantComponent); } // Plant system: while (PlantSystem.componentSetInfo.Count > 0) { PlantSystem.ComponentTransInfo setInfo = PlantSystem.componentSetInfo.Dequeue(); Translation trans = new Translation { Value = setInfo.trans }; entityManager.SetComponentData(setInfo.entity, trans); } while (PlantSystem.plantCreationDeletionInfo.Count > 0) { Entity info = (Entity)PlantSystem.plantCreationDeletionInfo.Dequeue(); // set deleted plants invisible and add them to the free plant list entityManager.AddComponent(info, typeof(Disabled)); PlantSystem.freePlants.Enqueue(info); } // // ALL NON-PARALLEL OPERATIONS WITH SYSTEMS THAT AREN'T COMMAND BUFFER RELATED // // // PERFORM TASK SYSTEM // // parallelization would be difficult since multiple farmers can potentially // turn the same tile into a tilled tile // Would have to make it so that only one farmer can set the tile // to parallelize this while (PerformTaskSystem.tillChanges.Count > 0) { float2 pos = PerformTaskSystem.tillChanges.Dequeue(); if ((int)pos.x != -1 && (int)pos.y != -1) { // set the uv's on the mesh // NOTE: set pos to be a specific number if you want to test it Mesh tmp = GridDataInitialization.getMesh((int)pos.x, (int)pos.y, GridDataInitialization.BoardWidth); int width = GridDataInitialization.getMeshWidth(tmp, (int)pos.x, (int)pos.y, GridDataInitialization.BoardWidth); NativeArray <float2> uvs = GridDataInitialization.getUVs((int)pos.x, (int)pos.y, GridDataInitialization.BoardWidth); TextureUV tex = GridDataInitialization.textures[(int)GridDataInitialization.BoardTypes.TilledDirt]; int uvStartIndex = (GridDataInitialization.getPosForMesh((int)pos.y) + width * GridDataInitialization.getPosForMesh((int)pos.x)) * 4; //Debug.Log("changing uv at! " + pos + " " + width + " " + uvStartIndex + " " + GridDataInitialization.getPosForMesh((int)pos.x) + // " " + GridDataInitialization.getPosForMesh((int)pos.y) + "array length: " + uv.Length); uvs[uvStartIndex] = new float2(tex.pixelStartX, tex.pixelStartY); uvs[uvStartIndex + 1] = new float2(tex.pixelStartX, tex.pixelEndY); uvs[uvStartIndex + 2] = new float2(tex.pixelEndX, tex.pixelEndY); uvs[uvStartIndex + 3] = new float2(tex.pixelEndX, tex.pixelStartY); tmp.SetUVs(0, uvs); tmp.MarkModified(); } } // max this gets run is once a frame and // many times it doesn't get run at all // not worth running in parallel if (PerformTaskSystem.plantsSold[0] > 0) { PerformTaskSystem.storeInfo.moneyForFarmers += PerformTaskSystem.plantsSold[0]; PerformTaskSystem.storeInfo.moneyForDrones += PerformTaskSystem.plantsSold[0]; if (PerformTaskSystem.storeInfo.moneyForFarmers >= 10 && GridDataInitialization.farmerCount < GridDataInitialization.MaxFarmers) { // spawn a new farmer - never more than 1 a frame PerformTaskSystem.storeInfo.moneyForFarmers -= 10; var instance = entityManager.Instantiate(GridDataInitialization.farmerEntity); GridDataInitialization.farmerCount++; int startX = System.Math.Abs(rand.NextInt()) % GridData.GetInstance().width; int startZ = System.Math.Abs(rand.NextInt()) % GridData.GetInstance().width; // Place the instantiated entity in a random position on the grid var position = new float3(startX, 2, startZ); entityManager.SetComponentData(instance, new Translation() { Value = position }); var farmerData = new MovementComponent { startPos = new float2(startX, startZ), speed = 2, targetPos = new float2(startX, startZ) }; var entityData = new EntityInfo { type = -1 }; entityManager.SetComponentData(instance, farmerData); entityManager.AddComponentData(instance, entityData); // give his first command entityManager.AddComponent <NeedsTaskTag>(instance); } if (PerformTaskSystem.storeInfo.moneyForDrones >= 50 && GridDataInitialization.droneCount < GridDataInitialization.MaxDrones) { // spawn a new drone PerformTaskSystem.storeInfo.moneyForDrones -= 50; var instance = entityManager.Instantiate(GridDataInitialization.droneEntity); GridDataInitialization.droneCount++; int startX = System.Math.Abs(rand.NextInt()) % GridData.GetInstance().width; int startZ = System.Math.Abs(rand.NextInt()) % GridData.GetInstance().width; // Place the instantiated entity in a random position on the grid var position = new float3(startX, 2, startZ); entityManager.SetComponentData(instance, new Translation() { Value = position }); var droneData = new MovementComponent { startPos = new float2(startX, startZ), speed = 2, targetPos = new float2(startX, startZ), }; var entityData = new EntityInfo { type = -1 }; entityManager.SetComponentData(instance, droneData); entityManager.SetComponentData(instance, entityData); // give his first command entityManager.AddComponent <NeedsTaskTag>(instance); } PerformTaskSystem.plantsSold[0] = 0; } // // DRONE TASK SYSTEM: // // This is here as hash table removals can't // be done in parallel (with good reason!) GridData data = GridData.GetInstance(); // take care of drones while (DroneTaskSystem.hashRemovalsDrone.Count > 0) { DroneTaskSystem.RemovalInfo remInfo = (DroneTaskSystem.RemovalInfo)DroneTaskSystem.hashRemovalsDrone.Dequeue(); int key = remInfo.key; EntityInfo value; if (data.gridStatus.TryGetValue(key, out value)) { if (value.type == (int)Tiles.Plant) { // this is a harvest, so try to remove and if we can // then set up the entity to harvest it if (data.gridStatus.ContainsKey(key)) { data.gridStatus.Remove(key); // set reserve data in plant component for this entity entityManager.SetComponentData(value.specificEntity, new PlantComponent { timeGrown = PlantSystem.MAX_GROWTH, state = (int)PlantState.None, reserveIndex = remInfo.requestingEntity.Index, }); } } else { data.gridStatus.Remove(key); } } } // // FARMER TASK SYSTEM: // // This is here because hash table removals can't // be done in parallel. while (FarmerTaskSystem.hashRemovalsFarmer.Count > 0) { FarmerTaskSystem.RemovalInfo remInfo = FarmerTaskSystem.hashRemovalsFarmer.Dequeue(); int key = remInfo.key; EntityInfo value; if (data.gridStatus.TryGetValue(key, out value)) { if (value.type == (int)Tiles.Till) { float plantingHeight = 1.0f; // we're planting here and need to add a plant entity data.gridStatus.Remove(key); float2 trans = new float2(GridData.getRow(key), GridData.getCol(key)); Entity instance; if (PlantSystem.freePlants.Count > 0) { // this will become the new plant to put it back into use instance = (Entity)PlantSystem.freePlants.Dequeue(); entityManager.RemoveComponent(instance, typeof(Disabled)); } else { // we really have to instantiate the plant int nextRandom = UnityEngine.Mathf.Abs(rand.NextInt()) % GridDataInitialization.DIFF_PLANT_COUNT; instance = entityManager.Instantiate(GridDataInitialization.plantEntity[nextRandom]); Rotation rotation = entityManager.GetComponentData <Rotation>(instance); var newRot = rotation.Value * Quaternion.Euler(0, 0, 90); entityManager.SetComponentData(instance, new Rotation { Value = newRot }); } EntityInfo plantInfo = new EntityInfo { type = (int)Tiles.Plant, specificEntity = instance }; if (data.gridStatus.TryAdd(key, plantInfo)) { float3 pos = new float3((int)trans.x, plantingHeight, (int)trans.y); entityManager.SetComponentData(instance, new Translation { Value = pos }); entityManager.SetComponentData(instance, new NonUniformScale { Value = new float3(1.0f, 1.0f, 1.0f) }); // for some reason the original plant mesh creation happens on the wrong axis, // so we have to rotate it 90 degrees entityManager.SetComponentData(instance, new PlantComponent { timeGrown = 0, state = (int)PlantState.Growing, }); //Debug.Log("added grid plant " + instance.Index); } } else if (value.type == (int)Tiles.Plant) { // this is a harvest, so try to remove and if we can // then set up the entity to harvest it if (data.gridStatus.ContainsKey(key)) { data.gridStatus.Remove(key); // set reserve data in plant component for this entity entityManager.SetComponentData(value.specificEntity, new PlantComponent { timeGrown = PlantSystem.MAX_GROWTH, state = (int)PlantState.None, reserveIndex = remInfo.requestingEntity.Index, }); } } else { data.gridStatus.Remove(key); } } } }