2 * Copyright (C) 2007 Benjamin Otte <otte@gnome.org>
4 * This library is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU Lesser General Public
6 * License as published by the Free Software Foundation; either
7 * version 2.1 of the License, or (at your option) any later version.
9 * This library is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 * Lesser General Public License for more details.
14 * You should have received a copy of the GNU Lesser General Public
15 * License along with this library; if not, write to the Free Software
16 * Foundation, Inc., 51 Franklin Street, Fifth Floor,
17 * Boston, MA 02110-1301 USA
27 #include "swfdec_interval.h"
28 #include "swfdec_as_context.h"
29 #include "swfdec_as_frame_internal.h"
30 #include "swfdec_as_function.h"
31 #include "swfdec_as_internal.h"
32 #include "swfdec_debug.h"
33 #include "swfdec_player_internal.h"
34 #include "swfdec_resource.h"
36 G_DEFINE_TYPE (SwfdecInterval
, swfdec_interval
, SWFDEC_TYPE_AS_OBJECT
)
39 swfdec_interval_mark (SwfdecGcObject
*object
)
42 SwfdecInterval
*interval
= SWFDEC_INTERVAL (object
);
44 swfdec_gc_object_mark (interval
->object
);
45 swfdec_gc_object_mark (interval
->sandbox
);
46 if (interval
->fun_name
)
47 swfdec_as_string_mark (interval
->fun_name
);
48 for (i
= 0; i
< interval
->n_args
; i
++) {
49 swfdec_as_value_mark (&interval
->args
[i
]);
52 SWFDEC_GC_OBJECT_CLASS (swfdec_interval_parent_class
)->mark (object
);
56 swfdec_interval_dispose (GObject
*object
)
58 SwfdecInterval
*interval
= SWFDEC_INTERVAL (object
);
60 if (interval
->n_args
) {
61 swfdec_as_context_unuse_mem (swfdec_gc_object_get_context (interval
),
62 interval
->n_args
* sizeof (SwfdecAsValue
));
63 g_free (interval
->args
);
64 interval
->args
= NULL
;
67 /* needed here when GC'ed by closing the player */
68 if (interval
->timeout
.callback
!= NULL
) {
69 swfdec_player_remove_timeout (SWFDEC_PLAYER (swfdec_gc_object_get_context (object
)), &interval
->timeout
);
70 interval
->timeout
.callback
= NULL
;
73 G_OBJECT_CLASS (swfdec_interval_parent_class
)->dispose (object
);
77 swfdec_interval_class_init (SwfdecIntervalClass
*klass
)
79 GObjectClass
*object_class
= G_OBJECT_CLASS (klass
);
80 SwfdecGcObjectClass
*gc_class
= SWFDEC_GC_OBJECT_CLASS (klass
);
82 object_class
->dispose
= swfdec_interval_dispose
;
84 gc_class
->mark
= swfdec_interval_mark
;
88 swfdec_interval_init (SwfdecInterval
*array
)
93 swfdec_interval_trigger (SwfdecTimeout
*timeout
)
96 SwfdecInterval
*interval
= SWFDEC_INTERVAL ((void *) (((guchar
*) timeout
)
97 - G_STRUCT_OFFSET (SwfdecInterval
, timeout
)));
98 SwfdecAsContext
*context
= swfdec_gc_object_get_context (interval
);
99 SwfdecPlayer
*player
= SWFDEC_PLAYER (context
);
101 if (interval
->repeat
) {
102 timeout
->timestamp
+= SWFDEC_MSECS_TO_TICKS (interval
->msecs
);
103 swfdec_player_add_timeout (SWFDEC_PLAYER (context
), timeout
);
105 player
->priv
->intervals
= g_list_remove (player
->priv
->intervals
, interval
);
106 interval
->timeout
.callback
= NULL
;
108 swfdec_sandbox_use (interval
->sandbox
);
109 if (interval
->fun_name
) {
110 swfdec_as_object_call (interval
->object
,
111 interval
->fun_name
, interval
->n_args
, interval
->args
, &ret
);
113 swfdec_as_function_call (SWFDEC_AS_FUNCTION (interval
->object
), NULL
,
114 interval
->n_args
, interval
->args
, &ret
);
115 swfdec_as_context_run (context
);
117 swfdec_sandbox_unuse (interval
->sandbox
);
121 swfdec_interval_new (SwfdecPlayer
*player
, guint msecs
, gboolean repeat
,
122 SwfdecAsObject
*object
, const char *fun_name
,
123 guint n_args
, const SwfdecAsValue
*args
)
125 SwfdecAsContext
*context
;
126 SwfdecInterval
*interval
;
128 context
= SWFDEC_AS_CONTEXT (player
);
129 if (n_args
&& !swfdec_as_context_try_use_mem (context
, n_args
* sizeof (SwfdecAsValue
))) {
130 swfdec_as_context_abort (context
,
131 "Too many arguments passed to setInterval/setTimeout");
134 interval
= g_object_new (SWFDEC_TYPE_INTERVAL
, "context", context
, NULL
);
136 interval
->id
= ++player
->priv
->interval_id
;
137 interval
->sandbox
= SWFDEC_SANDBOX (context
->global
);
138 interval
->msecs
= msecs
;
139 interval
->repeat
= repeat
;
140 interval
->object
= object
;
141 interval
->fun_name
= fun_name
;
142 interval
->n_args
= n_args
;
143 interval
->args
= g_memdup (args
, n_args
* sizeof (SwfdecAsValue
));
144 interval
->timeout
.timestamp
= player
->priv
->time
+ SWFDEC_MSECS_TO_TICKS (interval
->msecs
);
145 interval
->timeout
.callback
= swfdec_interval_trigger
;
146 swfdec_player_add_timeout (player
, &interval
->timeout
);
148 player
->priv
->intervals
=
149 g_list_prepend (player
->priv
->intervals
, interval
);
155 swfdec_interval_new_function (SwfdecPlayer
*player
, guint msecs
, gboolean repeat
,
156 SwfdecAsFunction
*fun
, guint n_args
, const SwfdecAsValue
*args
)
158 g_return_val_if_fail (SWFDEC_IS_PLAYER (player
), 0);
159 g_return_val_if_fail (msecs
> 0, 0);
160 g_return_val_if_fail (SWFDEC_IS_AS_FUNCTION (fun
), 0);
161 g_return_val_if_fail (n_args
== 0 || args
!= NULL
, 0);
163 return swfdec_interval_new (player
, msecs
, repeat
, SWFDEC_AS_OBJECT (fun
), NULL
, n_args
, args
);
167 swfdec_interval_new_object (SwfdecPlayer
*player
, guint msecs
, gboolean repeat
,
168 SwfdecAsObject
*thisp
, const char *fun_name
,
169 guint n_args
, const SwfdecAsValue
*args
)
171 g_return_val_if_fail (SWFDEC_IS_PLAYER (player
), 0);
172 g_return_val_if_fail (msecs
> 0, 0);
173 g_return_val_if_fail (SWFDEC_IS_AS_OBJECT (thisp
), 0);
174 g_return_val_if_fail (fun_name
!= NULL
, 0);
175 g_return_val_if_fail (n_args
== 0 || args
!= NULL
, 0);
177 return swfdec_interval_new (player
, msecs
, repeat
, thisp
, fun_name
, n_args
, args
);
181 swfdec_interval_remove (SwfdecPlayer
*player
, guint id
)
185 g_return_if_fail (SWFDEC_IS_PLAYER (player
));
187 for (walk
= player
->priv
->intervals
; walk
; walk
= walk
->next
) {
188 SwfdecInterval
*interval
= walk
->data
;
189 if (interval
->id
!= id
)
192 player
->priv
->intervals
= g_list_delete_link (player
->priv
->intervals
, walk
);
193 swfdec_player_remove_timeout (player
, &interval
->timeout
);
194 interval
->timeout
.callback
= NULL
;