Origin Version (Select Help-->About Origin): 7.5
Origin C has collection support for built-in objects like Columns and Pages, but not available for user classes. I have written an example below to show how to use Tree to build dynamic class collections that are typically the case for real applications. Using Tree actually have the additional advantage of being memory, as a Tree object is internally an XML object, while typical Origin C class instances consume far more memory. Also, Tree can be easily saved as XML files and also much simipler for Code Builder to view its contents during debugging
The following simple example is to show how to build a Peptide class from a collection of AminoAcidResidue class.
// define a list of IDs to check tree node is of the right type
enum {
ID_AMINOACIDERESIDUE = 1000,
ID_PEPTIDE,
ID_LAST_ENTRY};
// a base class to encapsulate a tree node so all access and interpretation of the tree node
// is centralized in this class or its derived class
class TreeNodeObject
{
protected:
// if construct new one, use this contrucctor
TreeNodeObject(int nID)
{
m_tree.ID = nID;
m_id = nID; // save for later verification
m_trNode = m_tree;
}
public:
// if construct from existing one in a tree node
TreeNodeObject(TreeNode& tr)
{
m_id = tr.ID;
m_trNode = tr;
}
public:
bool AddChild(TreeNodeObject& obj, int nChildID = 0)
{
TreeNode trN = obj.GetAsTreeNode();
if(trN.IsValid() && (0==nChildID || nChildID == trN.ID))
{
m_trNode.AddNode(trN.Clone());
return true;
}
return false;
}
TreeNode GetAsTreeNode()
{
return m_trNode;
}
bool Save(LPCSTR lpcszFilename)
{
Tree trTemp; // use a temp tree so regardless of how this class was constructed, we can save
trTemp = m_trNode;
return trTemp.Save(lpcszFilename);
}
bool Load(LPCSTR lpcszFilename)
{
if(m_tree.Load(lpcszFilename))
{
m_trNode = m_tree;
return true;
}
return false;
}
protected:
TreeNode m_trNode;
private:
Tree m_tree;
int m_id;
};
class AminoAcidResidue : public TreeNodeObject
{
public:
AminoAcidResidue(char cType) : TreeNodeObject(ID_AMINOACIDERESIDUE)
{
m_trNode.type.nVal = cType;
}
// if construct from existing one in a tree node
AminoAcidResidue(TreeNode& tr) : TreeNodeObject(tr)
{
}
public:
// other exposed functions
int GetType()
{
if(m_trNode)
return m_trNode.type.nVal;
return -1; // indicate invalid
}
};
class Peptide : public TreeNodeObject
{
public:
// if construct new one, use this contrucctor
Peptide() : TreeNodeObject(ID_PEPTIDE)
{
}
// if needed, can also add this constructor if we want to build a collection of Peptides
Peptide(TreeNode& tr) : TreeNodeObject(tr)
{
}
public:
// other exposed functions
void ShowSequence()
{
foreach(TreeNode tr in m_trNode.Children)
{
AminoAcidResidue aar(tr);
printf("%c", aar.GetType());
}
printf("\n");
}
};
void test()
{
Peptide pp;
for(int ii = 0; ii < 20; ii++)
{
int nType = rnd() > 0.5? 'G' : 'A';
AminoAcidResidue aa(nType);
pp.AddChild(aa);
}
pp.ShowSequence();
string strFile = GetAppPath() + "junk.xml";
pp.Save(strFile);
Peptide pp2;
if(pp2.Load(strFile))
pp2.ShowSequence();
}
CP
Edited by - cpyang on 12/12/2004 7:50:46 PM