Beispiel #1
0
// Loads an encapsulated block into a temporary list
INXObjList* BlockOperations::LoadBlock(INXString Info) {
	ifstream datafile(Info);
	INXObjList* encapsulated = new INXObjList;
	char type[256];
	long int id;

	// store the id value
	id = ConData::uniqueidgenerator;


	if(datafile.is_open())
	{
		int i = 0;
		while ((!datafile.eof()) && (!datafile.bad())) {
			i++;
			datafile >> type;
		//	TRACE(type);
			if (strcmp(type,"END_OF_BLOCKS")==0) break;
			else
			if (strcmp(type,"BEGIN_BLOCK")==0) {
				ConData *blob = new ConData;
				blob->Load(&datafile);
				encapsulated->AddTail((CObject*) blob);
			}
			if(i>500)
			{
			//	TRACE("hang\n");

			}

		}
	}
Beispiel #2
0
// This method gets a set of unique widget group names in a subsystem
void Project::getWidgetGroupNames(HTREEITEM hItem, set<INXString> &sWidgetGroupSet)
{
	INXString csProjectDir, csBlockFile, csWidgetGroupName;
	BlockOperations bo;
	INXObjList* encapsulated;
	INXPOSITION pos;
	ConData* blob;
	HTREEITEM hUserDefItem;
	CMainFrame* pFrame = (CMainFrame*)AfxGetApp()->m_pMainWnd;

	pProjMData->getProjectDir(csProjectDir);
	csBlockFile = csProjectDir + DEPDIR + pFrame->m_wndProjectBar.m_cProjTree.GetDEPPath(hItem) + (INXString)pFrame->m_wndProjectBar.m_cProjTree.GetItemText(hItem) + ".prg";
	encapsulated = bo.LoadBlock(csBlockFile);
			
	pos = encapsulated->GetHeadPosition();
	while(pos) {
		blob = (ConData *) (encapsulated->GetNext(pos));
		if (blob->m_iUserDefined) {
			hUserDefItem = pFrame->m_wndProjectBar.m_cProjTree.GetUserDefChildItem(blob, hItem);
			getWidgetGroupNames(hUserDefItem, sWidgetGroupSet);
		}
		else if (blob->isGuiWidget()) {
			blob->getScreenTag(csWidgetGroupName);
			sWidgetGroupSet.insert(csWidgetGroupName);
		}
	}
	bo.DeleteBlock(encapsulated);
}
Beispiel #3
0
// This method returns true if any of the Gui widgets in the paste list are in the project meta-data
// otherwise it returns false
// This method can be called recursively. For subsystems pass it the list of ConData objects for the subsystem.
// hItem is for the subsystem.
bool Project::IsPastedGuiWidgetsInProject(INXObjList* pPasteList, HTREEITEM hItem)
{
	INXPOSITION pos;
	ConData* pBlob;
	bool bRet = false;
	GuiWidget xWidget;
	INXString csBlockFile, csProjectDir;
	BlockOperations bo;
	HTREEITEM hUserDefItem;
	INXObjList* pEncapsulated;
	CMainFrame* pFrame = (CMainFrame*)AfxGetApp()->m_pMainWnd;

	pos = pPasteList->GetHeadPosition();
	while(pos) {
		pBlob = (ConData *) (pPasteList->GetNext(pos));
		if (pBlob->m_iUserDefined) {
			pProjMData->getProjectDir(csProjectDir);
			hUserDefItem = pFrame->m_wndProjectBar.m_cProjTree.GetUserDefChildItem(pBlob, hItem);
			csBlockFile = csProjectDir + DEPDIR + pFrame->m_wndProjectBar.m_cProjTree.GetDEPPath(hUserDefItem) + (INXString)pFrame->m_wndProjectBar.m_cProjTree.GetItemText(hUserDefItem) + ".prg";
			pEncapsulated = bo.LoadBlock(csBlockFile);
			if (IsPastedGuiWidgetsInProject(pEncapsulated, hUserDefItem)) {
				bRet = true;
			}
			bo.DeleteBlock(pEncapsulated);
		}
		else if (pBlob->isGuiWidget()) {
			GetWidget(pBlob, xWidget);
			if (pProjMData->guiWidgetInVec(xWidget)) {
				bRet = true;
			}
		}
	}

	return bRet;
}
Beispiel #4
0
void SODL::Copy2Flattened() {	
	ConData* blob;
	long int id = 0;
	INXPOSITION pos;
		char * type =new char[256];
		int blankcount=0;

	// Copy the condata list to the flattened list
	// save the condata list and then load it back in to flattened
	// Alternatively could use a copy constructor
	pos = flattened->GetHeadPosition();
	while(pos) {
		blob = (ConData *) (flattened->GetNext(pos));
		delete blob;
	}
	flattened->RemoveAll();
	// need to do save in view class
	//SaveProg(workDir + TEMPDIR + "temp");
	ifstream datafile(workDir + TEMPDIR + "temp");


	while ((!datafile.eof()) && (!datafile.bad()) && (blankcount<1000000)) {
		datafile >> type;
		if (strcmp(type,"END_OF_BLOCKS")==0)
			break;
		else
			if (strcmp(type,"BEGIN_BLOCK")==0) {
				blob = new ConData;
				blob->Load(&datafile);
				flattened->AddTail((INXObject*) blob);
				id = blob->identnum;
			} else {
				blankcount++;
			}
	}
	
	// set the uniqueidgenerator to the identnum of the last icon
	// This is necessary as it is possible that this value may be greater than
	// the number of icons loaded, due to icons being deleted previously. This
	// prevents icon IDs being duplicated
	// Need to add 1, since uniqueidgenerator is incremented after a new icon is
	// instantiated.
	id++;
	ConData::uniqueidgenerator = id;
	delete type;
}
Beispiel #5
0
INXObjList* EditList::LoadTemp() {	
	ConData* blob;
	long int id = 0;
	INXObjList* temp = new INXObjList;

	// Copy the condata list to the flattened list
	// save the condata list and then load it back in to flattened
	// Alternatively could use a copy constructor
	temp->RemoveAll();
	//SaveProg(workDir + TEMPDIR + "temp");
	ifstream datafile(workDir + TEMPDIR + "temp");
	char type[256];

	while ((!datafile.eof()) && (!datafile.fail())) {
		datafile >> type;
		if (strcmp(type,"END_OF_BLOCKS")==0) break;
		else
		if (strcmp(type,"BEGIN_BLOCK")==0) 
		{
			blob = new ConData;
			
			if(blob)
			{	blob->Load(&datafile);
				temp->AddTail((CObject*) blob);
				id = blob->identnum;
			}
			else
			{
				//delete blob;
				break;
			}
		}
	}
	
	// set the uniqueidgenerator to the identnum of the last icon
	// This is necessary as it is possible that this value may be greater than
	// the number of icons loaded, due to icons being deleted previously. This
	// prevents icon IDs being duplicated
	// Need to add 1, since uniqueidgenerator is incremented after a new icon is
	// instantiated.
	//id++;
	//ConData::uniqueidgenerator = id;
	return temp;
}
Beispiel #6
0
// method that adds widgets for a pasted list
void Project::addPastedGuiWidgets(HTREEITEM hItem, INXObjList* pasteList)
{
	INXPOSITION pos;
	ConData* blob;
	HTREEITEM hUserDefItem;
	CMainFrame* pFrame = (CMainFrame*)AfxGetApp()->m_pMainWnd;
	set<INXString> sWidgetGroupSet;
	vector<pair<INXString, INXString> > vWidgetGroupPairVec;
	INXString csWidgetGroupName;

	if (IsPastedGuiWidgetsInProject(pasteList, hItem)) {
		// Get a set of all the widget group names in the paste list
		pos = pasteList->GetHeadPosition();
		while(pos) {
			blob = (ConData *) (pasteList->GetNext(pos));
			if (blob->m_iUserDefined) {
				hUserDefItem = pFrame->m_wndProjectBar.m_cProjTree.GetUserDefChildItem(blob, hItem);
				getWidgetGroupNames(hUserDefItem, sWidgetGroupSet);
			}
			else if (blob->isGuiWidget()) {
				blob->getScreenTag(csWidgetGroupName);
				sWidgetGroupSet.insert(csWidgetGroupName);
			}
		}
	
		// Prompt the user to use a different group name for each group name in the set
		setWidgetGroupNames(sWidgetGroupSet, vWidgetGroupPairVec);
	}

	// Add all the Gui widgets in the paste list to the project meta-data
	pos = pasteList->GetHeadPosition();
	while(pos) {
		blob = (ConData *) (pasteList->GetNext(pos));
		if (blob->m_iUserDefined) {
			hUserDefItem = pFrame->m_wndProjectBar.m_cProjTree.GetUserDefChildItem(blob, hItem);
			updateWidgetGroupNames(hUserDefItem, vWidgetGroupPairVec);
		}
		else if (blob->isGuiWidget()) {
			updateWidgetGroup(blob, vWidgetGroupPairVec);
		}
	}
}
Beispiel #7
0
void Project::removeWidgetsInUserDefBlock(HTREEITEM hItem)
{
	INXString csProjectDir, csBlockFile;
	BlockOperations bo;
	INXObjList* encapsulated;
	INXPOSITION pos;
	ConData* blob;
	HTREEITEM hUserDefItem;
	DEP* pLoadedDEP;
	CMainFrame* pFrame = (CMainFrame*)AfxGetApp()->m_pMainWnd;

	// If DEP is in memory then need to remove widgets from this because the user may have added widgets
	// that have not been saved.
	pLoadedDEP = depIsLoaded(hItem);
	if (pLoadedDEP) {
		encapsulated = pLoadedDEP->condata;
	}
	else {
		pProjMData->getProjectDir(csProjectDir);
		csBlockFile = csProjectDir + DEPDIR + pFrame->m_wndProjectBar.m_cProjTree.GetDEPPath(hItem) + (INXString)pFrame->m_wndProjectBar.m_cProjTree.GetItemText(hItem) + ".prg";
		encapsulated = bo.LoadBlock(csBlockFile);
	}
			
	pos = encapsulated->GetHeadPosition();
	while(pos) {
		blob = (ConData *) (encapsulated->GetNext(pos));
		if (blob->m_iUserDefined) {
			hUserDefItem = pFrame->m_wndProjectBar.m_cProjTree.GetUserDefChildItem(blob, hItem);
			removeWidgetsInUserDefBlock(hUserDefItem);
		}
		else if (blob->isGuiWidget()) {
			removeGuiWidget(blob);
		}
	}

	// if the DEP is in memory don't do memory cleanup here
	if (!pLoadedDEP) {
		bo.DeleteBlock(encapsulated);
	}
}
Beispiel #8
0
// saves the copySelList
void EditList::SaveCopy(INXString Info) {
	ofstream datafile(Info);
	//put an error trap
	ConData *blob;

	datafile << "IconData" << endl;
	INXPOSITION pos;
	pos = copySelList->GetHeadPosition();
	
	if (!datafile.good()) {
		AfxMessageBox("File could not be written");
	}

	while (pos) { 		
		blob=(ConData *) (copySelList->GetNext(pos));
		datafile<<"BEGIN_BLOCK"<<endl;
		blob->Save(&datafile);
	} 

	datafile<<"END_OF_BLOCKS"<<endl;
	datafile.close();

}
Beispiel #9
0
// Loads the saved copySelList into the pasteList
INXObjList* EditList::LoadPaste(INXString Info) {
	ifstream datafile(Info);
	char type[256] = {'\0'};
	long int id;
	INXObjList* pasteList = NULL;

	datafile >> type;
	// if a file is empty don't load it
	if ((INXString)type == "") {
		return NULL;
	}
	datafile.close();

	datafile.open(Info);

	// store the id value
	id = ConData::uniqueidgenerator;

	while ((!datafile.eof()) && (!datafile.bad())) {
		datafile >> type;
		if (strcmp(type,"END_OF_BLOCKS")==0) break;
		else
		if (strcmp(type,"BEGIN_BLOCK")==0) {
			ConData *blob = new ConData;
			blob->Load(&datafile);
			if (!pasteList) {
				pasteList = new INXObjList;
			}
			pasteList->AddTail((CObject*) blob);
		}
	}

	// restore the id value, since it will have been increased when creating flattened
	ConData::uniqueidgenerator = id;

	return pasteList;
}
Beispiel #10
0
void SODL::WriteSODL(INXString sodlfile) {
	ofstream datafile(sodlfile);
	ConData *blob;
	INXPOSITION pos;
	INXString funcName;
	int funcArg = -1;
	int startFunc = 0;
	UINT i;
	UINT j;
	UINT funcInPortNum = 0, funcOutPortNum = 0, funcFinPortNum = 0;
	// *** lineID is an array of unsigned ints. However, it needs to store the value -1 if
	// a port is not connected. Could use a CArray of type int, but this gives a smaller range
	// of line IDs than using a CUIntArray. Using such an array means -1 is stored as 4294967295.
	// This value should never be reached.
	INXObjArray<unsigned int> lineType;
	CArray<long,long> lineID;
	vector<Group> vGroups;
	TagProjMetaSupportData_t tagData;
	INXString csTargetFileName = "", csMessage = "";

	if (!datafile.good()) {
		AfxMessageBox("File could not be written");
	}
	
	//AfxMessageBox( "Get ready to call Copy2Flattened" );
	// Flatten encapsulated blocks
	Copy2Flattened();

	//AfxMessageBox( "Get ready to call Flatten" );
	Flatten();
	//SaveProg2("tmp.prg");	
	// 1. Assign a unique incremental integer (within its data type) to each line
	//AfxMessageBox( "Get ready to call AssignLineIDNum" );
	AssignLineIDNum();
	// First write the number of groups to the sodl file.
	// Turn off scheduling
	//datafile << 0 << endl;

	//AfxMessageBox( "Get ready to call generate SODL proper" );
	//@todo - add the following datafile << "hashmark" << Project << endl;
/************* The following is where everything is written out. This should be a new function *******************/	
	// Write out the parameters for each group
	WriteVersionInformation(&datafile);
/************ Now add the group data **********************/
	pProject->pProjMData->getGroupVec(vGroups);
	datafile << vGroups.size() << endl;
	

	for (i=0; i<vGroups.size(); i++) {
		datafile << vGroups.at(i).ID << '\t';
		datafile << vGroups.at(i).Period << '\t';
		datafile << vGroups.at(i).Alloc << endl;
	}

	/***** Now add the programme body *******************/
	// 2. For each icon
	pos = flattened->GetHeadPosition();

	while(pos) {

		blob = (ConData *) (flattened->GetNext(pos));

		// check that a startport is connected or an internalport exists or it is the new style constant without a startport
		bool writeObject = FALSE;
		for (i=0; i<blob->startport_num; i++) {
			if (blob->startport[i]->line.exist || blob->startport[i]->initialise) {
				writeObject = true;
			}
		}

		if (blob->internalport_num > 0) {
			writeObject = true;
		}

		if (writeObject) {

			// 3. Write the tag and class name.
			datafile << "BEGIN ";
			datafile << (CString)blob->className << endl;

			// !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
			// Write the parameter string.
			// !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
			if (blob->iParamNum == 1) {
				datafile << NOPARAMS;

			} else {
				for (i=1; i<blob->iParamNum; i++) {
					// if the parameter is an empty string and there is only 1 parameter 
					// then write out "" else write out "NULL"
					if (blob->iconParam[i]->value == "_") {
						if (blob->iParamNum == 2) {
							datafile << "" << " ";
						}
						else {
							datafile << "NULL" << " ";
						}
					}
					// for string constants don't append a space
					else if (blob->m_csIconType == "const_s") {
							datafile << (CString)blob->iconParam[i]->value;
					}
					// for gui components prepend %%%_
					else if (i==1 && (blob->isGuiWidget())) {
						datafile << "%%%_" << (CString)blob->iconParam[i]->value << " ";
					}
					// for screen tags write out the target filename
					else if (blob->iconParam[i]->dataType == 4) {
						LucidErrEnum err = pProject->pProjMData->getScreenTagMetas((CString &)blob->iconParam[i]->value, tagData);
						assert (err == kErr_NoErr);
						datafile << (CString)tagData.tgtFilename << " ";
					}
					// write out target filename for data files
					else if (blob->m_csIconType.Find("file_ro") != -1 && blob->iconParam[i]->name == "File name") {
						if (pProject->pProjMData->getTargetFileNameForDataHostFileName(blob->iconParam[i]->value, csTargetFileName)) {
							csMessage.Format("File \"%s\" does not exist in the project. Your application may not work as expected.", blob->iconParam[i]->value);
							// Don't display message because IPlayer demo runs a script which relies on host filenames
							//AfxMessageBox(csMessage);
							datafile << (CString)blob->iconParam[i]->value << " ";
						}
						else {
							datafile << (CString)csTargetFileName << " ";
						}
					}
					else {
						datafile << (CString)blob->iconParam[i]->value << " ";
					}

				}

			} // (blob->iParamNum != 1)

			// !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
			// <ENDOF> Write the parameter string.
			// !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!


			datafile << endl;
			// 5. Write the tag to begin listing functions


			// !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
			// For each start trigger port
			// !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!

			for (i=0; i<blob->startport_num; i++) {

				funcInPortNum = 0; funcOutPortNum = 0, funcFinPortNum = 0;
				// if the start port is initialised SODL requires a start function
				if (blob->startport[i]->initialise) {
					startFunc = 1;
				}
				// if the start port is connected or initialised
				if (blob->startport[i]->line.exist || blob->startport[i]->initialise) {
					// 7.1 Write its function name. Is there only 1 function?
					funcName = blob->startport[i]->funcName->GetAt(0);
					datafile << (CString)funcName << '\t';
					// Write out atomic flag
					//datafile << blob->startport[i]->atomicFlag << '\t';
					datafile << 1 << '\t';
					// Write out group ID for start port
					datafile << blob->startport[i]->groupID << '\t';
					// Write out start trigger line ID
					datafile << blob->startport[i]->line.idNum << '\t';
					// 7.2 Search through all other ports to find any other references
					// to the function name
					lineID.RemoveAll();
					lineType.RemoveAll();
					for (j=0; j<blob->inputport_num; j++) {
						for (int k=0; k<blob->inputport[j]->funcName->GetSize(); k++) {
							if (blob->inputport[j]->funcName->GetAt(k) == funcName) {
								funcInPortNum++;
								funcArg = blob->inputport[j]->funcArg->GetAt(k);
								//store the line id and type in a temp. array
								// check if a line is connected
								if (blob->inputport[j]->line.exist) {
									lineID.SetAtGrow(funcArg, blob->inputport[j]->line.idNum);
								}
								else {
									lineID.SetAtGrow(funcArg, -1);		
								}
								lineType.SetAtGrow(funcArg, blob->inputport[j]->datatype);
							}
						}
					}

					// write out inputs
					datafile << funcInPortNum << " ";
					for (j=1; j<=funcInPortNum; j++) {
						datafile << convert.DataType2Char(lineType.GetAt(j)) << " ";
						// Originally wrote out a * for uncoonected ports. Now writes out -1.
						/*if (lineID.GetAt(j) == -1) {
							datafile << "* ";
						}
						else {*/
							datafile << lineID.GetAt(j) << " ";
						//}
					}

					for (j=0; j<blob->outputport_num; j++) {
						for (int k=0; k<blob->outputport[j]->funcName->GetSize(); k++) {
							if (blob->outputport[j]->funcName->GetAt(k) == funcName) {
								funcOutPortNum++;
								funcArg = blob->outputport[j]->funcArg->GetAt(k);
								//store the line id and type in a temp. array
								// check if a line is connected
								if (blob->outputport[j]->lineID > -1) {
									lineID.SetAtGrow(funcArg, blob->outputport[j]->lineID);
								}
								else {
									lineID.SetAtGrow(funcArg, -1);
								}
								lineType.SetAtGrow(funcArg, blob->outputport[j]->datatype);
							}
						}
					}
					
					// write out outputs
					datafile << '\t' << funcOutPortNum << " ";
					for (j=(funcInPortNum + 1); j<=(funcInPortNum + funcOutPortNum); j++) {
						datafile << convert.DataType2Char(lineType.GetAt(j)) << " ";
						datafile << lineID.GetAt(j) << " ";
					}
					
					for (j=0; j<blob->finishport_num; j++) {
						for (int k=0; k<blob->finishport[j]->funcName->GetSize(); k++) {
							if (blob->finishport[j]->funcName->GetAt(k) == funcName) {
								funcFinPortNum++;
								funcArg = blob->finishport[j]->funcArg->GetAt(k);
								//store the line id and type in a temp. array
								// check if a line is connected
								if (blob->finishport[j]->lineID > -1) {
									lineID.SetAtGrow(funcArg, blob->finishport[j]->lineID);
								}
								else {
									lineID.SetAtGrow(funcArg, -1);
								}
							}
						}
					}
					// write out finish ports
					datafile << '\t' << funcFinPortNum << " ";
					// Only write out the finish line numbers if there is at least one connection
					if (funcFinPortNum > 0) {
						for (int m=(funcInPortNum + funcOutPortNum + 1); m<lineID.GetSize(); m++) {
							datafile << lineID.GetAt(m) << " ";
						}
					}
					
					datafile << endl;
				}
			}
			// !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
			// <ENDOF> For each start trigger port
			// !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!



			// !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
			// For each internal trigger port
			// !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!

			for (i=0; i<blob->internalport_num; i++) {
				funcInPortNum = 0; funcOutPortNum = 0, funcFinPortNum = 0;
				// ***REVISIT. Write its function name. Is there only 1 function?
				funcName = blob->internalport[i]->funcName->GetAt(0);
				datafile << (CString)funcName << '\t';
				// Write out atomic flag
				//datafile << blob->internalport[i]->atomicFlag << '\t';
				datafile << 1 << '\t';
				// Write out group ID for internal port
				datafile << blob->internalport[i]->groupID << '\t';
				// The internal trigger does not have a line ID so write out 0 if it is the
				// Start function and -1 otherwise.
				if (funcName == START) {
					datafile << 0 << '\t';
				}
				else {
					datafile << -1 << '\t';
				}
				// 7.2 Search through all other ports to find any other references
				// to the function name
				lineID.RemoveAll();
				lineType.RemoveAll();
				for (j=0; j<blob->inputport_num; j++) {
					for (int k=0; k<blob->inputport[j]->funcName->GetSize(); k++) {
						if (blob->inputport[j]->funcName->GetAt(k) == funcName) {
							funcInPortNum++;
							funcArg = blob->inputport[j]->funcArg->GetAt(k);
							//store the line id and type in a temp. array
							// check if a line is connected
							if (blob->inputport[j]->line.exist) {
								lineID.SetAtGrow(funcArg, blob->inputport[j]->line.idNum);
							}
							else {
								lineID.SetAtGrow(funcArg, -1);		
							}
								lineType.SetAtGrow(funcArg, blob->inputport[j]->datatype);
						}
					}
				}
				// write out inputs
				datafile << funcInPortNum << " ";
				for (j=1; j<=funcInPortNum; j++) {
					datafile << convert.DataType2Char(lineType.GetAt(j)) << " ";
					datafile << lineID.GetAt(j) << " ";
				}

				for (j=0; j<blob->outputport_num; j++) {
					for (int k=0; k<blob->outputport[j]->funcName->GetSize(); k++) {
						if (blob->outputport[j]->funcName->GetAt(k) == funcName) {
							funcOutPortNum++;
							funcArg = blob->outputport[j]->funcArg->GetAt(k);
							//store the line id and type in a temp. array
							// check if a line is connected
							if (blob->outputport[j]->lineID > -1) {
								lineID.SetAtGrow(funcArg, blob->outputport[j]->lineID);
							}
							else {
								lineID.SetAtGrow(funcArg, -1);
							}
							lineType.SetAtGrow(funcArg, blob->outputport[j]->datatype);
						}
					}
				}
					
				// write out outputs
				datafile << '\t' << funcOutPortNum << " ";
				for (j=(funcInPortNum + 1); j<=(funcInPortNum + funcOutPortNum); j++) {
					int tmp = lineType.GetAt(j);
					datafile << convert.DataType2Char(lineType.GetAt(j)) << " ";
					datafile << lineID.GetAt(j) << " ";
				}
					
				for (j=0; j<blob->finishport_num; j++) {
					for (int k=0; k<blob->finishport[j]->funcName->GetSize(); k++) {
						if (blob->finishport[j]->funcName->GetAt(k) == funcName) {
							funcFinPortNum++;
							funcArg = blob->finishport[j]->funcArg->GetAt(k);
							//store the line id and type in a temp. array
							// check if a line is connected
							if (blob->finishport[j]->lineID > -1) {
									lineID.SetAtGrow(funcArg, blob->finishport[j]->lineID);
							}
							else {
								lineID.SetAtGrow(funcArg, -1);
							}
						}
					}
				}
				// write out finish ports
				datafile << '\t' << funcFinPortNum << " ";
				for (int m=(funcInPortNum + funcOutPortNum + 1); m<lineID.GetSize(); m++) {
					datafile << lineID.GetAt(m) << " ";
				}		
				datafile << endl;
			}
			// !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
			// <ENDOF> For each internal trigger port
			// !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!


			// 8. Write out end of icon tags
			datafile << "END" << endl;
			//datafile << endl;

		} //if (writeObject)
	}
	// Always Write out start function -- even if no other functions need initialising.
	//if (startFunc) {
		datafile << "BEGIN Start" << endl;
		datafile << "*" << endl;
		datafile << "Run_Start	1	1	0	0 	0 	1 1" << endl;
		datafile << "END" << endl;
	//}
	datafile.close();
}