Set<WebPage*> SearchEngine::generateT(const Set<WebPage*>& S) const {
    Set<WebPage*> T(S);

    // For each entry
    for(Set<WebPage*>::const_iterator it = S.begin(); it != S.end(); ++it)    {
        // Add all its outgoing links
        Set<WebPage*> outgoing = (*it)->allOutgoingLinks();
        for(Set<WebPage*>::iterator oit = outgoing.begin(); oit != outgoing.end(); ++oit) {
            T.insert(*oit);
        }

        // Add all its incoming links
        Set<WebPage*> incoming = (*it)->allIncomingLinks();
        for(Set<WebPage*>::iterator iit = incoming.begin(); iit != incoming.end(); ++iit)   {
            T.insert(*iit);
        }
    }
    return T;
}
TIMED_TEST(LexiconTests, compareTest_Lexicon, TEST_TIMEOUT_DEFAULT) {
    Lexicon lex;
    lex.add("a");
    lex.add("ab");
    lex.add("bc");
    Lexicon lex2;
    lex2.add("a");
    lex2.add("b");
    lex2.add("c");
    Lexicon lex3;
    compareTestHelper(lex, lex2, "Lexicon", /* compareTo */ -1);
    compareTestHelper(lex2, lex, "Lexicon", /* compareTo */ 1);
    compareTestHelper(lex, lex, "Lexicon", /* compareTo */ 0);

    Set<Lexicon> slex {lex, lex2, lex3};
    assertEqualsString("slex", "{{}, {\"a\", \"ab\", \"bc\"}, {\"a\", \"b\", \"c\"}}", slex.toString());
}
Exemple #3
0
Bool set_add(Set s, Type t) {
	if(s->root == NULL) {
		Node newNode = (Node) malloc(sizeof(struct strNode));
		newNode->data  = t;
		newNode->left  = NULL;
		newNode->right = NULL;
		s->size = 1;
		return TRUE;
	}

	Node current = s->root;
	Bool found = FALSE;
	Bool added = FALSE;
	while(!found && !added) {
		int c = s->compareFunc(t, current->data);  // t < current->data
		if(c == 0) {
			found = TRUE;
		} else if(c < 0) {
			if(current->left == NULL) {
				Node newNode = (Node) malloc(sizeof(struct strNode));
				newNode->data  = t;
				newNode->left  = NULL;
				newNode->right = NULL;
				current->left = newNode;
				added = TRUE;
			} else {
				current = current->left;
			}
		} else {  // c > 0
			if(current->right == NULL) {
				Node newNode = (Node) malloc(sizeof(struct strNode));
				newNode->data  = t;
				newNode->left  = NULL;
				newNode->right = NULL;
				current->right = newNode;
				added = TRUE;
			} else {
				current = current->right;
			}
		}
	}

	if(added) s->size ++;
	return added;
}
Set<MultipleDeriv>  
EvaluatableExpr::setDivision(const Set<MultipleDeriv>& a,
  const Set<MultipleDeriv>& b) const
{
  Set<MultipleDeriv> rtn;
  for (Set<MultipleDeriv>::const_iterator i=a.begin(); i!=a.end(); i++)
  {
    for (Set<MultipleDeriv>::const_iterator j=b.begin(); j!=b.end(); j++)
    {
      MultipleDeriv c = i->factorOutDeriv(*j);
      if (c.size() != 0) rtn.put(c);
      if (*i == *j) rtn.put(MultipleDeriv());
    }
  }
  return rtn;
}
Exemple #5
0
int Physics2DDirectSpaceStateSW::intersect_shape(const RID& p_shape, const Matrix32& p_xform,const Vector2& p_motion,float p_margin,ShapeResult *r_results,int p_result_max,const Set<RID>& p_exclude,uint32_t p_layer_mask,uint32_t p_object_type_mask) {

    if (p_result_max<=0)
        return 0;

    Shape2DSW *shape = static_cast<Physics2DServerSW*>(Physics2DServer::get_singleton())->shape_owner.get(p_shape);
    ERR_FAIL_COND_V(!shape,0);

    Rect2 aabb = p_xform.xform(shape->get_aabb());
    aabb=aabb.grow(p_margin);

    int amount = space->broadphase->cull_aabb(aabb,space->intersection_query_results,Space2DSW::INTERSECTION_QUERY_MAX,space->intersection_query_subindex_results);

    bool collided=false;
    int cc=0;

    for(int i=0; i<amount; i++) {

        if (!_match_object_type_query(space->intersection_query_results[i],p_layer_mask,p_object_type_mask))
            continue;

        if (p_exclude.has( space->intersection_query_results[i]->get_self()))
            continue;


        const CollisionObject2DSW *col_obj=space->intersection_query_results[i];
        int shape_idx=space->intersection_query_subindex_results[i];

        if (!CollisionSolver2DSW::solve(shape,p_xform,p_motion,col_obj->get_shape(shape_idx),col_obj->get_transform() * col_obj->get_shape_transform(shape_idx),Vector2(),NULL,NULL,NULL,p_margin))
            continue;

        r_results[cc].collider_id=col_obj->get_instance_id();
        if (r_results[cc].collider_id!=0)
            r_results[cc].collider=ObjectDB::get_instance(r_results[cc].collider_id);
        r_results[cc].rid=col_obj->get_self();
        r_results[cc].shape=shape_idx;
        r_results[cc].metadata=col_obj->get_shape_metadata(shape_idx);

        cc++;

    }

    return cc;

}
 Int rec( const Int& k, const Int& rem, const Int& x ) {
   if ( N - k <= std::min(in->N, Int(5)) ) {
     if ( ! S.count(x) )
       return 0;
   }
   if ( x < 0 || x - rem > 0 )
     return 0;
   if ( k >= N ) {
     return x == 0 ? 1 : 0;
   }
   if ( memo[k].count(x) )
     return memo[k][x];
   Int& res = memo[k][x];
   res = 0;
   res += rec(k + 1, rem - A[k], x);
   res += rec(k + 1, rem - A[k], x - A[k]);
   return res;
 }
  bool Set::intersectSets(Set& peerSet)
  {
      int i;      
      std::string tempValue;
      int len = this->getLength();
      for (i= len -1; i >= 0; i--)
      {
          tempValue = this->getValue(i);
	  if( peerSet.findItem(tempValue) == -1)
	  {
	      this->deleteItem(tempValue);
	  }
      }
      
      this->print();
      std::cout << "Intersetction Completed!" << std::endl;
      return true; 
  }
