2011-01-23 43 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庫應該允許您相當容易地定義配置格式。