首页 > 代码库 > boost::string 例题1
boost::string 例题1
假设有一个语法正确的shader源文件,其包含若干关于uniform变量的定义。请写一个程序从某个shader源文件中提取其所有定义的uniform变量,要求记录其名称、数据类型和初始值(如果有定义),并且可以设计一个函数可以修改某个uniform变量的值。
如下表所示,程序需要提取出一共6个uniform变量,并存放如某种数据结构中,其中3个有初始值,3个没有初始值,并且用户可以修改该数据结构中指定的uniform变量的值。
uniform vec3 uLightDirectionE; uniform vec3 uMaterialAmbient = vec3(0.3, 0.3, 0.3); uniform vec3 uMaterialDiffuse = vec3(0.9, 0.7, 0.7); uniform vec3 uLightAmbient = vec3(0.6, 0.6, 0.6); uniform vec3 uLightDiffuse; uniform bool uIsFirstFrame;
void main() { } |
#include <iostream> #include <fstream> #include <map> #include <vector> #include <boost/any.hpp> #include <boost/lexical_cast.hpp> #include <boost/algorithm/string.hpp> #include <boost/utility/string_ref.hpp> template<typename T> struct any_print { void operator()(boost::any &a) { try { std::cout << *boost::any_cast<T>(&a); } catch (boost::bad_any_cast& e) { std::cout << e.what() << std::endl; } } }; ////////////////////////////////////////////////////////////////////////// template<typename T> inline void any_print_fun(boost::any& a) { any_print<T>()(a); } struct vec3 { float x; float y; float z; vec3(float vX = 0.0f, float vY = 0.0f, float vZ = 0.0f) : x(vX), y(vY), z(vZ) {} friend std::ostream& operator<<(std::ostream& os, const vec3& vData) { os << "vec3(" << vData.x << "," << vData.y << "," << vData.z << ")"; return os; } }; class CTest { public: CTest() {} ~CTest() {} //********************************************************************************* //FUNCTION: void parseText(const char* vFileName) { std::ifstream Ifs(vFileName); if (!Ifs) { std::cout << "Can not open the file " << vFileName << std::endl; exit(-1); } std::string TmpStr; while (getline(Ifs, TmpStr)) { //std::cout << TmpStr << " xxx " << std::endl; if (TmpStr.find("uniform") != std::string::npos) { processUniformString(TmpStr); } } Ifs.close(); } //********************************************************************************* //FUNCTION: void setValue(const std::string& vValueName, const boost::any& vValue) { DataType::iterator It = m_ValueData.find(vValueName); if (It == m_ValueData.end()) { std::cout << "can not find the value " << vValueName << std::endl; return; } if (It->second.second.type() != vValue.type()) { std::cout << "The type is not the same" << vValueName << std::endl; return; } m_ValueData[vValueName] = std::make_pair(It->second.first, vValue); } //********************************************************************************* //FUNCTION: void printData() { for (DataType::iterator It=m_ValueData.begin(); It != m_ValueData.end(); ++It) { std::cout << It->first << " " << It->second.first << " "; if (It->second.first == "bool") any_print_fun<bool>(It->second.second); else if (It->second.first == "int") any_print_fun<int>(It->second.second); else if (It->second.first == "float") any_print_fun<float>(It->second.second); else if (It->second.first == "vec3") any_print_fun<vec3>(It->second.second); std::cout << std::endl; } } private: typedef boost::split_iterator<std::string::const_iterator> Split_String_Itearor; typedef std::map<std::string, std::pair<std::string, boost::any>> DataType; //********************************************************************************* //FUNCTION: 只处理了int,bool, float, vec3这几种类型 void processUniformString(const std::string& vSorceString) { Split_String_Itearor Bgn, End; std::vector<std::string> StrVec; for (Bgn = boost::algorithm::make_split_iterator(vSorceString, boost::algorithm::token_finder(boost::is_any_of(" (,);"))); Bgn != End; ++Bgn) { if ((*Bgn).size()>0) StrVec.push_back(std::string((*Bgn).begin(), (*Bgn).end())); } /*for (int i=0; i<StrVec.size(); ++i) { std::cout << "[" << StrVec[i] << "]" ; }std::cout << std::endl;*/ std::string ValueTeyp = StrVec[1]; std::string Key = StrVec[2]; if (ValueTeyp == "bool") { if (StrVec.size() == 3) m_ValueData[Key] = std::make_pair(ValueTeyp, boost::any(bool(0))); else if (StrVec.size() == 5) m_ValueData[Key] = std::make_pair(ValueTeyp, boost::any(boost::lexical_cast<bool>(StrVec[4]))); } else if (ValueTeyp == "int") { if (StrVec.size() == 3) m_ValueData[Key] = std::make_pair(ValueTeyp, boost::any(int(0))); else if (StrVec.size() == 5) m_ValueData[Key] = std::make_pair(ValueTeyp, boost::any(boost::lexical_cast<int>(StrVec[4]))); } else if (ValueTeyp == "float") { if (StrVec.size() == 3) m_ValueData[Key] = std::make_pair(ValueTeyp, boost::any(float(0))); else if (StrVec.size() == 5) m_ValueData[Key] = std::make_pair(ValueTeyp, boost::any(boost::lexical_cast<float>(StrVec[4]))); } else if (ValueTeyp == "vec3") { if (StrVec.size() == 3) m_ValueData[Key] = std::make_pair(ValueTeyp, boost::any(vec3(0, 0, 0))); else if (StrVec.size() == 8) { float x = boost::lexical_cast<float>(StrVec[5]); float y = boost::lexical_cast<float>(StrVec[6]); float z = boost::lexical_cast<float>(StrVec[7]); m_ValueData[Key] = std::make_pair(ValueTeyp, boost::any(vec3(x, y, z))); } } else { std::cout << "can not process the type :" << ValueTeyp << " the value may be wrong " << std::endl; } } private: DataType m_ValueData; }; int main() { CTest Test; Test.parseText("test.txt"); Test.printData(); Test.setValue("uLightDiffuse", boost::any(vec3(10.0, 1.0, 1.0))); Test.setValue("uIsFirstFrame", boost::any(bool(1))); Test.printData(); getchar(); return 0; }
声明:以上内容来自用户投稿及互联网公开渠道收集整理发布,本网站不拥有所有权,未作人工编辑处理,也不承担相关法律责任,若内容有误或涉及侵权可进行投诉: 投诉/举报 工作人员会在5个工作日内联系你,一经查实,本站将立刻删除涉嫌侵权内容。