1 /* --COPYRIGHT--,EPL
2 * Copyright (c) 2008 Texas Instruments and others.
3 * All rights reserved. This program and the accompanying materials
4 * are made available under the terms of the Eclipse Public License v1.0
5 * which accompanies this distribution, and is available at
6 * http://www.eclipse.org/legal/epl-v10.html
7 *
8 * Contributors:
9 * Texas Instruments - initial implementation
10 *
11 * --/COPYRIGHT--*/
12
13 /*!
14 * Callback notification on RTSC config parameters.
15 *
16 * Lets user code receive a notification whenever a
17 * config param of a module or instance is read or modified.
18 *
19 * @see ./doc-files/xdc/services/getset/package-summary.html JavaDoc
20 */
21 metaonlymodule GetSet
22 {
23 /*!
24 * ======== onGet ========
25 * Add a getter function to a field.
26 *
27 * Each getter acts like an interrupt that is triggered by a read
28 * a field of an object. The field could be a config param of a module
29 * or an instance, or a field of a struct.
30 *
31 * @a(example) 32 * The following example prints a message on any read of a
33 * config param named `cfg` in module `pkg.Mod`:
34 * @p(code) 35 * GetSet.onGet(Mod, "cfg", function(sel, val) {
36 * // prints "pkg.Mod.cfg returned <value>"
37 * print(this.$name + "." + sel + " returned " + val);
38 * });
39 * @p 40 */
41 function onGet(obj, sel, getter);
42
43 /*!
44 * ======== onSet ========
45 * Add a setter function to a field.
46 *
47 * Each setter acts like an interrupt that is triggered by modifying
48 * a field of an object. The field could be a config param of a module
49 * or an instance, or a field of a struct.
50 *
51 * Setters execute only when the field actually changes value. They do
52 * not execute if the field's current value is written back to it.
53 *
54 * Setters may themselves modify fields, and so trigger other setters.
55 * The original execution flow resumes when all fields stop changing
56 * value. In the case of cycles between setters, typically this means
57 * that at least one setter executes twice and makes no further
58 * changes the second time through.
59 *
60 * If the setter throws a JavaScript Error or Java exception, then
61 * the field's original value is restored. The exception bubbles back
62 * through the call stack, so that if a setter caused a cascade of
63 * changes, all are restored to their original values.
64 *
65 * @a(example) 66 * The following example prints a message on any write to a
67 * config param named `cfg` in module `pkg.Mod`:
68 * @p(code) 69 * GetSet.onSet(Mod, "cfg", function(sel, val, oldVal, exception) {
70 * // prints "pkg.Mod.cfg set to <value>"
71 * print(this.$name + "." + sel + " changed to " + val);
72 * // prints previous value before change
73 * print(" was " + oldVal);
74 * });
75 * @p 76 *
77 * @a(example) 78 * The following example makes it an error to change `Mod.cfg`:
79 * @p(code) 80 * GetSet.onSet(Mod, "cfg", function(sel, val, oldVal, exception) {
81 * // don't throw an exception if already recovering from one
82 * if (!exception) {
83 * throw new Error("You'll never change me!");
84 * }
85 * });
86 * @p 87 */
88 function onSet(obj, sel, setter);
89
90 /*!
91 * ======== createGroup ========
92 * Create a group of related setter functions.
93 *
94 * The purpose of a group is to control interactions between setters.
95 * If each setter acts like an interrupt, then a group is like an
96 * interrupt controller that determines when setters are permitted
97 * to run.
98 *
99 * Each group is non-reentrant. Once any setter in the group is
100 * running, it runs to completion before any other setter in the
101 * same group may run. This allows the setters to modify internal
102 * state without interference from other setters that operate on
103 * the same internal state.
104 *
105 * Each group runs to completion. When a setter in the group runs, it
106 * might modify other config params and cause further setters in the
107 * same group to run. All of these complete before control is returned
108 * to the original execution flow. From the point of view of code
109 * outside the group, all the setters ran as an atomic operation.
110 *
111 * Groups may be interrupted. When a setter modifies a config param
112 * that is being monitored by a second group, the second group starts
113 * running immediately. It will run to completion before returning
114 * control to the first group. So the first group sees the second
115 * group as atomic. This allows groups to be tested independently,
116 * and combined without affecting their behavior.
117 *
118 * Cycles aren't permitted in the execution flow between groups. If a
119 * setter gets triggered from a group that has already been interrupted,
120 * it is deferred and run when control eventually returns to its own
121 * group. Cycles between groups can break the appearance of atomic
122 * execution, and so should be avoided when possible.
123 *
124 * @a(returns) 125 * A Java object of class
126 * {@link ./doc-files/xdc/services/getset/Group.html Group}.
127 * Can then use Group.onSet() to add functions to the group.
128 *
129 * @a(example) 130 * The following example code forces the values of the config params
131 * `ModA.a` and `ModB.b` to be equal:
132 * @p(code) 133 * var group = GetSet.createGroup();
134 * group.onSet(ModA, "a", function aToB(){ ModB.b = ModA.a; });
135 * group.onSet(ModB, "b", function bToA(){ ModA.a = ModB.b; });
136 * @p 137 */
138 function createGroup();
139
140 /*!
141 * ======== init ========
142 * Add support for getters and setters to all fields of an object.
143 *
144 * Initializes getter and setter support for every field of
145 * the object. The object can be a module, instance, or structure.
146 *
147 * This is a convenience function. The `onSet` and `onGet` functions
148 * already add support to the one field of interest. The `init`
149 * function is useful mostly to make fields visible to global setters
150 * and getters, for example for debugging.
151 */
152 function init(obj);
153
154 /*!
155 * ======== debug ========
156 * Print execution trace info showing the flow of getters and setters.
157 */
158 config Bool debug = false;
159
160 /*!
161 * ======== maxIterations ========
162 * Limit the number of iterations allowed for a group to converge, to
163 * help debug. The default value of 0 means no limit.
164 */
165 configint maxIterations = 0;
166
167 /*!
168 * ======== maxStackDepth ========
169 * Set the maximum allowed depth of recursively nested setters, as
170 * a debugging aid. The default value of 0 means no limit.
171 */
172 configint maxStackDepth = 0;
173 }