MHEG5  18.9.0
MHEG5 Documentation
mh5tokenmanager.c
Go to the documentation of this file.
1 /*******************************************************************************
2  * Copyright © 2014 The DTVKit Open Software Foundation Ltd (www.dtvkit.org)
3  * Copyright © 2004 Ocean Blue Software Ltd
4  * Copyright © 2000 Koninklijke Philips Electronics N.V
5  *
6  * This file is part of a DTVKit Software Component
7  * You are permitted to copy, modify or distribute this file subject to the terms
8  * of the DTVKit 1.0 Licence which can be found in licence.txt or at www.dtvkit.org
9  *
10  * THIS CODE AND INFORMATION ARE PROVIDED "AS IS" WITHOUT WARRANTY OF ANY KIND,
11  * EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE IMPLIED WARRANTIES
12  * OF MERCHANTABILITY AND/OR FITNESS FOR A PARTICULAR PURPOSE.
13  *
14  * If you or your organisation is not a member of DTVKit then you have access
15  * to this source code outside of the terms of the licence agreement
16  * and you are expected to delete this and any associated files immediately.
17  * Further information on DTVKit, membership and terms can be found at www.dtvkit.org
18  *******************************************************************************/
34 /*---includes for this file--------------------------------------------------*/
35 #include "mh5variable.h" /* for actions */
36 #include "mh5object.h" /* for actions */
37 #include "mh5memory.h" /* Constructor / Destructor */
38 #include "mh5queue.h" /* Events */
39 #include "mh5tokenmanager.h"
40 #include "mh5tokengroup.h"
41 #include "mh5listgroup.h"
42 #include <stdlib.h>
43 
44 /*
45  Debug
46  */
47 #ifdef MH5PRINTOUT
48 
49 #include <string.h>
50 
51 static MHEG5IntList* MHEG5rowCopy(MHEG5IntList *source);
52 
59 void MHEG5intListPrint(MHEG5IntList *intList, char *out)
60 {
61  MHEG5IntList *currIntList = intList;
62 
63  MHEG_PRINT(out, "( ");
64  while (currIntList != NULL)
65  {
66  MHEG5intPrint(currIntList->number, out);
67  MHEG_PRINT(out, " ");
68  currIntList = currIntList->next;
69  }
70  MHEG_PRINT(out, ")");
71 }
72 
73 #if 0
74 
80 void MHEG5movementTablePrint(MHEG5MovementTable *movementTable, char *out)
81 {
82  MHEG5MovementTable *currMovementTable = movementTable;
83 
84  MHEG5incIndent();
85  MHEG5newLine(out);
86  while (currMovementTable != NULL)
87  {
88  MHEG5indent(out);
89  MHEG5intListPrint(currMovementTable->row, out);
90  currMovementTable = currMovementTable->next;
91  MHEG5newLine(out);
92  }
93  MHEG5decIndent();
94 }
95 
96 #endif //0
97 
104 void MHEG5tokenManagerPrint(MHEG5TokenManager *tokenManager, char *out)
105 {
106 #if 0
107  MHEG5indent(out);
108  MHEG_PRINT(out, ":movementTable: ");
109  MHEG5movementTablePrint(tokenManager->movementTable, out);
110  MHEG5newLine(out);
111 
112  MHEG5indent(out);
113  MHEG_PRINT(out, "// TokenPosition:\t");
114  MHEG5intPrint(tokenManager->tokenPosition, out);
115  MHEG5newLine(out);
116 #endif
117 }
118 
119 #endif /* MH5PRINTOUT */
120 
121 
128 {
129  assert(tokenManager);
130 
131  assert(tokenManager->movementTable == 0);
132 }
133 
141 {
142  assert(tokenManager);
143 
144  tokenManager->tokenPosition = 1;
145 }
146 
155 {
156  MHEG5MovementTable *lastMTEntry, *mtEntry;
157  MHEG5IntList *lastILEntry, *ilEntry;
158 
159  assert(tokenManager);
160 
161  mtEntry = tokenManager->movementTable;
162  while (mtEntry)
163  {
164  ilEntry = mtEntry->row;
165  while (ilEntry)
166  {
167  lastILEntry = ilEntry;
168  ilEntry = ilEntry->next;
169  MHEG5freeMem(lastILEntry);
170  }
171  lastMTEntry = mtEntry;
172  mtEntry = mtEntry->next;
173  MHEG5freeMem(lastMTEntry);
174  }
175 }
176 
184 {
185  MHEG5MovementTable *row, *find = 0;
186 
187  assert(tokenManager);
188  row = MHEG5getMem(sizeof(MHEG5MovementTable));
189  if (!row)
190  return;
191  row->next = 0;
192  row->row = 0;
193 
194  find = tokenManager->movementTable;
195 
196  if (find == NULL)
197  {
198  tokenManager->movementTable = row;
199  return;
200  }
201 
202  while (find->next)
203  find = find->next;
204  find->next = row;
205 }
206 
215 {
216  MHEG5MovementTable *find = 0;
217  MHEG5IntList *row, *newItem;
218 
219  assert(tokenManager);
220  find = tokenManager->movementTable;
221  if (!find)
222  return;
223  while (find->next)
224  find = find->next;
225  newItem = MHEG5getMem(sizeof(MHEG5IntList));
226  if (!newItem)
227  return;
228  newItem->next = 0;
229  newItem->number = number;
230  row = find->row;
231  if (!row)
232  {
233  find->row = newItem;
234  return;
235  }
236  while (row->next)
237  row = row->next;
238  row->next = newItem;
239 }
240 
241 /*
242  Clone Help
243  */
244 static MHEG5IntList* MHEG5rowCopy(MHEG5IntList *source)
245 {
246  MHEG5IntList *newList = 0, *prev = 0, *item = 0;
247 
248  while (source)
249  {
250  item = MHEG5getMem(sizeof(MHEG5IntList));
251  if (!item)
252  return newList;
253  if (!newList)
254  newList = item;
255  if (prev)
256  prev->next = item;
257  item->number = source->number;
258  item->next = 0;
259  prev = item;
260  source = source->next;
261  }
262  return newList;
263 }
264 
265 static MHEG5MovementTable* MHEG5movementTableCopy(MHEG5MovementTable *source)
266 {
267  MHEG5MovementTable *newTable = 0, *table = 0, *prev = 0;
268 
269  while (source)
270  {
271  table = MHEG5getMem(sizeof(MHEG5MovementTable));
272  if (!newTable)
273  newTable = table;
274  if (prev)
275  prev->next = table;
276  if (!table)
277  return newTable;
278  table->row = MHEG5rowCopy(source->row);
279  table->next = 0;
280  prev = table;
281  source = source->next;
282  }
283  return newTable;
284 }
285 
294 {
295  assert(destination);
296  assert(source);
297  destination->tokenPosition = source->tokenPosition;
298  destination->movementTable = MHEG5movementTableCopy(source->movementTable);
299 }
300 
301 /*
302  Internal behaviours
303  */
311 {
312  assert(tokenManager);
313 }
314 
315 /*
316  TransferToken (TargetElement)
317  Execute the following sequence of actions:
318  1. Generate a TokenMovedFrom event with the value of the TokenPosition
319  attribute as associated data.
320  2. Set the TokenPosition attribute to the value of the TargetElement
321  parameter..
322  3. Generate a TokenMovedTo event with the value of the TokenPosition
323  attribute as associated data.
324  The TokenMovedTo and TokenMovedFrom events will be generated even if
325  the value of TokenPosition after (before) the token moved was 0.
326  */
345 static void MHEG5tokenManagerTransferToken( MHEG5Root *source, MHEG5Int targetElement )
346 {
347  MHEG5TokenManager *tokenManager = &((MHEG5TokenGroup *) source)->tokenManager;
348 
349  if ((source->clazz != MHEG5LISTGROUP) ||
350  (targetElement <= ((MHEG5ListGroup *)source)->positionCount))
351  {
352  MHEG5sendSync(source, MHEG5TOKENMOVEDFROM, tokenManager->tokenPosition );
353  tokenManager->tokenPosition = targetElement;
354  MHEG5sendSync(source, MHEG5TOKENMOVEDTO, targetElement);
355  }
356 }
357 
358 /*
359  Actions
360  */
361 /*
362  Move
363  Move the token between elements of the group. The movement to apply from any
364  particular element location is described in the MovementTable attribute.
365  Execute the following sequence of actions:
366  1. Determine the TargetElement by using the MovementTable.
367  2. If the TargetElement does not have the token yet, apply the Transfer-
368  Token(TargetElement) behaviour of the TokenManager.
369 
370  Provisions of use:
371  The Target object shall be an available TokenManager.
372  */
384 {
385  MHEG5Int movementId = 0, row = 1, col = 1;
386  MHEG5MovementTable *movementTable;
387  MHEG5IntList *oneRow = 0;
388 
389  assert(target);
390 
391  if (!params)
393 
394  if ((target->clazz != MHEG5TOKENGROUP) &&
395  (target->clazz != MHEG5LISTGROUP))
396  return MHEG5ERR_WRONGTARGET;
397 
398  if (((MHEG5TokenGroup *) target)->tokenManager.tokenPosition < 1)
399  return MHEG5ERR_NOERROR;
400 
401  MHEG5resolveGenericInteger(params, &movementId);
402  movementTable = ((MHEG5TokenGroup *) target)->tokenManager.movementTable;
403 
404  while ((movementTable) && (row < movementId))
405  {
406  movementTable = movementTable->next;
407  row++;
408  }
409  if ((movementTable) && (row == movementId))
410  {
411  oneRow = movementTable->row;
412  while ((oneRow) && (col != ((MHEG5TokenGroup *) target)->tokenManager.tokenPosition))
413  {
414  oneRow = oneRow->next;
415  col++;
416  }
417  if ((oneRow) && (col == ((MHEG5TokenGroup *) target)->tokenManager.tokenPosition))
418  {
419  if (((MHEG5TokenGroup *) target)->tokenManager.tokenPosition != oneRow->number)
420  {
421  MHEG5tokenManagerTransferToken( target, oneRow->number );
422  }
423  }
424  }
425  return MHEG5ERR_NOERROR;
426 }
427 
428 /*
429  MoveTo (Index)
430  Move the token to a specific element of the group.
431  Execute the following sequence of actions:
432  1. Determine the TargetElement by using the Index parameter of the MoveTo
433  action
434  2. If the target element does not have the token yet, apply the Transfer-
435  Token(TargetElement) behaviour of the TokenManager.
436 
437  Provisions of use:
438  The Target object shall be an available TokenManager.
439  Index shall be set within the range [0, N], where N is the number of elements in
440  the group.
441  */
452 {
453  MHEG5Int movementId = 0;
454 
455  assert(target);
456 
457  if (!params)
459  if ((target->clazz != MHEG5TOKENGROUP) && (target->clazz != MHEG5LISTGROUP))
460  return MHEG5ERR_WRONGTARGET;
461  MHEG5resolveGenericInteger(params, &movementId);
462  if (((MHEG5TokenGroup *) target)->tokenManager.tokenPosition != movementId)
463  {
464  MHEG5tokenManagerTransferToken( target, movementId );
465  }
466  return MHEG5ERR_NOERROR;
467 }
468 
469 /*
470  GetTokenPosition (TokenPositionVar)
471 
472  Provisions of use:
473  The Target object shall be an available TokenManager.
474  TokenPositionVar shall refer to an active IntegerVariable object.
475  */
488 {
489  MHEG5Root *tpVar = 0;
490 
491  assert(target);
492 
493  if (!params)
495  if ((target->clazz != MHEG5TOKENGROUP) && (target->clazz != MHEG5LISTGROUP))
496  return MHEG5ERR_WRONGTARGET;
497 
498  MHEG5resolveORef(params, &tpVar);
499 
500  if (!tpVar)
502  if (tpVar->clazz != MHEG5INTEGERVARIABLE)
503  return MHEG5ERR_WRONGPARAM;
504  ((MHEG5IntegerVariable *) tpVar)->value =
505  ((MHEG5TokenGroup *) target)->tokenManager.tokenPosition;
506  return MHEG5ERR_NOERROR;
507 }
508 
void MHEG5tokenManagerInit(MHEG5TokenManager *tokenManager)
Initialise a tokenManager object with default values.
Implement the MHEG5 TokenManager Class 28 TokenManager Class Mix-in class that defines functions to m...
MHEG5GList * MHEG5resolveGenericInteger(MHEG5GList *params, MHEG5Int *value)
Definition: mh5object.c:510
MHEG5MovementTable * movementTable
#define MHEG5getMem
Definition: glue_memory.h:93
MHEG5Final clazz
Definition: mh5root.h:55
void MHEG5tokenManagerAddRow(MHEG5TokenManager *tokenManager)
Add a new row to a TokenManager.
Implement the MHEG5 Variable Class 21 Variable Class Defines a variable within the context of a Group...
struct sMHEG5IntList * next
long MHEG5Int
Definition: mh5base.h:73
void MHEG5tokenManagerAddNumber(MHEG5TokenManager *tokenManager, MHEG5Int number)
Insert a number into the last element of the movement table.
Implement the MHEG5 ListGroup Class Defines the location of list elements on the screen and theire in...
Implement the MHEG5 Tokengroup Class 29 TokenGroup Class. Defines a group of Visible objects for navi...
#define MHEG5freeMem
Definition: glue_memory.h:94
void MHEG5tokenManagerPrepare(MHEG5TokenManager *tokenManager)
Sets all internal attributes for the specified object to their default values.
MHEG5ErrorCode
Definition: mh5base.h:222
MHEG5ErrorCode MHEG5getTokenPosition(MHEG5Root *target, MHEG5GList *params)
Set the Variable referenced by TokenPositionVar to the value of the TokenPosition attribute...
Event handling. Implementation of a combined queue for events and actions. This is the eventsystem wh...
MHEG5ErrorCode MHEG5move(MHEG5Root *target, MHEG5GList *params)
Move the token between elements of the group. The movement to apply from any particular element locat...
Implement functions to retrieve MHEG5objects by GroupID and ID.
struct sMHEG5MovementTable * next
redirection include
MHEG5IntList * row
void MHEG5tokenManagerFree(MHEG5TokenManager *tokenManager)
Free off all memory associated with the specified object, including any exchanged attributes and inte...
MHEG5GList * MHEG5resolveORef(MHEG5GList *params, MHEG5Root **object)
Definition: mh5object.c:126
void MHEG5tokenManagerCopy(MHEG5TokenManager *destination, MHEG5TokenManager *source)
Copy a TokenManager object. The movement table of the TokenManager object is copied as well...
void MHEG5tokenManagerDestruct(MHEG5TokenManager *tokenManager)
Destruct a TokenManager object.
MHEG5ErrorCode MHEG5moveTo(MHEG5Root *target, MHEG5GList *params)
Move the token to a specific element of the group. Implementation of the MoveTo (Target, Index) action of the TokenManager class.
void MHEG5sendSync(MHEG5Root *source, MHEG5EventType event, MHEG5Int data)
Store an event in the synchronous event queue.
Definition: mh5queue.c:1651