<commit_before>#include "BooleanCircuit.h"

extern "C" {
#include "provsql_utils.h"
#include <unistd.h>
#include <math.h>
}

#include <cassert>
#include <string>
#include <fstream>
#include <sstream>
#include <cstdlib>
#include <iostream>

using namespace std;

// Has to be redefined because of name hiding
unsigned BooleanCircuit::setGate(const uuid &u, BooleanGate type)
{
 unsigned id = Circuit::setGate(u, type);
  if(type == BooleanGate::IN)
    inputs.insert(id);
  return id;
}

unsigned BooleanCircuit::setGate(const uuid &u, BooleanGate type, double p)
{
  unsigned id = setGate(u, type);
  prob[id] = p;
  return id;
}

unsigned BooleanCircuit::addGate()
{
  unsigned id=Circuit::addGate();
  prob.push_back(1);
  return id;
}

std::string BooleanCircuit::toString(unsigned g) const
{
  std::string op;
  string result;

  switch(gates[g]) {
    case BooleanGate::IN:
      if(prob[g]==0.) {
        return "⊥";
      } else if(prob[g]==1.) {
        return "⊤";
      } else {
        return to_string(g)+"["+to_string(prob[g])+"]";
      }
    case BooleanGate::NOT:
      op="¬";
      break;
    case BooleanGate::UNDETERMINED:
      op="?";
      break;
    case BooleanGate::AND:
      op="∧";
      break;
    case BooleanGate::OR:
      op="∨";
      break;
  }

  if(wires[g].empty()) {
    if(gates[g]==BooleanGate::AND)
      return "⊤";
    else if(gates[g]==BooleanGate::OR)
      return "⊥";
    else return op;
  }

  for(auto s: wires[g]) {
    if(gates[g]==BooleanGate::NOT)
      result = op;
    else if(!result.empty())
      result+=" "+op+" ";
    result+=toString(s);
  }

  return "("+result+")";
}

double BooleanCircuit::dDNNFEvaluation(unsigned g) const
{
  switch(gates[g]) {
    case BooleanGate::IN:
      return prob[g];
    case BooleanGate::NOT:
      return 1-prob[g];
    case BooleanGate::AND:
      break;
    case BooleanGate::OR:
      break;
    case BooleanGate::UNDETERMINED:
      throw CircuitException("Incorrect gate type");
  }

  double result=(gates[g]==BooleanGate::AND?1:0);
  for(auto s: wires[g]) {
    double d = dDNNFEvaluation(s);
    if(gates[g]==BooleanGate::AND)
      result*=d;
    else
      result+=d;
  }

  return result;
}

bool BooleanCircuit::evaluate(unsigned g, const unordered_set<unsigned> &sampled) const
{
  bool disjunction=false;

  switch(gates[g]) {
    case BooleanGate::IN:
      return sampled.find(g)!=sampled.end();
    case BooleanGate::NOT:
      return !evaluate(*(wires[g].begin()), sampled);
    case BooleanGate::AND:
      disjunction = false;
      break;
    case BooleanGate::OR:
      disjunction = true;
      break;
    case BooleanGate::UNDETERMINED:
      throw CircuitException("Incorrect gate type");
  }

  for(auto s: wires[g]) {
    bool e = evaluate(s, sampled);
    if(disjunction && e)
      return true;
    if(!disjunction && !e)
      return false;
  }

  if(disjunction)
    return false;
  else
    return true;
}

double BooleanCircuit::monteCarlo(unsigned g, unsigned samples) const
{
  unsigned success=0;

  for(unsigned i=0; i<samples; ++i) {
    unordered_set<unsigned> sampled;
    for(unsigned in : inputs) {
      if(rand() *1. / RAND_MAX < prob[in]) {
        sampled.insert(in);
      }
    }

    if(evaluate(g, sampled))
      ++success;

    if(provsql_interrupted)
      throw CircuitException("Interrupted after "+to_string(i+1)+" samples");
  }

  return success*1./samples;
}

double BooleanCircuit::possibleWorlds(unsigned g) const
{
  if(inputs.size()>=8*sizeof(unsigned long long))
    throw CircuitException("Too many possible worlds to iterate over");

  unsigned long long nb=(1<<inputs.size());
  double totalp=0.;

  for(unsigned long long i=0; i < nb; ++i) {
    unordered_set<unsigned> s;
    double p = 1;

    unsigned j=0;
    for(unsigned in : inputs) {
      if(i & (1 << j)) {
        s.insert(in);
        p*=prob[in];
      } else {
        p*=1-prob[in];
      }
      ++j;
    }

    if(evaluate(g, s))
      totalp+=p;

    if(provsql_interrupted)
      throw CircuitException("Interrupted");
  }

  return totalp;
}

std::string BooleanCircuit::Tseytin(unsigned g, bool display_prob=false) const {
  vector<vector<int>> clauses;

  // Tseytin transformation
  for(unsigned i=0; i<gates.size(); ++i) {
    switch(gates[i]) {
      case BooleanGate::AND:
        {
          int id=i+1;
          vector<int> c = {id};
          for(int s: wires[i]) {
            clauses.push_back({-id, s+1});
            c.push_back(-s-1);
          }
          clauses.push_back(c);
          break;
        }

      case BooleanGate::OR:
        {
          int id=i+1;
          vector<int> c = {-id};
          for(int s: wires[i]) {
            clauses.push_back({id, -s-1});
            c.push_back(s+1);
          }
          clauses.push_back(c);
        }
        break;

      case BooleanGate::NOT:
        {
          int id=i+1;
          int s=*wires[i].begin();
          clauses.push_back({-id,-s-1});
          clauses.push_back({id,s+1});
          break;
        }

      case BooleanGate::IN:
      case BooleanGate::UNDETERMINED:
        ;
    }
  }
  clauses.push_back({(int)g+1});

  int fd;
  char cfilename[] = "/tmp/provsqlXXXXXX";
  fd = mkstemp(cfilename);
  close(fd);

  string filename=cfilename;
  ofstream ofs(filename.c_str());

  ofs << "p cnf " << gates.size() << " " << clauses.size() << "\n";

  for(unsigned i=0;i<clauses.size();++i) {
    for(int x : clauses[i]) {
      ofs << x << " ";
    }
    ofs << "0\n";
  }
  if(display_prob) {
    for(unsigned in : inputs) {
      ofs << "w " << (in+1) << " " << to_string(prob[in]) << "\n";
      ofs << "w -" << (in+1) << " " << to_string(1. - prob[in]) << "\n";
    }
  }

  ofs.close();

  return filename;
}

double BooleanCircuit::compilation(unsigned g, string compiler) const {
  string filename=BooleanCircuit::Tseytin(g);
  string outfilename=filename+".nnf";

//  throw CircuitException("filename: "+filename);

    string cmdline=compiler+" ";
  if(compiler=="d4") {
    cmdline+=filename+" -out="+outfilename;
  } else if(compiler=="c2d") {
    cmdline+="-in "+filename+" -silent";
  } else if(compiler=="dsharp") {
    cmdline+="-q -Fnnf "+outfilename+" "+filename;
  } else {
    throw CircuitException("Unknown compiler '"+compiler+"'");
  }

  int retvalue=system(cmdline.c_str());

  if(unlink(filename.c_str())) {
    throw CircuitException("Error removing "+filename);
  }

  if(retvalue)
    throw CircuitException("Error executing "+compiler);

  ifstream ifs(outfilename.c_str());

  string nnf;
  getline(ifs, nnf, ' ');

  if(nnf!="nnf") // unsatisfiable formula
    return 0.;

  unsigned nb_nodes, foobar, nb_variables;
  ifs >> nb_nodes >> foobar >> nb_variables;

  BooleanCircuit dnnf;

  if(nb_variables!=gates.size())
    throw CircuitException("Unreadable d-DNNF (wrong number of variables: " + to_string(nb_variables) +" vs " + to_string(gates.size()) + ")");

  std::string line;
  getline(ifs,line);
  unsigned i=0;
  while(getline(ifs,line)) {
    stringstream ss(line);

    char c;
    ss >> c;

    if(c=='O') {
      int var, args;
      ss >> var >> args;
      unsigned id=dnnf.getGate(to_string(i));
      dnnf.setGate(to_string(i), BooleanGate::OR);
      int g;
      while(ss >> g) {
        unsigned id2=dnnf.getGate(to_string(g));
        dnnf.addWire(id,id2);
      }
    } else if(c=='A') {
      int args;
      ss >> args;
      unsigned id=dnnf.getGate(to_string(i));
      dnnf.setGate(to_string(i), BooleanGate::AND);
      int g;
      while(ss >> g) {
        unsigned id2=dnnf.getGate(to_string(g));
        dnnf.addWire(id,id2);
      }
    } else if(c=='L') {
      int leaf;
      ss >> leaf;
      if(gates[abs(leaf)-1]==BooleanGate::IN) {
        if(leaf<0) {
          dnnf.setGate(to_string(i), BooleanGate::IN, 1-prob[-leaf-1]);
        } else {
          dnnf.setGate(to_string(i), BooleanGate::IN, prob[leaf-1]);
        }
      } else
        dnnf.setGate(to_string(i), BooleanGate::IN, 1.);
    } else
      throw CircuitException(string("Unreadable d-DNNF (unknown node type: ")+c+")");

    ++i;
  }

  ifs.close();
  if(unlink(outfilename.c_str())) {
    throw CircuitException("Error removing "+outfilename);
  }

//  throw CircuitException(toString(g) + "\n" + dnnf.toString(dnnf.getGate(to_string(i-1))));

  return dnnf.dDNNFEvaluation(dnnf.getGate(to_string(i-1)));
}

double BooleanCircuit::WeightMC(unsigned g, string opt) const {
  string filename=BooleanCircuit::Tseytin(g, true);

  //opt of the form 'delta;epsilon'
  stringstream ssopt(opt);
  string delta_s, epsilon_s;
  getline(ssopt, delta_s, ';');
  getline(ssopt, epsilon_s, ';');

  double delta = 0;
  try {
    delta=stod(delta_s);
  } catch (invalid_argument &e) {
    delta=0;
  }
  double epsilon = 0;
  try {
    epsilon=stod(epsilon_s);
  } catch (invalid_argument &e) {
    epsilon=0;
  }
  if(delta == 0) delta=0.2;
  if(epsilon == 0) epsilon=0.8;

  //TODO calcul numIterations

  //calcul pivotAC
  double pivotAC=2*ceil(4.4817*(1+1/epsilon)*(1+1/epsilon));

  string cmdline="weightmc --startIteration=0 --gaussuntil=400 --verbosity=0 --pivotAC="+to_string(pivotAC)+ " "+filename+" > "+filename+".out";

  int retvalue=system(cmdline.c_str());
  if(retvalue) {
    throw CircuitException("Error executing weightmc");
  }

  //parsing
  ifstream ifs((filename+".out").c_str());
  string line, prev_line;
  while(getline(ifs,line))
    prev_line=line;

  stringstream ss(prev_line);
  string result;
  ss >> result >> result >> result >> result >> result;

  istringstream iss(result);
  string val, exp;
  getline(iss, val, 'x');
  getline(iss, exp);
  double value=stod(val);
  exp=exp.substr(2);
  double exponent=stod(exp);
  double ret=value*(pow(2.0,exponent));
//  throw CircuitException(to_string(ret));

  if(unlink(filename.c_str())) {
    throw CircuitException("Error removing "+filename);
  }

  if(unlink((filename+".out").c_str())) {
    throw CircuitException("Error removing "+filename+".out");
  }

  return ret;
}
<commit_msg>Explicit use of exponential function<commit_after>#include "BooleanCircuit.h"

