public SnapDictionary() { _items = new ConcurrentDictionary <TKey, LinkedNode>(); _generationObjects = new ConcurrentQueue <GenerationObject>(); _generationObject = null; // no initial gen exists _liveGen = _floorGen = 0; _nextGen = false; // first time, must create a snapshot _collectAuto = true; // collect automatically by default }
private void SoilMessageLogic(SoilMessage message) { Unspawn(); if(message.soilObject != null) { SoilObject = (GenerationObject)Instantiate(message.soilObject, transform.position, Quaternion.identity); if(message.action == Action.INCREMENT_GENERATION && SoilObject.SetGenerationIndex(message.soilObject.generationIndex+message.numberOfGenerationIncrement)) { AddGo(SoilObject.gameObject); } else if(message.action == Action.SET && SoilObject.SetGenerationIndex(message.soilObject.generationIndex)) { message.soilObject.gameObject.transform.position = transform.position; AddGo(message.soilObject.gameObject); } } }
public void ChangeSoilObject(int soilId, GenerationObject seedObject) { GenerationObject parentSoil = seedObject; SoilMessage m = new SoilMessage(); m.id = soilId; m.soilObject = parentSoil; m.Broadcast(genList[MAX_GENERATIONS - 1].gameObject); for (int i = MAX_GENERATIONS - 2; i >= 0; --i) { m = new SoilMessage(); m.id = soilId; m.soilObject = parentSoil; m.action = Action.INCREMENT_GENERATION; m.numberOfGenerationIncrement = MAX_GENERATIONS - i - 1; m.Broadcast(genList[i].gameObject); } }
public GenerationReference(GenerationObject generationObject) { GenerationObject = generationObject; }
public Snapshot CreateSnapshot() { var lockInfo = new ReadLockInfo(); try { Lock(lockInfo); // if no next generation is required, and we already have one, // use it and create a new snapshot if (_nextGen == false && _generationObject != null) { return(new Snapshot(this, _generationObject.GetReference())); } // else we need to try to create a new gen ref // whether we are wlocked or not, noone can rlock while we do, // so _liveGen and _nextGen are safe if (_wlocked > 0) // volatile, cannot ++ but could -- { // write-locked, cannot use latest gen (at least 1) so use previous var snapGen = _nextGen ? _liveGen - 1 : _liveGen; // create a new gen ref unless we already have it if (_generationObject == null) { _generationObjects.Enqueue(_generationObject = new GenerationObject(snapGen)); } else if (_generationObject.Gen != snapGen) { throw new Exception("panic"); } } else { // not write-locked, can use latest gen, create a new gen ref _generationObjects.Enqueue(_generationObject = new GenerationObject(_liveGen)); _nextGen = false; // this is the ONLY thing that triggers a _liveGen++ } // so... // the genRefRef has a weak ref to the genRef, and is queued // the snapshot has a ref to the genRef, which has a ref to the genRefRef // when the snapshot is disposed, it decreases genRefRef counter // so after a while, one of these conditions is going to be true: // - the genRefRef counter is zero because all snapshots have properly been disposed // - the genRefRef weak ref is dead because all snapshots have been collected // in both cases, we will dequeue and collect var snapshot = new Snapshot(this, _generationObject.GetReference()); // reading _floorGen is safe if _collectTask is null if (_collectTask == null && _collectAuto && _liveGen - _floorGen > CollectMinGenDelta) { CollectAsyncLocked(); } return(snapshot); } finally { Release(lockInfo); } }