public void Subscribe(Entity entity) { if (!Enable) { return; } if (!subscribers.Contains(entity)) { subscribers.Add(entity); } }
/// <summary> /// Publish event. /// </summary> /// <param name="eventMessage">Event message.</param> public void Publish <T> (T eventMessage) { var eventType = typeof(T); FastList <Func <T, bool> > list = null; lock (_syncObj) { if (_eventsInCall.Contains(eventType)) { Debug.LogError("Already in calling of " + eventType.Name); return; } object objList; if (_events.TryGetValue(eventType, out objList)) { list = (FastList <Func <T, bool> >)objList; // kept for no new GC alloc, but empty. if (list.Count == 0) { list = null; } } if (list != null) { _eventsInCall.Add(eventType); } } if (list != null) { var cacheList = _eventSpecificListCaches[eventType]; int i; int iMax; var listData = list.GetData(out iMax); cacheList.Reserve(iMax, true, false); var cacheListData = cacheList.GetData(); // we cant use direct copy because cached list dont know T-generic type of event. for (i = 0; i < iMax; i++) { cacheListData[i] = listData[i]; } try { for (i = 0; i < iMax; i++) { if (((Func <T, bool>)cacheListData[i])(eventMessage)) { // Event was interrupted / processed, we can exit. return; } } } finally { cacheList.Clear(); lock (_syncObj) { _eventsInCall.Remove(eventType); } } } }
public void RegisterCamera(CameraComponent cameraComponent) { if (cameraComponent == null) { Log.Error("Entity attempted to register a camera when no camera is attached."); return; } if (!cameraDb.Contains(cameraComponent)) { cameraDb.Add(cameraComponent); Log.Info($"{cameraComponent?.Entity.Name} camera has been registered with camera db."); } }
/* ----------------------- UpdateFreeEmitters() ----------------------- */ void UpdateFreeEmitters() { if ( verboseLogging ) { if ( Input.GetKeyDown( KeyCode.A ) ) { forceShowEmitterCount = !forceShowEmitterCount: } if ( forceShowEmitterCount ) { showPlayingEmitterCount = true: } } // display playing emitter count when the sound system is overwhelmed int total = 0, veryLow = 0, low = 0, def = 0, high = 0, veryHigh = 0: // find emitters that are done playing and add them to the nextFreeEmitters list for ( int i = 0: i < playingEmitters.size: ) { if ( playingEmitters[i] == null ) { Debug.LogError( "[AudioManager] ERROR: playingEmitters list had a null emitter! Something nuked a sound emitter!!!" ): playingEmitters.RemoveAtFast( i ): return: } if ( !playingEmitters[i].IsPlaying() ) { // add to the free list and remove from the playing list if ( verboseLogging ) { if ( nextFreeEmitters.Contains( playingEmitters[i] ) ) { Debug.LogError( "[AudioManager] ERROR: playing sound emitter already in the free emitters list!" ): } } playingEmitters[i].Stop(): nextFreeEmitters.Add( playingEmitters[i] ): playingEmitters.RemoveAtFast( i ): continue: } // debugging/profiling if ( verboseLogging && showPlayingEmitterCount ) { total++: switch ( playingEmitters[i].priority ) { case SoundPriority.VeryLow: veryLow++: break: case SoundPriority.Low: low++: break: case SoundPriority.Default: def++: break: case SoundPriority.High: high++: break: case SoundPriority.VeryHigh: veryHigh++: break: } } i++: } if ( verboseLogging && showPlayingEmitterCount ) { Debug.LogWarning( string.Format( "[AudioManager] Playing sounds: Total {0} | VeryLow {1} | Low {2} | Default {3} | High {4} | VeryHigh {5} | Free {6}", Fmt( total ), Fmt( veryLow ), Fmt( low ), Fmt( def ), Fmt( high ), Fmt( veryHigh ), FmtFree( nextFreeEmitters.Count ) ) ): showPlayingEmitterCount = false: } }
//从四叉树中移除一个对象 public void Remove(CollisionComponent coll) { if (m_objectList.Contains(coll)) { m_objectList.Remove(coll); m_objectListCount--; } else { for (int i = 0; i < m_childListCount; i++) { m_childList[i].Remove(coll); } } }
// Solved by ReleaseQuestionableSegments /*private static void CheckSplitSegmentAngle(ref NetTool.ControlPoint point, FastList<ushort> createdSegments, HashSet<ConnectionPoint> borderNodes) * { * if(point.m_segment != 0) * { * if (createdSegments.Contains(point.m_segment)) * return; * * if (point.m_node != 0) * return; * * Debug.Log("CheckSplitSegmentAngle: Snapping detected"); * NetSegment netSegment = NetAccess.GetSegment(point.m_segment); * netSegment.GetClosestPositionAndDirection(point.m_position, out Vector3 pos, out Vector3 dir); * float angle = Vector3.Angle(point.m_direction, dir); * if(angle < 5 || 180 - angle < 5) * { * Debug.Log("CheckSplitSegmentAngle: Releasing (" + angle + " deg)"); * bool inverted = ((netSegment.m_flags & NetSegment.Flags.Invert) != NetSegment.Flags.None); * ConnectionPoint p1 = new ConnectionPoint(netSegment.m_startNode, netSegment.m_startDirection, netSegment.Info, inverted); * ConnectionPoint p2 = new ConnectionPoint(netSegment.m_endNode, netSegment.m_endDirection, netSegment.Info, !inverted); * NetAccess.ReleaseSegment(point.m_segment, true); * if(NetAccess.ExistsNode(p1.Node) && NetAccess.ExistsNode(p2.Node)) * { * borderNodes.Add(p1); * borderNodes.Add(p2); * } * } * } * }*/ /* Sometimes the intersection end snaps to an existing road. But it can happen that the intersection road and the road it snaps to are (more or * less) parallel. Then we are left with a piece of old road overlapping the new road because the old segment for some reason doesn't show up as * colliding. We have to find it and release it. I think that it shouldn't happen more than once per intersection tho. */ private static void ReleaseQuestionableSegments(FastList <ushort> newNodes, FastList <ushort> newSegments) { foreach (ushort node in newNodes) { NetNode netNode = NetAccess.GetNode(node); ushort foundSegment = 0; for (int i = 0; i < 8; i++) { ushort segment = netNode.GetSegment(i); if (segment != 0 && newSegments.Contains(segment)) { if (foundSegment != 0) { goto continueOuterLoop; } else { foundSegment = segment; } } } Vector3 direction = NetAccess.GetSegment(foundSegment).GetDirection(node); for (int i = 0; i < 8; i++) { ushort segment = netNode.GetSegment(i); if (segment != 0 && segment != foundSegment) { float angle = Vector3.Angle(direction, NetAccess.GetSegment(segment).GetDirection(node)); if (angle < 10) { //Debug.Log("Releasing questionable segment " + segment); NetAccess.ReleaseSegment(segment); goto breakOuterLoop; } } } continueOuterLoop :; } breakOuterLoop :; }
public static bool Contains <T> (string messageName, Del <T> handler) where T : LSMessage { object o; if (events.TryGetValue(messageName, out o) == false) { return(false); } FastList <Del <T> > dels = o as FastList <Del <T> >; if (dels == null) { return(false); } if (dels.Contains(handler)) { return(true); } return(false); }
//从四叉树中移除一个对象 public bool Remove(CollisionComponent coll) { if (m_objectList.Contains(coll)) { m_objectList.Remove(coll); m_objectListCount--; return(true); } else { for (int i = 0; i < m_childListCount; i++) { bool isRemove = m_childList[i].Remove(coll); if (isRemove) { return(true); } } return(false); } }
private void ProcessInput() { float deltaTime = (float)Game.UpdateTime.Elapsed.TotalSeconds; translation = Vector3.Zero; yaw = 0f; pitch = 0f; // Keyboard and Gamepad based movement { // Our base speed is: one unit per second: // deltaTime contains the duration of the previous frame, let's say that in this update // or frame it is equal to 1/60, that means that the previous update ran 1/60 of a second ago // and the next will, in most cases, run in around 1/60 of a second from now. Knowing that, // we can move 1/60 of a unit on this frame so that in around 60 frames(1 second) // we will have travelled one whole unit in a second. // If you don't use deltaTime your speed will be dependant on the amount of frames rendered // on screen which often are inconsistent, meaning that if the player has performance issues, // this outlineComponent will move around slower. float speed = 1f * deltaTime; Vector3 dir = Vector3.Zero; if (Gamepad && Input.HasGamePad) { GamePadState padState = Input.DefaultGamePad.State; // LeftThumb can be positive or negative on both axis (pushed to the right or to the left) dir.Z += padState.LeftThumb.Y; dir.X += padState.LeftThumb.X; // Triggers are always positive, in this case using one to increase and the other to decrease dir.Y -= padState.LeftTrigger; dir.Y += padState.RightTrigger; // Increase speed when pressing A, LeftShoulder or RightShoulder // Here:does the enum flag 'Buttons' has one of the flag ('A','LeftShoulder' or 'RightShoulder') set if ((padState.Buttons & (GamePadButton.A | GamePadButton.LeftShoulder | GamePadButton.RightShoulder)) != 0) { speed *= SpeedFactor; } } if (Input.HasKeyboard) { // Move with keyboard // Forward/Backward if (Input.IsKeyDown(Keys.W) || Input.IsKeyDown(Keys.Up)) { dir.Z += 1; } if (Input.IsKeyDown(Keys.S) || Input.IsKeyDown(Keys.Down)) { dir.Z -= 1; } // Left/Right if (Input.IsKeyDown(Keys.A) || Input.IsKeyDown(Keys.Left)) { dir.X -= 1; } if (Input.IsKeyDown(Keys.D) || Input.IsKeyDown(Keys.Right)) { dir.X += 1; } // Down/Up if (Input.IsKeyDown(Keys.Q)) { dir.Y -= 1; } if (Input.IsKeyDown(Keys.E)) { dir.Y += 1; } // Increase speed when pressing shift if (Input.IsKeyDown(Keys.LeftShift) || Input.IsKeyDown(Keys.RightShift)) { speed *= SpeedFactor; } // If the player pushes down two or more buttons, the direction and ultimately the base speed // will be greater than one (vector(1, 1) is farther away from zero than vector(0, 1)), // normalizing the vector ensures that whichever direction the player chooses, that direction // will always be at most one unit in length. // We're keeping dir as is if isn't longer than one to retain sub unit movement: // a stick not entirely pushed forward should make the outlineComponent move slower. if (dir.Length() > 1f) { dir = Vector3.Normalize(dir); } } // Finally, push all of that to the translation variable which will be used within UpdateTransform() translation += dir * KeyboardMovementSpeed * speed; } // Keyboard and Gamepad based Rotation { // See Keyboard & Gamepad translation's deltaTime usage float speed = 1f * deltaTime; Vector2 rotation = Vector2.Zero; if (Gamepad && Input.HasGamePad) { GamePadState padState = Input.DefaultGamePad.State; rotation.X += padState.RightThumb.Y; rotation.Y += -padState.RightThumb.X; } if (Input.HasKeyboard) { if (Input.IsKeyDown(Keys.NumPad2)) { rotation.X += 1; } if (Input.IsKeyDown(Keys.NumPad8)) { rotation.X -= 1; } if (Input.IsKeyDown(Keys.NumPad4)) { rotation.Y += 1; } if (Input.IsKeyDown(Keys.NumPad6)) { rotation.Y -= 1; } // See Keyboard & Gamepad translation's Normalize() usage if (rotation.Length() > 1f) { rotation = Vector2.Normalize(rotation); } } // Modulate by speed rotation *= KeyboardRotationSpeed * speed; // Finally, push all of that to pitch & yaw which are going to be used within UpdateTransform() pitch += rotation.X; yaw += rotation.Y; } // Mouse movement and gestures { // This type of input should not use delta time at all, they already are frame-rate independent. // Lets say that you are going to move your finger/mouse for one second over 40 units, it doesn't matter // the amount of frames occuring within that time frame, each frame will receive the right amount of delta: // a quarter of a second -> 10 units, half a second -> 20 units, one second -> your 40 units. if (Input.HasMouse) { // Ray cast into the scene for outline highlighting if (Raycast(Input.MousePosition, CollisionFilterGroupFlags.CustomFilter10, out var _, out var outlineComponent)) { outlineComponent?.Enable(); if (!outlinedComponents.Contains(outlineComponent)) { outlinedComponents.Add(outlineComponent); } } else { foreach (var outlinedComponent in outlinedComponents) { outlinedComponent.Disable(); } } // Rotate with mouse if (Input.IsMouseButtonDown(MouseButton.Right)) { Input.LockMousePosition(); Game.IsMouseVisible = false; yaw -= Input.MouseDelta.X * MouseRotationSpeed.X; pitch -= Input.MouseDelta.Y * MouseRotationSpeed.Y; } else { Input.UnlockMousePosition(); Game.IsMouseVisible = true; } } // Handle gestures foreach (var gestureEvent in Input.GestureEvents) { switch (gestureEvent.Type) { // Rotate by dragging case GestureType.Drag: var drag = (GestureEventDrag)gestureEvent; var dragDistance = drag.DeltaTranslation; yaw = -dragDistance.X * TouchRotationSpeed.X; pitch = -dragDistance.Y * TouchRotationSpeed.Y; break; // Move along z-axis by scaling and in xy-plane by multi-touch dragging case GestureType.Composite: var composite = (GestureEventComposite)gestureEvent; translation.X = -composite.DeltaTranslation.X * TouchMovementSpeed.X; translation.Y = -composite.DeltaTranslation.Y * TouchMovementSpeed.Y; translation.Z = (float)Math.Log(composite.DeltaScale + 1) * TouchMovementSpeed.Z; break; } } }
/* Sometimes the intersection end snaps to an existing road. But it can happen that the intersection road and the road it snaps to are (more or * less) parallel. Then we are left with a piece of old road overlapping the new road because the old segment for some reason doesn't show up as * colliding. We have to find it and release it. I think that it shouldn't happen more than once per intersection tho. */ private static void ReleaseQuestionableSegments(FastList <ushort> newNodes, FastList <ushort> newSegments) { foreach (ushort node in newNodes) { NetNode netNode = NetUtil.Node(node); ushort foundSegment = 0; for (int i = 0; i < 8; i++) { ushort segment = netNode.GetSegment(i); if (segment != 0 && newSegments.Contains(segment)) { if (foundSegment != 0) { goto continueOuterLoop; } else { foundSegment = segment; } } } Vector3 direction = NetUtil.Segment(foundSegment).GetDirection(node); for (int i = 0; i < 8; i++) { ushort segment = netNode.GetSegment(i); if (segment != 0 && segment != foundSegment) { float angle = Vector3.Angle(direction, NetUtil.Segment(segment).GetDirection(node)); if (angle < 10) { //Debug.Log("Releasing questionable segment " + segment); //NetUtil.ReleaseSegment(segment); WrappedSegment segmentW = _networkDictionary.RegisterSegment(segment); _actionGroup.Actions.Add(segmentW); segmentW.IsBuildAction = false; segmentW.Release(); if (segmentW.StartNode.TryRelease()) { _actionGroup.Actions.Add(segmentW.StartNode); segmentW.StartNode.IsBuildAction = false; } if (segmentW.EndNode.TryRelease()) { _actionGroup.Actions.Add(segmentW.EndNode); segmentW.EndNode.IsBuildAction = false; } /*WrappedSegment segmentW = _networkDictionary.RegisterSegment(segment); * segmentW.Release();*/ goto breakOuterLoop; } } } continueOuterLoop :; } breakOuterLoop :; }
public bool IsResourceInRange(NaturalResource res) { return(nearResource.Contains(res)); }