"Initial commit to Gerrit"
[profile/ivi/cogl.git] / cogl / cogl-node.c
1 /*
2  * Cogl
3  *
4  * An object oriented GL/GLES Abstraction/Utility Layer
5  *
6  * Copyright (C) 2008,2009,2010 Intel Corporation.
7  *
8  * This library is free software; you can redistribute it and/or
9  * modify it under the terms of the GNU Lesser General Public
10  * License as published by the Free Software Foundation; either
11  * version 2 of the License, or (at your option) any later version.
12  *
13  * This library is distributed in the hope that it will be useful,
14  * but WITHOUT ANY WARRANTY; without even the implied warranty of
15  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
16  * Lesser General Public License for more details.
17  *
18  * You should have received a copy of the GNU Lesser General Public
19  * License along with this library. If not, see
20  * <http://www.gnu.org/licenses/>.
21  *
22  *
23  *
24  * Authors:
25  *   Robert Bragg <robert@linux.intel.com>
26  */
27
28 #ifdef HAVE_CONFIG_H
29 #include "config.h"
30 #endif
31
32 #include "cogl-util.h"
33 #include "cogl-node-private.h"
34
35 void
36 _cogl_pipeline_node_init (CoglNode *node)
37 {
38   node->parent = NULL;
39   COGL_LIST_INIT (&node->children);
40 }
41
42 void
43 _cogl_pipeline_node_set_parent_real (CoglNode *node,
44                                      CoglNode *parent,
45                                      CoglNodeUnparentVFunc unparent,
46                                      gboolean take_strong_reference)
47 {
48   /* NB: the old parent may indirectly be keeping the new parent alive
49    * so we have to ref the new parent before unrefing the old.
50    *
51    * Note: we take a reference here regardless of
52    * take_strong_reference because weak children may need special
53    * handling when the parent disposes itself which relies on a
54    * consistent link to all weak nodes. Once the node is linked to its
55    * parent then we remove the reference at the end if
56    * take_strong_reference == FALSE. */
57   cogl_object_ref (parent);
58
59   if (node->parent)
60     unparent (node);
61
62   COGL_LIST_INSERT_HEAD (&parent->children, node, list_node);
63
64   node->parent = parent;
65   node->has_parent_reference = take_strong_reference;
66
67   /* Now that there is a consistent parent->child link we can remove
68    * the parent reference if no reference was requested. If it turns
69    * out that the new parent was only being kept alive by the old
70    * parent then it will be disposed of here. */
71   if (!take_strong_reference)
72     cogl_object_unref (parent);
73 }
74
75 void
76 _cogl_pipeline_node_unparent_real (CoglNode *node)
77 {
78   CoglNode *parent = node->parent;
79
80   if (parent == NULL)
81     return;
82
83   _COGL_RETURN_IF_FAIL (!COGL_LIST_EMPTY (&parent->children));
84
85   COGL_LIST_REMOVE (node, list_node);
86
87   if (node->has_parent_reference)
88     cogl_object_unref (parent);
89
90   node->parent = NULL;
91 }
92
93 void
94 _cogl_pipeline_node_foreach_child (CoglNode *node,
95                                    CoglNodeChildCallback callback,
96                                    void *user_data)
97 {
98   CoglNode *child, *next;
99
100   COGL_LIST_FOREACH_SAFE (child, &node->children, list_node, next)
101     callback (child, user_data);
102 }
103
104