• 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;
    }


  • 相关阅读:
    MSSQL 2012 密钥
    同台同时多开DELPHI2007的解决办法
    DELPHI快捷键
    Delphi编码规范
    解决Delphi 2010启动时卡死并报“displayNotification: 堆栈溢出”错误
    Test
    sched python 定时任务
    springboot2.x 整合redis
    springboot 忽略null属性值,不传递
    logback.xml 配置使用
  • 原文地址:https://www.cnblogs.com/ldxsuanfa/p/10797725.html
  • Copyright © 2020-2023  润新知