add a -quick target for -create-patch
[AROS.git] / workbench / libs / realtime / setplayerattrsa.c
blob188aa889763b8fb14258a67bd299e7ba6ee3f0f5
1 /*
2 Copyright © 1995-2016, The AROS Development Team. All rights reserved.
3 $Id$
4 */
5 # define DEBUG 0
6 # include <aros/debug.h>
8 #include <proto/exec.h>
9 #include <proto/utility.h>
10 #include <proto/realtime.h>
11 #include <exec/lists.h>
12 #include "realtime_intern.h"
14 struct Conductor *createConductor(BOOL private, LONG *error,STRPTR name,
15 struct Library *RealTimeBase);
17 /*****************************************************************************
19 NAME */
21 #include <utility/tagitem.h>
22 #include <libraries/realtime.h>
24 AROS_LH2(BOOL, SetPlayerAttrsA,
26 /* SYNOPSIS */
28 AROS_LHA(struct Player *, player , A0),
29 AROS_LHA(struct TagItem *, tagList, A1),
31 /* LOCATION */
33 struct Library *, RealTimeBase, 9, RealTime)
35 /* FUNCTION
37 Sets the attributes of a player. An attribute not specified in the array
38 of tags is unchanged after this procedure.
40 INPUTS
42 player -- The player the attributes of which to set.
43 tagList -- Pointer to an array of tags describing the player's
44 attributes or NULL.
46 TAGS
48 The same tags as for CreatePlayerA().
50 RESULT
52 Success/failure indicator. If failure, then, in case the PLAYER_ErrorCode
53 is provided, more information can be obtained via that pointer.
55 NOTES
57 EXAMPLE
59 BUGS
61 SEE ALSO
63 DeletePlayer(), GetPlayerAttrsA()
65 INTERNALS
67 ******************************************************************************/
70 AROS_LIBFUNC_INIT
72 LONG *error = NULL;
73 struct TagItem *tl = tagList;
74 struct TagItem *tag;
75 APTR lock;
77 error = (LONG *)GetTagData(PLAYER_ErrorCode, (IPTR)NULL, tl);
79 while ((tag = NextTagItem(&tl)) != NULL)
81 switch(tag->ti_Tag)
83 case PLAYER_Name:
84 player->pl_Link.ln_Name = (APTR)tag->ti_Data;
85 break;
87 case PLAYER_Hook:
88 player->pl_Hook = (struct Hook *)tag->ti_Data;
89 break;
91 case PLAYER_Priority:
92 player->pl_Link.ln_Pri = (BYTE)tag->ti_Data;
94 if (player->pl_Link.ln_Succ != NULL)
96 /* If this node has been (is) inserted before, then remove it
97 and put it in the right place. */
99 /* Is this player attached to a conductor? */
100 if (player->pl_Source != NULL)
102 lock = LockRealTime(RT_CONDUCTORS);
103 Remove((struct Node *)player);
104 Enqueue((struct List *)&player->pl_Source->cdt_Players,
105 (struct Node *)player);
106 UnlockRealTime(lock);
108 else
110 if(error != NULL)
112 *error = RTE_NOCONDUCTOR;
115 return FALSE;
119 break;
121 case PLAYER_Conductor:
123 D(bug("Found PLAYER_Conductor tag\n"));
125 if ((IPTR)tag->ti_Data == -1UL)
127 player->pl_Source = createConductor(TRUE, error,
128 (STRPTR)tag->ti_Data,
129 RealTimeBase);
131 else
133 struct Conductor *cd = FindConductor((STRPTR)tag->ti_Data);
135 if (cd == NULL)
137 D(bug("Trying to create a public conductor.\n"));
138 player->pl_Source = createConductor(FALSE, error,
139 (STRPTR)tag->ti_Data,
140 RealTimeBase);
142 else
144 player->pl_Source = cd;
148 if (player->pl_Source != NULL)
150 APTR lock;
152 lock = LockRealTime(RT_CONDUCTORS);
154 /* Enqueue the player to the conductor list */
155 Enqueue((struct List *)&player->pl_Source->cdt_Players,
156 (struct Node *)player);
158 UnlockRealTime(lock);
160 else
162 if (error != NULL)
164 *error = RTE_NOCONDUCTOR;
165 return FALSE;
168 break;
170 case PLAYER_Ready:
171 if ((BOOL)tag->ti_Data)
173 struct Conductor *conductor = player->pl_Source;
175 player->pl_Flags |= PLAYERF_READY;
177 if (conductor != NULL)
179 ObtainSemaphoreShared(&conductor->cdt_Lock);
181 if (conductor->cdt_Barrier != NULL)
183 Signal(conductor->cdt_Barrier, SIGF_SINGLE);
186 ReleaseSemaphore(&conductor->cdt_Lock);
189 else
191 player->pl_Flags &= ~PLAYERF_READY;
194 break;
196 case PLAYER_AlarmTime:
197 player->pl_Flags |= PLAYERF_ALARMSET;
198 player->pl_AlarmTime = (LONG)tag->ti_Data;
199 break;
201 case PLAYER_Alarm:
202 if ((BOOL)tag->ti_Data)
204 player->pl_Flags |= PLAYERF_ALARMSET;
206 else
208 player->pl_Flags &= ~PLAYERF_ALARMSET;
211 break;
213 case PLAYER_AlarmSigTask:
214 if ((struct Task *)tag->ti_Data == NULL)
216 player->pl_Flags &= ~PLAYERF_ALARMSET;
219 player->pl_Task = (struct Task *)tag->ti_Data;
220 break;
222 case PLAYER_AlarmSigBit:
223 if ((BYTE)tag->ti_Data == -1)
225 player->pl_Flags &= ~PLAYERF_ALARMSET;
228 /* We could use player->pl_Link.ln_Type here */
229 player->pl_Reserved0 = (BYTE)tag->ti_Data; /* NOTE! */
230 break;
232 case PLAYER_Quiet:
233 if ((BOOL)tag->ti_Data)
235 player->pl_Flags |= PLAYERF_QUIET;
237 else
239 player->pl_Flags &= ~PLAYERF_QUIET;
242 break;
244 case PLAYER_UserData:
245 player->pl_UserData = (APTR)tag->ti_Data;
246 break;
248 case PLAYER_ID:
249 player->pl_PlayerID = (UWORD)tag->ti_Data;
250 break;
252 case PLAYER_Conducted:
253 if ((BOOL)tag->ti_Data)
255 player->pl_Flags |= PLAYERF_CONDUCTED;
257 else
259 player->pl_Flags &= ~PLAYERF_CONDUCTED;
262 break;
264 case PLAYER_ExtSync:
265 lock = LockRealTime(RT_CONDUCTORS);
267 if ((BOOL)tag->ti_Data)
269 if (player->pl_Source->cdt_Flags & CONDUCTF_EXTERNAL)
271 /* Only one external synchronizer at a time, please */
272 UnlockRealTime(lock);
274 return FALSE;
277 player->pl_Source->cdt_Flags |= CONDUCTF_EXTERNAL;
278 player->pl_Flags |= PLAYERF_EXTSYNC;
280 else
282 /* If this player was the external synchronizer, we
283 clean up */
284 if (player->pl_Flags & PLAYERF_EXTSYNC)
286 player->pl_Source->cdt_Flags &= ~CONDUCTF_EXTERNAL;
287 player->pl_Source->cdt_Flags &= ~CONDUCTF_GOTTICK;
290 player->pl_Flags &= ~PLAYERF_EXTSYNC;
293 UnlockRealTime(lock);
295 break;
299 /* Consistency checks */
300 if (player->pl_Task == NULL)
302 player->pl_Flags &= ~PLAYERF_ALARMSET;
305 return TRUE;
307 AROS_LIBFUNC_EXIT
308 } /* SetPlayerAttrsA */
310 struct Conductor *createConductor(BOOL private, LONG *error, STRPTR name,
311 struct Library *RealTimeBase)
313 struct Conductor *cd = AllocMem(sizeof(struct Conductor),
314 MEMF_PUBLIC | MEMF_CLEAR);
316 if (cd == NULL)
318 if (error != NULL)
320 *error = RTE_NOMEMORY;
323 return NULL;
326 cd->cdt_Link.ln_Name = name;
328 NEWLIST(&cd->cdt_Players);
329 InitSemaphore(&cd->cdt_Lock);
331 /* Initialize conductor clock */
332 cd->cdt_ClockTime = GPB(RealTimeBase)->rtb_Time;
333 cd->cdt_StartTime = GPB(RealTimeBase)->rtb_Time;
335 /* Conductors are created in 'stopped' mode. To make the clock start
336 running, call SetConductorState(player, CONDSTATE_RUNNING, _); */
337 cd->cdt_State = CONDSTATE_STOPPED;
339 if (private)
341 cd->cdt_Flags |= CONDUCTF_PRIVATE;
345 /* Add the conductor to the realtime library conductor list */
346 APTR lock;
348 lock = LockRealTime(RT_CONDUCTORS);
350 AddTail((struct List *)&GPB(RealTimeBase)->rtb_ConductorList,
351 (struct Node *)cd);
353 UnlockRealTime(lock);
356 return cd;