1// tTask.h 
2// 
3// Simple and efficient task management using a heap-based priority queue. 
4// 
5// Copyright (c) 2006, 2017 Tristan Grimmer. 
6// Permission to use, copy, modify, and/or distribute this software for any purpose with or without fee is hereby 
7// granted, provided that the above copyright notice and this permission notice appear in all copies. 
8// 
9// THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL 
10// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, 
11// INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN 
12// AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR 
13// PERFORMANCE OF THIS SOFTWARE. 
14 
15#pragma once 
16#include <Foundation/tPriorityQueue.h> 
17 
18 
19// The tTask class is virtual. All tasks that you want in a collection must be derived from a tTask. 
20struct tTask 
21
22 tTask() { } 
23 virtual ~tTask() { } 
24 
25 // Return the next time you want Execute to be called in seconds. If you return 0.0 or less the task will execute 
26 // on the next update. 
27 virtual double Execute(double deltaTime) = 0
28}; 
29 
30 
31class tTaskSet 
32
33public
34 // CounterFreq must be given in Hz. MaxTimeDelta is the ceiling on the elapsed time that the Execute() fn gets 
35 // called with. Useful for things like collision detection where we need some guarantees. If the max is hit because 
36 // the fps is slow then the objects will, only at that point, start to slow down. 
37 tTaskSet(int64 counterFreq, double maxTimeDelta); 
38 
39 // Sometimes it's not convenient to set the counter freq and max delta in the constructor. Call SetCounter if you 
40 // use this constructor. 
41 tTaskSet(); 
42 ~tTaskSet() { } 
43 
44 void SetCounter(int64 counterFreq, double maxTimeDelta) { CounterFreq = counterFreq; MaxTimeDelta = maxTimeDelta; } 
45 
46 // Inserts a task in O(lg(n)) time. Memory for tTask is managed by the caller. When a task is first inserted, it 
47 // gets scheduled to be executed on the next call to Update. After that, the task controls the next execution time 
48 // by returning the desired number of seconds. 
49 void Insert(tTask* t) { PriorityQueue.Insert( tPQ<tTask*>::tItem(t, ExecuteTime) ); } 
50 
51 // Removes a task in O(n) time. You'll probably want to delete it after. Internally the tQueueItem isn't removed 
52 // until it's about to be executed again, but you don't need to know that. 
53 void Remove(tTask* t) { PriorityQueue.Replace( t, nullptr ); } 
54 
55 // Executes any tasks that are ready. O(lg(n)). Call this as often as you like. 
56 void Update(int64 counter); 
57 
58private
59 int64 ExecuteTime; // Time execute was run last. 
60 int64 CounterFreq; // How quickly the counter value that gets passed to Execute() is going in Hz. 
61 double MaxTimeDelta
62 tPriorityQueue<tTask*> PriorityQueue
63 
64 static const int NumTasks = 64
65 static const int GrowSize = 32
66}; 
67