len3d

  博客园  :: 首页  :: 新随笔  :: 联系 :: 订阅 订阅  :: 管理
//---------------------------------------------------------------------------------------------
Parser::Parser()
{
}

//---------------------------------------------------------------------------------------------
Parser::~Parser()
{
}

//---------------------------------------------------------------------------------------------
int Parser::Call(int id, std::vector<std::string> & args)
{
    
switch( id ) {
    
case 1:        return g_Renderer->world_begin();
    
case 2:        return g_Renderer->world_end();
    
case 3:        return g_Renderer->frame_begin();
    
case 4:        return g_Renderer->frame_end();
    
case 5:        return g_Renderer->group_begin( AsString(args[0]) );
    
case 6:        return g_Renderer->group_end();
    
case 7:        return g_Renderer->init_instance( AsString(args[0]) );
    
case 8:        return g_Renderer->object_begin( AsString(args[0]), AsString(args[1]) );
    
case 9:        return g_Renderer->object_end();
    
case 10:    return g_Renderer->motion_begin();
    
case 11:    return g_Renderer->motion_end();
    
case 12:    return g_Renderer->vertex( AsFloat(args[0]), AsFloat(args[1]), AsFloat(args[2]),
                                            AsFloat(args[
3]), AsFloat(args[4]) );
    
case 13:    return g_Renderer->vertex( AsInteger(args[0]) );
    
case 14:    return g_Renderer->normal( AsFloat(args[0]), AsFloat(args[1]), AsFloat(args[2]) );
    
case 15:    return g_Renderer->primitive_begin( AsString(args[0]) );
    
case 16:    return g_Renderer->primitive_end();
    
case 17:    return g_Renderer->texture( AsString(args[0]), AsString(args[1]) );
    
case 18:    return g_Renderer->translate( AsFloat(args[0]), AsFloat(args[1]), AsFloat(args[2]) );
    
case 19:    return g_Renderer->rotate( AsFloat(args[0]), AsFloat(args[1]), AsFloat(args[2]) );
    
case 20:    return g_Renderer->scale( AsFloat(args[0]), AsFloat(args[1]), AsFloat(args[2]) );
    
case 21:    return g_Renderer->material_begin( AsString(args[0]) );
    
case 22:    return g_Renderer->material_end();
    
case 23:    return g_Renderer->light_begin( AsString(args[0]), AsString(args[1]) );
    
case 24:    return g_Renderer->light_end();
    
case 25:    return g_Renderer->select_group( AsString(args[0]) );
    
case 26:    return g_Renderer->delete_group( AsString(args[0]) );
    
case 27:    return g_Renderer->select_object( AsString(args[0]) );
    
case 28:    return g_Renderer->delete_object( AsString(args[0]) );
    
case 29:    return g_Renderer->select_material( AsString(args[0]) );
    
case 30:    return g_Renderer->delete_material( AsString(args[0]) );
    
case 31:    return g_Renderer->select_light( AsString(args[0]) );
    
case 32:    return g_Renderer->select_light( AsString(args[0]) );
    
case 33:    return g_Renderer->select_end();
    
default:
        
return FALSE;
    }

}

//---------------------------------------------------------------------------------------------
int Parser::SetOption(int id, std::string & value)
{
    
if( id >= FLOAT_OPTION_BEGIN && id <= FLOAT_OPTION_END )
        
return g_Renderer->set_option( id, AsFloat(value) );
    
else if( id >= INTEGER_OPTION_BEGIN && id <= INTEGER_OPTION_END )
        
return g_Renderer->set_option( id, AsInteger(value) );
    
else if( id >= STRING_OPTION_BEGIN && id <= STRING_OPTION_END )
        
return g_Renderer->set_option( id, AsString(value) );
    
else if( id >= BOOLEAN_OPTION_BEGIN && id <= BOOLEAN_OPTION_END )
        
return g_Renderer->set_option( id, AsBoolean(value) );
    
else {
        std::vector
<float>    vec;
        AsVector( value, vec );
        
switch( vec.size() ) {
        
case 2:
            
return g_Renderer->set_option( id, vec[0], vec[1] );
        
case 3:
            
return g_Renderer->set_option( id, vec[0], vec[1], vec[2] );
        
case 4:
            
return g_Renderer->set_option( id, vec[0], vec[1], vec[2], vec[3] );
        
default:
            
return FALSE;
        }

    }

}

