1 /*
2  * This program is free software; you can redistribute it and/or
3  * modify it under the terms of the GNU General Public License
4  * as published by the Free Software Foundation; either version 2
5  * of the License, or (at your option) any later version.
6  *
7  * This program is distributed in the hope that it will be useful,
8  * but WITHOUT ANY WARRANTY; without even the implied warranty of
9  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
10  * GNU General Public License for more details.
11  *
12  * You should have received a copy of the GNU General Public License
13  * along with this program; if not, write to the Free Software Foundation,
14  * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
15  *
16  * The Original Code is Copyright (C) 2019 Blender Foundation.
17  * All rights reserved.
18  */
19 
20 /** \file
21  * \ingroup depsgraph
22  */
23 
24 #pragma once
25 
26 #include "intern/node/deg_node.h"
27 #include "intern/node/deg_node_operation.h"
28 
29 struct ID;
30 struct PointerRNA;
31 struct PropertyRNA;
32 
33 namespace blender {
34 namespace deg {
35 
36 struct Depsgraph;
37 struct Node;
38 class RNANodeQueryIDData;
39 class DepsgraphBuilder;
40 
41 /* For queries which gives operation node or key defines whether we are
42  * interested in a result of the given property or whether we are linking some
43  * dependency to that property. */
44 enum class RNAPointerSource {
45   /* Query will return pointer to an entry operation of component which is
46    * responsible for evaluation of the given property. */
47   ENTRY,
48   /* Query will return pointer to an exit operation of component which is
49    * responsible for evaluation of the given property.
50    * More precisely, it will return operation at which the property is known
51    * to be evaluated. */
52   EXIT,
53 };
54 
55 /* A helper structure which wraps all fields needed to find a node inside of
56  * the dependency graph. */
57 class RNANodeIdentifier {
58  public:
59   RNANodeIdentifier();
60 
61   /* Check whether this identifier is valid and usable. */
62   bool is_valid() const;
63 
64   ID *id;
65   NodeType type;
66   const char *component_name;
67   OperationCode operation_code;
68   const char *operation_name;
69   int operation_name_tag;
70 };
71 
72 /* Helper class which performs optimized lookups of a node within a given
73  * dependency graph which satisfies given RNA pointer or RAN path. */
74 class RNANodeQuery {
75  public:
76   RNANodeQuery(Depsgraph *depsgraph, DepsgraphBuilder *builder);
77   ~RNANodeQuery();
78 
79   Node *find_node(const PointerRNA *ptr, const PropertyRNA *prop, RNAPointerSource source);
80 
81  protected:
82   Depsgraph *depsgraph_;
83   DepsgraphBuilder *builder_;
84 
85   /* Indexed by an ID, returns RNANodeQueryIDData associated with that ID. */
86   Map<const ID *, unique_ptr<RNANodeQueryIDData>> id_data_map_;
87 
88   /* Construct identifier of the node which corresponds given configuration
89    * of RNA property. */
90   RNANodeIdentifier construct_node_identifier(const PointerRNA *ptr,
91                                               const PropertyRNA *prop,
92                                               RNAPointerSource source);
93 
94   /* Make sure ID data exists for the given ID, and returns it. */
95   RNANodeQueryIDData *ensure_id_data(const ID *id);
96 
97   /* Check whether prop_identifier contains rna_path_component.
98    *
99    * This checks more than a sub-string:
100    *
101    * prop_identifier           contains(prop_identifier, "location")
102    * ------------------------  -------------------------------------
103    * location                  true
104    * ["test_location"]         false
105    * pose["bone"].location     true
106    * pose["bone"].location.x   true
107    */
108   static bool contains(const char *prop_identifier, const char *rna_path_component);
109 };
110 
111 }  // namespace deg
112 }  // namespace blender
113