Material* SceneImporter<real>::ReadBlinnPhongMaterial( std::istream& stream, const std::string& name ) { BlinnPhongMaterial<real>* material = new BlinnPhongMaterial<real>; material->SetSurface( ReadColor( stream ) ); ReadNextExactToken( stream, "," ); material->SetAmbient( ReadColor( stream ) ); ReadNextExactToken( stream, "," ); material->SetDiffuse( ReadColor( stream ) ); ReadNextExactToken( stream, "," ); material->SetSpecular( ReadColor( stream ) ); ReadNextExactToken( stream, "," ); material->SetMetallic( ReadColor( stream ) ); ReadNextExactToken( stream, "," ); material->SetReflection( ReadColor( stream ) ); ReadNextExactToken( stream, "," ); material->SetRefraction( ReadColor( stream ) ); ReadNextExactToken( stream, "," ); material->SetRefractionIndex( ReadReal( stream ) ); ReadNextExactToken( stream, "," ); material->SetShininess( ReadReal( stream ) ); ReadNextExactToken( stream, "," ); material->SetWireframe( ReadBoolean( stream ) ); ReadNextExactToken( stream, "," ); material->SetTexture( GetTexture( ReadNextToken( stream ) ) ); ReadNextExactToken( stream, "," ); Texture<real>* environment = GetTexture( ReadNextToken( stream ) ); if ( environment && ( environment->GetTextureType() != Texture<real>::TypeCubeMap ) ) throw "Environment must be a CubeMap"; material->SetEnvironment( (CubeMap<real>*)environment ); material->SetName( name ); return material; }
T ReadNext(std::istream& stream, int& line) { std::string s; ReadNextToken(stream, s, line); if (s == "") throw EndOfFile(); return ParseType<T>(s); }
inline std::string ReadNext<std::string>(std::istream& stream, int& line) { std::string s; ReadNextToken(stream, s, line); if (s == "") throw EndOfFile(); return s; }
std::string SceneImporter<real>::ReadNextExactToken( std::istream& stream, const std::string& tokenToMatch ) { std::string nextToken = ReadNextToken( stream ); if ( nextToken != tokenToMatch ) throw ( std::string( "Cannot read token: " ) + tokenToMatch ).c_str(); return nextToken; }
void SceneImporter<real>::ReadVisualNodeHeader( std::istream& stream, VisualNode<real>* ioNode ) { ReadNodeHeader( stream, ioNode ); ReadNextExactToken( stream, "," ); std::string materialName = ReadNextToken( stream ); ReadNextExactToken( stream, "," ); bool isVisible = ReadBoolean( stream ); ioNode->SetMaterial( GetMaterial( materialName ) ); ioNode->SetVisible( isVisible ); }
MetaTagList* ParseMetaTagValues( Tokenizer* tokenizer ) { MetaTagDataStorage* metaTagStorage = tokenizer->metaTagData; Token* token = ReadNextToken( tokenizer ); MetaTagList* valueList = &metaTagStorage->lists[ metaTagStorage->listCount++ ]; valueList->tagCount = 0; int tokenType = token->tokenType; while( tokenType != TokenType::CloseParen && tokenType != TokenType::EndOfStream ) { if( tokenType == TokenType::StringLiteral || tokenType == TokenType::Number) { valueList->tagTokens[ valueList->tagCount++ ] = token; } token = ReadNextToken( tokenizer ); tokenType = token->tokenType; } tokenizer->tokensSinceLastMeta = 0; return valueList; }
/* ExtractWordsIntoList * -------------------- * This uses the Scanner to extract the words from the file, by looping * calling ReadNextToken until it returns false (which indicates end of * file). If the word is over the minimum length, we add it to the list * if not already present. Since we know that we are parsing HTML files, * we make a specific effort to exclude tags by checking if the token * begins with '<', and if so, we quickly skip everything up to the * closing '>'. This avoids entering HTML tag words in our list. * We use the stack for the storage for the word (again since the stack * is cheap and quick), but if we need to store the word permanently * in the list, we have to make a new heap copy, since the stack buffer * will be overwritten each time we read a new token. This copy is made * when adding the word to the list (see function AddWordIfAbsent). */ static void ExtractWordsIntoList(Scanner s, struct wordlist *list) { char word[MAX_WORD_LEN]; while (ReadNextToken(s, word, MAX_WORD_LEN)) { if (word[0] == '<') // if HTML opening tag SkipUntil(s, ">"); // skip to end of tag else if (strlen(word) >= MIN_WORD_LEN && ContainsOnlyAscii(word)) // long enough to list AddWordIfAbsent(word, list); } }
bool mcMapParser::GetNextToken (csString& str) { str.Replace (m_next_token); if (m_next_token.IsEmpty() && !m_empty_token) { return false; } ReadNextToken (m_next_token); return true; }
void SceneImporter<real>::ReadNodeHeader( std::istream& stream, Node<real>* ioNode ) { std::string parentName = ReadNextToken( stream ); ReadNextExactToken( stream, "," ); Transformation<real> transformation = ReadTransformation( stream ); Node<real>* parent = GetNode( parentName ); if ( parent ) parent->AddChild( ioNode ); ioNode->SetLocalTransformation( transformation ); }
Material* SceneImporter<real>::ReadEnvironmentMaterial( std::istream& stream, const std::string& name ) { EnvironmentMaterial<real>* material = new EnvironmentMaterial<real>; Texture<real>* cubeMap = GetTexture( ReadNextToken( stream ) ); assert( cubeMap->GetTextureType() == Texture<real>::TypeCubeMap ); material->SetTexture( cubeMap ); material->SetName( name ); return material; }
IExpression *ReadNonNumberedToken(std::list<char>& tokenList) { std::list<char>::iterator itr = tokenList.begin(); char c = (*itr); tokenList.pop_front(); IExpression *left = ReadNextToken(tokenList); IExpression *right = ReadNextToken(tokenList); if (c == '+') { return new AddExpression(left, right); } else if (c == '-') { return new SubstractExpression(left, right); } else { return NULL; } }
bool SceneImporter<real>::ReadBoolean( std::istream& stream ) { std::string token = ReadNextToken( stream ); if ( token == "true" ) return true; else if ( token == "false" ) return false; throw "Cannot read boolean"; return false; }
bool mcMapParser::Open(const char* filename) { csRef<iVFS> vfs = csQueryRegistry<iVFS>(m_object_reg); m_file = vfs->Open(filename, VFS_FILE_READ); if (!m_file.IsValid()) { ReportError("Error opening map \"%s\"", filename); return false; } m_current_line = 1; if ( !ReadNextToken(m_next_token) ) { m_next_token.Clear(); } return true; }
void SceneImporter<real>::ReadScene( std::istream& stream, Scene<real>& oScene ) { // Read the 'Scene' token ReadNextExactToken( stream, "Scene" ); ReadNextExactToken( stream, "{" ); // Read scene components std::string token = ReadNextToken( stream ); while( token != "}" ) { if ( token == "SceneInfo" ) { ReadNextExactToken( stream, "(" ); ReadSceneInfo( stream, oScene ); ReadNextExactToken( stream, ")" ); ReadNextExactToken( stream, ";" ); } else if ( token == "TurntableCamera" ) { std::string name = ReadNextToken( stream ); ReadNextExactToken( stream, "(" ); Camera<real>* camera = ReadTurntableCamera( stream, name ); ReadNextExactToken( stream, ")" ); ReadNextExactToken( stream, ";" ); oScene.AddObject( camera, true ); } else if ( token == "DirectionalLight" ) { std::string name = ReadNextToken( stream ); ReadNextExactToken( stream, "(" ); Light<real>* light = ReadDirectionalLight( stream, name ); ReadNextExactToken( stream, ")" ); ReadNextExactToken( stream, ";" ); oScene.AddObject( light, true ); } else if ( token == "PointLight" ) { std::string name = ReadNextToken( stream ); ReadNextExactToken( stream, "(" ); Light<real>* light = ReadPointLight( stream, name ); ReadNextExactToken( stream, ")" ); ReadNextExactToken( stream, ";" ); oScene.AddObject( light, true ); } else if ( token == "SpotLight" ) { std::string name = ReadNextToken( stream ); ReadNextExactToken( stream, "(" ); Light<real>* light = ReadSpotLight( stream, name ); ReadNextExactToken( stream, ")" ); ReadNextExactToken( stream, ";" ); oScene.AddObject( light, true ); } else if ( token == "BlinnPhongMaterial" ) { std::string name = ReadNextToken( stream ); ReadNextExactToken( stream, "(" ); Material* material = ReadBlinnPhongMaterial( stream, name ); ReadNextExactToken( stream, ")" ); ReadNextExactToken( stream, ";" ); oScene.AddObject( material, true ); } else if ( token == "EnvironmentMaterial" ) { std::string name = ReadNextToken( stream ); ReadNextExactToken( stream, "(" ); Material* material = ReadEnvironmentMaterial( stream, name ); ReadNextExactToken( stream, ")" ); ReadNextExactToken( stream, ";" ); oScene.AddObject( material, true ); } else if ( token == "CubeMap" ) { std::string name = ReadNextToken( stream ); ReadNextExactToken( stream, "(" ); Texture<real>* cubeMap = ReadCubeMap( stream, name ); ReadNextExactToken( stream, ")" ); ReadNextExactToken( stream, ";" ); oScene.AddObject( cubeMap, true ); } else if ( token == "Texture2D" ) { std::string name = ReadNextToken( stream ); ReadNextExactToken( stream, "(" ); Texture<real>* texture = ReadTexture2D( stream, name ); ReadNextExactToken( stream, ")" ); ReadNextExactToken( stream, ";" ); oScene.AddObject( texture, true ); } else if ( token == "Box" ) { std::string name = ReadNextToken( stream ); ReadNextExactToken( stream, "(" ); Node<real>* box = ReadBox( stream, name ); ReadNextExactToken( stream, ")" ); ReadNextExactToken( stream, ";" ); oScene.AddObject( box, true ); } else if ( token == "Cone" ) { std::string name = ReadNextToken( stream ); ReadNextExactToken( stream, "(" ); Node<real>* cone = ReadCone( stream, name ); ReadNextExactToken( stream, ")" ); ReadNextExactToken( stream, ";" ); oScene.AddObject( cone, true ); } else if ( token == "Cylinder" ) { std::string name = ReadNextToken( stream ); ReadNextExactToken( stream, "(" ); Node<real>* cylinder = ReadCylinder( stream, name ); ReadNextExactToken( stream, ")" ); ReadNextExactToken( stream, ";" ); oScene.AddObject( cylinder, true ); } else if ( token == "Plane" ) { std::string name = ReadNextToken( stream ); ReadNextExactToken( stream, "(" ); Node<real>* plane = ReadPlane( stream, name ); ReadNextExactToken( stream, ")" ); ReadNextExactToken( stream, ";" ); oScene.AddObject( plane, true ); } else if ( token == "Sphere" ) { std::string name = ReadNextToken( stream ); ReadNextExactToken( stream, "(" ); Node<real>* sphere = ReadSphere( stream, name ); ReadNextExactToken( stream, ")" ); ReadNextExactToken( stream, ";" ); oScene.AddObject( sphere, true ); } else if ( token == "TriMesh" ) { std::string name = ReadNextToken( stream ); ReadNextExactToken( stream, "(" ); Node<real>* triMesh = ReadTriMesh( stream, name ); ReadNextExactToken( stream, ")" ); ReadNextExactToken( stream, ";" ); oScene.AddObject( triMesh, true ); } else if ( token == "Node" ) { std::string name = ReadNextToken( stream ); ReadNextExactToken( stream, "(" ); Node<real>* node = ReadNode( stream, name ); ReadNextExactToken( stream, ")" ); ReadNextExactToken( stream, ";" ); oScene.AddObject( node, true ); } else { throw ( std::string( "Unknown token: " ) + token ).c_str(); } token = ReadNextToken( stream ); } // Read scene ending token ReadNextExactToken( stream, ";" ); }
void SceneImporter<real>::ReadSceneInfo( std::istream& stream, Scene<real>& oScene ) { oScene.SetBackground( ReadColor( stream ) ); ReadNextExactToken( stream, "," ); oScene.SetActiveCamera( GetCamera( ReadNextToken( stream ) ) ); ReadNextExactToken( stream, "," ); oScene.SetSceneGraphNode( GetNode( ReadNextToken( stream ) ) ); }
void main( int argc, char** argv ) { //Reminder for self if( strcmp( argv[1], "-h" ) == 0 || argc < 3 ) { printf("Format: input src file, out file path------\n\n" ); return; } char* headerName = "Meta.h"; char* cppName = "Meta.cpp"; char* fileToProcess = argv[1]; char* outputBasePath = argv[2]; int outputBasePathLen = strlen( outputBasePath ); char generatedHeaderFilePath [128] = { }; char generatedCPPFilePath [128] = { }; memcpy( &generatedHeaderFilePath[0], outputBasePath, outputBasePathLen ); memcpy( &generatedCPPFilePath[0], outputBasePath, outputBasePathLen ); memcpy( &generatedHeaderFilePath[ outputBasePathLen ], headerName, strlen( headerName ) ); memcpy( &generatedCPPFilePath[ outputBasePathLen ], cppName, strlen( cppName ) ); char* sourceFileToProcess = ReadSourceFileIntoMemoryAndNullTerminate( fileToProcess ); if( !sourceFileToProcess ) { printf("Error reading source file\n" ); return; } outFile_H = fopen( generatedHeaderFilePath, "w" ); outFile_CPP = fopen( generatedCPPFilePath, "w" ); writeConstStringToFile( "#define meta(...)\n\n", outFile_H ); writeConstStringToFile( "#if 1\n", outFile_H ); writeConstStringToFile( "#if 1\n", outFile_CPP ); int structPattern [3] = { TokenType::kwStruct, TokenType::Identifier, TokenType::OpenBrace }; PatternTrackingState structPatternTracking = { structPattern, 3, 0 }; int metaTagPattern [2] = { TokenType::MetaTag, TokenType::OpenParen }; MetaTagDataStorage metaTagStorage = { (MetaTagList*)calloc( 64, sizeof(MetaTagList) ), 0, 64, { metaTagPattern, 2, 0 } }; Tokenizer tokenizer = { }; tokenizer.at = sourceFileToProcess; tokenizer.tokenCount = 0; tokenizer.tokens = (Token*)calloc( MAX_TOKENS, sizeof(Token) ); tokenizer.tokensSinceLastMeta = 1; tokenizer.metaTagData = &metaTagStorage; StructDefinitionList sdList = { (StructDefinition*)calloc( 120, sizeof(StructDefinition) ), 120, 0 }; while( tokenizer.at[0] ) { Token* token = ReadNextToken( &tokenizer ); if( UpdatePatternTracker( &metaTagStorage.metaTagPatternTracker, token ) ) { ParseMetaTagValues( &tokenizer ); } if( UpdatePatternTracker( &structPatternTracking, token ) ) { StructDefinition structDefinition = ParseStructDefinition( &tokenizer ); //Add to list of definitions if( sdList.count < sdList.maxCount ) { sdList.definitions[ sdList.count++ ] = structDefinition; } } } writeConstStringToFile( "\n#endif", outFile_H ); writeConstStringToFile( "\n#endif", outFile_CPP ); fclose( outFile_H ); fclose( outFile_CPP ); }
StructDefinition ParseStructDefinition( Tokenizer* tokenizer ) { StructDefinition definition = { }; bool hasMetaData = tokenizer->tokensSinceLastMeta <= 3; MetaTagDataStorage* allMetaData = tokenizer->metaTagData; MetaTagList* metaData = &allMetaData->lists[ allMetaData->listCount - 1 ]; definition.typeNameToken = &tokenizer->tokens[ tokenizer->tokenCount - 2 ]; if( hasMetaData ) { definition.metaData = metaData; } else { definition.metaData = NULL; } int stdMemberPattern [3] = { TokenType::Identifier, TokenType::Identifier, TokenType::SemiColon }; PatternTrackingState stdMemberChecking = { stdMemberPattern, 3, 0 }; int ptrLevel = 0; MetaTagList* metaTags = NULL; while( tokenizer->at[0] ) { Token* token = ReadNextToken( tokenizer ); if( token->tokenType == TokenType::CloseBrace ) break; if( UpdatePatternTracker( &tokenizer->metaTagData->metaTagPatternTracker, token ) ) { metaTags = ParseMetaTagValues( tokenizer ); ptrLevel = 0; } //The idea here, is skip any indicaters of pointers, just check for the //identifier - identifier - semicolon pattern but retain how deep //the pointer reference level is //(i.e. char vs char* vs char** is 0 vs 1 vs 2, etc. ) if( token->tokenType == TokenType::Star ) { ++ptrLevel; //Skip updating the memberDef tracker continue; } //the 'Static' keyword should reset pattern tracking logic, since //members definitions only start with that, so for now we ignore such //modifiers if( token->tokenType == TokenType::kwStatic ) { stdMemberChecking.trackingIndex = 0; ptrLevel = 0; continue; } if( UpdatePatternTracker( &stdMemberChecking, token ) ) { int memberTypeTokenIndex = tokenizer->tokenCount - ptrLevel - 3; int memberNameTokenIndex = tokenizer->tokenCount - 2; definition.memberDefinitions[ definition.memberCount ] = { &tokenizer->tokens[ memberTypeTokenIndex ], &tokenizer->tokens[ memberNameTokenIndex ], metaTags, ptrLevel }; ++definition.memberCount; metaTags = NULL; } if( token->tokenType == TokenType::SemiColon ) { ptrLevel = 0; } } //Forward declare struct type writeConstStringToFile( "\nstruct ", outFile_H ); writeTokenDataToFile( definition.typeNameToken, outFile_H ); writeConstStringToFile( ";", outFile_H ); //Check for meta programming code generation flags if( hasMetaData ) { //Output introspection data, assume its functionality is needed GenerateIntrospectionCode( &definition ); char* editableMetaFlag = "Editable"; char* serializableMetaFlag = "Serializable"; char* prevMetaString = metaData->tagTokens[0]->tokenStart; if( IsStringMatch( prevMetaString, editableMetaFlag ) ) { GenerateImguiEditor( &definition ); } else if( IsStringMatch( prevMetaString, serializableMetaFlag ) ) { //GenerateSerializationCode( &definition ); } } return definition; }
IExpression *ReadToken(std::list<char>& tokenList) { return ReadNextToken(tokenList); }