//---------------------------------------------------------------------------------------------
int Parser::SetParameter(const char *name, std::string & value)
{
    
int    ret = TRUE;
    
if( (ret = g_Renderer->set_parameter( name, AsFloat(value) )) != TRUE ) {
        
if( (ret = g_Renderer->set_parameter( name, AsInteger(value) )) != TRUE ) {
            
if( (ret = g_Renderer->set_parameter( name, AsBoolean(value) )) != TRUE ) {
                
if( (ret = g_Renderer->set_parameter( name, AsString(value) )) != TRUE ) {
                    std::vector
<float>    vec;
                    AsVector( value, vec );
                    
switch( vec.size() ) {
                    
case 2:
                        ret 
= g_Renderer->set_parameter( name, vec[0], vec[1] );
                        
break;
                    
case 3:
                        ret 
= g_Renderer->set_parameter( name, vec[0], vec[1], vec[2] );
                        
break;
                    
case 4:
                        ret 
= g_Renderer->set_parameter( name, vec[0], vec[1], vec[2], vec[3] );
                        
break;
                    
default:
                        
return FALSE;
                    }

                }

            }

        }

    }

    
return ret;
}

//---------------------------------------------------------------------------------------------
int Parser::Load(const char *name)
{
    std::ifstream    file( name );
    
if!file )
        
return FALSE;
    std::
string        cstr;
    size_t            pos 
= 0;
    
int                ret = TRUE;
    keepOnLoading 
= true;
    
while( keepOnLoading && ReadString( file, cstr ) ) {
        g_Window
->print( cstr.c_str() );
        
if( (pos = cstr.find( KEYWORD_COMMENT )) != std::string::npos )
            cstr 
= cstr.substr( 0, pos );
        TrimLeft( cstr );
        TrimRight( cstr );
        
if( cstr.empty() )
            
continue;
        cstr 
+= KEYWORD_NEWLINE;
        std::vector
<std::string>    args;
        size_t                        len;
        
for(int i = 0; i < FUNCTION_AMOUNT; ++i) {
            len 
= strlen( SDL[i].name );
            
if( cstr.substr( 0, len ) == SDL[i].name ) {
                
if( i == 20 /* material */ && g_Renderer->objectBegin )
                    
break;
                
else if( i == 11 /* vertex */ && g_Renderer->primitiveBegin )
                    
continue;
                
if( cstr[len] == KEYWORD_ARGUMENT_BEGIN1 ||
                    cstr[len] 
== KEYWORD_ARGUMENT_BEGIN2 ||
                    cstr[len] 
== KEYWORD_NEWLINE ) {
                    std::
string        para, sect;
                    para 
= cstr.substr( len + 1, cstr.length() - len - 1 );
                    
for(int j = 0; j < (int) para.length(); ++j) {
                        
if( para[j] != KEYWORD_ARGUMENT_DELIMITER &&
                            para[j] 
!= KEYWORD_ARGUMENT_END )
                            sect 
+= para[j];
                        
else {
                            args.push_back( sect );
                            sect.clear();
                        }

                    }

                    
if!args.empty() ) {
                        
for(int j = 0; j < (int) args.size() - 1++j) {
                            TrimLeft( args[j] );
                            TrimRight( args[j] );
                        }

                        TrimLeft( args.back() );
                    }

                    
if( args.size() == SDL[i].noArg ) {
                        
if( (ret = Call( i + 1, args )) != TRUE )
                            
goto OPTIONS;
                        
else
                            
goto END_OF_LOOP;
                    }

                }

            }

        }

OPTIONS:
        
for(int i = 0; i < OPTION_AMOUNT; ++i) {
            len 
= strlen( OptMap[i].name );
            
if( cstr.substr( 0, len ) == OptMap[i].name ) {
                
for(int j = (int) len; j < (int) cstr.length(); ++j) {
                    
if( cstr[j] != KEYWORD_SPACE1 &&
                        cstr[j] 
!= KEYWORD_SPACE2 &&
                        cstr[j] 
!= KEYWORD_SPACE3 &&
                        cstr[j] 
!= KEYWORD_SET1    &&
                        cstr[j] 
!= KEYWORD_SET2 ) {
                        
goto END_OF_LOOP;
                    }
 else if( cstr[j] == KEYWORD_SET1 || cstr[j] == KEYWORD_SET2 ) {
                        std::
string        value;
                        value 
= cstr.substr( j + 1, cstr.length() - j - 1 );
                        TrimLeft( value );
                        
if( (ret = SetOption( OptMap[i].id, value )) != TRUE )
                            
goto PARAMETERS;
                        
else
                            
goto END_OF_LOOP;
                    }

                }

            }

        }

