Jamoma API  0.6.0.a19
TTViewer.cpp
Go to the documentation of this file.
1 /** @file
2  *
3  * @ingroup modularLibrary
4  *
5  * @brief A Viewer Object.
6  *
7  * @details
8  *
9  * @authors Théo de la Hogue
10  *
11  * @copyright © 2010, Théo de la Hogue @n
12  * This code is licensed under the terms of the "New BSD License" @n
13  * http://creativecommons.org/licenses/BSD/
14  */
15 
16 
17 #include "TTViewer.h"
18 
19 #define thisTTClass TTViewer
20 #define thisTTClassName "Viewer"
21 #define thisTTClassTags "viewer"
22 
23 TTObjectBasePtr TTViewer::instantiate (TTSymbol name, TTValue arguments)
24 {
25  return new TTViewer(arguments);
26 }
27 
28 extern "C" void TTViewer::registerClass()
29 {
30  TTClassRegister(TTSymbol("Viewer"), thisTTClassTags, TTViewer::instantiate);
31 }
32 
33 TTViewer::TTViewer(const TTValue& arguments) :
34 TTCallback(arguments),
35 mAddress(kTTAdrsEmpty),
36 mDescription(kTTSym_none),
37 mType(kTTSym_generic),
38 mTags(kTTSym_none),
39 mHighlight(NO),
40 mFreeze(NO),
41 mDataspace(kTTSym_none),
42 mDataspaceUnit(kTTSym_none),
43 mDataspaceConverter("dataspace"),
44 mActive(YES)
45 {
47  addAttribute(Description, kTypeSymbol);
52 
53  addAttribute(Dataspace, kTypeSymbol);
54  addAttributeProperty(Dataspace, readOnly, YES);
55  addAttributeProperty(Dataspace, hidden, YES);
56  addAttributeWithSetter(DataspaceUnit, kTypeSymbol);
57 
59 
61  addAttributeProperty(ReturnedValue, readOnly, YES);
62  addAttributeProperty(ReturnedValue, hidden, YES);
63 
65  addMessageProperty(Send, hidden, YES);
66 
68  addMessageProperty(Grab, hidden, YES);
69 }
70 
71 TTViewer::~TTViewer()
72 {
73  // disable reception to avoid crash
74  mActive = NO;
75 }
76 
77 TTErr TTViewer::setAddress(const TTValue& value)
78 {
79  TTBoolean memoActive = mActive;
80 
81  mAddress = value[0];
82 
83  // disable reception to avoid crash
84  mActive = NO;
85 
86  // if no address : delete sender, receiver and observers
87  if (mAddress == kTTAdrsEmpty) {
88 
89  if (mSender.valid()) {
90  mSender.set(kTTSym_address, kTTAdrsEmpty);
91  mSender = TTObject();
92  }
93 
94  if (mReceiver.valid()) {
95  mReceiver.set(kTTSym_address, kTTAdrsEmpty);
96  mReceiver = TTObject();
97  }
98 
99  if (mDataspaceObserver.valid()) {
100  mDataspaceObserver.set(kTTSym_address, kTTAdrsEmpty);
101  mDataspaceObserver = TTObject();
102  }
103 
104  if (mDataspaceUnitObserver.valid()) {
105  mDataspaceUnitObserver.set(kTTSym_address, kTTAdrsEmpty);
106  mDataspaceUnitObserver = TTObject();
107  }
108 
109  return kTTErrGeneric;
110  }
111 
112  // the default attribute to bind is value
113  if (mAddress.getAttribute() == NO_ATTRIBUTE)
114  mAddress.appendAttribute(kTTSym_value);
115 
116  // create sender if needed
117  if (!mSender.valid())
118  mSender = TTObject(kTTSym_Sender);
119 
120  // change sender address
121  mSender.set(kTTSym_address, mAddress);
122 
123  // create receiver if needed
124  if (!mReceiver.valid()) {
125 
126  TTValue args;
127 
128  TTObject returnAddressCallback = TTObject("callback");
129  returnAddressCallback.set(kTTSym_baton, TTObject(this));
130  returnAddressCallback.set(kTTSym_function, TTPtr(&TTViewerReceiveAddressCallback));
131  args.append(returnAddressCallback);
132 
133  TTObject returnValueCallback = TTObject("callback");
134  returnValueCallback.set(kTTSym_baton, TTObject(this));
135  returnValueCallback.set(kTTSym_function, TTPtr(&TTViewerReceiveValueCallback));
136  args.append(returnValueCallback);
137 
138  mReceiver = TTObject(kTTSym_Receiver, args);
139  }
140 
141  // change receiver address
142  mReceiver.set(kTTSym_address, mAddress);
143 
144  // create dataspace observer if needed
145  if (!mDataspaceObserver.valid()) {
146 
147  TTValue args;
148  TTObject empty;
149 
150  args.append(empty);
151 
152  TTObject returnDataspaceCallback = TTObject("callback");
153  returnDataspaceCallback.set(kTTSym_baton, TTObject(this));
154  returnDataspaceCallback.set(kTTSym_function, TTPtr(&TTViewerDataspaceCallback));
155  args.append(returnDataspaceCallback);
156 
157  mDataspaceObserver = TTObject(kTTSym_Receiver, args);
158  }
159 
160  // change dataspace observer address and get the value
161  mDataspaceObserver.set(kTTSym_address, mAddress.appendAttribute(kTTSym_dataspace));
162  mDataspaceObserver.send(kTTSym_Get);
163 
164  // create dataspace unit observer if needed
165  if (!mDataspaceUnitObserver.valid()) {
166 
167  TTValue args;
168  TTObject empty;
169 
170  args.append(empty);
171 
172  TTObject returnDataspaceUnitCallback = TTObject("callback");
173  returnDataspaceUnitCallback.set(kTTSym_baton, TTObject(this));
174  returnDataspaceUnitCallback.set(kTTSym_function, TTPtr(&TTViewerDataspaceUnitCallback));
175  args.append(returnDataspaceUnitCallback);
176 
177  mDataspaceUnitObserver = TTObject(kTTSym_Receiver, args);
178  }
179 
180  // change dataspace unit observer address and get the value
181  mDataspaceUnitObserver.set(kTTSym_address, mAddress.appendAttribute(kTTSym_dataspaceUnit));
182  mDataspaceUnitObserver.send(kTTSym_Get);
183 
184  // enable reception
185  mActive = memoActive;
186 
187  // refresh
188  return mReceiver.send(kTTSym_Get);
189 }
190 
191 TTErr TTViewer::setActive(const TTValue& value)
192 {
193  mActive = value;
194 
195  if (mReceiver.valid()) {
196 
197  mReceiver.set(kTTSym_active, mActive);
198 
199  if (mActive)
200  return mReceiver.send(kTTSym_Get);
201  else
202  return kTTErrNone;
203  }
204 
205  return kTTErrGeneric;
206 }
207 
208 TTErr TTViewer::setHighlight(const TTValue& value)
209 {
210  TTAttributePtr anAttribute = NULL;
211  TTErr err;
212 
213  mHighlight = value;
214 
215  err = this->findAttribute(kTTSym_highlight, &anAttribute);
216 
217  if (!err)
218  anAttribute->sendNotification(kTTSym_notify, mHighlight); // we use kTTSym_notify because we know that observers are TTCallback
219 
220  return kTTErrNone;
221 }
222 
223 TTErr TTViewer::setFreeze(const TTValue& value)
224 {
225  mFreeze = value;
226 
227  if (mReceiver.valid()) {
228 
229  // update the value if the Viewer is unfreezed
230  if (!mFreeze)
231  return mReceiver.send(kTTSym_Get);
232  else
233  return kTTErrNone;
234  }
235 
236  return kTTErrGeneric;
237 }
238 
239 TTErr TTViewer::setReturnedValue(const TTValue& value)
240 {
241  TTAttributePtr anAttribute = NULL;
242  TTErr err;
243 
244  mReturnedValue = value;
245 
246  err = this->findAttribute(kTTSym_returnedValue, &anAttribute);
247 
248  if (!err)
249  anAttribute->sendNotification(kTTSym_notify, mReturnedValue); // we use kTTSym_notify because we know that observers are TTCallback
250 
251  return kTTErrNone;
252 }
253 
254 TTErr TTViewer::Send(const TTValue& inputValue, TTValue& outputValue)
255 {
256  if (!mActive)
257  return kTTErrNone;
258 
259  TTValue none, valueToSend;
260 
261  // insert view unit before "ramp" (except for empty value)
262  if (inputValue.size() > 0 &&
263  mDataspaceUnit != kTTSym_none &&
264  (mAddress.getAttribute() == kTTSym_value || mAddress.getAttribute() == kTTSymEmpty))
265  {
266  TTBoolean ramp = false;
267 
268  for (TTInt32 i = 0; i < inputValue.size(); i++)
269  {
270  if (inputValue[i].type() == kTypeSymbol)
271  {
272  TTSymbol s = inputValue[i];
273  if (s == kTTSym_ramp)
274  {
275  ramp = true;
276  valueToSend.append(mDataspaceUnit);
277  }
278  }
279 
280  valueToSend.append(inputValue[i]);
281  }
282 
283  if (!ramp)
284  valueToSend.append(mDataspaceUnit);
285  }
286  else
287  valueToSend = inputValue;
288 
289  if (mSender.valid())
290  return mSender.send(kTTSym_Send, valueToSend);
291  else
292  return kTTErrGeneric;
293 }
294 
295 TTErr TTViewer::Grab(const TTValue& inputValue, TTValue& outputValue)
296 {
297  if (mReceiver.valid()) {
298 
299  return mReceiver.send(kTTSym_Grab, inputValue, outputValue);
300  }
301 
302  return kTTErrGeneric;
303 }
304 
305 TTErr TTViewer::setDataspaceUnit(const TTValue& value)
306 {
307  TTValue n = value; // use new value to protect the attribute
308  mDataspaceUnit = value;
309 
310  return mDataspaceConverter.set("outputUnit", mDataspaceUnit);
311 
312  // TODO : notifyObservers(kTTSym_dataspaceUnit, n);
313 }
314 
315 #if 0
316 #pragma mark -
317 #pragma mark Some Methods
318 #endif
319 
321 {
322  return kTTErrNone;
323 }
324 
326 {
327  TTObject o;
328  TTViewerPtr aViewer;
329  TTValue converted;
330 
331  // unpack baton (a #TTViewer)
332  o = baton[0];
333  aViewer = (TTViewerPtr)o.instance();
334 
335  if (aViewer->mActive) {
336 
337  if (!aViewer->mFreeze)
338  // convert data
339  aViewer->mDataspaceConverter.send("convert", data, converted);
340 
341  else
342  // use last data
343  converted = aViewer->mReturnedValue;
344 
345  // return value
346  aViewer->deliver(converted);
347  aViewer->setReturnedValue(converted);
348  }
349 
350  return kTTErrNone;
351 }
352 
353 TTErr TTViewerDataspaceCallback(const TTValue& baton, const TTValue& data)
354 {
355  TTObject o;
356  TTViewerPtr aViewer;
357  TTValue v;
358  TTSymbol dataspace;
359 
360  // unpack baton (a #TTViewer)
361  o = baton[0];
362  aViewer = (TTViewerPtr)o.instance();
363 
364  dataspace = data;
365 
366  // filter repetitions
367  if (dataspace != aViewer->mDataspace) {
368 
369  aViewer->mDataspace = data;
370 
371  return aViewer->mDataspaceConverter.set(kTTSym_dataspace, aViewer->mDataspace);
372  }
373 
374  return kTTErrNone;
375 }
376 
378 {
379  TTObject o;
380  TTViewerPtr aViewer;
381  TTValue v;
382  TTErr err;
383 
384  // unpack baton (a #TTViewer)
385  o = baton[0];
386  aViewer = (TTViewerPtr)o.instance();
387 
388  // set input unit like the data unit
389  aViewer->mDataspaceConverter.set("inputUnit", data);
390 
391  // if no unit : set the output unit like the data unit
392  if (aViewer->mDataspaceUnit == kTTSym_none)
393  aViewer->mDataspaceUnit = data;
394 
395  // if the unit is wrong : use the default unit
396  err = aViewer->mDataspaceConverter.set("outputUnit", aViewer->mDataspaceUnit);
397  if (err) {
398  aViewer->mDataspaceConverter.get("outputUnit", v);
399  aViewer->mDataspaceUnit = v[0];
400  aViewer->mDataspaceConverter.set("outputUnit", aViewer->mDataspaceUnit);
401  }
402 
403  return kTTErrNone;
404 }
bool TTBoolean
Boolean flag, same as Boolean on the Mac.
Definition: TTBase.h:167
TTErr TTViewerDataspaceUnitCallback(const TTValue &baton, const TTValue &data)
Definition: TTViewer.cpp:377
This class is used to be sensitive to any TTObject notifications and report them using a function wit...
Definition: TTCallback.h:28
TTErr TTViewerReceiveAddressCallback(const TTValue &baton, const TTValue &data)
Definition: TTViewer.cpp:320
TTErr TTViewerDataspaceCallback(const TTValue &baton, const TTValue &data)
Definition: TTViewer.cpp:353
#define addAttribute(name, type)
A convenience macro to be used by subclasses for registering attributes with a custom getter...
Definition: TTAttribute.h:29
Create and use Jamoma object instances.
Definition: TTObject.h:29
size_type size() const noexcept
Return the number of elements.
TTErr TTViewerReceiveValueCallback(const TTValue &baton, const TTValue &data)
Definition: TTViewer.cpp:325
TTErr sendNotification(const TTSymbol name, const TTValue &arguments)
Send a notification.
TTErr set(const TTSymbol aName, T aValue)
Set an attribute value for an object This is the same as calling setAttributeValue().
Definition: TTObjectBase.h:251
This class represents a single attribute, as used by the TTObjectBase class.
Definition: TTAttribute.h:79
Base class for all first-class Jamoma objects.
Definition: TTObjectBase.h:109
Symbol type.
Definition: TTBase.h:282
This is a special type used by TTAttribute to indicate that a value is a TTValue and is locally maint...
Definition: TTBase.h:286
void append(const T &anElementValueToAppend)
Insert a single TTElement at the end.
Definition: TTValue.h:243
void * TTPtr
A generic pointer.
Definition: TTBase.h:248
#define addAttributeProperty(attributeName, propertyName, initialValue)
A convenience macro to be used for registering properties of attributes.
Definition: TTAttribute.h:68
TTErr set(const TTSymbol aName, T aValue)
Set an attribute value for an object.
The TTSymbol class is used to represent a string and efficiently pass and compare that string...
Definition: TTSymbol.h:26
An MVC viewer object.
Boolean (1/0) or (true/false) flag.
Definition: TTBase.h:281
#define addMessageWithArguments(name)
A convenience macro to be used by subclasses for registering messages.
Definition: TTMessage.h:27
std::int32_t TTInt32
32 bit signed integer
Definition: TTBase.h:177
void set(const TTUInt16 index, const T &anElementValue)
DEPRECATED.
Definition: TTValue.h:569
Something went wrong, but what exactly is not known. Typically used for context-specific problems...
Definition: TTBase.h:344
TTErr
Jamoma Error Codes Enumeration of error codes that might be returned by any of the TTBlue functions a...
Definition: TTBase.h:342
#define addAttributeWithSetter(name, type)
A convenience macro to be used by subclasses for registering attributes with a custom setter...
Definition: TTAttribute.h:47
TTObjectBase * instance() const
Return a direct pointer to the internal instance.
Definition: TTObject.cpp:105
No Error.
Definition: TTBase.h:343
[doxygenAppendixC_copyExample]
Definition: TTValue.h:34
#define addMessageProperty(messageName, propertyName, initialValue)
A convenience macro to be used for registering properties of messages.
Definition: TTMessage.h:37