extern "C" {
#include "provsql_utils.h"
#include <unistd.h>
#include <math.h>
}

#include <cassert>
#include <string>
#include <fstream>
#include <sstream>
#include <cstdlib>
#include <iostream>

using namespace std;

// Has to be redefined because of name hiding
unsigned BooleanCircuit::setGate(const uuid &u, BooleanGate type)
{
 unsigned id = Circuit::setGate(u, type);
  if(type == BooleanGate::IN)
    inputs.insert(id);
  return id;
}

unsigned BooleanCircuit::setGate(const uuid &u, BooleanGate type, double p)
{
  unsigned id = setGate(u, type);
  prob[id] = p;
  return id;
}

unsigned BooleanCircuit::addGate()
{
  unsigned id=Circuit::addGate();
  prob.push_back(1);
  return id;
}

std::string BooleanCircuit::toString(unsigned g) const
{
  std::string op;
  string result;

  switch(gates[g]) {
    case BooleanGate::IN:
      if(prob[g]==0.) {
        return "⊥";
      } else if(prob[g]==1.) {
        return "⊤";
      } else {
        return to_string(g)+"["+to_string(prob[g])+"]";
      }
    case BooleanGate::NOT:
      op="¬";
      break;
    case BooleanGate::UNDETERMINED:
      op="?";
      break;
    case BooleanGate::AND:
      op="∧";
      break;
    case BooleanGate::OR:
      op="∨";
      break;
  }

  if(wires[g].empty()) {
    if(gates[g]==BooleanGate::AND)
      return "⊤";
    else if(gates[g]==BooleanGate::OR)
      return "⊥";
    else return op;
  }

  for(auto s: wires[g]) {
    if(gates[g]==BooleanGate::NOT)
      result = op;
    else if(!result.empty())
      result+=" "+op+" ";
    result+=toString(s);
  }

  return "("+result+")";
}

double BooleanCircuit::dDNNFEvaluation(unsigned g) const
{
  switch(gates[g]) {
    case BooleanGate::IN:
      return prob[g];
    case BooleanGate::NOT:
      return 1-prob[g];
    case BooleanGate::AND:
      break;
    case BooleanGate::OR:
      break;
    case BooleanGate::UNDETERMINED:
      throw CircuitException("Incorrect gate type");
  }

  double result=(gates[g]==BooleanGate::AND?1:0);
  for(auto s: wires[g]) {
    double d = dDNNFEvaluation(s);
    if(gates[g]==BooleanGate::AND)
      result*=d;
    else
      result+=d;
  }

  return result;
}

bool BooleanCircuit::evaluate(unsigned g, const unordered_set<unsigned> &sampled) const
{
  bool disjunction=false;

  switch(gates[g]) {
    case BooleanGate::IN:
      return sampled.find(g)!=sampled.end();
    case BooleanGate::NOT:
      return !evaluate(*(wires[g].begin()), sampled);
    case BooleanGate::AND:
      disjunction = false;
      break;
    case BooleanGate::OR:
      disjunction = true;
      break;
    case BooleanGate::UNDETERMINED:
      throw CircuitException("Incorrect gate type");
  }

  for(auto s: wires[g]) {
    bool e = evaluate(s, sampled);
    if(disjunction && e)
      return true;
    if(!disjunction && !e)
      return false;
  }

  if(disjunction)
    return false;
  else
    return true;
}

double BooleanCircuit::monteCarlo(unsigned g, unsigned samples) const
{
  unsigned success=0;

  for(unsigned i=0; i<samples; ++i) {
    unordered_set<unsigned> sampled;
    for(unsigned in : inputs) {
      if(rand() *1. / RAND_MAX < prob[in]) {
        sampled.insert(in);
      }
    }

    if(evaluate(g, sampled))
      ++success;

    if(provsql_interrupted)
      throw CircuitException("Interrupted after "+to_string(i+1)+" samples");
  }

  return success*1./samples;
}

double BooleanCircuit::possibleWorlds(unsigned g) const
{
  if(inputs.size()>=8*sizeof(unsigned long long))
    throw CircuitException("Too many possible worlds to iterate over");

  unsigned long long nb=(1<<inputs.size());
  double totalp=0.;

  for(unsigned long long i=0; i < nb; ++i) {
    unordered_set<unsigned> s;
    double p = 1;

    unsigned j=0;
    for(unsigned in : inputs) {
      if(i & (1 << j)) {
        s.insert(in);
        p*=prob[in];
      } else {
        p*=1-prob[in];
      }
      ++j;
    }

    if(evaluate(g, s))
      totalp+=p;

    if(provsql_interrupted)
      throw CircuitException("Interrupted");
  }

  return totalp;
}

std::string BooleanCircuit::Tseytin(unsigned g, bool display_prob=false) const {
  vector<vector<int>> clauses;

  // Tseytin transformation
  for(unsigned i=0; i<gates.size(); ++i) {
    switch(gates[i]) {
      case BooleanGate::AND:
        {
          int id=i+1;
          vector<int> c = {id};
          for(int s: wires[i]) {
            clauses.push_back({-id, s+1});
            c.push_back(-s-1);
          }
          clauses.push_back(c);
          break;
        }

      case BooleanGate::OR:
        {
          int id=i+1;
          vector<int> c = {-id};
          for(int s: wires[i]) {
            clauses.push_back({id, -s-1});
            c.push_back(s+1);
          }
          clauses.push_back(c);
        }
        break;

      case BooleanGate::NOT:
        {
          int id=i+1;
          int s=*wires[i].begin();
          clauses.push_back({-id,-s-1});
          clauses.push_back({id,s+1});
          break;
        }

      case BooleanGate::IN:
      case BooleanGate::UNDETERMINED:
        ;
    }
  }
  clauses.push_back({(int)g+1});

  int fd;
  char cfilename[] = "/tmp/provsqlXXXXXX";
  fd = mkstemp(cfilename);
  close(fd);

  string filename=cfilename;
  ofstream ofs(filename.c_str());

  ofs << "p cnf " << gates.size() << " " << clauses.size() << "\n";

  for(unsigned i=0;i<clauses.size();++i) {
    for(int x : clauses[i]) {
      ofs << x << " ";
    }
    ofs << "0\n";
  }
  if(display_prob) {
    for(unsigned in : inputs) {
      ofs << "w " << (in+1) << " " << to_string(prob[in]) << "\n";
      ofs << "w -" << (in+1) << " " << to_string(1. - prob[in]) << "\n";
    }
  }

  ofs.close();

  return filename;
}

double BooleanCircuit::compilation(unsigned g, string compiler) const {
  string filename=BooleanCircuit::Tseytin(g);
  string outfilename=filename+".nnf";

//  throw CircuitException("filename: "+filename);

    string cmdline=compiler+" ";
  if(compiler=="d4") {
    cmdline+=filename+" -out="+outfilename;
  } else if(compiler=="c2d") {
    cmdline+="-in "+filename+" -silent";
  } else if(compiler=="dsharp") {
    cmdline+="-q -Fnnf "+outfilename+" "+filename;
  } else {
    throw CircuitException("Unknown compiler '"+compiler+"'");
  }

  int retvalue=system(cmdline.c_str());

  if(unlink(filename.c_str())) {
    throw CircuitException("Error removing "+filename);
  }

  if(retvalue)
    throw CircuitException("Error executing "+compiler);

  ifstream ifs(outfilename.c_str());

  string nnf;
  getline(ifs, nnf, ' ');

  if(nnf!="nnf") // unsatisfiable formula
    return 0.;

  unsigned nb_nodes, foobar, nb_variables;
  ifs >> nb_nodes >> foobar >> nb_variables;

  BooleanCircuit dnnf;

  if(nb_variables!=gates.size())
    throw CircuitException("Unreadable d-DNNF (wrong number of variables: " + to_string(nb_variables) +" vs " + to_string(gates.size()) + ")");

  std::string line;
  getline(ifs,line);
  unsigned i=0;
  while(getline(ifs,line)) {
    stringstream ss(line);

    char c;
    ss >> c;

    if(c=='O') {
      int var, args;
      ss >> var >> args;
      unsigned id=dnnf.getGate(to_string(i));
      dnnf.setGate(to_string(i), BooleanGate::OR);
      int g;
      while(ss >> g) {
        unsigned id2=dnnf.getGate(to_string(g));
        dnnf.addWire(id,id2);
      }
    } else if(c=='A') {
      int args;
      ss >> args;
      unsigned id=dnnf.getGate(to_string(i));
      dnnf.setGate(to_string(i), BooleanGate::AND);
      int g;
      while(ss >> g) {
        unsigned id2=dnnf.getGate(to_string(g));
        dnnf.addWire(id,id2);
      }
    } else if(c=='L') {
      int leaf;
      ss >> leaf;
      if(gates[abs(leaf)-1]==BooleanGate::IN) {
        if(leaf<0) {
          dnnf.setGate(to_string(i), BooleanGate::IN, 1-prob[-leaf-1]);
        } else {
          dnnf.setGate(to_string(i), BooleanGate::IN, prob[leaf-1]);
        }
      } else
        dnnf.setGate(to_string(i), BooleanGate::IN, 1.);
    } else
      throw CircuitException(string("Unreadable d-DNNF (unknown node type: ")+c+")");

    ++i;
  }

  ifs.close();
  if(unlink(outfilename.c_str())) {
    throw CircuitException("Error removing "+outfilename);
  }

//  throw CircuitException(toString(g) + "\n" + dnnf.toString(dnnf.getGate(to_string(i-1))));

  return dnnf.dDNNFEvaluation(dnnf.getGate(to_string(i-1)));
}

