View Javadoc

1   /***
2    * Created by IntelliJ IDEA.
3    * User: gareth
4    * Date: Sep 11, 2003
5    * Time: 6:43:19 PM
6    */
7   package com.tapina.robe.swi;
8   
9   import com.tapina.robe.runtime.ByteArrayUtils;
10  import com.tapina.robe.runtime.Environment;
11  import com.tapina.robe.runtime.MemoryMap;
12  import com.tapina.robe.runtime.RawDataBlock;
13  import com.tapina.robe.swi.wimp.WimpTask;
14  
15  import java.lang.reflect.Method;
16  import java.util.ArrayList;
17  import java.util.Collections;
18  import java.util.Iterator;
19  import java.util.List;
20  
21  public final class TaskManager extends SWIHandler {
22      private static TaskManager ourInstance;
23  
24      public synchronized static TaskManager getInstance() {
25          if (ourInstance == null) {
26              ourInstance = new TaskManager();
27          }
28          return ourInstance;
29      }
30  
31      private TaskManager() {
32      }
33  
34      public static int getBase() {
35          return 0x42680;
36      }
37  
38      private static final String[] methodNames = new String[] {
39          "TaskNameFromHandle", "EnumerateTasks", "", "", "", "", "", "", // 0x42680
40          "", "", "", "", "", "", "", "", // 0x42688
41          "", "", "", "", "", "", "", "", // 0x42690
42          "", "", "", "", "", "", "", "", // 0x42698
43          "", "", "", "", "", "", "", "", // 0x426a0
44          "", "", "", "", "", "", "", "", // 0x426a8
45          "", "", "", "", "", "", "", "", // 0x426b0
46          "", "", "", "", "", "", "", "" // 0x426b8
47      };
48  
49      public static Method getMethod(Integer offset) throws NoSuchMethodException {
50          return getMethod(methodNames[offset.intValue()]);
51      }
52  
53      private static final Method getMethod(String name) throws NoSuchMethodException {
54          return TaskManager.class.getMethod(name, METHOD_PARAMETERS);
55      }
56  
57      private static final List taskList = new ArrayList(5);
58  
59      static void registerTask(WimpTask task) {
60          synchronized (taskList) {
61              taskList.add(task);
62          }
63      }
64  
65      public final void TaskNameFromHandle(Environment env) {
66          final int[] R = env.getCpu().R;
67          final MemoryMap memoryMap = env.getMemoryMap();
68          String taskName = taskNameFromHandle(R[0]);
69          if (taskName == null) {
70              taskName = "";
71          }
72          // TODO: Fix memory leak here
73          final RawDataBlock nameDataBlock = memoryMap.createSystemDataBlock(taskName);
74          R[0] = nameDataBlock.getAddress();
75      }
76  
77      public final String taskNameFromHandle(int taskHandle) {
78          synchronized (taskList) {
79              for (Iterator iterator = taskList.iterator(); iterator.hasNext();) {
80                  WimpTask task = (WimpTask) iterator.next();
81                  if (task.getTaskHandle() == taskHandle) {
82                      return task.getTaskName();
83                  }
84              }
85          }
86          return null;
87      }
88  
89      private Iterator taskIterator = null;
90  
91      public final void EnumerateTasks(Environment env) {
92          final int[] R = env.getCpu().R;
93          final MemoryMap memoryMap = env.getMemoryMap();
94          if (R[2] < 16) {
95              throw new SWIError(0, "Not enough space for task data.");
96          }
97          final WimpTask task = enumerateTasks(R[0] == 0);
98          if (task != null) {
99              // TODO: Fix memory leak here
100             final RawDataBlock nameDataBlock = memoryMap.createSystemDataBlock(task.getTaskName());
101             final int[] bufferData = new int[] {
102                 task.getTaskHandle(),
103                 nameDataBlock.getAddress(),
104                 task.getSlotSize() >> 10,
105                 task.getFlags()
106             };
107             memoryMap.storeWords(R[1], bufferData);
108             R[0]++;
109             R[1] += 16;
110             R[2] -= 16;
111         } else {
112             R[0] = -1;
113         }
114     }
115 
116     /***
117      * Return the next task to be enumerated from the list of all tasks.
118      * @param firstCall start at the beginning of the list, therefore returning the first task
119      * @return next task in list, or null if there are no more tasks
120      */
121     public final WimpTask enumerateTasks(boolean firstCall) {
122         if (firstCall) {
123             synchronized (taskList) {
124                 final List taskListSnapshot = Collections.unmodifiableList(new ArrayList(taskList));
125                 taskIterator = taskListSnapshot.iterator();
126             }
127         }
128         final WimpTask nextTask;
129         if (taskIterator.hasNext()) {
130             nextTask = (WimpTask) taskIterator.next();
131         } else {
132             nextTask = null;
133         }
134         return nextTask;
135     }
136 
137 }
138