My old project for strange attractors
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
This repo is archived. You can view files and clone it, but cannot push or open issues/pull-requests.
 
 
 

282 lines
7.7 KiB

#include <iostream>
#include <fstream>
#include "stf.hpp"
using namespace std;
using stfu::node;
/*! \author Nick Overdijk
* \version 1.2
* \date 2009-04-27
*
* STFU Example App
*/
void prettyprint(const string &title) {
cout
<< "\t\t-----" << title << "-----\t\t\n"
<< endl;
}
void read_examples(node &n) {
prettyprint("Reading Examples");
cout
<< "Reading a STF file in a node is trivial with the stream insertion operator, it returns whether it had success: true/false\n"
<< endl;
if ("test.stf" >> n) {
prettyprint("Outputting a node/tree");
cout << n;
cout
<< "\n\nnode::getChild() returns a node&, so we can easily output nested nodes:\n"
<< endl;
cout << n.getChild("child");
cout
<< "\n\nnode::getValue() returns a string&, so we can easily output values too:\n"
<< endl;
cout << n.getValue("imthefirst");
cout
<< "\n\nThe constness of getChild and getValue depend on the object."
<< endl;
} else {
cerr << "Couldn't read file!" << endl;
}
}
void change_examples(node &n) {
cout
<< "\t\t-----Change examples------\t\t\n"
<< endl;
if ("test.stf" >> n) {
prettyprint("Edit a value");
cout << "Before:" << endl;
cout << n;
n.value("imthefirst") = "O YEAH!";
cout << "After: " << endl;
cout << n;
prettyprint("Edit a node");
cout << "Before:" << endl;
cout << n;
n.child("child") = n;
cout << "After: " << endl;
cout << n;
prettyprint("Edit the name of a value");
cout << "Before:" << endl;
cout << n;
n.renameValue("imthefirst", "roflolmao");
cout << "After: " << endl;
cout << n;
prettyprint("Edit the name of a child");
cout << "Before:" << endl;
cout << n;
n.renameChild("child", "NEW NAMEZ");
cout << "After: " << endl;
cout << n;
} else {
cerr << "Couldn't read file!" << endl;
}
}
void create_examples(node &n) {
prettyprint("Creation examples");
node screenoptions;
node soundoptions;
if (!("screenoptions.stf" >> screenoptions && "soundoptions.stf" >> soundoptions)) {
cerr << "Couldn't read files!" << endl;
return;
}
cout << "You can merge these two tree quite easily into one tree (aka \"Adding children\"):" << endl;
cout << "Before (screenoptions):" << endl;
cout << screenoptions << endl;
cout << "Before (soundoptions):" << endl;
cout << soundoptions << endl;
//child() creates the child when it doesn't exist
n.child("Screen options") = screenoptions;
//but you can do this too
n.addChild("Sound options", soundoptions);
cout << "After (both are now children of options):" << endl;
cout << n;
prettyprint("Adding a value");
cout << "Before:" << endl;
cout << n;
//this way, NOT sure child() won't create a child (if it doesn't exist, it'll create it)
//also not sure value() won't alter a value (if the value[index] exists, it'll change that)
n.child("Screen options").value("Contrast") = "70.1";
//this way, 100% sure that getChild() won't create a child, and addValue() will always add a value
//get{Child|Value} throw an out_of_range when they can't find the {Child|Value}.
n.getChild("Screen options").addValue("Brightness") = "1.5";
cout << "After:" << endl;
cout << n;
prettyprint("Writing to a file (aka \"Saving to a file\")");
const char *filename = "ExampleProgramOutput.stf";
if (!(filename << n)) {
cerr << "Couldn't write to ";
} else {
cout << "Node succesfully saved to ";
}
cout << filename << endl << endl;
}
void remove_examples(node &n) {
prettyprint("Removal examples");
if (!("test.stf" >> n)) {
cerr << "Couldn't open file!" << endl;
}
prettyprint("Deleting a value");
cout << "Before:" << endl;
cout << n;
//remove{Child|Value} throws an out_of_range when the child/value isn't found
n.removeValue("imthefirst");
cout << "After:" << endl;
cout << n;
prettyprint("Deleting a child/node");
cout << "Before:" << endl;
cout << n;
n.removeChild("child");
cout << "After:" << endl;
cout << n;
}
void array_examples(node &n) {
prettyprint("Array Examples");
if (!("arrays.stf" >> n)) {
cerr << "Couldn't open arrays.stf!" << endl;
return;
}
prettyprint("Iterating over an array: try/catch method");
node &array = n.getChild("array");
try {
size_t i = 0;
while (true) {
//use getValue(), it throws an out_of_range when there are no more elements
cout << array.getValue(i) << endl;
i++;
}
} catch (out_of_range &e) {/*we're done! ;-)*/}
prettyprint("Iterating over an array: size() method");
size_t max = array.values.size();
for(size_t i = 0; i < max; i++){
cout << array.getValue(i) << endl;
}
prettyprint("Iterating over a 2D-array: size() method");
node &multiarray = n.getChild("2D array");
//rows are children
size_t rows = multiarray.children.size();
//each row can have a different amount of cols
size_t cols[rows];
for(size_t i = 0; i < rows; i++){
//same as with size() method above
cols[i] = multiarray.getChild(i).values.size();
//output to see it for yourself
cout << i << ',' << cols[i] << endl;
}
//so, we're done. Code could've been written in 100 ways, but this does it step by step to be clear.
for(size_t row = 0; row < rows; row++){
for(size_t col = 0; col < cols[row]; col++){
cout << multiarray.getChild(row).getValue(col) << ", ";
}
cout << "\b\b " << endl;
}
/*Arrays are simply unnamed nodes/values. Nothing more, nothing less.
You can change them like nodes/values, add them the same way, etc.
Most of the functions are overloaded so that you don't have to specify a name
These functions call their overloaded brethren with name = "" */
prettyprint("Creating an array");
cout << "Before:\n\n";
cout << n << endl;
node &newarray = n.addChild("my new array");
stringstream buf;
for(size_t i = 0; i < 10; i++){
buf << i;
newarray.addValue() = buf.str();
}
cout << "After:\n\n";
cout << n << endl;
}
int main() {
prettyprint("Welcome to the stf example app");
ifstream license("LICENSE.txt");
if (license.good()) {
string line;
while (getline(license, line)) {
cout << line << endl;
}
license.close();
} else {
cerr << "Couldn't open/read LICENSE.txt" << endl;
exit(-1);
}
cout << endl;
cout
<< "This application shows how easy it is to use STFU (Simple Tree File Utility).\n"
<< "STF is a \"new\" way to store leveled data, just as XML can do, for example.\n"
<< "The format looks like a C(++) struct, which we think is easier to read than XML.\n"
<< "Each {...} is a node, a node has other nodes and values. The file itself is the\n"
<< "(unnamed) root node.\n"
<< endl;
//create an empty node
node n;
read_examples(n);
n.clear();
change_examples(n);
n.clear();
create_examples(n);
n.clear();
remove_examples(n);
n.clear();
array_examples(n);
n.clear();
return 0;
}