/// <summary> /// Function that display the information of passed node. /// </summary> public void DisplayNodeData(TimerNode __node) { GUILayout.Label("\tUsedByClass: " + __node.delegatedCallback.Method.ReflectedType.FullName); GUILayout.Label("\tMethod: " + __node.delegatedCallback.Method.Name); GUILayout.Label("\tFrames to wait:" + __node.framesToWait); GUILayout.Label("\tFrame Counter:" + __node.frameCounter); GUILayout.Label("\tTime to wait:" + __node.timeToWait); GUILayout.Label("\tCurrent Time Step:" + __node.currentTimeStep); GUILayout.Label("\tCurrent State:" + __node.currentState); GUILayout.Label("\tUpdate Mode:" + __node.updateMode); GUILayout.Label("\tIs Loop:" + __node.usingLoop); GUILayout.Label("\tLoop Iteration:" + __node.loopIteration); if (__node.associatedObject) { GUILayout.BeginHorizontal(); GUILayout.Label("\tAssociated GameObject:" + __node.associatedObject.name); if (GUILayout.Button("Select")) { Selection.activeGameObject = __node.associatedObject; } GUILayout.FlexibleSpace(); GUILayout.EndHorizontal(); } }
/// <summary> /// <para>Called by the timer thread to fire the expired timers. Returns true if there are future timers /// in the queue, and if so, also sets nextExpiration.</para> /// </summary> internal bool Fire(out int nextExpiration) { while (true) { // Check if we got to the end. If so, free the handle. TimerNode timer = _timers.Next; if (timer == _timers) { lock (_timers) { timer = _timers.Next; if (timer == _timers) { if (_thisHandle != IntPtr.Zero) { ((GCHandle)_thisHandle).Free(); _thisHandle = IntPtr.Zero; } nextExpiration = 0; return(false); } } } if (!timer.Fire()) { nextExpiration = timer.Expiration; return(true); } } }
private void SetState(State p_state) { if (CurrentState == p_state) { return; } _currentState = p_state; _water.SetActive(CurrentState != State.DRY); _navMeshSourceTag.enabled = CurrentState != State.IMMERSE; switch (CurrentState) { case State.FLOODED: AudioController.Instance.Play(Tags.Ambience_WaterFillingAdjacent); break; case State.IMMERSE: _timerNode?.Cancel(); _timerNode = Timer.WaitSeconds(GameSettings.FORCE_FLOOD_ADJACENT_TIME, () => { onMaxPressure?.Invoke(this, null); }); break; } onChangeState?.Invoke(this, new OnChangeStateEventArgs(CurrentState, _currentFillAmount)); }
/// <summary> /// 添加TimerNode到本地创建的定时器 /// </summary> /// <param name="delay"></param> /// <param name="func"></param> /// <param name="repeat"></param> /// <param name="interval"></param> /// <returns></returns> public TimerNode AddLocalTimer(float delay, Action func, int repeat = 0, float interval = 0) { var node = new TimerNode(delay, func, repeat, interval); m_TimerNodeList.AddLast(node); return(node); }
/// <summary> /// <para>Cancels the timer. Returns true if it hasn't and won't fire; false if it has or will, or has already been cancelled.</para> /// </summary> internal override bool Cancel() { if (m_TimerState == TimerState.Ready) { lock (m_QueueLock) { if (m_TimerState == TimerState.Ready) { // Remove it from the list. This keeps the list from getting to big when there are a lot of rapid creations // and cancellations. This is done before setting it to Cancelled to try to prevent the Fire() loop from // seeing it, or if it does, of having to take a lock to synchronize with the state of the list. Next.Prev = Prev; Prev.Next = Next; // Just cleanup. Doesn't need to be in the lock but is easier to have here. Next = null; Prev = null; m_Callback = null; m_Context = null; m_TimerState = TimerState.Cancelled; GlobalLog.Print("TimerThreadTimer#" + StartTime.ToString() + "::Cancel() (success)"); return(true); } } } GlobalLog.Print("TimerThreadTimer#" + StartTime.ToString() + "::Cancel() (failure)"); return(false); }
//private static Timer m_GlobalTimer; /// <summary> /// 添加定时器 /// </summary> /// <param name="delay"> 调用延迟时间, 0为下帧调用</param> /// <param name="cbFunc"> 回调函数</param> /// <param name="repeat"> 重复次数</param> /// <param name="interval"> 重复调用间隔</param> /// <returns></returns> public static TimerNode AddTimer(float delay, Action cbFunc, int repeat = 0, float interval = 0) { var timer = Singleton.GetInstance <Timer>(); var node = new TimerNode(delay, cbFunc, repeat, interval); timer.m_TimerNodeList.AddLast(node); return(node); }
/// <summary> /// <para>Create a new TimerQueue. TimerQueues must be created while s_NewQueues is locked in /// order to synchronize with Shutdown().</para> /// </summary> /// <param name="durationMilliseconds"></param> internal TimerQueue(int durationMilliseconds) : base(durationMilliseconds) { // Create the doubly-linked list with a sentinel head and tail so that this member never needs updating. _timers = new TimerNode(); _timers.Next = _timers; _timers.Prev = _timers; }
void Start() { explosionTimer = GetComponent <TimerNode>(); if (GameSettings.bombUpwardsModifier == false) { upwardsModifier = 0; } }
internal int ScheduleEachFrame(Action action) { int id = GetNewTimerId(); TimerNode tn = GetTimerNode(id, action); m_eachFrameTimers.Add(id, tn); return(id); }
public void Construct() { // Arrange // Act var node = new TimerNode(); // Assert Check.That(node).IsNotNull(); }
/// <summary> /// <para>Create a new TimerQueue. TimerQueues must be created while s_NewQueues is locked in /// order to synchronize with Shutdown().</para> /// </summary> /// <param name="durationMilliseconds"></param> internal TimerQueue(int durationMilliseconds) : base(durationMilliseconds) { // Create the doubly-linked list with a sentinel head and tail so that this member never needs updating. m_Timers = new TimerNode(); m_Timers.Next = m_Timers; m_Timers.Prev = m_Timers; // If ReleaseHandle comes back, we need something like this here. // m_HandleFrozen = s_ThreadState == (int) TimerThreadState.Stopped ? 1 : 0; }
public void NodeType() { // Arrange var timerNode = new TimerNode(); var questionNode = new QuestionNode(); // Act // Assert Check.That(timerNode.NodeType).Equals("TimerNode"); Check.That(questionNode.NodeType).Equals("QuestionNode"); }
public void AddNode() { // Arrange var node = new TimerNode { Delay = 10000 }; // Act _target.AddNode(node); // Assert Check.That(_context.Nodes).ContainsExactly(node); }
public void SimulateMouseTap(int p_id, Vector3 p_position) { PressFinger(p_id, p_position); if (_tapTimerNodule != null) { _tapTimerNodule.Cancel(); } _tapTimerNodule = Timer.WaitSeconds(0.1f, delegate { ReleaseFinger(p_id, p_position); }); }
public void Open(MapItem p_object) { _nodeClose?.Cancel(); foreach (GameObject __child in _menuPanel.GetComponentsInChildren <Button>().Select(c => c.gameObject)) { Destroy(__child); } Vector2 __point; RectTransformUtility.ScreenPointToLocalPointInRectangle(_menuCanvas, Input.mousePosition, _view, out __point); IInteractable __actions = p_object as IInteractable; Vector2 __buttonSize = _menuButton.GetComponent <RectTransform>().sizeDelta; _menuPanel.sizeDelta = new Vector2(_menuPanel.sizeDelta.x, 26f + __buttonSize.y * __actions.ListAction.Count + 3 * __actions.ListAction.Count); _menuPanel.position = _menuCanvas.TransformPoint(__point); _menuText.text = p_object.ItemName; __actions.ListAction.Select(p_objectAction => { RectTransform __actionButton = Instantiate(_menuButton).GetComponent <RectTransform>(); ButtonSettings __settings = __actionButton.GetComponent <ButtonSettings>(); __settings.Text = p_objectAction.GetDescription(); __settings.ClickAction = () => { ActivateContextMenu(false); onClickAction?.Invoke(null, new OnClickActionEventArgs(p_objectAction, p_object)); }; return(__actionButton); }).ToList().ForEach(b => { b.SetParent(_menuPanel); b.localScale = Vector3.one; b.localRotation = Quaternion.identity; b.localPosition = Vector3.zero; b.offsetMax = Vector2.down * 12 * (_menuPanel.childCount - 1); b.offsetMin = Vector2.down * 12 * _menuPanel.childCount; b.sizeDelta = new Vector2(90f, 15f); }); ActivateContextMenu(true); _nodeClose = Timer.WaitSeconds(2f, () => ActivateContextMenu(false)); }
public ITimer AddTimer(uint afterTick, OnTimerTimeout callback, params object[] userData) { var expireTick = afterTick + index; var node = new TimerNode() { ExpireTick = expireTick, Callback = callback, UserData = userData, }; timerNodesSet.Push(node); return(node); }
TimerNode GetTimerNode(int id, Action action) { TimerNode tn; if (m_timerNodePool.Count > 0) { tn = m_timerNodePool.Pop(); } else { tn = new TimerNode(); } tn.id = id; tn.callback = action; return(tn); }
private void OnWindowPrepare(UIWindow window) { OnSortWindowDepth(window.WindowLayer); window.InternalCreate(); window.InternalRefresh(); if (window.WindowOpenAnimationTime > 0f) { var tween = TimerNode.AllocateDelay(window.WindowOpenAnimationTime, () => { OnSetWindowVisible(); }); TweenManager.Instance.Play(tween, window.Go); } else { OnSetWindowVisible(); } }
/* * Add a timer. * @param callback the callback for the timer. * @param usec_delay The interval of the timer. */ internal static void Timer_Add(Action callback, uint usec_delay, bool callonce) { TimerNode node; if (s_timerNodeCount == s_timerNodeSize) { s_timerNodeSize += 2; Array.Resize(ref s_timerNodes, s_timerNodeSize); //s_timerNodes = (TimerNode *)realloc(s_timerNodes, s_timerNodeSize * sizeof(TimerNode)); s_timerNodes[s_timerNodeSize - 2] = new TimerNode(); s_timerNodes[s_timerNodeSize - 1] = new TimerNode(); } node = s_timerNodes[s_timerNodeCount++]; node.usec_left = usec_delay; node.usec_delay = usec_delay; node.callback = callback; node.callonce = callonce; }
void ReturnTimerNode(TimerNode tn) { if (tn == null) { return; } tn.Reset(); if (m_timerNodePool.Count < MAX_TIMER_NODE_POOL_SIZE) { if (m_timerNodePool.Count > 0 && m_timerNodePool.Peek() == tn) { return; } m_timerNodePool.Push(tn); } }
/// <summary> /// <para>Creates new timers. This method is thread-safe.</para> /// </summary> internal override Timer CreateTimer(Callback callback, object context) { TimerNode timer = new TimerNode(callback, context, Duration, _timers); // Add this on the tail. (Actually, one before the tail - _timers is the sentinel tail.) bool needProd = false; lock (_timers) { if (!(_timers.Prev.Next == _timers)) { if (GlobalLog.IsEnabled) { GlobalLog.AssertFormat("TimerThread#{0}::CreateTimer()|Tail corruption.", Thread.CurrentThread.ManagedThreadId.ToString()); } Debug.Fail(string.Format("TimerThread#{0}::CreateTimer()|Tail corruption.", Thread.CurrentThread.ManagedThreadId.ToString())); } // If this is the first timer in the list, we need to create a queue handle and prod the timer thread. if (_timers.Next == _timers) { if (_thisHandle == IntPtr.Zero) { _thisHandle = (IntPtr)GCHandle.Alloc(this); } needProd = true; } timer.Next = _timers; timer.Prev = _timers.Prev; _timers.Prev.Next = timer; _timers.Prev = timer; } // If, after we add the new tail, there is a chance that the tail is the next // node to be processed, we need to wake up the timer thread. if (needProd) { TimerThread.Prod(); } return(timer); }
/// <summary> /// <para>Creates new timers. This method is thread-safe.</para> /// </summary> internal override Timer CreateTimer(Callback callback, object context) { TimerNode timer = new TimerNode(callback, context, Duration, _timers); // Add this on the tail. (Actually, one before the tail - _timers is the sentinel tail.) bool needProd = false; lock (_timers) { if (!(_timers.Prev.Next == _timers)) { NetEventSource.Fail(this, $"Tail corruption."); } // If this is the first timer in the list, we need to create a queue handle and prod the timer thread. if (_timers.Next == _timers) { if (_thisHandle == IntPtr.Zero) { _thisHandle = (IntPtr)GCHandle.Alloc(this); } needProd = true; } timer.Next = _timers; timer.Prev = _timers.Prev; _timers.Prev.Next = timer; _timers.Prev = timer; } // If, after we add the new tail, there is a chance that the tail is the next // node to be processed, we need to wake up the timer thread. if (needProd) { TimerThread.Prod(); } return(timer); }
public void AddNode() { // Arrange var games = new List <Game>() { new Game(), new Game() { Nodes = new List <Node>() { new TimerNode() } }, new Game() }; _context.Games.AddRange(games); _context.SaveChanges(); var node = new TimerNode(); // Act _target.AddNode(games[1].Id, node); // Assert Check.That(games[1].Nodes).HasSize(2); }
/// <summary> /// <para>Cancels the timer. Returns true if it hasn't and won't fire; false if it has or will, or has already been cancelled.</para> /// </summary> internal override bool Cancel() { if (_timerState == TimerState.Ready) { lock (_queueLock) { if (_timerState == TimerState.Ready) { // Remove it from the list. This keeps the list from getting too big when there are a lot of rapid creations // and cancellations. This is done before setting it to Cancelled to try to prevent the Fire() loop from // seeing it, or if it does, of having to take a lock to synchronize with the state of the list. Next.Prev = Prev; Prev.Next = Next; // Just cleanup. Doesn't need to be in the lock but is easier to have here. Next = null; Prev = null; _callback = null; _context = null; _timerState = TimerState.Cancelled; if (NetEventSource.IsEnabled) { NetEventSource.Info(this, $"TimerThreadTimer#{StartTime} Cancel (success)"); } return(true); } } } if (NetEventSource.IsEnabled) { NetEventSource.Info(this, $"TimerThreadTimer#{StartTime} Cancel (failure)"); } return(false); }
/// <summary> /// <para>Fires the timer if it is still active and has expired. Returns /// true if it can be deleted, or false if it is still timing.</para> /// </summary> internal bool Fire() { if (_timerState == TimerState.Sentinel) { if (GlobalLog.IsEnabled) { GlobalLog.AssertFormat("TimerThread#{0}::Fire()|TimerQueue tried to Fire a Sentinel.", Thread.CurrentThread.ManagedThreadId.ToString()); } Debug.Fail(string.Format("TimerThread#{0}::Fire()|TimerQueue tried to Fire a Sentinel.", Thread.CurrentThread.ManagedThreadId.ToString())); } if (_timerState != TimerState.Ready) { return true; } // Must get the current tick count within this method so it is guaranteed not to be before // StartTime, which is set in the constructor. int nowMilliseconds = Environment.TickCount; if (IsTickBetween(StartTime, Expiration, nowMilliseconds)) { if (GlobalLog.IsEnabled) { GlobalLog.Print("TimerThreadTimer#" + StartTime + "::Fire() Not firing (" + StartTime + " <= " + nowMilliseconds + " < " + Expiration + ")"); } return false; } bool needCallback = false; lock (_queueLock) { if (_timerState == TimerState.Ready) { if (GlobalLog.IsEnabled) { GlobalLog.Print("TimerThreadTimer#" + StartTime + "::Fire() Firing (" + StartTime + " <= " + nowMilliseconds + " >= " + Expiration + ")"); } _timerState = TimerState.Fired; // Remove it from the list. Next.Prev = Prev; Prev.Next = Next; Next = null; Prev = null; needCallback = _callback != null; } } if (needCallback) { try { Callback callback = _callback; object context = _context; _callback = null; _context = null; callback(this, nowMilliseconds, context); } catch (Exception exception) { if (ExceptionCheck.IsFatal(exception)) throw; if (NetEventSource.Log.IsEnabled()) NetEventSource.PrintError(NetEventSource.ComponentType.Web, "TimerThreadTimer#" + StartTime.ToString(NumberFormatInfo.InvariantInfo) + "::Fire() - exception in callback: " + exception); if (GlobalLog.IsEnabled) { GlobalLog.Print("TimerThreadTimer#" + StartTime + "::Fire() exception in callback: " + exception); } // This thread is not allowed to go into user code, so we should never get an exception here. // So, in debug, throw it up, killing the AppDomain. In release, we'll just ignore it. #if DEBUG throw; #endif } } return true; }
/// <summary> /// 重复计时节点 /// </summary> public static ITweenChain Repeat(this ITweenChain chain, float delay, float interval, long maxTriggerCount, System.Action triggerCallback = null) { return(chain.Append(TimerNode.AllocateRepeat(delay, interval, maxTriggerCount, triggerCallback))); }
/// <summary> /// 持续计时节点 /// </summary> public static ITweenChain Duration(this ITweenChain chain, float delay, float duration, System.Action triggerCallback = null) { return(chain.Append(TimerNode.AllocateDuration(delay, duration, triggerCallback))); }
/// <summary> /// <para>Fires the timer if it is still active and has expired. Returns /// true if it can be deleted, or false if it is still timing.</para> /// </summary> internal bool Fire() { if (_timerState == TimerState.Sentinel) { if (NetEventSource.IsEnabled) { NetEventSource.Info(this, "TimerQueue tried to Fire a Sentinel."); } } if (_timerState != TimerState.Ready) { return(true); } // Must get the current tick count within this method so it is guaranteed not to be before // StartTime, which is set in the constructor. int nowMilliseconds = Environment.TickCount; if (IsTickBetween(StartTime, Expiration, nowMilliseconds)) { if (NetEventSource.IsEnabled) { NetEventSource.Info(this, $"TimerThreadTimer#{StartTime}::Fire() Not firing ({StartTime} <= {nowMilliseconds} < {Expiration})"); } return(false); } bool needCallback = false; lock (_queueLock) { if (_timerState == TimerState.Ready) { if (NetEventSource.IsEnabled) { NetEventSource.Info(this, $"TimerThreadTimer#{StartTime}::Fire() Firing ({StartTime} <= {nowMilliseconds} >= " + Expiration + ")"); } _timerState = TimerState.Fired; // Remove it from the list. Next.Prev = Prev; Prev.Next = Next; Next = null; Prev = null; needCallback = _callback != null; } } if (needCallback) { try { Callback callback = _callback; object context = _context; _callback = null; _context = null; callback(this, nowMilliseconds, context); } catch (Exception exception) { if (ExceptionCheck.IsFatal(exception)) { throw; } if (NetEventSource.IsEnabled) { NetEventSource.Error(this, $"exception in callback: {exception}"); } // This thread is not allowed to go into user code, so we should never get an exception here. // So, in debug, throw it up, killing the AppDomain. In release, we'll just ignore it. #if DEBUG throw; #endif } } return(true); }
public void TimerEventScenario(int s) { var startNode = new StartNode("1. Submit"); var n2 = new TimerNode("2. Wait 2 seconds", new TimeSpan(0, 0, s)); var endNode = new EndNode("3. Closed"); var t12 = new SequenceFlow(startNode, n2); var t23 = new SequenceFlow(n2, endNode); this.process = new Process(startNode); }
/// <summary> /// <para>Cancels the timer. Returns true if it hasn't and won't fire; false if it has or will, or has already been cancelled.</para> /// </summary> internal override bool Cancel() { if (_timerState == TimerState.Ready) { lock (_queueLock) { if (_timerState == TimerState.Ready) { // Remove it from the list. This keeps the list from getting too big when there are a lot of rapid creations // and cancellations. This is done before setting it to Cancelled to try to prevent the Fire() loop from // seeing it, or if it does, of having to take a lock to synchronize with the state of the list. Next.Prev = Prev; Prev.Next = Next; // Just cleanup. Doesn't need to be in the lock but is easier to have here. Next = null; Prev = null; _callback = null; _context = null; _timerState = TimerState.Cancelled; if (NetEventSource.IsEnabled) NetEventSource.Info(this, $"TimerThreadTimer#{StartTime} Cancel (success)"); return true; } } } if (NetEventSource.IsEnabled) NetEventSource.Info(this, $"TimerThreadTimer#{StartTime} Cancel (failure)"); return false; }
/// <summary> /// <para>Cancels the timer. Returns true if it hasn't and won't fire; false if it has or will, or has already been cancelled.</para> /// </summary> internal override bool Cancel() { if (m_TimerState == TimerState.Ready) { lock (m_QueueLock) { if (m_TimerState == TimerState.Ready) { // Remove it from the list. This keeps the list from getting to big when there are a lot of rapid creations // and cancellations. This is done before setting it to Cancelled to try to prevent the Fire() loop from // seeing it, or if it does, of having to take a lock to synchronize with the state of the list. Next.Prev = Prev; Prev.Next = Next; // Just cleanup. Doesn't need to be in the lock but is easier to have here. Next = null; Prev = null; m_Callback = null; m_Context = null; m_TimerState = TimerState.Cancelled; GlobalLog.Print("TimerThreadTimer#" + StartTime.ToString() + "::Cancel() (success)"); return true; } } } GlobalLog.Print("TimerThreadTimer#" + StartTime.ToString() + "::Cancel() (failure)"); return false; }
/// <summary> /// <para>Fires the timer if it is still active and has expired. Returns /// true if it can be deleted, or false if it is still timing.</para> /// </summary> internal bool Fire() { GlobalLog.Assert(m_TimerState != TimerState.Sentinel, "TimerThread#{0}::Fire()|TimerQueue tried to Fire a Sentinel.", Thread.CurrentThread.ManagedThreadId.ToString()); if (m_TimerState != TimerState.Ready) { return true; } // Must get the current tick count within this method so it is guaranteed not to be before // StartTime, which is set in the constructor. int nowMilliseconds = Environment.TickCount; if (IsTickBetween(StartTime, Expiration, nowMilliseconds)) { GlobalLog.Print("TimerThreadTimer#" + StartTime + "::Fire() Not firing (" + StartTime + " <= " + nowMilliseconds + " < " + Expiration + ")"); return false; } bool needCallback = false; lock (m_QueueLock) { if (m_TimerState == TimerState.Ready) { GlobalLog.Print("TimerThreadTimer#" + StartTime + "::Fire() Firing (" + StartTime + " <= " + nowMilliseconds + " >= " + Expiration + ")"); m_TimerState = TimerState.Fired; // Remove it from the list. Next.Prev = Prev; Prev.Next = Next; // Doesn't need to be in the lock but is easier to have here. Next = null; Prev = null; needCallback = m_Callback != null; } } if (needCallback) { try { Callback callback = m_Callback; object context = m_Context; m_Callback = null; m_Context = null; callback(this, nowMilliseconds, context); } catch (Exception exception) { if (NclUtilities.IsFatal(exception)) throw; if (Logging.On) Logging.PrintError(Logging.Web, "TimerThreadTimer#" + StartTime.ToString(NumberFormatInfo.InvariantInfo) + "::Fire() - " + SR.GetString(SR.net_log_exception_in_callback, exception)); GlobalLog.Print("TimerThreadTimer#" + StartTime + "::Fire() exception in callback: " + exception); // This thread is not allowed to go into user code, so we should never get an exception here. // So, in debug, throw it up, killing the AppDomain. In release, we'll just ignore it. #if DEBUG throw; #endif } } return true; }
/// <summary> /// <para>Creates new timers. This method is thread-safe.</para> /// </summary> internal override Timer CreateTimer(Callback callback, object context) { TimerNode timer = new TimerNode(callback, context, Duration, m_Timers); // Add this on the tail. (Actually, one before the tail - m_Timers is the sentinel tail.) bool needProd = false; lock (m_Timers) { GlobalLog.Assert(m_Timers.Prev.Next == m_Timers, "TimerThread#{0}::CreateTimer()|m_Tail corruption.", Thread.CurrentThread.ManagedThreadId.ToString()); // If this is the first timer in the list, we need to create a queue handle and prod the timer thread. if (m_Timers.Next == m_Timers) { if (m_ThisHandle == IntPtr.Zero) { m_ThisHandle = (IntPtr) GCHandle.Alloc(this); } needProd = true; } timer.Next = m_Timers; timer.Prev = m_Timers.Prev; m_Timers.Prev.Next = timer; m_Timers.Prev = timer; } // If, after we add the new tail, there is a chance that the tail is the next // node to be processed, we need to wake up the timer thread. if (needProd) { TimerThread.Prod(); } return timer; }
/// <summary> /// <para>Fires the timer if it is still active and has expired. Returns /// true if it can be deleted, or false if it is still timing.</para> /// </summary> internal bool Fire() { GlobalLog.Assert(m_TimerState != TimerState.Sentinel, "TimerThread#{0}::Fire()|TimerQueue tried to Fire a Sentinel.", Thread.CurrentThread.ManagedThreadId.ToString()); if (m_TimerState != TimerState.Ready) { return(true); } // Must get the current tick count within this method so it is guaranteed not to be before // StartTime, which is set in the constructor. int nowMilliseconds = Environment.TickCount; if (IsTickBetween(StartTime, Expiration, nowMilliseconds)) { GlobalLog.Print("TimerThreadTimer#" + StartTime + "::Fire() Not firing (" + StartTime + " <= " + nowMilliseconds + " < " + Expiration + ")"); return(false); } bool needCallback = false; lock (m_QueueLock) { if (m_TimerState == TimerState.Ready) { GlobalLog.Print("TimerThreadTimer#" + StartTime + "::Fire() Firing (" + StartTime + " <= " + nowMilliseconds + " >= " + Expiration + ")"); m_TimerState = TimerState.Fired; // Remove it from the list. Next.Prev = Prev; Prev.Next = Next; // Doesn't need to be in the lock but is easier to have here. Next = null; Prev = null; needCallback = m_Callback != null; } } if (needCallback) { try { Callback callback = m_Callback; object context = m_Context; m_Callback = null; m_Context = null; callback(this, nowMilliseconds, context); } catch (Exception exception) { if (NclUtilities.IsFatal(exception)) { throw; } if (Logging.On) { Logging.PrintError(Logging.Web, "TimerThreadTimer#" + StartTime.ToString(NumberFormatInfo.InvariantInfo) + "::Fire() - " + SR.GetString(SR.net_log_exception_in_callback, exception)); } GlobalLog.Print("TimerThreadTimer#" + StartTime + "::Fire() exception in callback: " + exception); // This thread is not allowed to go into user code, so we should never get an exception here. // So, in debug, throw it up, killing the AppDomain. In release, we'll just ignore it. #if DEBUG throw; #endif } } return(true); }
//Is called when a selection from the context menu is made void ContextCallback(object obj) { //make the passed object to a string string clb = obj.ToString(); //add the node we want if (clb.Equals("inputNode")) { InputNode inputNode = ScriptableObject.CreateInstance <InputNode>(); inputNode.WindowRect = new Rect(mousePos.x, mousePos.y, 200, 80); windows.Add(inputNode); } else if (clb.Equals("outputNode")) { OutputNode outputNode = ScriptableObject.CreateInstance <OutputNode>(); outputNode.WindowRect = new Rect(mousePos.x, mousePos.y, 200, 80); windows.Add(outputNode); } else if (clb.Equals("calcNode")) { CalcNode calcNode = ScriptableObject.CreateInstance <CalcNode>(); calcNode.WindowRect = new Rect(mousePos.x, mousePos.y, 200, 95); windows.Add(calcNode); } else if (clb.Equals("compNode")) { ComparisonNode compNode = ScriptableObject.CreateInstance <ComparisonNode>(); compNode.WindowRect = new Rect(mousePos.x, mousePos.y, 200, 95); windows.Add(compNode); } else if (clb.Equals("numNode")) { NumberNode numNode = ScriptableObject.CreateInstance <NumberNode>(); numNode.WindowRect = new Rect(mousePos.x, mousePos.y, 200, 95); windows.Add(numNode); } else if (clb.Equals("goObj")) { GameObjectNode goObj = ScriptableObject.CreateInstance <GameObjectNode>(); goObj.WindowRect = new Rect(mousePos.x, mousePos.y, 200, 100); windows.Add(goObj); } else if (clb.Equals("goActive")) { GameObjectActive goNode = ScriptableObject.CreateInstance <GameObjectActive>(); goNode.WindowRect = new Rect(mousePos.x, mousePos.y, 200, 80); windows.Add(goNode); } else if (clb.Equals("goDistance")) { GameObjectDistance goDistance = ScriptableObject.CreateInstance <GameObjectDistance>(); goDistance.WindowRect = new Rect(mousePos.x, mousePos.y, 200, 80); windows.Add(goDistance); } else if (clb.Equals("timerNode")) { TimerNode tNode = ScriptableObject.CreateInstance <TimerNode>(); tNode.WindowRect = new Rect(mousePos.x, mousePos.y, 200, 95); windows.Add(tNode); } else if (clb.Equals("boolNode")) { BoolNode bNode = ScriptableObject.CreateInstance <BoolNode>(); bNode.WindowRect = new Rect(mousePos.x, mousePos.y, 120, 75); windows.Add(bNode); } else if (clb.Equals("clearAll")) { windows.Clear(); } else if (clb.Equals("reset")) { PanX = PanY = 0; } else if (clb.Equals("makeTransition")) //if it's a transition { bool clickedOnWindow = false; int selectedIndex = -1; //find the window that it was clicked for (int i = 0; i < windows.Count; i++) { if (windows[i].WindowRect.Contains(mousePos)) { selectedIndex = i; clickedOnWindow = true; break; } } //and make it the selected node of the transition if (clickedOnWindow) { selectedNode = windows[selectedIndex]; makeTransitionMode = true; } } else if (clb.Equals("deleteNode")) //if it's a delete node { bool clickedOnWindow = false; int selectedIndex = -1; //find the selected node for (int i = 0; i < windows.Count; i++) { if (windows[i].WindowRect.Contains(mousePos)) { selectedIndex = i; clickedOnWindow = true; break; } } if (clickedOnWindow) { //delete it from our list BaseNode selNode = windows[selectedIndex]; windows.RemoveAt(selectedIndex); //then pass it to all our nodes that is deleted foreach (BaseNode n in windows) { n.NodeDeleted(selNode); } } } //we use else if instead of a switch because: /*Selecting from a set of multiple cases is faster with if statements than with switch */ }
/// <summary> /// <para>Fires the timer if it is still active and has expired. Returns /// true if it can be deleted, or false if it is still timing.</para> /// </summary> internal bool Fire() { if (_timerState == TimerState.Sentinel) { if (GlobalLog.IsEnabled) { GlobalLog.AssertFormat("TimerThread#{0}::Fire()|TimerQueue tried to Fire a Sentinel.", Thread.CurrentThread.ManagedThreadId.ToString()); } Debug.Fail(string.Format("TimerThread#{0}::Fire()|TimerQueue tried to Fire a Sentinel.", Thread.CurrentThread.ManagedThreadId.ToString())); } if (_timerState != TimerState.Ready) { return(true); } // Must get the current tick count within this method so it is guaranteed not to be before // StartTime, which is set in the constructor. int nowMilliseconds = Environment.TickCount; if (IsTickBetween(StartTime, Expiration, nowMilliseconds)) { if (GlobalLog.IsEnabled) { GlobalLog.Print("TimerThreadTimer#" + StartTime + "::Fire() Not firing (" + StartTime + " <= " + nowMilliseconds + " < " + Expiration + ")"); } return(false); } bool needCallback = false; lock (_queueLock) { if (_timerState == TimerState.Ready) { if (GlobalLog.IsEnabled) { GlobalLog.Print("TimerThreadTimer#" + StartTime + "::Fire() Firing (" + StartTime + " <= " + nowMilliseconds + " >= " + Expiration + ")"); } _timerState = TimerState.Fired; // Remove it from the list. Next.Prev = Prev; Prev.Next = Next; Next = null; Prev = null; needCallback = _callback != null; } } if (needCallback) { try { Callback callback = _callback; object context = _context; _callback = null; _context = null; callback(this, nowMilliseconds, context); } catch (Exception exception) { if (ExceptionCheck.IsFatal(exception)) { throw; } if (NetEventSource.Log.IsEnabled()) { NetEventSource.PrintError(NetEventSource.ComponentType.Web, "TimerThreadTimer#" + StartTime.ToString(NumberFormatInfo.InvariantInfo) + "::Fire() - exception in callback: " + exception); } if (GlobalLog.IsEnabled) { GlobalLog.Print("TimerThreadTimer#" + StartTime + "::Fire() exception in callback: " + exception); } // This thread is not allowed to go into user code, so we should never get an exception here. // So, in debug, throw it up, killing the AppDomain. In release, we'll just ignore it. #if DEBUG throw; #endif } } return(true); }
/// <summary> /// <para>Creates new timers. This method is thread-safe.</para> /// </summary> internal override Timer CreateTimer(Callback callback, object context) { TimerNode timer = new TimerNode(callback, context, Duration, _timers); // Add this on the tail. (Actually, one before the tail - _timers is the sentinel tail.) bool needProd = false; lock (_timers) { if (!(_timers.Prev.Next == _timers)) { NetEventSource.Fail(this, $"Tail corruption."); } // If this is the first timer in the list, we need to create a queue handle and prod the timer thread. if (_timers.Next == _timers) { if (_thisHandle == IntPtr.Zero) { _thisHandle = (IntPtr)GCHandle.Alloc(this); } needProd = true; } timer.Next = _timers; timer.Prev = _timers.Prev; _timers.Prev.Next = timer; _timers.Prev = timer; } // If, after we add the new tail, there is a chance that the tail is the next // node to be processed, we need to wake up the timer thread. if (needProd) { TimerThread.Prod(); } return timer; }
/// <summary> /// <para>Fires the timer if it is still active and has expired. Returns /// true if it can be deleted, or false if it is still timing.</para> /// </summary> internal bool Fire() { if (_timerState == TimerState.Sentinel) { if (NetEventSource.IsEnabled) NetEventSource.Info(this, "TimerQueue tried to Fire a Sentinel."); } if (_timerState != TimerState.Ready) { return true; } // Must get the current tick count within this method so it is guaranteed not to be before // StartTime, which is set in the constructor. int nowMilliseconds = Environment.TickCount; if (IsTickBetween(StartTime, Expiration, nowMilliseconds)) { if (NetEventSource.IsEnabled) NetEventSource.Info(this, $"TimerThreadTimer#{StartTime}::Fire() Not firing ({StartTime} <= {nowMilliseconds} < {Expiration})"); return false; } bool needCallback = false; lock (_queueLock) { if (_timerState == TimerState.Ready) { if (NetEventSource.IsEnabled) NetEventSource.Info(this, $"TimerThreadTimer#{StartTime}::Fire() Firing ({StartTime} <= {nowMilliseconds} >= " + Expiration + ")"); _timerState = TimerState.Fired; // Remove it from the list. Next.Prev = Prev; Prev.Next = Next; Next = null; Prev = null; needCallback = _callback != null; } } if (needCallback) { try { Callback callback = _callback; object context = _context; _callback = null; _context = null; callback(this, nowMilliseconds, context); } catch (Exception exception) { if (ExceptionCheck.IsFatal(exception)) throw; if (NetEventSource.IsEnabled) NetEventSource.Error(this, $"exception in callback: {exception}"); // This thread is not allowed to go into user code, so we should never get an exception here. // So, in debug, throw it up, killing the AppDomain. In release, we'll just ignore it. #if DEBUG throw; #endif } } return true; }