HDK
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
STY_Styler.h
Go to the documentation of this file.
1 /*
2  * PROPRIETARY INFORMATION. This software is proprietary to
3  * Side Effects Software Inc., and is not to be reproduced,
4  * transmitted, or disclosed in any way without written permission.
5  *
6  * NAME: STY_Styler.h (STY Library, C++)
7  *
8  * COMMENTS:
9  */
10 
11 #ifndef __STY_Styler__
12 #define __STY_Styler__
13 
14 #include "STY_API.h"
15 #include "STY_Types.h"
16 #include "STY_StylerMatch.h"
17 #include "STY_StyleSheet.h"
18 #include <UT/UT_Array.h>
19 
21 class STY_Results;
22 class STY_ResultsFilter;
23 class STY_Subject;
24 class STY_SubjectGroup;
25 class STY_Style;
26 class STY_StylerGroup;
28 
29 /// Styler represents a state of style sheets after a sequence of
30 /// "transformations" that pruned some old entries given the styled subjects
31 /// and added new style sheets from new sources.
32 /// These transformations are performed with clone() methods.
33 /// After that, at any point, any relevant overrides can be obtained
34 /// with getResults() method.
35 /// Eg, a new style sheet can be added to the original styler, which returns
36 /// a newly cloned styler that holds its entries, then these entries
37 /// can be matched to the subject with clone() method, which will fully match
38 /// certain entries, partially match some other ones, and reject the remaining
39 /// ones, returning a newly cloned styler that encodes this match state;
40 /// finally getResults() can be called on the styler that was cloned last
41 /// to obtain overrides for the subject with which the it was cloned.
43 {
44 public:
45  /// Styler with an empty tree node. Serves as the root of a tree.
46  STY_Styler();
47 
48  /// Convenience constructor for non-empty root of the tree.
49  explicit STY_Styler(const STY_StyleSheetHandle &stylesheet);
50 
51  /// Destructor.
52  ~STY_Styler();
53 
54  /// Returns true if this styler contains any information at all. This
55  /// can be either styles or style sheet references.
56  bool hasAnyData() const
57  { return myData && (myData->myMatches.entries() > 0 ||
58  myData->myStyleSheets.entries() > 0); }
59 
60  /// Returns true if this styler may produce override values at this level
61  /// or for some child subject. This is different than calling getResults
62  /// and checking for values because getResults requires a full match in
63  /// order to return a value. This is also slightly more inclusive than
64  /// hasAnyData because we don't care about referenced style sheets.
65  bool hasStyles() const
66  { return myData && (myData->myMatches.entries() > 0); }
67 
68  /// Returns true if this styler has any non-full matches at this level. In
69  /// other words, different child subjects may produce different sets of
70  /// overrides. If this styler has only full matches (and the child subjects
71  /// don't add any styles) then regardless of what child subjects are
72  /// applied, all the styles will match.
74  {
75  if (myData)
76  for (auto &&match : myData->myMatches)
77  if (!match->isFullMatch())
78  return true;
79 
80  return false;
81  }
82 
83  /// Returns true if this styler has at least one stylesheet, and the last
84  /// stylesheet is marked with the "final" flag, meaning no further styles
85  /// should be processed.
86  bool isSolo() const;
87 
88  /// Returns a styler that reflects style sheets entries after processing
89  /// them with the given subject.
90  /// The returned styler will contain only the entries whose targets were
91  /// matched by the given subject, and potentially some new entries
92  /// supplied by the subject for itself and its children (if the subject
93  /// exists in some hierarchical structure).
94  /// This method can be thought of as a "transformation" of the original
95  /// styler, with the help of the given subject (which prunes some
96  /// old entries and provides some new ones), that results in a new styler
97  /// that reflects the new state.
98  STY_Styler cloneWithSubject(
99  const STY_Subject &subject,
100  UT_WorkBuffer *errors = NULL) const;
101 
102  /// Adds a new style sheet to the styler.
103  /// Conceptually, the styler pushes the new style sheet onto its own
104  /// style sheet stack. By design, the entries from that new style sheet
105  /// have lower priority than the entries from the style sheets already
106  /// on the stack (which allows parents to reconfigure children).
107  /// Thus, the overrides from the new style sheet will be used only if
108  /// old style sheets don't specify these overrides.
109  /// The resulting values can be querried with getResults().
110  STY_Styler cloneWithAddedStyleSheet(
111  const STY_StyleSheetHandle &stylesheet) const;
112 
113  /// Combines this styler with another and returns the result.
114  /// The provided styler can be essentially concatenated with the current
115  /// styler by providing an empty push_target. Or the provided styler can
116  /// be treated as a styler of sub-components of this styler by providing
117  /// a push_target that indicates which sub-components should be affected
118  /// by the provided styler.
119  STY_Styler cloneWithAddedStyler(
120  const STY_Styler &styler,
121  const STY_TargetHandle &push_target = STY_TargetHandle()) const;
122 
123  /// Returns a new styler with all styles that override the given
124  /// categories and properties removed.
125  STY_Styler cloneWithOverridesRemoved(
126  const STY_OverrideNames *extra_override_names,
127  bool remove_full_matches) const;
128 
129  /// Obtains overrides given the current state of the styler.
130  /// This method returns overrides from entries whose targets have been
131  /// previously fully matched by the subjects in the subject hierarchy.
132  /// It is implemented as a wrapper around the STY_StylerGroup interface.
133  /// Whenever possible, the Group interface should be used directly to
134  /// process multiple style sheets in a single pass.
135  ///
136  /// @param filter An object that decides what kind of override
137  /// values the caller is interested in. It filters out overrides
138  /// that are not needed, and allows in the ones that the caller
139  /// wants to obtain. Eg, the caller may want only the overrides
140  /// in the 'materialParameters' category.
141  void getResults(
142  STY_Results &results,
143  const STY_ResultsFilter &filter) const;
144 
145  /// Obtains a material defined inside a style sheet.
146  /// Returns true if a material by the given name was defined in a style
147  /// sheet, or false otherwise.
148  bool getMaterialDefinition(
149  STY_MaterialProperties &material_properties,
150  const char *material_name) const;
151 
152  /// Get errors generated parsing the style sheet.
153  void getErrors(UT_WorkBuffer &errors) const;
154 
155  /// Saves the style sheet represented by this styler as a JSON string.
156  void saveStyleSheet(UT_StringHolder &stylesheet,
157  bool verbose = false,
158  bool path = false) const;
159 
160  /// These are for DefaultClearer below, for use by UT::ArrayMap and
161  /// UT::ArraySet.
162  /// @{
164  void clear()
165  {
166  myData.reset();
167  }
169  bool isClear()
170  {
171  return myData != nullptr;
172  }
173  /// @}
174 
175 private:
176  /// Internally, the styler represents a style sheet stack. All style
177  /// sheets that define this stack are referenced to prevent deletion of
178  /// data that we need (the STY_Style objects held in each
179  /// STY_StylerMatchHandle). The style sheets also hold the scripts and
180  /// material definitions used by the style sheet entries. The style
181  /// sheet entries we keep have been pruned to ensure that they either
182  /// apply directly to the subject to which this Styler refers, or may
183  /// match a child of that subject.
184  class STY_StylerData :
185  public UT_IntrusiveRefCounter<STY_StylerData>
186  {
187  public:
188  /// The underlying style sheets that may be referenced by the matches
189  /// stored in this styler (ie, myMatches).
190  UT_Array<STY_StyleSheetHandle> myStyleSheets;
191 
192  /// List of active entries that affect subjects, that were passed
193  /// as an argument to clone methods, or their children.
194  /// This is a list of entries successfully matched so far when cloning
195  /// stylers. This list references the underlying style sheet entries,
196  /// but contains its own version of targets.
198  };
199  typedef UT_IntrusivePtr<STY_StylerData> STY_StylerDataHandle;
200 
201  /// Helper for adding a new style sheet to an existing one. Takes an
202  /// optional subject that is used for filtering self targets. Any
203  /// non-self target entries are left intact, allowing subject children
204  /// to match them, and allowing getResults() for subject to skip them.
205  /// Modifies this Styler, so should only be used during the construction
206  /// of a new styler.
207  void addStyler(const STY_Styler &styler,
208  const STY_Subject *self,
209  STY_StylerGroupMatchHandle *group_matches = NULL,
210  int subject_index = -1);
211 
212  /// Helper for adding a new style sheet to an existing one. Takes an
213  /// optional target that is used to add a level of targeting to all
214  /// styles on the added style sheet. This can be used to compose a bunch
215  /// of lower level (e.g. primitive attribute style sheets) into a higher
216  /// level (e.g. object primitive) style sheet.
217  void addStyler(const STY_Styler &add_styler,
218  const STY_TargetHandle &push_target = STY_TargetHandle());
219 
220  /// Helper function for pruning a styler for a subject. Generates the new
221  /// closure when a matching entry is found.
223  getNewClosure(const STY_StylerMatch &match,
224  const STY_Subject &subject,
225  const STY_TargetMatchStatus &match_status) const;
226 
227  /// Prunes the current style sheet stack, getting rid of any entries
228  /// that don't match the subject. Modifies this Styler, so should only
229  /// be used during the construction of a new styler. The match_map and
230  /// closure_map parameters tell this function to output the results of
231  /// all candidate match attempts to these arrays. They are used by our
232  /// array-based processing of STY_StylerGroup.
233  void pruneWithSubject(
234  const STY_Subject &subject,
235  STY_StylerGroupMatchHandle *group_matches = NULL,
236  int subject_index = -1);
237 
238  /// Prunes any overrides that match the provided category/name pairs.
239  /// This may involve removing whole style entries, or just some of the
240  /// overrides from a style entry.
241  void pruneOverrides(
242  const STY_OverrideNames *extra_override_names,
243  bool remove_full_matches);
244 
245  /// Styler data.
246  /// Ultimately, STY_Styler is a convenience wrapper around this pointer.
247  /// Using smart pointers is convenient to pass stylers around by value,
248  /// which provides a much nicer interface for cloning stylers.
249  STY_StylerDataHandle myData;
250 
251  /// This class needs access to our internal functions for implementation
252  /// of efficient array-based styler methods.
253  friend class STY_StylerGroup;
254  friend class sty_PruneWithSubjectTask;
255 };
256 
257 namespace UT {
258 template<>
260 {
262  static void clear(STY_Styler&v) { v.clear(); }
264  static bool isClear(STY_Styler &v) { return v.isClear(); }
266  static void clearConstruct(STY_Styler *p) { new((void *)p) STY_Styler(); }
267 
268  static const bool clearNeedsDestruction = false;
269 };
270 }
271 
272 #endif
273 
bool hasStyles() const
Definition: STY_Styler.h:65
static SYS_FORCE_INLINE void clearConstruct(STY_Styler *p)
Definition: STY_Styler.h:266
Provides values for the properties of materials defined in a style sheet.
const GLdouble * v
Definition: glcorearb.h:836
GLsizei const GLchar *const * path
Definition: glcorearb.h:3340
Contains information about the style subject match to the style target.
Represents a style sheet entry that contains a target and overrides.
Definition: STY_Style.h:28
#define STY_API
Definition: STY_API.h:10
A reference counter base class for use with UT_IntrusivePtr.
static SYS_FORCE_INLINE void clear(STY_Styler &v)
Definition: STY_Styler.h:262
#define SYS_FORCE_INLINE
Definition: SYS_Inline.h:45
static SYS_FORCE_INLINE bool isClear(STY_Styler &v)
Definition: STY_Styler.h:264
Wrapper around hboost::intrusive_ptr.
bool hasAnyPartialMatchStyles() const
Definition: STY_Styler.h:73
bool hasAnyData() const
Definition: STY_Styler.h:56
UT_IntrusivePtr< const STY_Target > STY_TargetHandle
Definition: STY_Types.h:110
SYS_FORCE_INLINE void clear()
Definition: STY_Styler.h:164
SYS_FORCE_INLINE bool isClear()
Definition: STY_Styler.h:169
GLint GLint GLint GLint GLint GLint GLint GLbitfield GLenum filter
Definition: glcorearb.h:1296