Exemple #8
0
static void _find_identifiers_in_block(GDCompletionContext& context,int p_line,bool p_only_functions,Set<String>& result) {

	if (p_only_functions)
		return;

	for (int i=0;i<context.block->statements.size();i++) {

		if (context.block->statements[i]->line>p_line)
			continue;


		if (context.block->statements[i]->type==GDParser::BlockNode::TYPE_LOCAL_VAR) {

			const GDParser::LocalVarNode *lv=static_cast<const GDParser::LocalVarNode *>(context.block->statements[i]);
			result.insert(lv->name.operator String());
		}
	}
}
void SceneSaver::SaveScene(Scene *scene, const FilePath &fileName, Set<String> &errorLog)
{
    DVASSERT(0 == texturesForSave.size())
    
    String relativeFilename = fileName.GetRelativePathname(sceneUtils.dataSourceFolder);
    sceneUtils.workingFolder = fileName.GetDirectory().GetRelativePathname(sceneUtils.dataSourceFolder);
    
    FileSystem::Instance()->CreateDirectory(sceneUtils.dataFolder + sceneUtils.workingFolder, true);

    scene->Update(0.1f);

    FilePath oldPath = SceneValidator::Instance()->SetPathForChecking(sceneUtils.dataSourceFolder);
    SceneValidator::Instance()->ValidateScene(scene, fileName, errorLog);

    texturesForSave.clear();
    SceneHelper::EnumerateTextures(scene, texturesForSave);

    CopyTextures(scene, errorLog);
	ReleaseTextures();

	Landscape *landscape = FindLandscape(scene);
    if (landscape)
    {
        sceneUtils.CopyFile(landscape->GetHeightmapPathname(), errorLog);
    }

	CopyReferencedObject(scene, errorLog);
	CopyEffects(scene, errorLog);
	CopyCustomColorTexture(scene, fileName.GetDirectory(), errorLog);

    //save scene to new place
    FilePath tempSceneName = sceneUtils.dataSourceFolder + relativeFilename;
    tempSceneName.ReplaceExtension(".saved.sc2");
    
    scene->Save(tempSceneName, true);

    bool moved = FileSystem::Instance()->MoveFile(tempSceneName, sceneUtils.dataFolder + relativeFilename, true);
	if(!moved)
	{
		errorLog.insert(Format("Can't move file %s", fileName.GetAbsolutePathname().c_str()));
	}
    
    SceneValidator::Instance()->SetPathForChecking(oldPath);
}
Exemple #10
0
Provenance::Set* Provenance::ancestors(const Set& roots)
{
    Set open = roots;
    Set* closed = new Set();
    while (!open.empty()) {
	const Provenance* n = *(open.begin());
	std::pair<CommandChronicle::ParentVector::const_iterator,
	          CommandChronicle::ParentVector::const_iterator>
	    pr = n->parents();
	for (CommandChronicle::ParentVector::const_iterator it = pr.first;
	     it != pr.second; ++it) {
	    const Provenance* prov = *it;
	    if (closed->count(prov) == 0)
		open.insert(prov);
	}
	open.erase(n);
	closed->insert(n);
    }
    return closed;
}
Exemple #11
0
void unite(const Set& s1, const Set& s2, Set& result)
{
    Set A = s1;
    Set B = s2;
    result = A;
         
    for (int a = 0; a < A.size(); a++)
    {
        ItemType value;
        A.get(a, value);
        if (B.contains(value))
        {
            
            B.erase(value);    //if set B contains a value in A, then erase it from B
        }
    }
    for (int c = 0; c < B.size(); c++)  
    {
        ItemType value;
        B.get(c, value);
        result.insert(value);       //now insert every value in B into result (these don't contain any DUPLICATES from A)
    }
    
}
Exemple #12
0
int PhysicsDirectSpaceStateSW::intersect_point(const Vector3 &p_point, ShapeResult *r_results, int p_result_max, const Set<RID> &p_exclude, uint32_t p_collision_mask) {

	ERR_FAIL_COND_V(space->locked, false);
	int amount = space->broadphase->cull_point(p_point, space->intersection_query_results, SpaceSW::INTERSECTION_QUERY_MAX, space->intersection_query_subindex_results);
	int cc = 0;

	//Transform ai = p_xform.affine_inverse();

	for (int i = 0; i < amount; i++) {

		if (cc >= p_result_max)
			break;

		if (!_can_collide_with(space->intersection_query_results[i], p_collision_mask))
			continue;

		//area can't be picked by ray (default)

		if (p_exclude.has(space->intersection_query_results[i]->get_self()))
			continue;

		const CollisionObjectSW *col_obj = space->intersection_query_results[i];
		int shape_idx = space->intersection_query_subindex_results[i];

		Transform inv_xform = col_obj->get_transform() * col_obj->get_shape_transform(shape_idx);
		inv_xform.affine_invert();

		if (!col_obj->get_shape(shape_idx)->intersect_point(inv_xform.xform(p_point)))
			continue;

		r_results[cc].collider_id = col_obj->get_instance_id();
		if (r_results[cc].collider_id != 0)
			r_results[cc].collider = ObjectDB::get_instance(r_results[cc].collider_id);
		else
			r_results[cc].collider = NULL;
		r_results[cc].rid = col_obj->get_self();
		r_results[cc].shape = shape_idx;

		cc++;
	}

	return cc;
}
Exemple #13
0
int main(void) {
	Set<int> a = { 1, 2, 3 };
	Set<int> b = { 2, 4, 6 };

	print("a: %v", &a);
	print("b: %v", &b);

	print("a ismember 3: %s", a.ismember(3) ? "OK" : "FAIL");

	Set<int> c;
	c = a | b;
	print("union: %v", &c);

	c = a & b;
	print("intersection: %v", &c);

	c = a - b;
	print("difference: %v", &c);

	c = a ^ b;
	print("symmetric difference: %v", &c);

	c = { 1, 2, 3 };
	print("eq: %s", (a == c) ? "OK" : "FAIL");
	c |= b;
	print("lt: %s", (a < c) ? "OK" : "FAIL");
	print("le: %s", (a <= c) ? "OK" : "FAIL");

	c = { 4, 5, 6 };
	print("disjoint: %s", a.isdisjoint(c) ? "OK" : "FAIL");

	a.remove(2);
	print("a.remove(2): %v", &a);

	while(len(b) > 0) {
		print("b.pop(): %d", b.pop());
	}

	del(a);
	print("del(a): %v len: %zu", &a, len(a));
	print("a.empty(): %s", a.empty() ? "OK" : "FAIL");
	print("operator!(): %s", (!a) ? "OK" : "FAIL");

	return 0;
}
Set<MultipleDeriv> 
EvaluatableExpr::setProduct(const Set<MultipleDeriv>& a,
  const Set<MultipleDeriv>& b) const
{
  Set<MultipleDeriv> rtn;
  for (Set<MultipleDeriv>::const_iterator i=a.begin(); i!=a.end(); i++)
  {
    for (Set<MultipleDeriv>::const_iterator j=b.begin(); j!=b.end(); j++)
    {
      rtn.put(i->product(*j));
    }
  }
  return rtn;
}
Exemple #15
0
void Theme::get_type_list(List<StringName> *p_list) const {

    Set<StringName> types;

    const StringName *key=NULL;

    while((key=icon_map.next(key))) {

        types.insert(*key);
    }

    key=NULL;

    while((key=style_map.next(key))) {

        types.insert(*key);
    }

    key=NULL;

    while((key=font_map.next(key))) {

        types.insert(*key);
    }

    key=NULL;

    while((key=color_map.next(key))) {

        types.insert(*key);
    }

    key=NULL;

    while((key=constant_map.next(key))) {

        types.insert(*key);
    }


    for(Set<StringName>::Element *E=types.front(); E; E=E->next()) {

        p_list->push_back(E->get());
    }
}
Exemple #16
0
//helper function for computerWordSearch()
void Boggle::searchWord2(int row, int col, string word, bool visited[4][4], Set<string>& result) {
    if (visited[row][col])
        return;
    word += getLetter(row, col);
    if (!dict.containsPrefix(word))
        return;
    if (checkWord(word))
        result.add(word);

    visited[row][col] = true;

    //cycle through every letter
    for (int r = 0; r < 8; r++) {
        int oi = row + di[r], oj = col + dj[r];
        if (on_board(oi, oj))
            searchWord2(oi, oj, word, visited, result);
    }

    visited[row][col] = false;
}
Exemple #17
0
static bool validateNeedsInclude(const Dep *source, const Dep *header, Set<uint32_t> &seen)
{
    if (!seen.insert(header->fileId)) {
        // error() << "already seen" << Location::path(source->fileId);
        return false;
    }
    if (source->references.contains(header->fileId)) {
        // error() << "Got ref" << Location::path(header->fileId);
        return true;
    }
    for (const auto &child : header->includes) {
        // error() << "Checking child" << Location::path(child.second->fileId);
        if (validateNeedsInclude(source, static_cast<const Dep*>(child.second), seen)) {
            return true;
        }
    }

    // error() << "Checking" << Location::path(source->fileId) << "doesn't seem to need" << Location::path(header->fileId) << depth;
    return false;
}
Exemple #18
0
void dirtyUsr(UsrMap &map, const Set<uint32_t> &dirty)
{
    UsrMap::iterator it = map.begin();
    while (it != map.end()) {
        Set<Location> &locations = it->second;
        Set<Location>::iterator i = locations.begin();
        while (i != locations.end()) {
            if (dirty.contains(i->fileId())) {
                locations.erase(i++);
            } else {
                ++i;
            }
        }
        if (locations.isEmpty()) {
            map.erase(it++);
        } else {
            ++it;
        }
    }
}
Exemple #19
0
void Set::contains(Set theSet, int num)
{
    //store the set in a temp
    vector<int> tempSet=theSet.getSet();

    cout << "Searching the set for " << num << "..." << endl;

    //loop through the set looking for the number
    for(auto number : tempSet)
    {
        if(number==num)
        {
            cout << "Found the number you were looking for -> " << num << endl;
        }
        else
        {
            cout << "Couldn't find the number you were searching for" << endl;
        }
    }
}
Exemple #20
0
void PrintGraph(Set<nodeT *> &graph) {
    cout << endl;
    cout << endl;
    Set<nodeT *>::Iterator itr = graph.iterator();
    
    while (itr.hasNext()) {
        nodeT *n = itr.next();
        cout << n->name << ":" << n->x << ":" << n->y << endl;
        cout << "ARCS:" << endl;
        
        Vector<arcT *>::Iterator itrArc = n->links.iterator();
        
        while (itrArc.hasNext()) {
            arcT *arc = itrArc.next();
            cout << arc->distance << ":" << arc->start->name << ":"
            << arc->end->name << endl;
        }
        cout << endl;
    }
}
Exemple #21
0
int main() {

    Set<int> a;
    ///set<int> a;

    a.insert(3);
    a.insert(4);
    a.insert(5);
    a.insert(4);
    a.insert(3);
    a.insert(2);
    a.insert(6);
    printSet(a);

    a.erase( a.begin() );
    printSet(a);

return 0;
}
Exemple #22
0
public List<String> wordBreak(String s, Set<String> dict) {
    List<String> list=new ArrayList<String>();

    if(map.containsKey(s)) return map.get(s);

    for(int i=1; i<=s.length();i++){
        String left=s.substring(0,i);
        String right=s.substring(i);
        if(dict.contains(left)){
            List<String> a=wordBreak(right, dict);
            for(String b:a){
                list.add(left+" "+b);
            }
            if(right.length()==0) list.add(left);
        }

    }

    map.put(s, list);
    return list;
}
void BVH::trace(RayBuffer& rays, RayStats* stats) const
{
    for(S32 i=0;i<rays.getSize();i++)
    {
        Ray ray = rays.getRayForSlot(i);    // takes a local copy
        RayResult& result = rays.getMutableResultForSlot(i);

        result.clear();

        currentTreelet = -2;
        uniqueTreelets.clear();

        if(stats)
        {
            stats->platform = m_platform;
            stats->numRays++;
        }

        traceRecursive(m_root, ray,result,rays.getNeedClosestHit(), stats);
    }
}
Exemple #24
0
bool findWord(string sofar, pointT position, Grid<char> &board, Lexicon &lex, Vector<pointT> deltas, Set<string> &acc) { 
	
	if( validBoggle(sofar, lex) ) { 
		acc.add(sofar); 
		return true; 
	}
	
	Vector<pointT> next = successors(position, board, deltas); 
	
	for (int i = 0; i < next.size(); i++) { 
		pointT nextPt = next[i]; 
		char ch = board.getAt(nextPt.row, nextPt.col);
		string prefix = sofar + ch; 
		if ( lex.containsPrefix( prefix ) ) { 
			Grid<char> copy = board; 
			copy.setAt(nextPt.row, nextPt.col, 'f'); 
			if ( findWord(prefix, nextPt, copy, lex, deltas, acc) ) return true; 
		}
	}
	return false; 
}
Exemple #25
0
void TestTools::set_initializerList()
{
    Set<int> set = {1, 1, 2, 3, 4, 5};
    QCOMPARE(set.count(), 5);
    QVERIFY(set.contains(1));
    QVERIFY(set.contains(2));
    QVERIFY(set.contains(3));
    QVERIFY(set.contains(4));
    QVERIFY(set.contains(5));

    // check _which_ of the equal elements gets inserted (in the QHash/QMap case, it's the last):
    const Set<IdentityTracker> set2 = {{1, 0}, {1, 1}, {2, 2}, {3, 3}, {4, 4}, {5, 5}};
    QCOMPARE(set2.count(), 5);
    const int dummy = -1;
    const IdentityTracker searchKey = {1, dummy};
    QCOMPARE(set2.find(searchKey)->id, 0);

    Set<int> emptySet{};
    QVERIFY(emptySet.isEmpty());

    Set<int> set3{{}, {}, {}};
    QVERIFY(!set3.isEmpty());
}
void SceneSaver::ResaveFile(const String &fileName, Set<String> &errorLog)
{
    DVASSERT(0);    //TODO: check save

	Logger::Info("[SceneSaver::ResaveFile] %s", fileName.c_str());

	FilePath sc2Filename = sceneUtils.dataSourceFolder + fileName;

	//Load scene with *.sc2
	Scene *scene = new Scene();
	Entity *rootNode = scene->GetRootNode(sc2Filename);
	if(rootNode)
	{
		int32 count = rootNode->GetChildrenCount();

		Vector<Entity*> tempV;
		tempV.reserve((count));
		for(int32 i = 0; i < count; ++i)
		{
			tempV.push_back(rootNode->GetChild(i));
		}
		for(int32 i = 0; i < count; ++i)
		{
			scene->AddNode(tempV[i]);
		}

		scene->Update(0.f);

		SceneFileV2 * outFile = new SceneFileV2();
		outFile->EnableDebugLog(false);
		outFile->SaveScene(sc2Filename, scene);
		SafeRelease(outFile);
	}
	else
	{
		errorLog.insert(Format("[SceneSaver::ResaveFile] Can't open file %s", fileName.c_str()));
	}

	SafeRelease(scene);
}
Exemple #27
0
Set operator&(const Set& a, const Set& b)
{
   Set intersect;
   Set::Iterator it_a = a.begin();
   while( it_a != a.end() ){
      Set::Iterator it_b = b.begin();
      while( it_b != b.end( ) )
      {
         if( *it_a == *it_b )
            intersect.insert( *it_a );
         it_b++;
      }
      it_a++;
    }
   return intersect;
}
Exemple #28
0
  void initMesh(int nc, int p){

    graph.clear();
    set.clear();
    initial.clear();
    constraint.clear();

    numCir = nc;
    poly = p;

    Circle cir = CXY(1);
    for (int i = 0; i < numCir; ++i){
      VT radius = 1 + 2.0 * (float)i/numCir;
      Circle tcir = cir.dilate( log( radius ) );
      for (int j = 0; j < poly; ++j ){
          VT theta = TWOPI * j / poly;
          theta += (rtheta * i * PI/poly);
          Point p = Round::pnt_cir(tcir, theta );
          set.add( p );
      }
    }

    bool bSwitch = false;
    for (int j = 0; j < poly; ++j){
      int a = j;
      int b = ( j < poly - 1 ) ? j + 1 : 0;
      int c = j + poly;
      //cout << a << " " << b << " " << c << endl;
      initial.add( Rigid2( set[c], set[a], set[b], bSwitch ) );
      bSwitch = !bSwitch;
    }

     bSwitch = false;

    for (int i = 1; i < numCir-1; ++i){
      for (int j = 0; j < poly; ++j ){
        int a = i * poly + j;
        int b = a + poly;
        int c = j < poly -1 ? a + 1 : i * poly;
        int d = j < poly -1 ? a - poly + 1 : (i-1)*poly;
        constraint.add( Rigid3( set[b], set[a], set[d], set[c], bSwitch ) );
        bSwitch = !bSwitch;

      }
    }

  }
