TTErr TTAddressItem::append(TTAddress addressToAppend, TTAddressItemPtr *returnedItem) { TTAddressItemPtr anItem = this; TTAddressItemPtr nextItem; TTList nameInstanceList; TTSymbol nameInstance(kTTSymEmpty); addressToAppend.listNameInstance(nameInstanceList); for (nameInstanceList.begin(); nameInstanceList.end(); nameInstanceList.next()) { nameInstance = nameInstanceList.current()[0]; nextItem = anItem->getItem(nameInstance); if (!nextItem) { nextItem = new TTAddressItem(nameInstance, anItem); ((TTListPtr)anItem)->append((TTPtr)nextItem); } anItem = nextItem; } anItem->options->appendUnique(addressToAppend.getAttribute()); *returnedItem = anItem; return kTTErrNone; }
TTErr TTEnvironment::registerClass(const TTSymbolPtr className, const TTString& tagString, const TTObjectInstantiationMethod anInstantiationMethod) { TTValue v((TTString&)tagString); // The tags to be associated with the class we are registering. TTValue tagObjects; // Contains a TTList of objects in the environment with the given tag. TTClassPtr theClass; TTErr err; TTList* classNamesForTag; // The TTList contained by tagObjects TTUInt16 size; TTSymbolPtr tag; TTValue result; err = classes->lookup(className, result); // If a class is already registered with this name, then we do not want to register another class with the same name! if (err == kTTErrValueNotFound) { // 1. Turn the string into an array of symbols v.transformCSVStringToSymbolArray(); // 2. Create the class and associate it with its name theClass = new TTClass(className, v, anInstantiationMethod); // 3. For each symbol in the TTValue array... size = v.getSize(); for (TTUInt16 i=0; i<size; i++) { v.get(i, &tag); // 4. Look to see if this tag exists yet err = tags->lookup(tag, tagObjects); if (!err) { classNamesForTag = (TTList*)(TTPtr(tagObjects)); // TODO: The following code demonstrates so extreme lameness that we need to evaluate. // First, we should probably just do this section of code with TTValue instead of TTList (but we needed code to test TTList) // Second, TTList is taking references but keeping things internally as pointers, which leads to lots of confusion // Third, we have to pass objects that are permanent - so no temporaries are allowed unless we make TTList do a copy // etc. // TODO: We need to factor out a function to add a tag for a named class (or a given class ptr) //classNamesForTag->append(className); classNamesForTag->append(*new TTValue(className)); } else { classNamesForTag = new TTList; tagObjects = TTPtr(classNamesForTag); tags->append(tag ,tagObjects); classNamesForTag->append(*new TTValue(className)); } } // 4. Register it err = registerClass(theClass); } return err; }
int Namespace::namespaceParameterGetInstanceNumber(std::string address) { TTList returnedChildrenInstance; TTNodePtr parentNode; std::string parentAddress, childAddress; // split the address size_t lastSlashPos = address.find_last_of("/"); parentAddress = address.substr(0, lastSlashPos); childAddress = address.substr(lastSlashPos+1, std::string::npos); // get the parent node at the given address NSPDirectory->getTTNodeForOSC(TT(AppName + parentAddress), &parentNode); // get the list of children instances parentNode->getChildrenInstance(TT(childAddress), returnedChildrenInstance); return returnedChildrenInstance.getSize(); }
void snapshot(XMLNode xmlNode, TTNodePtr ttNode) { TTSymbolPtr OSCaddress; TTValue v, attributeNames; TTList childList; TTNodePtr p_node; TTString s; ttNode->getOscAddress(&OSCaddress); ttNode->getChildren(S_WILDCARD, S_WILDCARD, childList); const char* address = OSCaddress->getCString(); char* nodeName; XMLNode childNode = xmlNode; // don't write the first node AppName in xml because already written in application xml header // don't write the node name if is an instance, don't want it in xml file, replaced by dynamic instances attribute if (strcmp(address, AppName.c_str()) != 0 && strrchr(address, '.') == NULL) { // get the substring representing the last node name if (strlen(address) > 1) { const char* c = strrchr(address, '/'); int start = c-address+1; int end = strlen(address)-1; nodeName = str_sub(address, start, end); childNode = xmlNode.addChild(nodeName); } if (childList.isEmpty()) { // get the Data object of the Node TTObjectPtr param = ttNode->getObject(); if (param != NULL) { addAttributeToXml(param, childNode, kTTSym_type); addAttributeToXml(param, childNode, kTTSym_valueDefault); addAttributeToXml(param, childNode, kTTSym_rangeBounds); addAttributeToXml(param, childNode, kTTSym_rangeClipmode); addAttributeToXml(param, childNode, kTTSym_valueStepsize); addAttributeToXml(param, childNode, TTSymbol("dynamicInstances")); addAttributeToXml(param, childNode, TTSymbol("instanceBounds")); addAttributeToXml(param, childNode, kTTSym_priority); addAttributeToXml(param, childNode, kTTSym_description); addAttributeToXml(param, childNode, kTTSym_repetitionsFilter); addAttributeToXml(param, childNode, kTTSym_readonly); } } } // repeat recursively for each child for (childList.begin(); childList.end(); childList.next()) { childList.current().get(0,(TTPtr*)&p_node); snapshot(childNode, p_node); } }
TTErr TTEnvironment::getClassNamesWithTags(TTValue& classNames, const TTValue& searchTags) { // TODO: right now we only look for the first tag, we should look for each and then do a union on the results. // Well, that's not what's really happening, but the point is that this really only works if we are searching for one tag. TTUInt16 size = searchTags.getSize(); TTSymbolPtr tag; TTValue tagObjects; TTErr err = kTTErrGeneric; TTList* classNamesForTag; for (TTUInt16 i=0; i<size; i++) { searchTags.get(i, &tag); err = tags->lookup(tag, tagObjects); if (!err) { classNamesForTag = (TTList*)(TTPtr(tagObjects)); classNamesForTag->assignToValue(classNames); } } return err; }
TTErr TTHash::getKeysSorted(TTValue& hashKeysSorted, TTBoolean(comparisonFunction)(TTValue&, TTValue&)) { lock(); TTList listToSort; TTValue v; TTSymbol key; // fill a list to sort for (TTHashMapIter iter = HASHMAP->begin(); iter != HASHMAP->end(); iter++) { TTPtrSizedInt a = iter->first; TTSymbol b((TTSymbolBase*)a); if (comparisonFunction) { v = b; // the key v.append(TTPtr(iter->second)); // a pointer to the stored value listToSort.append(v); } else listToSort.append(b); } listToSort.sort(comparisonFunction); // fill the result hashKeysSorted.clear(); for (listToSort.begin(); listToSort.end(); listToSort.next()) { if (comparisonFunction) { key = listToSort.current()[0]; hashKeysSorted.append(key); } else hashKeysSorted.append(listToSort.current()); } unlock(); return kTTErrNone; }
TTErr TTAddressItem::find(TTAddress addressToFind, TTAddressItemPtr *returnedItem) { TTAddressItemPtr anItem = this; TTAddressItemPtr nextItem; TTList nameInstanceList; TTSymbol nameInstance(kTTSymEmpty); TTValue v; addressToFind.listNameInstance(nameInstanceList); if (nameInstanceList.isEmpty()) return kTTErrGeneric; for (nameInstanceList.begin(); nameInstanceList.end(); nameInstanceList.next()) { nameInstance = nameInstanceList.current()[0]; nextItem = anItem->getItem(nameInstance); if (!nextItem) return kTTErrValueNotFound; else anItem = nextItem; } if (anItem->options->isEmpty() && addressToFind.getAttribute() == NO_ATTRIBUTE) { *returnedItem = anItem; return kTTErrNone; } if (!anItem->options->findEquals(addressToFind.getAttribute(), v)) { *returnedItem = anItem; return kTTErrNone; } return kTTErrValueNotFound; }