<commit_before>/* 
 * TTBlue Global Object
 * Copyright © 2008, <NAME>
 * 
 * License: This code is licensed under the terms of the "New BSD License"
 * http://creativecommons.org/licenses/BSD/
 */

#include "TTFoundation.h"
#include "TTEnvironment.h"
#include "TTClass.h"

#define thisTTClass TTEnvironment


// The environment object has one instance, which is global in scope.
TTEnvironment*	ttEnvironment = NULL;


/****************************************************************************************************/

TTEnvironment::TTEnvironment()
	: TTObject(kTTValNONE), mDebugBasic(false), mDebugMessaging(false), mSampleRate(0)
{	
	classes = new TTHash();
	tags = new TTHash();

	addAttribute(DebugBasic,		kTypeBoolean);
	addAttribute(DebugMessaging,	kTypeBoolean);
	addAttribute(SampleRate,		kTypeUInt32);

	addMessageWithArgument(getVersion);

	// can't use the SymbolCache here because it hasn't been initialized yet!
	setAttributeValue(TT("sampleRate"), 44100);
}


TTEnvironment::~TTEnvironment()
{
	// If on Windows, we need to call FreeLibrary() on all plug-ins loaded with LoadLibrary()
	// On the Mac, we may need to do the equivalent

	delete tags;
	delete classes;
}


TTErr TTEnvironment::getVersion(TTValue &value)
{
	value = TTFOUNDATION_VERSION_STRING;
	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;
}


TTErr TTEnvironment::registerClass(TTClassPtr theClass)
{
	return classes->append(theClass->name, TTPtr(theClass));
}


TTErr TTEnvironment::getAllClassNames(TTValue& returnedClassNames)
{
	return classes->getKeys(returnedClassNames);
}


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 TTEnvironment::createInstance(const TTSymbolPtr className, TTObjectPtr* anObject, const TTValue& anArgument)
{
	return createInstance(className, anObject, (TTValue&)anArgument); // throw away the const (I know, I know...), maybe the non-const constructor shouldn't exist at all?
}

TTErr TTEnvironment::createInstance(const TTSymbolPtr className, TTObjectPtr* anObject, TTValue& anArgument)
{
	TTValue		v;
	TTClassPtr	theClass;
	TTErr		err;
	TTObjectPtr	newObject = NULL;
	TTObjectPtr	oldObject = NULL;

	err = classes->lookup(className, v);
	if (!err) {
		theClass = TTClassPtr(TTPtr(v));
		if (theClass)
			err = theClass->createInstance(&newObject, anArgument);
		else
			err = kTTErrGeneric;
	}
	
	if (!err && newObject) {
		if (*anObject)
			oldObject = *anObject;<commit_msg>getClassNamesWithTags can now search for classes defined by more than just one tag.<commit_after>/* 
 * TTBlue Global Object
 * Copyright © 2008, <NAME>
 * 
 * License: This code is licensed under the terms of the "New BSD License"
 * http://creativecommons.org/licenses/BSD/
 */

#include "TTFoundation.h"
#include "TTEnvironment.h"
#include "TTClass.h"

#define thisTTClass TTEnvironment


// The environment object has one instance, which is global in scope.
TTEnvironment*	ttEnvironment = NULL;


/****************************************************************************************************/

TTEnvironment::TTEnvironment()
	: TTObject(kTTValNONE), mDebugBasic(false), mDebugMessaging(false), mSampleRate(0)
{	
	classes = new TTHash();
	tags = new TTHash();

	addAttribute(DebugBasic,		kTypeBoolean);
	addAttribute(DebugMessaging,	kTypeBoolean);
	addAttribute(SampleRate,		kTypeUInt32);

	addMessageWithArgument(getVersion);

	// can't use the SymbolCache here because it hasn't been initialized yet!
	setAttributeValue(TT("sampleRate"), 44100);
}


TTEnvironment::~TTEnvironment()
{
	// If on Windows, we need to call FreeLibrary() on all plug-ins loaded with LoadLibrary()
	// On the Mac, we may need to do the equivalent

	delete tags;
	delete classes;
}


TTErr TTEnvironment::getVersion(TTValue &value)
{
	value = TTFOUNDATION_VERSION_STRING;
	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;
}


TTErr TTEnvironment::registerClass(TTClassPtr theClass)
{
	return classes->append(theClass->name, TTPtr(theClass));
}


TTErr TTEnvironment::getAllClassNames(TTValue& returnedClassNames)
{
	return classes->getKeys(returnedClassNames);
}


TTErr TTEnvironment::getClassNamesWithTags(TTValue& classNames, const TTValue& searchTags)
{	
	TTUInt16	size = searchTags.getSize();
	TTSymbolPtr	tag;
	TTValue		tagObjects;
	TTErr		err = kTTErrGeneric;
	TTList*		classNamesForTag;
	
	classNames.clear();
	
	searchTags.get(0, &tag);
	err = tags->lookup(tag, tagObjects);
	if (err)
		return err;
	
	classNamesForTag = (TTList*)(TTPtr(tagObjects));
	
	for (TTUInt16 i=0; i<classNamesForTag->getSize(); i++) {
		TTValue classNameValue; 
		TTSymbolPtr className;
		TTValue tags;
		TTValue   aClassValue;
		TTClassPtr aClass;
		TTUInt16	success = 0;
		
		classNamesForTag->getIndex(i, classNameValue); 
		classNameValue.get(0, &className);
		
		classes->lookup(className, aClassValue);
		aClass = TTClassPtr(TTPtr(aClassValue));
		tags = aClass->tags;
		
		for (TTUInt16 j=0; j<tags.getSize(); j++){
			TTSymbolPtr someTag;
			
			tags.get(j, &someTag);
			
			for (TTUInt16 k=1; k<size; k++){
				searchTags.get(k, &tag);
				if (tag==someTag) {
					success += 1;
					break;
				}
			}
				
			if (success==size-1)
				break;
		}
		if (success==size-1) 			
			classNames.append(className);
	}
	return kTTErrNone;
}


TTErr TTEnvironment::createInstance(const TTSymbolPtr className, TTObjectPtr* anObject, const TTValue& anArgument)
{
	return createInstance(className, anObject, (TTValue&)anArgument); // throw away the const (I know, I know...), maybe the non-const constructor shouldn't exist at all?
}

TTErr TTEnvironment::createInstance(const TTSymbolPtr className, TTObjectPtr* anObject, TTValue& anArgument)
{
	TTValue		v;
	TTClassPtr	theClass;
	TTErr		err;
	TTObjectPtr	newObject = NULL;
	TTObjectPtr	oldObject = NULL;

	err = classes->lookup(className, v);
	if (!err) {
		theClass = TTClassPtr(TTPtr(v));
		if (theClass)
			err = theClass->createInstance(&newObject, anArgument);
		else
			err = kTTErrGeneric;
	}
	
	if (!err && newObject) {
		if (*anObject)
			oldObject = *anObject;
{'fraction_non_alphanumeric': 0.11950435979807252, 'fraction_numerical': 0.006241395135383203, 'mean_word_length': 4.213397129186603, 'pattern_counts': {'":': 0, '<': 11, '<?xml version=': 0, '>': 34, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '1664080', 'n_tokens_mistral': 3841, 'n_tokens_neox': 3353, 'n_words': 1076}