Set<MultiSet<int> > ProductExpr::internalFindQ_W(int order, const EvalContext& context) const
{
  Tabs tab0(0);
  int verb = context.setupVerbosity();
  SUNDANCE_MSG2(verb, tab0 << "ProdExpr::internalFindQ_W(" << order << ")");

  Set<MultiSet<int> > rtn;
  if (order > 2) return rtn;

  if (order==2)
  {
    rtn.put(makeMultiSet<int>(0,1));
    return rtn;
  }

  Tabs tab1;
  SUNDANCE_MSG3(verb, tab1 << "calling findW(0) for left");
  const Set<MultipleDeriv>& wLeft 
    = leftEvaluatable()->findW(0, context);
  SUNDANCE_MSG3(verb, tab1 << "found wLeft(0)=" << wLeft);

  SUNDANCE_MSG3(verb, tab1 << "calling findW(0) for right");
  const Set<MultipleDeriv>& wRight
    = rightEvaluatable()->findW(0, context);
  SUNDANCE_MSG3(verb, tab1 << "found wRight(0)=" << wRight);
  
  if (order==0)
  {
    if (wLeft.size() > 0)
    {
      rtn.put(makeMultiSet<int>(0));
    }
    if (wRight.size() > 0)
    {
      rtn.put(makeMultiSet<int>(1));
    }
  }
  
  if (order==1)
  {
    if (wLeft.size() > 0) rtn.put(makeMultiSet<int>(1));
    if (wRight.size() > 0) rtn.put(makeMultiSet<int>(0));
  }
  
  SUNDANCE_MSG2(verb, tab0 << "Q_W[" << order << "]=" << rtn);
  return rtn;
}
Exemple #30
0
void System::LoadObject(const DataNode &node, Set<Planet> &planets, int parent)
{
	int index = objects.size();
	objects.push_back(StellarObject());
	StellarObject &object = objects.back();
	object.parent = parent;
	
	bool isAdded = (node.Token(0) == "add");
	if(node.Size() >= 2 + isAdded)
	{
		Planet *planet = planets.Get(node.Token(1 + isAdded));
		object.planet = planet;
		planet->SetSystem(this);
	}
	
	for(const DataNode &child : node)
	{
		if(child.Token(0) == "sprite" && child.Size() >= 2)
		{
			object.LoadSprite(child);
			object.isStar = !child.Token(1).compare(0, 5, "star/");
			if(!object.isStar)
			{
				object.isStation = !child.Token(1).compare(0, 14, "planet/station");
				object.isMoon = (!object.isStation && parent >= 0 && !objects[parent].IsStar());
			}
		}
		else if(child.Token(0) == "distance" && child.Size() >= 2)
			object.distance = child.Value(1);
		else if(child.Token(0) == "period" && child.Size() >= 2)
			object.speed = 360. / child.Value(1);
		else if(child.Token(0) == "offset" && child.Size() >= 2)
			object.offset = child.Value(1);
		else if(child.Token(0) == "object")
			LoadObject(child, planets, index);
		else
			child.PrintTrace("Skipping unrecognized attribute:");
	}
}