double BooleanCircuit::WeightMC(unsigned g, string opt) const {
  string filename=BooleanCircuit::Tseytin(g, true);

  //opt of the form 'delta;epsilon'
  stringstream ssopt(opt);
  string delta_s, epsilon_s;
  getline(ssopt, delta_s, ';');
  getline(ssopt, epsilon_s, ';');

  double delta = 0;
  try {
    delta=stod(delta_s);
  } catch (invalid_argument &e) {
    delta=0;
  }
  double epsilon = 0;
  try {
    epsilon=stod(epsilon_s);
  } catch (invalid_argument &e) {
    epsilon=0;
  }
  if(delta == 0) delta=0.2;
  if(epsilon == 0) epsilon=0.8;

  //TODO calcul numIterations

  //calcul pivotAC
  final double pivotAC=2*ceil(exp(3./2)*(1+1/epsilon)*(1+1/epsilon));

  string cmdline="weightmc --startIteration=0 --gaussuntil=400 --verbosity=0 --pivotAC="+to_string(pivotAC)+ " "+filename+" > "+filename+".out";

  int retvalue=system(cmdline.c_str());
  if(retvalue) {
    throw CircuitException("Error executing weightmc");
  }

  //parsing
  ifstream ifs((filename+".out").c_str());
  string line, prev_line;
  while(getline(ifs,line))
    prev_line=line;

  stringstream ss(prev_line);
  string result;
  ss >> result >> result >> result >> result >> result;

  istringstream iss(result);
  string val, exp;
  getline(iss, val, 'x');
  getline(iss, exp);
  double value=stod(val);
  exp=exp.substr(2);
  double exponent=stod(exp);
  double ret=value*(pow(2.0,exponent));
//  throw CircuitException(to_string(ret));

  if(unlink(filename.c_str())) {
    throw CircuitException("Error removing "+filename);
  }

  if(unlink((filename+".out").c_str())) {
    throw CircuitException("Error removing "+filename+".out");
  }

  return ret;
}
<|endoftext|>


<commit_before>#include "environment.hpp"
#include "value_printer.hpp"

using shiranui::runtime::value::Value;
using shiranui::syntax::ast::Identifier;
namespace shiranui{
    namespace runtime{
        namespace environment{
            Environment::Environment(){
            }
            Environment::Environment(sp<Environment> par)
                : parent(par){
            }

            bool Environment::is_here(Identifier id) const{
                return vars.find(id) != vars.end()
                    or consts.find(id) != consts.end();

            }
            bool Environment::has(Identifier id) const{
                if(parent == nullptr){
                    return is_here(id);
                }else{
                    return is_here(id) or parent->has(id);
                }
            }
            bool Environment::is_const(Identifier id) const{
                if(is_here(id)){
                    return consts.find(id) != consts.end();
                }else if(parent == nullptr){
                    return false;
                }else{
                    return parent->is_const(id);
                }
            }
            sp<Value> Environment::get(Identifier id){
                if(is_here(id)){
                    if(is_const(id)){
                        return consts[id];
                    }else{
                        return vars[id];
                    }
                }else{
                    if(parent == nullptr){
                        // throw exception?
                        return nullptr;
                    }else{
                        return parent->get(id);
                    }
                }
            }
            void Environment::set(Identifier id,sp<Value> v){
                if(is_here(id)){
                    current_version++;
                    changes.push_back(std::make_shared<timemachine::EnvSetChange>(id,vars[id],v));
                    vars[id] = v;
                }else{
                    parent->set(id,v);
                }
            }
            // ----- for rollback ---------------------------------
            void Environment::remove(Identifier id){
                if(vars.find(id) != vars.end()){
                    vars.erase(id);
                }else if(consts.find(id) != consts.end()){
                    consts.erase(id);
                }else{
                    throw timemachine::TimeMachineException();
                }
            }
            void Environment::force_set(Identifier id,sp<Value> v){
                if(vars.find(id) != vars.end()){
                    vars.erase(id);
                }else if(consts.find(id) != consts.end()){
                    consts.erase(id);
                }else{
                    throw timemachine::TimeMachineException();
                }
            }
                // -----------------------------------------------

            void Environment::define(Identifier id,sp<Value> v,bool is_const){
                if(is_const){
                    consts[id] = v;
                }else{
                    vars[id] = v;
                }
                current_version++;
                changes.push_back(std::make_shared<timemachine::EnvDefineChange>(id,v,is_const));
            }
            void Environment::clear(){
                vars.clear();
                consts.clear();
                changes.clear();
                parent = nullptr;
            }
            std::ostream& operator<<(std::ostream& os,const Environment& e){
                using namespace runtime::value;
                if(e.parent != nullptr){
                    os << *(e.parent) << std::endl;
                }
                os << "===== layer  =====" << std::endl;
                os << "---- consts ----" << std::endl;
                for(const auto p : e.consts){
                    os << p.first.name << " -> " << to_reproductive(p.second) << std::endl;
                }
                os << "---- var    ----" << std::endl;
                for(const auto p : e.vars){
                    os << p.first.name << " -> " << to_reproductive(p.second) << std::endl;
                }
                os << "==================" << std::endl;
                return os;
            }

            std::map<syntax::ast::Identifier,
                     sp<value::Value> >
            filter_environment(const Environment& e,std::set<syntax::ast::Identifier> filter){
                std::map<syntax::ast::Identifier,sp<value::Value> > ret;
                // first,filter parent
                if(e.parent != nullptr){
                    ret = filter_environment(*(e.parent),filter);
                }

                // overwrite parent environment
                for(auto m : {e.vars,e.consts}){
                    for(auto p : m){
                        if(filter.find(p.first) != filter.end()){
                            ret[p.first] = p.second;
                        }
                    }
                }
                return ret;
            }
        }
        namespace timemachine{
            EnvSetChange::EnvSetChange(syntax::ast::Identifier i,sp<Value> p,sp<Value> n)
                : id(i),prev(p),next(n) {}
            void EnvSetChange::rollback(sp<environment::Environment> target){
                // prev will not be nullptr
                target->force_set(id,prev);
            }
            void EnvSetChange::flash(sp<environment::Environment> target){
                target->force_set(id,next);
            }
            EnvDefineChange::EnvDefineChange(syntax::ast::Identifier i,sp<value::Value> v,bool is_const_)
                : id(i),value(v),is_const(is_const_) {}
            void EnvDefineChange::rollback(sp<environment::Environment> target){
                target->remove(id);
            }
            void EnvDefineChange::flash(sp<environment::Environment> target){
                target->define(id,value,is_const);
            }
        }
    }

}
<commit_msg>fix environment timemachine<commit_after>#include "environment.hpp"
#include "value_printer.hpp"

using shiranui::runtime::value::Value;
using shiranui::syntax::ast::Identifier;
namespace shiranui{
    namespace runtime{
        namespace environment{
            Environment::Environment(){
            }
            Environment::Environment(sp<Environment> par)
                : parent(par){
            }

            bool Environment::is_here(Identifier id) const{
                return vars.find(id) != vars.end()
                    or consts.find(id) != consts.end();

            }
            bool Environment::has(Identifier id) const{
                if(parent == nullptr){
                    return is_here(id);
                }else{
                    return is_here(id) or parent->has(id);
                }
            }
            bool Environment::is_const(Identifier id) const{
                if(is_here(id)){
                    return consts.find(id) != consts.end();
                }else if(parent == nullptr){
                    return false;
                }else{
                    return parent->is_const(id);
                }
            }
            sp<Value> Environment::get(Identifier id){
                if(is_here(id)){
                    if(is_const(id)){
                        return consts[id];
                    }else{
                        return vars[id];
                    }
                }else{
                    if(parent == nullptr){
                        // throw exception?
                        return nullptr;
                    }else{
                        return parent->get(id);
                    }
                }
            }
            void Environment::set(Identifier id,sp<Value> v){
                if(is_here(id)){
                    current_version++;
                    changes.push_back(std::make_shared<timemachine::EnvSetChange>(id,vars[id],v));
                    vars[id] = v;
                }else{
                    parent->set(id,v);
                }
            }
            // ----- for rollback ---------------------------------
            void Environment::remove(Identifier id){
                if(vars.find(id) != vars.end()){
                    vars.erase(id);
                }else if(consts.find(id) != consts.end()){
                    consts.erase(id);
                }else{
                    throw timemachine::TimeMachineException();
                }
            }
            void Environment::force_set(Identifier id,sp<Value> v){
                if(vars.find(id) != vars.end()){
                    vars[id] = v;
                }else{
                    throw timemachine::TimeMachineException();
                }
            }
                // -----------------------------------------------

            void Environment::define(Identifier id,sp<Value> v,bool is_const){
                if(is_const){
                    consts[id] = v;
                }else{
                    vars[id] = v;
                }
                current_version++;
                changes.push_back(std::make_shared<timemachine::EnvDefineChange>(id,v,is_const));
            }
            void Environment::clear(){
                vars.clear();
                consts.clear();
                changes.clear();
                parent = nullptr;
            }
            std::ostream& operator<<(std::ostream& os,const Environment& e){
                using namespace runtime::value;
                if(e.parent != nullptr){
                    os << *(e.parent) << std::endl;
                }
                os << "===== layer  =====" << std::endl;
                os << "---- consts ----" << std::endl;
                for(const auto p : e.consts){
                    os << p.first.name << " -> " << to_reproductive(p.second) << std::endl;
                }
                os << "---- var    ----" << std::endl;
                for(const auto p : e.vars){
                    os << p.first.name << " -> " << to_reproductive(p.second) << std::endl;
                }
                os << "==================" << std::endl;
                return os;
            }

            std::map<syntax::ast::Identifier,
                     sp<value::Value> >
            filter_environment(const Environment& e,std::set<syntax::ast::Identifier> filter){
                std::map<syntax::ast::Identifier,sp<value::Value> > ret;
                // first,filter parent
                if(e.parent != nullptr){
                    ret = filter_environment(*(e.parent),filter);
                }

                // overwrite parent environment
                for(auto m : {e.vars,e.consts}){
                    for(auto p : m){
                        if(filter.find(p.first) != filter.end()){
                            ret[p.first] = p.second;
                        }
                    }
                }
                return ret;
            }
        }
        namespace timemachine{
            EnvSetChange::EnvSetChange(syntax::ast::Identifier i,sp<Value> p,sp<Value> n)
                : id(i),prev(p),next(n) {}
            void EnvSetChange::rollback(sp<environment::Environment> target){
                // prev will not be nullptr
                target->force_set(id,prev);
            }
            void EnvSetChange::flash(sp<environment::Environment> target){
                target->force_set(id,next);
            }
            EnvDefineChange::EnvDefineChange(syntax::ast::Identifier i,sp<value::Value> v,bool is_const_)
                : id(i),value(v),is_const(is_const_) {}
            void EnvDefineChange::rollback(sp<environment::Environment> target){
                target->remove(id);
            }
            void EnvDefineChange::flash(sp<environment::Environment> target){
                target->define(id,value,is_const);
            }
        }
    }

}
<|endoftext|>


<commit_before>// Copyright (c) 2012 Steinwurf ApS
// All Rights Reserved
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are met:
//     * Redistributions of source code must retain the above copyright
//       notice, this list of conditions and the following disclaimer.
//     * Redistributions in binary form must reproduce the above copyright
//       notice, this list of conditions and the following disclaimer in the
//       documentation and/or other materials provided with the distribution.
//     * Neither the name of Steinwurf ApS nor the
//       names of its contributors may be used to endorse or promote products
//       derived from this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
// ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
// WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
// DISCLAIMED. IN NO EVENT SHALL Steinwurf ApS BE LIABLE FOR ANY
// DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
// (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
// LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
// ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
// SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

