diff --git a/src/SConscript b/src/SConscript index 22f8bd8..ce89d16 100644 --- a/src/SConscript +++ b/src/SConscript @@ -21,6 +21,7 @@ files = [ 'object.cc', 'object_sphere.cc', 'object_plane.cc', + 'reader_yaml.cc', 'scene.cc', 'writer_png.cc', ] @@ -30,7 +31,7 @@ for f in files: objs.append(env.Object(f)) lib = env.Library('charles', files) -prog = env.Program('charles', ['charles.cc'], LIBS=[lib, 'png']) +prog = env.Program('charles', ['charles.cc'], LIBS=[lib, 'png', 'yaml']) env.Alias('charles', prog) env.Default('charles') diff --git a/src/reader.hh b/src/reader.hh new file mode 100644 index 0000000..b235953 --- /dev/null +++ b/src/reader.hh @@ -0,0 +1,32 @@ +/* reader.hh + * vim: set tw=80: + * Eryn Wells + */ +/** + * Interface for an input file reader. + */ + + +#ifndef __READER_HH__ +#define __READER_HH__ + +#include "scene.h" + + +struct Reader +{ + Reader(Scene& scene) + : mScene(scene) + { } + + virtual + ~Reader() + { } + + virtual ssize_t read_file(const std::string& filename) = 0; + +protected: + Scene& mScene; +}; + +#endif /* __READER_HH__ */ diff --git a/src/reader_yaml.cc b/src/reader_yaml.cc new file mode 100644 index 0000000..7e485b4 --- /dev/null +++ b/src/reader_yaml.cc @@ -0,0 +1,208 @@ +/* reader_yaml.cc + * vim: set tw=80: + * Eryn Wells + */ +/** + * An input file reader for YAML files. + */ + +#include +#include + +#include "yaml.h" + +#include "reader_yaml.hh" + + +struct Parser; +typedef std::stack ParserStack; + + +struct Parser +{ + Parser(Scene& scene, + ParserStack& parsers) + : mScene(scene), + mParsers(parsers) + { } + + virtual + ~Parser() + { } + + virtual void + handle_start_event(yaml_event_t& event) + { } + + virtual void + handle_end_event(yaml_event_t& event) + { } + + virtual void + handle_event(yaml_event_t& event) + { } + +protected: + Scene& mScene; + ParserStack &mParsers; + +private: + Parser(); + Parser(Parser& other); +}; + + +struct DocumentParser + : public Parser +{ + DocumentParser(Scene& scene, + ParserStack& parsers) + : Parser(scene, parsers) + { + printf("DocumentParser\n"); + } + + ~DocumentParser() + { + printf("~DocumentParser\n"); + } + + void + handle_event(yaml_event_t& event) + { + + } +}; + + +struct StreamParser + : public Parser +{ + StreamParser(Scene& scene, + ParserStack& parsers) + : Parser(scene, parsers) + { + printf("StreamParser\n"); + } + + ~StreamParser() + { + printf("~StreamParser\n"); + } + + void + handle_start_event(yaml_event_t& event) + { + printf("Stream start\n"); + } + + void + handle_end_event(yaml_event_t& event) + { + switch (event.type) { + case YAML_DOCUMENT_START_EVENT: + mParsers.push(new DocumentParser(mScene, mParsers)); + mParsers.top()->handle_start_event(event); + break; + default: + /* TODO: Error out, somehow. */ + break; + } + } + + void + handle_event(yaml_event_t& event) + { } + +private: + StreamParser(); + StreamParser(StreamParser& other); +}; + + +struct SceneDocumentParser +{ + +}; + + +ssize_t +YAMLReader::read_file(const std::string& filename) +{ + + FILE *yaml_infile = fopen(filename.c_str(), "rb"); + if (!yaml_infile) { + fprintf(stderr, "Couldn't open file: %s\n", filename.c_str()); + return -1; + } + + yaml_parser_t parser; + yaml_parser_initialize(&parser); + + printf("Reading file: %s\n", filename.c_str()); + yaml_parser_set_input_file(&parser, yaml_infile); + + ParserStack parsers; + bool success = true; + bool done = false; + yaml_event_t event; + while (!done) { + if (!yaml_parser_parse(&parser, &event)) { + success = false; + goto error; + } + + switch (event.type) { + case YAML_NO_EVENT: + printf("YAML_NO_EVENT\n"); + break; + + case YAML_STREAM_START_EVENT: + printf("YAML_STREAM_START_EVENT\n"); + parsers.push(new StreamParser(mScene, parsers)); + parsers.top()->handle_start_event(event); + break; + case YAML_STREAM_END_EVENT: + printf("YAML_STREAM_END_EVENT\n"); + parsers.top()->handle_end_event(event); + delete parsers.top(); + parsers.pop(); + break; + + case YAML_DOCUMENT_START_EVENT: + printf("YAML_DOCUMENT_START_EVENT\n"); + break; + case YAML_DOCUMENT_END_EVENT: + printf("YAML_DOCUMENT_END_EVENT\n"); + break; + + case YAML_ALIAS_EVENT: + printf("YAML_ALIAS_EVENT\n"); + break; + case YAML_SCALAR_EVENT: + printf("YAML_SCALAR_EVENT\n"); + break; + + case YAML_SEQUENCE_START_EVENT: + printf("YAML_SEQUENCE_START_EVENT\n"); + break; + case YAML_SEQUENCE_END_EVENT: + printf("YAML_SEQUENCE_END_EVENT\n"); + break; + + case YAML_MAPPING_START_EVENT: + printf("YAML_MAPPING_START_EVENT\n"); + break; + case YAML_MAPPING_END_EVENT: + printf("YAML_MAPPING_END_EVENT\n"); + break; + } + + done = (event.type == YAML_STREAM_END_EVENT); + yaml_event_delete(&event); + } + +error: + yaml_parser_delete(&parser); + return success; +} diff --git a/src/reader_yaml.hh b/src/reader_yaml.hh new file mode 100644 index 0000000..ecf4c09 --- /dev/null +++ b/src/reader_yaml.hh @@ -0,0 +1,29 @@ +/* reader_yaml.hh + * vim: set tw=80: + * Eryn Wells + */ +/** + * An input file reader for YAML files. + */ + + +#ifndef __READER_YAML_HH__ +#define __READER_YAML_HH__ + +#include "reader.hh" +#include "scene.h" + + +struct YAMLReader + : public Reader +{ + YAMLReader(Scene& scene) + : Reader(scene) + { } + + ~YAMLReader() { } + + ssize_t read_file(const std::string& filename); +}; + +#endif /* __READER_YAML_HH__ */