Do not install wrong cache routine if called before SysBase is complete.
[AROS.git] / workbench / libs / realtime / createplayera.c
blob3260ebfcd31f8f5beda242ea91aee3d96307e3f1
1 /*
2 Copyright © 1995-2004, The AROS Development Team. All rights reserved.
3 $Id$
4 */
5 # define DEBUG 1
6 # include <aros/debug.h>
8 #include <proto/exec.h>
9 #include <proto/realtime.h>
10 #include <proto/utility.h>
11 #include <exec/memory.h>
12 #include <utility/tagitem.h>
13 #include "realtime_intern.h"
15 struct Conductor *createConductor(BOOL private, LONG *error,STRPTR name,
16 struct Library *RealTimeBase);
18 /*****************************************************************************
20 NAME */
21 #include <libraries/realtime.h>
23 AROS_LH1(struct Player *, CreatePlayerA,
25 /* SYNOPSIS */
27 AROS_LHA(struct TagItem *, tagList, A0),
29 /* LOCATION */
31 struct Library *, RealTimeBase, 7, RealTime)
33 /* FUNCTION
35 Create a player.
37 INPUTS
39 tagList -- pointer to an array of tags describing the player's
40 attributes or NULL.
42 TAGS
44 PLAYER_Name (STRPTR) -- The name of the player; default is no
45 name.
47 PLAYER_Hook (struct Hook *) -- Function to call every time the time
48 changes; default is none. The hook is
49 called with
51 a0 -- address of Hook structure
52 a1 -- message (see <libraries/realtime.h>)
53 a2 -- address of Player structure
55 Be aware of that the function is not
56 necessarily called TICK_FREQ times per
57 second: this is the upper limit of times
58 it may be called.
60 PLAYER_Priority (BYTE) -- The priority of the player; default is 0.
62 PLAYER_Conductor (STRPTR) -- The name of the conductor to link the
63 player to. If the conductor doesn't exist,
64 it's created automatically. Passing ~0
65 creates a private conductor.
67 PLAYER_Ready (BOOL) -- Set / clear the ready flag; default is
68 TRUE.
70 PLAYER_AlarmTime (LONG) -- Set player's alarm time; implies setting
71 the PLAYERF_ALARMSET flag.
73 PLAYER_Alarm (BOOL) -- Set / clear the PLAYERF_ALARMSET flag;
74 default is FALSE.
76 PLAYER_AlarmSigTask (struct Task *)
77 -- The task to signal when the alarm goes
78 off; default is no task. If no task is
79 specified PLAYERF_ALARMSET is turned
80 off.
82 PLAYER_AlarmSigBit (BYTE) -- Signal bit to use for the alarm or -1
83 to disable signalling; default is -1.
85 PLAYER_Quiet (BOOL) -- Specify whether this player should be
86 ignored or not; default is FALSE.
87 Generally only used by external sync
88 applications.
90 PLAYER_UserData (VOID *) -- Set pointer to user specific data;
91 default is NULL.
93 PLAYER_ID (UWORD) -- Set the player's ID; default is 0.
95 PLAYER_Conducted (BOOL) -- Set / clear the PLAYERF_CONDUCTED flag;
96 default is FALSE.
98 PLAYER_ExtSync (BOOL) -- If TRUE, this player attempts to become
99 the external sync source.
101 PLAYER_ErrorCode (LONG *) -- Optional pointer to a LONG that will
102 contain an error code if the function
103 fails. Possible error values are:
105 RTE_NOMEMORY -- memory allocation failed
106 RTE_NOTIMER -- timer allocation failed
108 RESULT
110 A pointer to a player structure or NULL if failure. In case of a failure
111 additional information may be retreived from the LONG variable pointed
112 to by PLAYER_ErrorCode if you have specified that tag.
114 NOTES
116 EXAMPLE
118 BUGS
120 SEE ALSO
122 DeletePlayer(), GetPlayerAttrsA(), SetPlayerAttrsA()
124 INTERNALS
126 ******************************************************************************/
129 AROS_LIBFUNC_INIT
131 const struct TagItem *tl = tagList;
132 struct TagItem *tag;
133 struct Player *player = AllocMem(sizeof(struct Player),
134 MEMF_PUBLIC | MEMF_CLEAR);
135 LONG *error;
137 D(bug("Entering CreatePlayerA()\n"));
139 error = (LONG *) GetTagData(PLAYER_ErrorCode, (IPTR) NULL, tl);
141 if (player == NULL)
143 if (error != NULL)
145 *error = RTE_NOMEMORY;
148 return NULL;
151 /* Set default values */
152 player->pl_Reserved0 = -1; /* AlarmSigBit */
153 player->pl_Flags |= PLAYERF_READY;
155 while((tag = NextTagItem(&tl)) != NULL)
157 switch (tag->ti_Tag)
159 case PLAYER_Conductor:
161 D(bug("Found PLAYER_Conductor tag\n"));
163 if ((IPTR)tag->ti_Data == -1)
165 player->pl_Source = createConductor(TRUE, error,
166 (STRPTR)tag->ti_Data,
167 RealTimeBase);
169 else
171 struct Conductor *cd = FindConductor((STRPTR)tag->ti_Data);
173 if (cd == NULL)
175 D(bug("Trying to create a public conductor.\n"));
176 player->pl_Source = createConductor(FALSE, error,
177 (STRPTR)tag->ti_Data,
178 RealTimeBase);
180 else
182 player->pl_Source = cd;
186 if (player->pl_Source != NULL)
188 APTR lock;
190 lock = LockRealTime(RT_CONDUCTORS);
192 /* Enqueue the player to the conductor list */
193 Enqueue((struct List *)&player->pl_Source->cdt_Players,
194 (struct Node *)player);
196 UnlockRealTime(lock);
199 break;
202 /* The rest of the tags are taken care of in SetPlayerAttrsA() */
205 D(bug("Calling SetPlayerAttrsA()\n"));
207 if (SetPlayerAttrsA(player, tagList))
209 return player;
211 else
213 return NULL;
216 AROS_LIBFUNC_EXIT
217 } /* CreatePlayerA */
220 struct Conductor *createConductor(BOOL private, LONG *error, STRPTR name,
221 struct Library *RealTimeBase)
223 struct Conductor *cd = AllocMem(sizeof(struct Conductor),
224 MEMF_PUBLIC | MEMF_CLEAR);
226 if (cd == NULL)
228 if (error != NULL)
230 *error = RTE_NOMEMORY;
233 return NULL;
236 cd->cdt_Link.ln_Name = name;
238 NEWLIST(&cd->cdt_Players);
239 InitSemaphore(&cd->cdt_Lock);
241 /* Initialize conductor clock */
242 cd->cdt_ClockTime = GPB(RealTimeBase)->rtb_Time;
243 cd->cdt_StartTime = GPB(RealTimeBase)->rtb_Time;
245 /* Conductors are created in 'stopped' mode. To make the clock start
246 running, call SetConductorState(player, CONDSTATE_RUNNING, _); */
247 cd->cdt_State = CONDSTATE_STOPPED;
249 if (private)
251 cd->cdt_Flags |= CONDUCTF_PRIVATE;
255 /* Add the conductor to the realtime library conductor list */
256 APTR lock;
258 lock = LockRealTime(RT_CONDUCTORS);
260 AddTail((struct List *)&GPB(RealTimeBase)->rtb_ConductorList,
261 (struct Node *)cd);
263 UnlockRealTime(lock);
266 return cd;