#ifndef SAK_OBJECT_REGISTRY_HPP
#define SAK_OBJECT_REGISTRY_HPP

#include <map>

#include <boost/function.hpp>

#include "object_factory_impl.hpp"

namespace sak
{

    /// Object registry used to store factories to construct objects of
    /// the registered types.
    class object_registry
    {
    private:

        /// The map associating an object id to an object factory
        typedef std::map<object_id, boost::shared_ptr<object_factory> >
            factory_map;

        /// The map associating an object id to an object factory
        typedef std::map<object_id, boost::shared_ptr<object> >
            object_map;

    public:

        /// Constructor of the factory registry
        object_registry()
            { }

        /// @return a factory stored in the registry
        template<class Factory>
        boost::shared_ptr<Factory> get_factory()
            {
                auto factory_id = *get_object_id<Factory>();
                auto factory = find(m_lookup_by_factory_id, factory_id);

                assert(factory);

                typedef object_factory_impl<Factory> factory_type;

                auto factory_impl =
                    boost::dynamic_pointer_cast<factory_type>(factory);

                assert(factory_impl);
                assert(factory_impl->m_factory);
                return factory_impl->m_factory;
            }

        /// Registers an object factory with the object registry
        /// Once a factory has been registered objects can be created
        template<class Factory, class Object>
        void set_factory()
            {
                auto factory_id = *get_object_id<Factory>();
                auto object_id  = *get_object_id<Object>();

                // Did you forget to make the id function in the class Factory?
                assert(factory_id.m_id != object::id()->m_id);

                // Did you forget to make the id function in the class Object?
                assert(object_id.m_id != object::id()->m_id);

                auto factory =
                    boost::make_shared< object_factory_impl<Factory> >();

                m_lookup_by_factory_id[factory_id] = factory;
                m_lookup_by_object_id[object_id] = factory;
            }

        /// Registers an object factory function with the object registry
        /// Once a factory function has been registered objects can be created
        template<class Object>
        void set_factory(const boost::function<boost::shared_ptr<Object>(
                             object_registry &)> &function)
            {
                auto object_id = *get_object_id<Object>();

                // Did you forget to make the id function in the class Object?
                assert(object_id.m_id != object::id()->m_id);

                auto factory =
                    boost::make_shared< object_factory_function<Object> >(function);

                m_lookup_by_object_id[object_id] = factory;
            }

        /// Registers an object factory with the object registry. This methods
        /// can be used for factories with a non-standard build function.
        /// Users can call the get function and invoke the custom build function
        template<class Object>
        void set_object()
            {
                auto object_id = *get_object_id<Object>();

                // Did you forget to make the id function in the class Factory?
                assert(object_id.m_id != object::id()->m_id);

                auto object = boost::make_shared<Object>();

                m_lookup_by_shared_object_id[object_id] = object;
            }

        /// @return a factory stored in the registry
        template<class Object>
        boost::shared_ptr<Object> get_object()
            {
                auto object_id = *get_object_id<Object>();
                auto object = find(m_lookup_by_shared_object_id, object_id);

                assert(object);
                return boost::dynamic_pointer_cast<Object>(object);
            }

        /// Clears all registered factories
        void clear_factories()
            {
                m_lookup_by_factory_id.clear();
                m_lookup_by_object_id.clear();
            }

        /// @return an object created using the registered factories
        template<class Object>
        boost::shared_ptr<Object> build()
            {
                assert(has_object_id(m_lookup_by_object_id, *Object::id()));

                auto factory =
                    find(m_lookup_by_object_id, *Object::id());

                assert(factory);

                auto object = factory->build(*this);

                return boost::dynamic_pointer_cast<Object>(object);
            }

    private:

        /// Checks if an object id is registered in a specific category
        template<class Map>
        bool has_object_id(const Map &map, const object_id &id) const
            {
                return map.find(id) != map.end();
            }

        /*template<class Object>
        object_id get_object_id() const
            {
                return *Object::id();
            }*/

        /// Finds and returns an object factory in the given map with a
        /// "compatible" object_id.
        boost::shared_ptr<object_factory>
        find(const factory_map &map, const object_id &id) const
            {
                assert(has_object_id(map,id));
                return map.at(id);
            }

        /// Finds and returns an object factory in the given map with a
        /// "compatible" object_id.
        boost::shared_ptr<object>
        find(const object_map &map, const object_id &id) const
            {
                assert(has_object_id(map,id));
                return map.at(id);
            }

    private:

        /// Map allowing a factory to be found based on an object's object id
        factory_map m_lookup_by_object_id;

        /// Map allowing a shared object to be found based on an object's object id
        object_map m_lookup_by_shared_object_id;

        /// Map allowing a factory to be found based on a factory's object id
        factory_map m_lookup_by_factory_id;

    };

    /// Template must be specialized by all object classes used with the object registry
    template<class Object> object_id* get_object_id();
}

#endif

<commit_msg>object_registry.hpp id() fixed<commit_after>// Copyright (c) 2012 Steinwurf ApS
// All Rights Reserved
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are met:
//     * Redistributions of source code must retain the above copyright
//       notice, this list of conditions and the following disclaimer.
//     * Redistributions in binary form must reproduce the above copyright
//       notice, this list of conditions and the following disclaimer in the
//       documentation and/or other materials provided with the distribution.
//     * Neither the name of Steinwurf ApS nor the
//       names of its contributors may be used to endorse or promote products
//       derived from this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
// ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
// WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
// DISCLAIMED. IN NO EVENT SHALL Steinwurf ApS BE LIABLE FOR ANY
// DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
// (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
// LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
// ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
// SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

#ifndef SAK_OBJECT_REGISTRY_HPP
#define SAK_OBJECT_REGISTRY_HPP

#include <map>

#include <boost/function.hpp>

#include "object_factory_impl.hpp"

namespace sak
{

    /// Object registry used to store factories to construct objects of
    /// the registered types.
    class object_registry
    {
    private:

        /// The map associating an object id to an object factory
        typedef std::map<object_id, boost::shared_ptr<object_factory> >
            factory_map;

        /// The map associating an object id to an object factory
        typedef std::map<object_id, boost::shared_ptr<object> >
            object_map;

    public:

        /// Constructor of the factory registry
        object_registry()
            { }

        /// @return a factory stored in the registry
        template<class Factory>
        boost::shared_ptr<Factory> get_factory()
            {
                auto factory_id = *get_object_id<Factory>();
                auto factory = find(m_lookup_by_factory_id, factory_id);

                assert(factory);

                typedef object_factory_impl<Factory> factory_type;

                auto factory_impl =
                    boost::dynamic_pointer_cast<factory_type>(factory);

                assert(factory_impl);
                assert(factory_impl->m_factory);
                return factory_impl->m_factory;
            }

        /// Registers an object factory with the object registry
        /// Once a factory has been registered objects can be created
        template<class Factory, class Object>
        void set_factory()
            {
                auto factory_id = *get_object_id<Factory>();
                auto object_id  = *get_object_id<Object>();

                // Did you forget to make the id function in the class Factory?
                assert(factory_id.m_id != object::id()->m_id);

                // Did you forget to make the id function in the class Object?
                assert(object_id.m_id != object::id()->m_id);

                auto factory =
                    boost::make_shared< object_factory_impl<Factory> >();

                m_lookup_by_factory_id[factory_id] = factory;
                m_lookup_by_object_id[object_id] = factory;
            }

        /// Registers an object factory function with the object registry
        /// Once a factory function has been registered objects can be created
        template<class Object>
        void set_factory(const boost::function<boost::shared_ptr<Object>(
                             object_registry &)> &function)
            {
                auto object_id = *get_object_id<Object>();

                // Did you forget to make the id function in the class Object?
                assert(object_id.m_id != object::id()->m_id);

                auto factory =
                    boost::make_shared< object_factory_function<Object> >(function);

                m_lookup_by_object_id[object_id] = factory;
            }

        /// Registers an object factory with the object registry. This methods
        /// can be used for factories with a non-standard build function.
        /// Users can call the get function and invoke the custom build function
        template<class Object>
        void set_object()
            {
                auto object_id = *get_object_id<Object>();

                // Did you forget to make the id function in the class Factory?
                assert(object_id.m_id != object::id()->m_id);

                auto object = boost::make_shared<Object>();

                m_lookup_by_shared_object_id[object_id] = object;
            }

        /// @return a factory stored in the registry
        template<class Object>
        boost::shared_ptr<Object> get_object()
            {
                auto object_id = *get_object_id<Object>();
                auto object = find(m_lookup_by_shared_object_id, object_id);

                assert(object);
                return boost::dynamic_pointer_cast<Object>(object);
            }

        /// Clears all registered factories
        void clear_factories()
            {
                m_lookup_by_factory_id.clear();
                m_lookup_by_object_id.clear();
            }

        /// @return an object created using the registered factories
        template<class Object>
        boost::shared_ptr<Object> build()
            {
                assert(has_object_id(m_lookup_by_object_id, *get_object_id<Object>() ));

                auto factory = find(m_lookup_by_object_id, *get_object_id<Object>() );

                assert(factory);

                auto object = factory->build(*this);

                return boost::dynamic_pointer_cast<Object>(object);
            }

    private:

        /// Checks if an object id is registered in a specific category
        template<class Map>
        bool has_object_id(const Map &map, const object_id &id) const
            {
                return map.find(id) != map.end();
            }

        /*template<class Object>
        object_id get_object_id() const
            {
                return *Object::id();
            }*/

        /// Finds and returns an object factory in the given map with a
        /// "compatible" object_id.
        boost::shared_ptr<object_factory>
        find(const factory_map &map, const object_id &id) const
            {
                assert(has_object_id(map,id));
                return map.at(id);
            }

        /// Finds and returns an object factory in the given map with a
        /// "compatible" object_id.
        boost::shared_ptr<object>
        find(const object_map &map, const object_id &id) const
            {
                assert(has_object_id(map,id));
                return map.at(id);
            }

    private:

        /// Map allowing a factory to be found based on an object's object id
        factory_map m_lookup_by_object_id;

        /// Map allowing a shared object to be found based on an object's object id
        object_map m_lookup_by_shared_object_id;

        /// Map allowing a factory to be found based on a factory's object id
        factory_map m_lookup_by_factory_id;

    };

    /// Template must be specialized by all object classes used with the object registry
    template<class Object> object_id* get_object_id();
}

#endif

<|endoftext|>


