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.  |
20 | struct 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 |   |
31 | class tTaskSet  |
32 | {  |
33 | public:  |
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 |   |
58 | private:  |
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 | |