PARAMETERS:
        
if( (pos = cstr.find( KEYWORD_CUSTOM_SET )) != std::string::npos ) {
            std::
string        value;
            value 
= cstr.substr( pos + 1, cstr.length() - pos - 1 );
            cstr 
= cstr.substr( 0, pos );
            TrimLeft( cstr );
            TrimRight( cstr );
            TrimLeft( value );
            TrimRight( value );
            
if( (ret = SetParameter( cstr.c_str(), value )) != TRUE ) {
                
return ret;
            }

        }
 else
            
return FALSE;
END_OF_LOOP:;
    }
;
    
return TRUE;
}

//---------------------------------------------------------------------------------------------
bool Parser::ReadString(std::ifstream & file, std::string & str)
{
    str.clear();
    
char    ch;
    
while( file.get(ch) ) {
        
if( ch == KEYWORD_NEWLINE )
            
return true;
        str 
+= ch;
    }
;
    
return false;
}

//---------------------------------------------------------------------------------------------
void Parser::TrimLeft(std::string & str)
{
    
for(int i = 0; i < (int) str.length(); ++i) {
        
if( str[i] != KEYWORD_SPACE1 && str[i] != KEYWORD_SPACE2 && str[i] != KEYWORD_SPACE3 ) {
            str.erase( 
0, i );
            
return;
        }

    }

    str.clear();
}

//---------------------------------------------------------------------------------------------
void Parser::TrimRight(std::string & str)
{
    
for(int i = (int) str.length() - 1; i >= 0--i) {
        
if( str[i] != KEYWORD_SPACE1 && str[i] != KEYWORD_SPACE2 && str[i] != KEYWORD_SPACE3 ) {
            str.erase( i 
+ 1, str.length() - i - 1 );
            
return;
        }

    }

    str.clear();
}

//---------------------------------------------------------------------------------------------
float Parser::AsFloat(const std::string & str)
{
    
return (float) atof( str.c_str() );
}

//---------------------------------------------------------------------------------------------
int Parser::AsInteger(const std::string & str)
{
    
return atoi( str.c_str() );
}

//---------------------------------------------------------------------------------------------
bool Parser::AsBoolean(std::string & str)
{
    
if( str[str.length() - 1== KEYWORD_NEWLINE )
        str.erase( str.end() 
- 1 );
    
if( str == KEYWORD_TRUE1 || str == KEYWORD_TRUE2 )
        
return true;
    
else
        
return false;
}

//---------------------------------------------------------------------------------------------
const char *Parser::AsString(std::string & str)
{
    
if( str[str.length() - 1== KEYWORD_NEWLINE )
        str.erase( str.end() 
- 1 );
    
if( str[0== KEYWORD_STRING_BEGIN && str[str.length() - 1== KEYWORD_STRING_END ) {
        str.erase( str.begin() );
        str.erase( str.end() 
- 1 );
        
return str.c_str();
    }
 else
        
return NULL;
}

//---------------------------------------------------------------------------------------------
bool Parser::AsVector(std::string & str, std::vector<float> & vec)
{
    
if( str[str.length() - 1== KEYWORD_NEWLINE )
        str.erase( str.end() 
- 1 );
    
if( str[0== KEYWORD_VECTOR_BEGIN && str[str.length() - 1== KEYWORD_VECTOR_END ) {
        std::
string        sect;
        
for(int i = 1; i < (int) str.length(); ++i) {
            
if( str[i] != KEYWORD_VECTOR_DELIMITER &&
                str[i] 
!= KEYWORD_VECTOR_END )
                sect 
+= str[i];
            
else {
                vec.push_back( (
float) atof( sect.c_str() ) );
                sect.clear();
            }

        }

        
return true;
    }
 else
        
return false;
}
posted on 2006-03-22 14:55  Len3d  阅读(470)  评论(0编辑  收藏  举报