<commit_before>//------------------------------------------------------------------------------
//  RenderEnumsTest.cc
//------------------------------------------------------------------------------
#include "Pre.h"
#include "UnitTest++/src/UnitTest++.h"
#include "Core/String/String.h"
#include "Render/Types/PixelFormat.h"
#include "Render/Types/PrimitiveType.h"
#include "Render/Types/TextureType.h"
#include "Render/Types/Usage.h"
#include "Render/Types/TextureWrapMode.h"
#include "Render/Types/IndexType.h"
#include "Render/Types/TextureFilterMode.h"
#include "Render/Types/VertexFormat.h"
#include "Render/Types/VertexAttr.h"

using namespace Oryol::Core;
using namespace Oryol::Render;

//------------------------------------------------------------------------------
TEST(PixelFormatTest) {
    CHECK(PixelFormat::NumPixelFormats == 15);

    CHECK(PixelFormat::FromString("R8G8B8A8") == PixelFormat::R8G8B8A8);
    CHECK(PixelFormat::FromString("R8G8B8") == PixelFormat::R8G8B8);
    CHECK(PixelFormat::FromString("R5G6B5") == PixelFormat::R5G6B5);
    CHECK(PixelFormat::FromString("R5G5B5A1") == PixelFormat::R5G5B5A1);
    CHECK(PixelFormat::FromString("R4G4B4A4") == PixelFormat::R4G4B4A4);
    CHECK(PixelFormat::FromString("L8") == PixelFormat::L8);
    CHECK(PixelFormat::FromString("DXT1") == PixelFormat::DXT1);
    CHECK(PixelFormat::FromString("DXT3") == PixelFormat::DXT3);
    CHECK(PixelFormat::FromString("DXT5") == PixelFormat::DXT5);
    CHECK(PixelFormat::FromString("D16") == PixelFormat::D16);
    CHECK(PixelFormat::FromString("D32") == PixelFormat::D32);
    CHECK(PixelFormat::FromString("D24S8") == PixelFormat::D24S8);
    CHECK(PixelFormat::FromString("R32F") == PixelFormat::R32F);
    CHECK(PixelFormat::FromString("PVRTC2") == PixelFormat::PVRTC2);
    CHECK(PixelFormat::FromString("PVRTC4") == PixelFormat::PVRTC4);

    CHECK(String(PixelFormat::ToString(PixelFormat::R8G8B8A8)) == "R8G8B8A8");
    CHECK(String(PixelFormat::ToString(PixelFormat::R8G8B8)) == "R8G8B8");
    CHECK(String(PixelFormat::ToString(PixelFormat::R5G6B5)) == "R5G6B5");
    CHECK(String(PixelFormat::ToString(PixelFormat::R5G5B5A1)) == "R5G5B5A1");
    CHECK(String(PixelFormat::ToString(PixelFormat::R4G4B4A4)) == "R4G4B4A4");
    CHECK(String(PixelFormat::ToString(PixelFormat::L8)) == "L8");
    CHECK(String(PixelFormat::ToString(PixelFormat::DXT1)) == "DXT1");
    CHECK(String(PixelFormat::ToString(PixelFormat::DXT3)) == "DXT3");
    CHECK(String(PixelFormat::ToString(PixelFormat::DXT5)) == "DXT5");
    CHECK(String(PixelFormat::ToString(PixelFormat::D16)) == "D16");
    CHECK(String(PixelFormat::ToString(PixelFormat::D32)) == "D32");
    CHECK(String(PixelFormat::ToString(PixelFormat::D24S8)) == "D24S8");
    CHECK(String(PixelFormat::ToString(PixelFormat::R32F)) == "R32F");
    CHECK(String(PixelFormat::ToString(PixelFormat::PVRTC2)) == "PVRTC2");
    CHECK(String(PixelFormat::ToString(PixelFormat::PVRTC4)) == "PVRTC4");
}

//------------------------------------------------------------------------------
TEST(TextureTypeTest) {
    CHECK(TextureType::NumTextureTypes == 3);
    CHECK(TextureType::FromString("Texture2D") == TextureType::Texture2D);
    CHECK(TextureType::FromString("Texture3D") == TextureType::Texture3D);
    CHECK(TextureType::FromString("TextureCube") == TextureType::TextureCube);
    CHECK(TextureType::FromString("Bla") == TextureType::InvalidTextureType);
    CHECK(String(TextureType::ToString(TextureType::Texture2D)) == "Texture2D");
    CHECK(String(TextureType::ToString(TextureType::Texture3D)) == "Texture3D");
    CHECK(String(TextureType::ToString(TextureType::TextureCube)) == "TextureCube");
}

//------------------------------------------------------------------------------
TEST(PrimitiveTypeTest) {
    CHECK(PrimitiveType::NumPrimitiveTypes == 7);

    CHECK(PrimitiveType::FromString("Points") == PrimitiveType::Points);
    CHECK(PrimitiveType::FromString("LineStrip") == PrimitiveType::LineStrip);
    CHECK(PrimitiveType::FromString("LineLoop") == PrimitiveType::LineLoop);
    CHECK(PrimitiveType::FromString("Lines") == PrimitiveType::Lines);
    CHECK(PrimitiveType::FromString("TriangleStrip") == PrimitiveType::TriangleStrip);
    CHECK(PrimitiveType::FromString("TriangleFan") == PrimitiveType::TriangleFan);
    CHECK(PrimitiveType::FromString("Triangles") == PrimitiveType::Triangles);

    CHECK(String(PrimitiveType::ToString(PrimitiveType::Points)) == "Points");
    CHECK(String(PrimitiveType::ToString(PrimitiveType::LineStrip)) == "LineStrip");
    CHECK(String(PrimitiveType::ToString(PrimitiveType::LineLoop)) == "LineLoop");
    CHECK(String(PrimitiveType::ToString(PrimitiveType::Lines)) == "Lines");
    CHECK(String(PrimitiveType::ToString(PrimitiveType::TriangleStrip)) == "TriangleStrip");
    CHECK(String(PrimitiveType::ToString(PrimitiveType::TriangleFan)) == "TriangleFan");
    CHECK(String(PrimitiveType::ToString(PrimitiveType::Triangles)) == "Triangles");
}

//------------------------------------------------------------------------------
TEST(UsageTest) {
    CHECK(Usage::NumUsages == 3);
    CHECK(Usage::FromString("Immutable") == Usage::Immutable);
    CHECK(Usage::FromString("DynamicWrite") == Usage::DynamicWrite);
    CHECK(Usage::FromString("DynamicStream") == Usage::DynamicStream);
    CHECK(Usage::FromString("Bla") == Usage::InvalidUsage);
    CHECK(String(Usage::ToString(Usage::Immutable)) == "Immutable");
    CHECK(String(Usage::ToString(Usage::DynamicWrite)) == "DynamicWrite");
    CHECK(String(Usage::ToString(Usage::DynamicStream)) == "DynamicStream");
}

//------------------------------------------------------------------------------
TEST(TextureWrapMode) {
    CHECK(TextureWrapMode::NumTextureWrapModes == 3);
    CHECK(TextureWrapMode::FromString("ClampToEdge") == TextureWrapMode::ClampToEdge);
    CHECK(TextureWrapMode::FromString("Repeat") == TextureWrapMode::Repeat);
    CHECK(TextureWrapMode::FromString("MirroredRepeat") == TextureWrapMode::MirroredRepeat);
    CHECK(String(TextureWrapMode::ToString(TextureWrapMode::ClampToEdge)) == "ClampToEdge");
    CHECK(String(TextureWrapMode::ToString(TextureWrapMode::Repeat)) == "Repeat");
    CHECK(String(TextureWrapMode::ToString(TextureWrapMode::MirroredRepeat)) == "MirroredRepeat");
}

//------------------------------------------------------------------------------
TEST(IndexTypeTest) {
    CHECK(IndexType::NumIndexTypes == 3);
    CHECK(IndexType::FromString("None") == IndexType::None);
    CHECK(IndexType::FromString("Index16") == IndexType::Index16);
    CHECK(IndexType::FromString("Index32") == IndexType::Index32);
    CHECK(String(IndexType::ToString(IndexType::None)) == "None");
    CHECK(String(IndexType::ToString(IndexType::Index16)) == "Index16");
    CHECK(String(IndexType::ToString(IndexType::Index32)) == "Index32");
    CHECK(IndexType::ByteSize(IndexType::Index16) == 2);
    CHECK(IndexType::ByteSize(IndexType::Index32) == 4);
}

//------------------------------------------------------------------------------
TEST(TextureFilterModeTest) {
    CHECK(TextureFilterMode::NumTextureFilterModes == 6);
    CHECK(TextureFilterMode::FromString("Nearest") == TextureFilterMode::Nearest);
    CHECK(TextureFilterMode::FromString("Linear") == TextureFilterMode::Linear);
    CHECK(TextureFilterMode::FromString("NearestMipmapNearest") == TextureFilterMode::NearestMipmapNearest);
    CHECK(TextureFilterMode::FromString("NearestMipmapLinear") == TextureFilterMode::NearestMipmapLinear);
    CHECK(TextureFilterMode::FromString("LinearMipmapNearest") == TextureFilterMode::LinearMipmapNearest);
    CHECK(TextureFilterMode::FromString("LinearMipmapLinear") == TextureFilterMode::LinearMipmapLinear);
    CHECK(String(TextureFilterMode::ToString(TextureFilterMode::Nearest)) == "Nearest");
    CHECK(String(TextureFilterMode::ToString(TextureFilterMode::Linear)) == "Linear");
    CHECK(String(TextureFilterMode::ToString(TextureFilterMode::NearestMipmapNearest)) == "NearestMipmapNearest");
    CHECK(String(TextureFilterMode::ToString(TextureFilterMode::NearestMipmapLinear)) == "NearestMipmapLinear");
    CHECK(String(TextureFilterMode::ToString(TextureFilterMode::LinearMipmapNearest)) == "LinearMipmapNearest");
    CHECK(String(TextureFilterMode::ToString(TextureFilterMode::LinearMipmapLinear)) == "LinearMipmapLinear");
}

