2011-01-23 112 views
0

那么......有没有任何标准库在提升创建一些脚本/ xmls读者,将该脚本映射到对象通过一些rool?如何使用Boost C++创建脚本解释器

+0

我的主要观点 - 我有很多以不同顺序启动的类会产生不同的结果。我需要一些东西来按照希望的顺序开始tham。应用程序编译完成后。 – Rella 2011-01-23 17:28:53

回答

1

如果你想让你的类以特定的顺序启动,我认为脚本语言已被过度杀死。你需要的是一个地形排序。

你所需要的

升压有一个topographical sort。你也可以阅读一个非常易读的C#实现,如果boost库对你来说有点多,那么你应该很容易转到C++。那可以找到here

什么基本上,你所提供的排序算法与你的类,然后添加它们的依赖(排序算法认为这些为顶点和边)。一旦你完成,你应用算法。你得出的是什么对象取决于什么。

当我有一堆需要加载的子系统时,我使用了这种确切的方法,其中一些子系统依赖于其他子系统,一些子系统没有。子系统的数量是任意的,并且由于程序的插件性质,在编译时是未知的。

我为每个子系统分配一个唯一的标识符(顺便说一句,使用boost::uuid),每个子系统列出了依赖它的其他子系统的标识符。这被送到分拣机,我的初始化命令出现在后端。 (注意:此时,我不知道boost库存在,这是我自己实现的,它基于来自上面提供的链接的C#代码)。

(http://support.microsoft.com/kb/)为了帮助您,
 // class TopologicalSorter 
     template<typename TYPE> class TopologicalSorter 
     { 
     private: 

      std::vector<TYPE>    m_Vertices; 
      std::vector<std::vector<TYPE> > m_Matrix; 
      std::vector<TYPE>    m_Sorted; 
      TYPE       m_nNumVerts; 
      TYPE       m_nSize; 

      // private helpers 
      int noSuccessors() 
      { 
       bool isEdge; 
       for(TYPE row(0); row < m_nNumVerts; row++) 
       { 
        isEdge = false; 
        for(TYPE col(0); col < m_nNumVerts; col++) 
        { 
         if(m_Matrix[row][col] > 0) // edge to another? 
         { 
          isEdge = true; 
          break; 
         }; 
        }; 

        if(!isEdge) 
         return(row); 
       }; 

       return(-1); // nope! 
      }; // eo noSuccessors 

      void deleteVertex(TYPE _vertex) 
      { 
       if(_vertex != m_nNumVerts - 1) 
       { 
        for(TYPE j(_vertex); j < m_nNumVerts - 1; j++) 
         m_Vertices[j] = m_Vertices[j + 1]; 

        for(TYPE row(_vertex); row < m_nNumVerts - 1; row++) 
         moveRowUp(row, m_nNumVerts); 

        for(TYPE col(_vertex); col < m_nNumVerts - 1; col++) 
         moveColLeft(col, m_nNumVerts - 1); 
       }; 

       --m_nNumVerts; 
      }; // eo deleteVertex 

      void moveRowUp(TYPE _row, TYPE _length) 
      { 
       for(TYPE col(0); col < _length; col++) 
        m_Matrix[_row][col] = m_Matrix[_row + 1][col]; 
      }; // eo moveRowUp 

      void moveColLeft(TYPE _col, TYPE _length) 
      { 
       for(TYPE row(0); row < _length; row++) 
        m_Matrix[row][ _col] = m_Matrix[row][_col + 1]; 
      }; // eo moveColLeft 

     public: 
      TopologicalSorter(TYPE _size) : m_nNumVerts(0) 
              , m_Vertices(_size) 
              , m_Matrix(_size) 
              , m_Sorted(_size) 
              , m_nSize(_size) 
      { 
       assert(_size > 0); 
       for(TYPE i(0); i < m_nSize; ++i) 
       { 
        for(TYPE j(0); j < m_nSize; ++j) 
         m_Matrix[i].push_back(0); 
       }; 
      }; // eo ctor 


      ~TopologicalSorter(){}; 


      // public methods 


      TYPE addVertex(TYPE _vertex) 
      { 
       m_Vertices[m_nNumVerts++] = _vertex; 
       return(m_nNumVerts - 1); 
      }; // eo addVertex 

      void addEdge(TYPE _start, TYPE _end) 
      { 
       m_Matrix[_start][_end] = 1; 
      }; // eo addEdge 

      std::vector<TYPE> sort() 
      { 
       int currVertex; 
       while(m_nNumVerts) 
       { 
        currVertex = noSuccessors(); 
        coreAssert(currVertex != -1, "Graph has cycles"); 

        m_Sorted[m_nNumVerts - 1] = m_Vertices[currVertex]; 
        deleteVertex(currVertex); 
       }; // eo while(m_nNumVerts) 

       return(std::move(m_Sorted)); 
      }; // eo sort 

     }; // eo class TopologicalSorter 

现在,这是怎么这与加载和初始化子系统使用(UUID是只为boost::uuids::uuid一个typedef

// create a topological sorter: 
    utility::TopologicalSorter<ManagerVector_sz> sorter(m_Managers.size()); 
    std::map<Uuid, ManagerVector_sz> indexes; 

    // add vertices and edges 
    for(ManagerVector_sz i(0); i < m_Managers.size(); ++i) 
     indexes.insert(std::pair<Uuid, ManagerVector_sz>(m_Managers[i]->getUuid(), sorter.addVertex(i))); 

    for(ManagerVector_sz i(0); i < m_Managers.size(); ++i) 
    { 
     if(m_Managers[i]->getDependencies().size()) 
     { 
      for(ManagerVector_sz j(0); j < m_Managers[i]->getDependencies().size(); ++j) 
       sorter.addEdge(i, indexes[m_Managers[i]->getDependencies()[j]]); 
     }; 
    }; 

    // get the order in which we should initialise 
    m_SortedIndexes = sorter.sort(); 

    // and initialise 
    ManagerVector* mv(&m_Managers); 
    std::for_each(m_SortedIndexes.rbegin(), 
        m_SortedIndexes.rend(), 
        [&mv](int i){mv->at(i)->initialise();}); 

希望这有助于避免了没有必要的脚本!

2

Boost Spirit库应该允许您相当容易地定义配置格式。