#include "oyagame.h"


// Object List maintenance
/*	Usage:
		ObjectList()->RegisterObject(obj);
		ObjectList()->UnregisterObject(obj);

		ObjectList()->reset();
		while(obj=ObjectList()->fetch()){
			// do something here
		}
*/
	
ObjectListClass* ObjectList(){
	static ObjectListClass obj;
	return &obj;
}

ObjectListClass::ObjectListClass(){
	ZeroMemory(this,sizeof(*this));
}
ObjectListClass::~ObjectListClass(){
	delete buff;
}
void ObjectListClass::reset(){
	next=0;
}
IDispatch* ObjectListClass::fetch(){
	if (num<=next) return NULL;
	return buff[next++];
}
void ObjectListClass::RegisterObject(IDispatch* obj){
	buff[Redim((void***)&buff,&num)]=obj;
}
void ObjectListClass::UnregisterObject(IDispatch* obj){
	for (int i=num-1;0<=i;i--) {
		if (buff[i]!=obj) continue;
		// Note: do not delete obj here although Discard functin is used in following line.
		// It will be deleted in IUnknown class.
		Discard((void**)buff,i,&num);
		return;
	}
}


// Create COM Object
IDispatch* NewComObjcet(){
	IClassFactory* ppv;
	IDispatch* ppvObject;
	DllGetClassObject(CLSID_COM,IID_IClassFactory,(LPVOID*)&ppv);
	ppv->QueryInterface(IID_IClassFactory, (void**) &ppv);
	ppv->Release();
	ppv->CreateInstance(NULL,IID_IUnknown,(void**)&ppvObject);
	ppv->Release();
	ppvObject->QueryInterface(IID_IDispatch,(void**)&ppvObject);
	ppvObject->Release();
	return ppvObject;
}
// Create Structure Object
IDispatch* NewStructureObject(STRUCTURE_TYPE what, void* pStructure /* =NULL */){
	IDispatch* pDisp;
	// Check if the same structure already exists.
	if (pStructure) {
		ObjectList()->reset();
		while (pDisp=ObjectList()->fetch()) {
			if (GetDataFromComClass(pDisp)->pStructure()!=pStructure) continue;
			pDisp->AddRef(); // Increment the number used.
			return pDisp;
		}
	}
	// Not found. Let's create new object.
	pDisp=NewComObjcet();
	GetDataFromComClass(pDisp)->SetStructure((int)what,pStructure);
	return pDisp;
}