//------------------------------------------------------------------------------
TEST(VertexFormatTest) {
    CHECK(VertexFormat::NumVertexFormats == 12);

    CHECK(VertexFormat::FromString("Float") == VertexFormat::Float);
    CHECK(VertexFormat::FromString("Float2") == VertexFormat::Float2);
    CHECK(VertexFormat::FromString("Float3") == VertexFormat::Float3);
    CHECK(VertexFormat::FromString("Float4") == VertexFormat::Float4);
    CHECK(VertexFormat::FromString("Byte4") == VertexFormat::Byte4);
    CHECK(VertexFormat::FromString("Byte4N") == VertexFormat::Byte4N);
    CHECK(VertexFormat::FromString("UByte4") == VertexFormat::UByte4);
    CHECK(VertexFormat::FromString("UByte4N") == VertexFormat::UByte4N);
    CHECK(VertexFormat::FromString("Short2") == VertexFormat::Short2);
    CHECK(VertexFormat::FromString("Short2N") == VertexFormat::Short2N);
    CHECK(VertexFormat::FromString("Short4") == VertexFormat::Short4);
    CHECK(VertexFormat::FromString("Short4N") == VertexFormat::Short4N);

    CHECK(String(VertexFormat::ToString(VertexFormat::Float)) == "Float");
    CHECK(String(VertexFormat::ToString(VertexFormat::Float2)) == "Float2");
    CHECK(String(VertexFormat::ToString(VertexFormat::Float3)) == "Float3");
    CHECK(String(VertexFormat::ToString(VertexFormat::Float4)) == "Float4");
    CHECK(String(VertexFormat::ToString(VertexFormat::Byte4)) == "Byte4");
    CHECK(String(VertexFormat::ToString(VertexFormat::Byte4N)) == "Byte4N");
    CHECK(String(VertexFormat::ToString(VertexFormat::UByte4)) == "UByte4");
    CHECK(String(VertexFormat::ToString(VertexFormat::UByte4N)) == "UByte4N");
    CHECK(String(VertexFormat::ToString(VertexFormat::Short2)) == "Short2");
    CHECK(String(VertexFormat::ToString(VertexFormat::Short2N)) == "Short2N");
    CHECK(String(VertexFormat::ToString(VertexFormat::Short4)) == "Short4");
    CHECK(String(VertexFormat::ToString(VertexFormat::Short4N)) == "Short4N");

    CHECK(VertexFormat::ByteSize(VertexFormat::Float) == 4);
    CHECK(VertexFormat::ByteSize(VertexFormat::Float2) == 8);
    CHECK(VertexFormat::ByteSize(VertexFormat::Float3) == 12);
    CHECK(VertexFormat::ByteSize(VertexFormat::Float4) == 16);
    CHECK(VertexFormat::ByteSize(VertexFormat::Byte4) == 4);
    CHECK(VertexFormat::ByteSize(VertexFormat::Byte4N) == 4);
    CHECK(VertexFormat::ByteSize(VertexFormat::UByte4) == 4);
    CHECK(VertexFormat::ByteSize(VertexFormat::UByte4N) == 4);
    CHECK(VertexFormat::ByteSize(VertexFormat::Short2) == 4);
    CHECK(VertexFormat::ByteSize(VertexFormat::Short2N) == 4);
    CHECK(VertexFormat::ByteSize(VertexFormat::Short4) == 8);
    CHECK(VertexFormat::ByteSize(VertexFormat::Short4N) == 8);
}

//------------------------------------------------------------------------------
TEST(VertexAttrTest) {
    CHECK(VertexAttr::NumVertexAttrs == 16);

    CHECK(VertexAttr::FromString("position") == VertexAttr::Position);
    CHECK(VertexAttr::FromString("normal") == VertexAttr::Normal);
    CHECK(VertexAttr::FromString("texcoord0") == VertexAttr::TexCoord0);
    CHECK(VertexAttr::FromString("texcoord1") == VertexAttr::TexCoord1);
    CHECK(VertexAttr::FromString("texcoord2") == VertexAttr::TexCoord2);
    CHECK(VertexAttr::FromString("texcoord3") == VertexAttr::TexCoord3);
    CHECK(VertexAttr::FromString("tangent") == VertexAttr::Tangent);
    CHECK(VertexAttr::FromString("binormal") == VertexAttr::Binormal);
    CHECK(VertexAttr::FromString("weights") == VertexAttr::Weights);
    CHECK(VertexAttr::FromString("indices") == VertexAttr::Indices);
    CHECK(VertexAttr::FromString("color0") == VertexAttr::Color0);
    CHECK(VertexAttr::FromString("color1") == VertexAttr::Color1);
    CHECK(VertexAttr::FromString("custom0") == VertexAttr::Custom0);
    CHECK(VertexAttr::FromString("custom1") == VertexAttr::Custom1);
    CHECK(VertexAttr::FromString("custom2") == VertexAttr::Custom2);
    CHECK(VertexAttr::FromString("custom3") == VertexAttr::Custom3);

    CHECK(String(VertexAttr::ToString(VertexAttr::Position)) == "position");
    CHECK(String(VertexAttr::ToString(VertexAttr::Normal)) == "normal");
    CHECK(String(VertexAttr::ToString(VertexAttr::TexCoord0)) == "texcoord0");
    CHECK(String(VertexAttr::ToString(VertexAttr::TexCoord1)) == "texcoord1");
    CHECK(String(VertexAttr::ToString(VertexAttr::TexCoord2)) == "texcoord2");
    CHECK(String(VertexAttr::ToString(VertexAttr::TexCoord3)) == "texcoord3");
    CHECK(String(VertexAttr::ToString(VertexAttr::Tangent)) == "tangent");
    CHECK(String(VertexAttr::ToString(VertexAttr::Binormal)) == "binormal");
    CHECK(String(VertexAttr::ToString(VertexAttr::Weights)) == "weights");
    CHECK(String(VertexAttr::ToString(VertexAttr::Indices)) == "indices");
    CHECK(String(VertexAttr::ToString(VertexAttr::Color0)) == "color0");
    CHECK(String(VertexAttr::ToString(VertexAttr::Color1)) == "color1");
    CHECK(String(VertexAttr::ToString(VertexAttr::Custom0)) == "custom0");
    CHECK(String(VertexAttr::ToString(VertexAttr::Custom1)) == "custom1");
    CHECK(String(VertexAttr::ToString(VertexAttr::Custom2)) == "custom2");
    CHECK(String(VertexAttr::ToString(VertexAttr::Custom3)) == "custom3");
}
<commit_msg>Render system enum unit test updated<commit_after>//------------------------------------------------------------------------------
//  RenderEnumsTest.cc
//------------------------------------------------------------------------------
#include "Pre.h"
#include "UnitTest++/src/UnitTest++.h"
#include "Core/String/String.h"
#include "Render/Types/PixelFormat.h"
#include "Render/Types/PrimitiveType.h"
#include "Render/Types/TextureType.h"
#include "Render/Types/Usage.h"
#include "Render/Types/TextureWrapMode.h"
#include "Render/Types/IndexType.h"
#include "Render/Types/TextureFilterMode.h"
#include "Render/Types/VertexFormat.h"
#include "Render/Types/VertexAttr.h"
#include "Render/Types/ResourceType.h"
#include "Render/Types/TransformType.h"

using namespace Oryol::Core;
using namespace Oryol::Render;

//------------------------------------------------------------------------------
TEST(PixelFormatTest) {
    CHECK(PixelFormat::NumPixelFormats == 15);

    CHECK(PixelFormat::FromString("R8G8B8A8") == PixelFormat::R8G8B8A8);
    CHECK(PixelFormat::FromString("R8G8B8") == PixelFormat::R8G8B8);
    CHECK(PixelFormat::FromString("R5G6B5") == PixelFormat::R5G6B5);
    CHECK(PixelFormat::FromString("R5G5B5A1") == PixelFormat::R5G5B5A1);
    CHECK(PixelFormat::FromString("R4G4B4A4") == PixelFormat::R4G4B4A4);
    CHECK(PixelFormat::FromString("L8") == PixelFormat::L8);
    CHECK(PixelFormat::FromString("DXT1") == PixelFormat::DXT1);
    CHECK(PixelFormat::FromString("DXT3") == PixelFormat::DXT3);
    CHECK(PixelFormat::FromString("DXT5") == PixelFormat::DXT5);
    CHECK(PixelFormat::FromString("D16") == PixelFormat::D16);
    CHECK(PixelFormat::FromString("D32") == PixelFormat::D32);
    CHECK(PixelFormat::FromString("D24S8") == PixelFormat::D24S8);
    CHECK(PixelFormat::FromString("R32F") == PixelFormat::R32F);
    CHECK(PixelFormat::FromString("PVRTC2") == PixelFormat::PVRTC2);
    CHECK(PixelFormat::FromString("PVRTC4") == PixelFormat::PVRTC4);

    CHECK(String(PixelFormat::ToString(PixelFormat::R8G8B8A8)) == "R8G8B8A8");
    CHECK(String(PixelFormat::ToString(PixelFormat::R8G8B8)) == "R8G8B8");
    CHECK(String(PixelFormat::ToString(PixelFormat::R5G6B5)) == "R5G6B5");
    CHECK(String(PixelFormat::ToString(PixelFormat::R5G5B5A1)) == "R5G5B5A1");
    CHECK(String(PixelFormat::ToString(PixelFormat::R4G4B4A4)) == "R4G4B4A4");
    CHECK(String(PixelFormat::ToString(PixelFormat::L8)) == "L8");
    CHECK(String(PixelFormat::ToString(PixelFormat::DXT1)) == "DXT1");
    CHECK(String(PixelFormat::ToString(PixelFormat::DXT3)) == "DXT3");
    CHECK(String(PixelFormat::ToString(PixelFormat::DXT5)) == "DXT5");
    CHECK(String(PixelFormat::ToString(PixelFormat::D16)) == "D16");
    CHECK(String(PixelFormat::ToString(PixelFormat::D32)) == "D32");
    CHECK(String(PixelFormat::ToString(PixelFormat::D24S8)) == "D24S8");
    CHECK(String(PixelFormat::ToString(PixelFormat::R32F)) == "R32F");
    CHECK(String(PixelFormat::ToString(PixelFormat::PVRTC2)) == "PVRTC2");
    CHECK(String(PixelFormat::ToString(PixelFormat::PVRTC4)) == "PVRTC4");
}

//------------------------------------------------------------------------------
TEST(TextureTypeTest) {
    CHECK(TextureType::NumTextureTypes == 3);
    CHECK(TextureType::FromString("Texture2D") == TextureType::Texture2D);
    CHECK(TextureType::FromString("Texture3D") == TextureType::Texture3D);
    CHECK(TextureType::FromString("TextureCube") == TextureType::TextureCube);
    CHECK(TextureType::FromString("Bla") == TextureType::InvalidTextureType);
    CHECK(String(TextureType::ToString(TextureType::Texture2D)) == "Texture2D");
    CHECK(String(TextureType::ToString(TextureType::Texture3D)) == "Texture3D");
    CHECK(String(TextureType::ToString(TextureType::TextureCube)) == "TextureCube");
}

//------------------------------------------------------------------------------
TEST(PrimitiveTypeTest) {
    CHECK(PrimitiveType::NumPrimitiveTypes == 7);

    CHECK(PrimitiveType::FromString("Points") == PrimitiveType::Points);
    CHECK(PrimitiveType::FromString("LineStrip") == PrimitiveType::LineStrip);
    CHECK(PrimitiveType::FromString("LineLoop") == PrimitiveType::LineLoop);
    CHECK(PrimitiveType::FromString("Lines") == PrimitiveType::Lines);
    CHECK(PrimitiveType::FromString("TriangleStrip") == PrimitiveType::TriangleStrip);
    CHECK(PrimitiveType::FromString("TriangleFan") == PrimitiveType::TriangleFan);
    CHECK(PrimitiveType::FromString("Triangles") == PrimitiveType::Triangles);

    CHECK(String(PrimitiveType::ToString(PrimitiveType::Points)) == "Points");
    CHECK(String(PrimitiveType::ToString(PrimitiveType::LineStrip)) == "LineStrip");
    CHECK(String(PrimitiveType::ToString(PrimitiveType::LineLoop)) == "LineLoop");
    CHECK(String(PrimitiveType::ToString(PrimitiveType::Lines)) == "Lines");
    CHECK(String(PrimitiveType::ToString(PrimitiveType::TriangleStrip)) == "TriangleStrip");
    CHECK(String(PrimitiveType::ToString(PrimitiveType::TriangleFan)) == "TriangleFan");
    CHECK(String(PrimitiveType::ToString(PrimitiveType::Triangles)) == "Triangles");
}

//------------------------------------------------------------------------------
TEST(UsageTest) {
    CHECK(Usage::NumUsages == 3);
    CHECK(Usage::FromString("Immutable") == Usage::Immutable);
    CHECK(Usage::FromString("DynamicWrite") == Usage::DynamicWrite);
    CHECK(Usage::FromString("DynamicStream") == Usage::DynamicStream);
    CHECK(Usage::FromString("Bla") == Usage::InvalidUsage);
    CHECK(String(Usage::ToString(Usage::Immutable)) == "Immutable");
    CHECK(String(Usage::ToString(Usage::DynamicWrite)) == "DynamicWrite");
    CHECK(String(Usage::ToString(Usage::DynamicStream)) == "DynamicStream");
}

//------------------------------------------------------------------------------
TEST(TextureWrapMode) {
    CHECK(TextureWrapMode::NumTextureWrapModes == 3);
    CHECK(TextureWrapMode::FromString("ClampToEdge") == TextureWrapMode::ClampToEdge);
    CHECK(TextureWrapMode::FromString("Repeat") == TextureWrapMode::Repeat);
    CHECK(TextureWrapMode::FromString("MirroredRepeat") == TextureWrapMode::MirroredRepeat);
    CHECK(String(TextureWrapMode::ToString(TextureWrapMode::ClampToEdge)) == "ClampToEdge");
    CHECK(String(TextureWrapMode::ToString(TextureWrapMode::Repeat)) == "Repeat");
    CHECK(String(TextureWrapMode::ToString(TextureWrapMode::MirroredRepeat)) == "MirroredRepeat");
}

//------------------------------------------------------------------------------
TEST(IndexTypeTest) {
    CHECK(IndexType::NumIndexTypes == 3);
    CHECK(IndexType::FromString("None") == IndexType::None);
    CHECK(IndexType::FromString("Index16") == IndexType::Index16);
    CHECK(IndexType::FromString("Index32") == IndexType::Index32);
    CHECK(String(IndexType::ToString(IndexType::None)) == "None");
    CHECK(String(IndexType::ToString(IndexType::Index16)) == "Index16");
    CHECK(String(IndexType::ToString(IndexType::Index32)) == "Index32");
    CHECK(IndexType::ByteSize(IndexType::Index16) == 2);
    CHECK(IndexType::ByteSize(IndexType::Index32) == 4);
}

//------------------------------------------------------------------------------
TEST(TextureFilterModeTest) {
    CHECK(TextureFilterMode::NumTextureFilterModes == 6);
    CHECK(TextureFilterMode::FromString("Nearest") == TextureFilterMode::Nearest);
    CHECK(TextureFilterMode::FromString("Linear") == TextureFilterMode::Linear);
    CHECK(TextureFilterMode::FromString("NearestMipmapNearest") == TextureFilterMode::NearestMipmapNearest);
    CHECK(TextureFilterMode::FromString("NearestMipmapLinear") == TextureFilterMode::NearestMipmapLinear);
    CHECK(TextureFilterMode::FromString("LinearMipmapNearest") == TextureFilterMode::LinearMipmapNearest);
    CHECK(TextureFilterMode::FromString("LinearMipmapLinear") == TextureFilterMode::LinearMipmapLinear);
    CHECK(String(TextureFilterMode::ToString(TextureFilterMode::Nearest)) == "Nearest");
    CHECK(String(TextureFilterMode::ToString(TextureFilterMode::Linear)) == "Linear");
    CHECK(String(TextureFilterMode::ToString(TextureFilterMode::NearestMipmapNearest)) == "NearestMipmapNearest");
    CHECK(String(TextureFilterMode::ToString(TextureFilterMode::NearestMipmapLinear)) == "NearestMipmapLinear");
    CHECK(String(TextureFilterMode::ToString(TextureFilterMode::LinearMipmapNearest)) == "LinearMipmapNearest");
    CHECK(String(TextureFilterMode::ToString(TextureFilterMode::LinearMipmapLinear)) == "LinearMipmapLinear");
}

//------------------------------------------------------------------------------
TEST(VertexFormatTest) {
    CHECK(VertexFormat::NumVertexFormats == 12);

    CHECK(VertexFormat::FromString("Float") == VertexFormat::Float);
    CHECK(VertexFormat::FromString("Float2") == VertexFormat::Float2);
    CHECK(VertexFormat::FromString("Float3") == VertexFormat::Float3);
    CHECK(VertexFormat::FromString("Float4") == VertexFormat::Float4);
    CHECK(VertexFormat::FromString("Byte4") == VertexFormat::Byte4);
    CHECK(VertexFormat::FromString("Byte4N") == VertexFormat::Byte4N);
    CHECK(VertexFormat::FromString("UByte4") == VertexFormat::UByte4);
    CHECK(VertexFormat::FromString("UByte4N") == VertexFormat::UByte4N);
    CHECK(VertexFormat::FromString("Short2") == VertexFormat::Short2);
    CHECK(VertexFormat::FromString("Short2N") == VertexFormat::Short2N);
    CHECK(VertexFormat::FromString("Short4") == VertexFormat::Short4);
    CHECK(VertexFormat::FromString("Short4N") == VertexFormat::Short4N);

    CHECK(String(VertexFormat::ToString(VertexFormat::Float)) == "Float");
    CHECK(String(VertexFormat::ToString(VertexFormat::Float2)) == "Float2");
    CHECK(String(VertexFormat::ToString(VertexFormat::Float3)) == "Float3");
    CHECK(String(VertexFormat::ToString(VertexFormat::Float4)) == "Float4");
    CHECK(String(VertexFormat::ToString(VertexFormat::Byte4)) == "Byte4");
    CHECK(String(VertexFormat::ToString(VertexFormat::Byte4N)) == "Byte4N");
    CHECK(String(VertexFormat::ToString(VertexFormat::UByte4)) == "UByte4");
    CHECK(String(VertexFormat::ToString(VertexFormat::UByte4N)) == "UByte4N");
    CHECK(String(VertexFormat::ToString(VertexFormat::Short2)) == "Short2");
    CHECK(String(VertexFormat::ToString(VertexFormat::Short2N)) == "Short2N");
    CHECK(String(VertexFormat::ToString(VertexFormat::Short4)) == "Short4");
    CHECK(String(VertexFormat::ToString(VertexFormat::Short4N)) == "Short4N");

    CHECK(VertexFormat::ByteSize(VertexFormat::Float) == 4);
    CHECK(VertexFormat::ByteSize(VertexFormat::Float2) == 8);
    CHECK(VertexFormat::ByteSize(VertexFormat::Float3) == 12);
    CHECK(VertexFormat::ByteSize(VertexFormat::Float4) == 16);
    CHECK(VertexFormat::ByteSize(VertexFormat::Byte4) == 4);
    CHECK(VertexFormat::ByteSize(VertexFormat::Byte4N) == 4);
    CHECK(VertexFormat::ByteSize(VertexFormat::UByte4) == 4);
    CHECK(VertexFormat::ByteSize(VertexFormat::UByte4N) == 4);
    CHECK(VertexFormat::ByteSize(VertexFormat::Short2) == 4);
    CHECK(VertexFormat::ByteSize(VertexFormat::Short2N) == 4);
    CHECK(VertexFormat::ByteSize(VertexFormat::Short4) == 8);
    CHECK(VertexFormat::ByteSize(VertexFormat::Short4N) == 8);
}

//------------------------------------------------------------------------------
TEST(VertexAttrTest) {
    CHECK(VertexAttr::NumVertexAttrs == 16);

    CHECK(VertexAttr::FromString("position") == VertexAttr::Position);
    CHECK(VertexAttr::FromString("normal") == VertexAttr::Normal);
    CHECK(VertexAttr::FromString("texcoord0") == VertexAttr::TexCoord0);
    CHECK(VertexAttr::FromString("texcoord1") == VertexAttr::TexCoord1);
    CHECK(VertexAttr::FromString("texcoord2") == VertexAttr::TexCoord2);
    CHECK(VertexAttr::FromString("texcoord3") == VertexAttr::TexCoord3);
    CHECK(VertexAttr::FromString("tangent") == VertexAttr::Tangent);
    CHECK(VertexAttr::FromString("binormal") == VertexAttr::Binormal);
    CHECK(VertexAttr::FromString("weights") == VertexAttr::Weights);
    CHECK(VertexAttr::FromString("indices") == VertexAttr::Indices);
    CHECK(VertexAttr::FromString("color0") == VertexAttr::Color0);
    CHECK(VertexAttr::FromString("color1") == VertexAttr::Color1);
    CHECK(VertexAttr::FromString("custom0") == VertexAttr::Custom0);
    CHECK(VertexAttr::FromString("custom1") == VertexAttr::Custom1);
    CHECK(VertexAttr::FromString("custom2") == VertexAttr::Custom2);
    CHECK(VertexAttr::FromString("custom3") == VertexAttr::Custom3);

    CHECK(String(VertexAttr::ToString(VertexAttr::Position)) == "position");
    CHECK(String(VertexAttr::ToString(VertexAttr::Normal)) == "normal");
    CHECK(String(VertexAttr::ToString(VertexAttr::TexCoord0)) == "texcoord0");
    CHECK(String(VertexAttr::ToString(VertexAttr::TexCoord1)) == "texcoord1");
    CHECK(String(VertexAttr::ToString(VertexAttr::TexCoord2)) == "texcoord2");
    CHECK(String(VertexAttr::ToString(VertexAttr::TexCoord3)) == "texcoord3");
    CHECK(String(VertexAttr::ToString(VertexAttr::Tangent)) == "tangent");
    CHECK(String(VertexAttr::ToString(VertexAttr::Binormal)) == "binormal");
    CHECK(String(VertexAttr::ToString(VertexAttr::Weights)) == "weights");
    CHECK(String(VertexAttr::ToString(VertexAttr::Indices)) == "indices");
    CHECK(String(VertexAttr::ToString(VertexAttr::Color0)) == "color0");
    CHECK(String(VertexAttr::ToString(VertexAttr::Color1)) == "color1");
    CHECK(String(VertexAttr::ToString(VertexAttr::Custom0)) == "custom0");
    CHECK(String(VertexAttr::ToString(VertexAttr::Custom1)) == "custom1");
    CHECK(String(VertexAttr::ToString(VertexAttr::Custom2)) == "custom2");
    CHECK(String(VertexAttr::ToString(VertexAttr::Custom3)) == "custom3");
}

//------------------------------------------------------------------------------
TEST(RenderResourceTypeTest) {
    CHECK(ResourceType::NumResourceTypes == 5);

    CHECK(ResourceType::FromString("Texture") == ResourceType::Texture);
    CHECK(ResourceType::FromString("Mesh") == ResourceType::Mesh);
    CHECK(ResourceType::FromString("Program") == ResourceType::Program);
    CHECK(ResourceType::FromString("StateBlock") == ResourceType::StateBlock);
    CHECK(ResourceType::FromString("ConstantBlock") == ResourceType::ConstantBlock);

    CHECK(String(ResourceType::ToString(ResourceType::Texture)) == "Texture");
    CHECK(String(ResourceType::ToString(ResourceType::Mesh)) == "Mesh");
    CHECK(String(ResourceType::ToString(ResourceType::Program)) == "Program");
    CHECK(String(ResourceType::ToString(ResourceType::StateBlock)) == "StateBlock");
    CHECK(String(ResourceType::ToString(ResourceType::ConstantBlock)) == "ConstantBlock");
}

//------------------------------------------------------------------------------
TEST(TransformTypeTest) {
    CHECK(TransformType::NumTransformTypes == 12);

    CHECK(TransformType::FromString("Model") == TransformType::Model);
    CHECK(TransformType::FromString("View") == TransformType::View);
    CHECK(TransformType::FromString("Proj") == TransformType::Proj);
    CHECK(TransformType::FromString("ModelView") == TransformType::ModelView);
    CHECK(TransformType::FromString("ViewProj") == TransformType::ViewProj);
    CHECK(TransformType::FromString("ModelViewProj") == TransformType::ModelViewProj);
    CHECK(TransformType::FromString("InvModel") == TransformType::InvModel);
    CHECK(TransformType::FromString("InvView") == TransformType::InvView);
    CHECK(TransformType::FromString("InvProj") == TransformType::InvProj);
    CHECK(TransformType::FromString("InvModelView") == TransformType::InvModelView);
    CHECK(TransformType::FromString("InvModelViewProj") == TransformType::InvModelViewProj);
    CHECK(TransformType::FromString("InvViewProj") == TransformType::InvViewProj);

    CHECK(String(TransformType::ToString(TransformType::Model)) == "Model");
    CHECK(String(TransformType::ToString(TransformType::View)) == "View");
    CHECK(String(TransformType::ToString(TransformType::Proj)) == "Proj");
    CHECK(String(TransformType::ToString(TransformType::ModelView)) == "ModelView");
    CHECK(String(TransformType::ToString(TransformType::ViewProj)) == "ViewProj");
    CHECK(String(TransformType::ToString(TransformType::ModelViewProj)) == "ModelViewProj");
    CHECK(String(TransformType::ToString(TransformType::InvModel)) == "InvModel");
    CHECK(String(TransformType::ToString(TransformType::InvView)) == "InvView");
    CHECK(String(TransformType::ToString(TransformType::InvProj)) == "InvProj");
    CHECK(String(TransformType::ToString(TransformType::InvModelView)) == "InvModelView");
    CHECK(String(TransformType::ToString(TransformType::InvModelViewProj)) == "InvModelViewProj");
    CHECK(String(TransformType::ToString(TransformType::InvViewProj)) == "InvViewProj");
}<|endoftext|>


<commit_before>#include "flashmem.h"
#include <EEPROM.h>

FlashMem::FlashMem() {}

void FlashMem::init() {
  this->content_valid = false;
  Serial.println("Initializing flashmem");

  EEPROM.begin(FLASHMEM_SZ);

  for(size_t i = 0; i < sizeof(content); i++) {
    this->content_bytes[i] = EEPROM.read(FLASHMEM_ADDR + i);
    Serial.print((char)this->content_bytes[i]);
  }

  Serial.println("");

  if (this->content.ssid_len <= 127 &&
      this->content.pwd_len  <= 127)
  {
    this->content_valid = true;
    this->content.ssid[content.ssid_len] = 0x00;
    this->content.pwd[content.pwd_len] = 0x00;
  }
}

bool FlashMem::is_valid() {
  return this->content_valid;
}

String FlashMem::get_ssid() {
  if (!this->content_valid)
    return "";

  return String((char*)this->content.ssid);
}

String FlashMem::get_password() {
  if (!this->content_valid)
    return "";

  return String((char*)this->content.pwd);
}

bool FlashMem::set_ssid(String &ssid) {
  if (!this->content_valid)
    return false;

  for (size_t i = 0; i < ssid.length(); i++)
    this->content.ssid[i] = ssid.c_str()[i];

  this->content.ssid[ssid.length()] = 0;
  this->content.ssid_len = ssid.length();
  return true;
}

bool FlashMem::set_password(String &password) {
  if (!this->content_valid)
    return false;

  for (size_t i = 0; i < password.length(); i++)
    this->content.pwd[i] = password.c_str()[i];

  this->content.pwd[password.length()] = 0;
  this->content.pwd_len = password.length();
  return true;
}

bool FlashMem::commit() {
  for (size_t i = 0; i < sizeof(content); i++)
    EEPROM.write(FLASHMEM_ADDR + i, this->content_bytes[i]);

  if (this->content.ssid_len <= 127 &&
      this->content.pwd_len  <= 127)
    this->content_valid = true;

  return EEPROM.commit();
}
<commit_msg>More debug<commit_after>#include "flashmem.h"
#include <EEPROM.h>

FlashMem::FlashMem() {}

void FlashMem::init() {
  this->content_valid = false;
  Serial.println("Initializing flashmem");

  EEPROM.begin(FLASHMEM_SZ);

  for(size_t i = 0; i < sizeof(this->content); i++) {
    this->content_bytes[i] = EEPROM.read(FLASHMEM_ADDR + i);
    Serial.print((char)this->content_bytes[i]);
  }

  Serial.println("");

  if (this->content.ssid_len <= 127 &&
      this->content.pwd_len  <= 127)
  {
    this->content_valid = true;
    this->content.ssid[content.ssid_len] = 0x00;
    this->content.pwd[content.pwd_len] = 0x00;
  }
}

bool FlashMem::is_valid() {
  return this->content_valid;
}

String FlashMem::get_ssid() {
  if (!this->content_valid)
    return "";

  return String((char*)this->content.ssid);
}

String FlashMem::get_password() {
  if (!this->content_valid)
    return "";

  return String((char*)this->content.pwd);
}

bool FlashMem::set_ssid(String &ssid) {
  if (!this->content_valid)
    return false;

  for (size_t i = 0; i < ssid.length(); i++)
    this->content.ssid[i] = ssid.c_str()[i];

  this->content.ssid[ssid.length()] = 0;
  this->content.ssid_len = ssid.length();
  return true;
}

bool FlashMem::set_password(String &password) {
  if (!this->content_valid)
    return false;

  for (size_t i = 0; i < password.length(); i++)
    this->content.pwd[i] = password.c_str()[i];

  this->content.pwd[password.length()] = 0;
  this->content.pwd_len = password.length();
  return true;
}

bool FlashMem::commit() {
  for (size_t i = 0; i < sizeof(this->content); i++) {
    EEPROM.write(FLASHMEM_ADDR + i, this->content_bytes[i]);
    Serial.print((char)this->content_bytes[i]);
  }

  Serial.println("");

  if (this->content.ssid_len <= 127 &&
      this->content.pwd_len  <= 127)
    this->content_valid = true;

  return EEPROM.commit();
}
<|endoftext|>


<commit_before>#ifndef _PNMC_CONF_CONFIGURATION_HH_
#define _PNMC_CONF_CONFIGURATION_HH_

#include <chrono>
#include <iosfwd>
#include <string>

#include <boost/optional.hpp>

namespace pnmc { namespace conf {

/*------------------------------------------------------------------------------------------------*/

enum class input_format {bpn, prod, tina, xml};

struct pnmc_configuration
{
  std::string file_name;
  input_format file_type;
  bool read_stdin;
  bool delete_file;

  bool order_random;
  bool order_show;
  bool order_force_flat;
  bool order_ordering_force;
  unsigned int order_min_height;

  bool show_relation;
  bool show_time;

  bool compute_dead_transitions;
  bool compute_dead_states;
  unsigned int marking_bound;

  bool show_final_sdd_bytes;

  boost::optional<std::string> export_final_sdd_dot_file;
  boost::optional<std::string> export_to_lua_file;
  boost::optional<std::string> json_file;
  boost::optional<std::string> hypergraph_dot_file;

  std::chrono::duration<double> max_time;
};

/*------------------------------------------------------------------------------------------------*/

}} // namespace pnmc::configuration

#endif // _PNMC_CONF_CONFIGURATION_HH_
<commit_msg>Comments.<commit_after>#ifndef _PNMC_CONF_CONFIGURATION_HH_
#define _PNMC_CONF_CONFIGURATION_HH_

#include <chrono>
#include <iosfwd>
#include <string>

#include <boost/optional.hpp>

namespace pnmc { namespace conf {

/*------------------------------------------------------------------------------------------------*/

/// @brief The accepted input formats.
enum class input_format {bpn, prod, tina, xml};

/*------------------------------------------------------------------------------------------------*/

/// @brief The configuration of pnmc at runtime.
struct pnmc_configuration
{
  /// @brief The model's file to process.
  std::string file_name;

  /// @brief The model's format to process.
  input_format file_type;

  /// @brief Read from standard input rather than from a file.
  bool read_stdin;

  /// @brief Delete model file after reading it.
  bool delete_file;

  /// @brief A random order is computed.
  bool order_random;

  /// @brief Show order after its creation.
  bool order_show;

  /// @brief Remove all hierarchy from order.
  bool order_force_flat;

  /// @brief Use the FORCE ordering heuristic.
  bool order_ordering_force;
  unsigned int order_min_height;

  /// @brief Show the homomorphism of the transition relation.
  bool show_relation;

  /// @brief Show the time spent in various steps.
  bool show_time;

  /// @bref Display, if any, dead transitions.
  bool compute_dead_transitions;

  /// @brief Display, if any, dead states.
  bool compute_dead_states;

  /// @brief Stop state space generation if a place's marking reaches this limit.
  unsigned int marking_bound;

  /// @brief Display the memory usage of the state space's SDD.
  bool show_final_sdd_bytes;

  boost::optional<std::string> export_final_sdd_dot_file;
  boost::optional<std::string> export_to_lua_file;
  boost::optional<std::string> json_file;
  boost::optional<std::string> hypergraph_dot_file;

  /// @brief Stop state space generation after this much time.
  std::chrono::duration<double> max_time;
};

/*------------------------------------------------------------------------------------------------*/

}} // namespace pnmc::configuration

#endif // _PNMC_CONF_CONFIGURATION_HH_
<|endoftext|>