Refactor library GC to its own namespace

This commit is contained in:
Ilari Liusvaara 2014-11-10 16:06:04 +02:00
parent 9a69dc3511
commit b5ed0f73b1
10 changed files with 77 additions and 72 deletions

View file

@ -32,8 +32,8 @@ struct memwatch_printer
/** /**
* Get a printer object corresponding to this object. * Get a printer object corresponding to this object.
*/ */
gcroot_pointer<memorywatch::item_printer> get_printer_obj( GC::pointer<memorywatch::item_printer> get_printer_obj(
std::function<gcroot_pointer<mathexpr::mathexpr>(const std::string& n)> vars); std::function<GC::pointer<mathexpr::mathexpr>(const std::string& n)> vars);
//Fields. //Fields.
enum position_category { enum position_category {
PC_DISABLED, PC_DISABLED,

View file

@ -3,11 +3,13 @@
#include <cstdlib> #include <cstdlib>
class garbage_collectable namespace GC
{
class item
{ {
public: public:
garbage_collectable(); item();
virtual ~garbage_collectable(); virtual ~item();
void mark_root(); void mark_root();
void unmark_root(); void unmark_root();
static void do_gc(); static void do_gc();
@ -19,28 +21,28 @@ private:
bool reachable; bool reachable;
}; };
struct gcroot_pointer_object_tag {}; struct obj_tag {};
template<class T> class gcroot_pointer template<class T> class pointer
{ {
public: public:
gcroot_pointer() pointer()
{ {
ptr = NULL; ptr = NULL;
} }
gcroot_pointer(T* obj) pointer(T* obj)
{ {
ptr = obj; ptr = obj;
} }
template<typename... U> gcroot_pointer(gcroot_pointer_object_tag tag, U... args) template<typename... U> pointer(obj_tag tag, U... args)
{ {
ptr = new T(args...); ptr = new T(args...);
} }
gcroot_pointer(const gcroot_pointer& p) pointer(const pointer& p)
{ {
if(p.ptr) p.ptr->mark_root(); if(p.ptr) p.ptr->mark_root();
ptr = p.ptr; ptr = p.ptr;
} }
gcroot_pointer& operator=(const gcroot_pointer& p) pointer& operator=(const pointer& p)
{ {
if(ptr == p.ptr) return *this; if(ptr == p.ptr) return *this;
if(ptr) ptr->unmark_root(); if(ptr) ptr->unmark_root();
@ -48,7 +50,7 @@ public:
ptr = p.ptr; ptr = p.ptr;
return *this; return *this;
} }
~gcroot_pointer() ~pointer()
{ {
if(ptr) ptr->unmark_root(); if(ptr) ptr->unmark_root();
} }
@ -62,5 +64,6 @@ public:
private: private:
T* ptr; T* ptr;
}; };
}
#endif #endif

View file

@ -216,7 +216,7 @@ template<class T> struct typeinfo_wrapper : public typeinfo
} }
}; };
class mathexpr : public garbage_collectable class mathexpr : public GC::item
{ {
public: public:
enum eval_state enum eval_state
@ -234,13 +234,13 @@ public:
//Undefined value of specified type. //Undefined value of specified type.
mathexpr(typeinfo* _type); mathexpr(typeinfo* _type);
//Forward evaluation. //Forward evaluation.
mathexpr(typeinfo* _type, gcroot_pointer<mathexpr> fwd); mathexpr(typeinfo* _type, GC::pointer<mathexpr> fwd);
//Value of specified type. //Value of specified type.
mathexpr(value value); mathexpr(value value);
//Value of specified type. //Value of specified type.
mathexpr(typeinfo* _type, const std::string& value, bool string); mathexpr(typeinfo* _type, const std::string& value, bool string);
//Specified Operator. //Specified Operator.
mathexpr(typeinfo* _type, operinfo* fn, std::vector<gcroot_pointer<mathexpr>> _args, mathexpr(typeinfo* _type, operinfo* fn, std::vector<GC::pointer<mathexpr>> _args,
bool _owns_operator = false); bool _owns_operator = false);
//Dtor. //Dtor.
~mathexpr(); ~mathexpr();
@ -254,8 +254,8 @@ public:
//Reset. //Reset.
void reset(); void reset();
//Parse an expression. //Parse an expression.
static gcroot_pointer<mathexpr> parse(typeinfo& _type, const std::string& expr, static GC::pointer<mathexpr> parse(typeinfo& _type, const std::string& expr,
std::function<gcroot_pointer<mathexpr>(const std::string&)> vars); std::function<GC::pointer<mathexpr>(const std::string&)> vars);
protected: protected:
void trace(); void trace();
private: private:

View file

@ -21,9 +21,9 @@ struct output_fb : public item_printer
void show(const std::string& iname, const std::string& val); void show(const std::string& iname, const std::string& val);
void reset(); void reset();
bool cond_enable; bool cond_enable;
gcroot_pointer<mathexpr::mathexpr> enabled; GC::pointer<mathexpr::mathexpr> enabled;
gcroot_pointer<mathexpr::mathexpr> pos_x; GC::pointer<mathexpr::mathexpr> pos_x;
gcroot_pointer<mathexpr::mathexpr> pos_y; GC::pointer<mathexpr::mathexpr> pos_y;
bool alt_origin_x; bool alt_origin_x;
bool alt_origin_y; bool alt_origin_y;
bool cliprange_x; bool cliprange_x;

View file

@ -16,7 +16,7 @@ struct output_list : public item_printer
void show(const std::string& iname, const std::string& val); void show(const std::string& iname, const std::string& val);
void reset(); void reset();
bool cond_enable; bool cond_enable;
gcroot_pointer<mathexpr::mathexpr> enabled; GC::pointer<mathexpr::mathexpr> enabled;
//State variables. //State variables.
std::function<void(const std::string& n, const std::string& v)> fn; std::function<void(const std::string& n, const std::string& v)> fn;
}; };

View file

@ -43,7 +43,7 @@ struct memread_oper : public mathexpr::operinfo
/** /**
* Memory watch item printer. * Memory watch item printer.
*/ */
struct item_printer : public garbage_collectable struct item_printer : public GC::item
{ {
/** /**
* Dtor. * Dtor.
@ -72,7 +72,7 @@ struct item
* Parameter t: The type of the result. * Parameter t: The type of the result.
*/ */
item(mathexpr::typeinfo& t) item(mathexpr::typeinfo& t)
: expr(gcroot_pointer_object_tag(), &t) : expr(GC::obj_tag(), &t)
{ {
} }
/** /**
@ -86,8 +86,8 @@ struct item
*/ */
void show(const std::string& iname); void show(const std::string& iname);
//Fields. //Fields.
gcroot_pointer<item_printer> printer; //Printer to use. GC::pointer<item_printer> printer; //Printer to use.
gcroot_pointer<mathexpr::mathexpr> expr; //Expression to watch. GC::pointer<mathexpr::mathexpr> expr; //Expression to watch.
std::string format; //Formatting to use. std::string format; //Formatting to use.
}; };

View file

@ -156,10 +156,10 @@ void memwatch_printer::unserialize(const JSON::node& node)
onscreen_halo_color = json_signed_default(node, "onscreen_halo_color", false); onscreen_halo_color = json_signed_default(node, "onscreen_halo_color", false);
} }
gcroot_pointer<memorywatch::item_printer> memwatch_printer::get_printer_obj( GC::pointer<memorywatch::item_printer> memwatch_printer::get_printer_obj(
std::function<gcroot_pointer<mathexpr::mathexpr>(const std::string& n)> vars) std::function<GC::pointer<mathexpr::mathexpr>(const std::string& n)> vars)
{ {
gcroot_pointer<memorywatch::item_printer> ptr; GC::pointer<memorywatch::item_printer> ptr;
memorywatch::output_list* l; memorywatch::output_list* l;
memorywatch::output_fb* f; memorywatch::output_fb* f;
@ -167,10 +167,10 @@ gcroot_pointer<memorywatch::item_printer> memwatch_printer::get_printer_obj(
switch(position) { switch(position) {
case PC_DISABLED: case PC_DISABLED:
ptr = gcroot_pointer<memorywatch::item_printer>(new memorywatch::output_null); ptr = GC::pointer<memorywatch::item_printer>(new memorywatch::output_null);
break; break;
case PC_MEMORYWATCH: case PC_MEMORYWATCH:
ptr = gcroot_pointer<memorywatch::item_printer>(new memorywatch::output_list); ptr = GC::pointer<memorywatch::item_printer>(new memorywatch::output_list);
l = dynamic_cast<memorywatch::output_list*>(ptr.as_pointer()); l = dynamic_cast<memorywatch::output_list*>(ptr.as_pointer());
l->cond_enable = cond_enable; l->cond_enable = cond_enable;
try { try {
@ -184,7 +184,7 @@ gcroot_pointer<memorywatch::item_printer> memwatch_printer::get_printer_obj(
l->set_output(dummy_target_fn); l->set_output(dummy_target_fn);
break; break;
case PC_ONSCREEN: case PC_ONSCREEN:
ptr = gcroot_pointer<memorywatch::item_printer>(new memorywatch::output_fb); ptr = GC::pointer<memorywatch::item_printer>(new memorywatch::output_fb);
f = dynamic_cast<memorywatch::output_fb*>(ptr.as_pointer()); f = dynamic_cast<memorywatch::output_fb*>(ptr.as_pointer());
f->font = NULL; f->font = NULL;
f->set_dtor_cb([](memorywatch::output_fb& obj) { put_font(obj.font); }); f->set_dtor_cb([](memorywatch::output_fb& obj) { put_font(obj.font); });
@ -497,19 +497,19 @@ void memwatch_set::rebuild(std::map<std::string, memwatch_item>& nitems)
{ {
{ {
memorywatch::set new_set; memorywatch::set new_set;
std::map<std::string, gcroot_pointer<mathexpr::mathexpr>> vars; std::map<std::string, GC::pointer<mathexpr::mathexpr>> vars;
auto vars_fn = [&vars](const std::string& n) -> gcroot_pointer<mathexpr::mathexpr> { auto vars_fn = [&vars](const std::string& n) -> GC::pointer<mathexpr::mathexpr> {
if(!vars.count(n)) if(!vars.count(n))
vars[n] = gcroot_pointer<mathexpr::mathexpr>(gcroot_pointer_object_tag(), vars[n] = GC::pointer<mathexpr::mathexpr>(GC::obj_tag(),
mathexpr::expression_value()); mathexpr::expression_value());
return vars[n]; return vars[n];
}; };
for(auto& i : nitems) { for(auto& i : nitems) {
mathexpr::operinfo* memread_oper = i.second.get_memread_oper(); mathexpr::operinfo* memread_oper = i.second.get_memread_oper();
try { try {
gcroot_pointer<mathexpr::mathexpr> rt_expr; GC::pointer<mathexpr::mathexpr> rt_expr;
gcroot_pointer<memorywatch::item_printer> rt_printer; GC::pointer<memorywatch::item_printer> rt_printer;
std::vector<gcroot_pointer<mathexpr::mathexpr>> v; std::vector<GC::pointer<mathexpr::mathexpr>> v;
try { try {
rt_expr = mathexpr::mathexpr::parse(*mathexpr::expression_value(), rt_expr = mathexpr::mathexpr::parse(*mathexpr::expression_value(),
i.second.expr, vars_fn); i.second.expr, vars_fn);
@ -519,7 +519,7 @@ void memwatch_set::rebuild(std::map<std::string, memwatch_item>& nitems)
} }
v.push_back(rt_expr); v.push_back(rt_expr);
if(memread_oper) { if(memread_oper) {
rt_expr = gcroot_pointer<mathexpr::mathexpr>(gcroot_pointer_object_tag(), rt_expr = GC::pointer<mathexpr::mathexpr>(GC::obj_tag(),
mathexpr::expression_value(), memread_oper, v, true); mathexpr::expression_value(), memread_oper, v, true);
memread_oper = NULL; memread_oper = NULL;
} }
@ -545,7 +545,7 @@ void memwatch_set::rebuild(std::map<std::string, memwatch_item>& nitems)
} }
watch_set.swap(new_set); watch_set.swap(new_set);
} }
garbage_collectable::do_gc(); GC::item::do_gc();
} }
void memwatch_set::watch_output(const std::string& name, const std::string& value) void memwatch_set::watch_output(const std::string& name, const std::string& value)

View file

@ -3,34 +3,36 @@
#include <iostream> #include <iostream>
#include <set> #include <set>
namespace GC
{
namespace namespace
{ {
std::set<garbage_collectable*>* gc_items; std::set<item*>* gc_items;
} }
garbage_collectable::garbage_collectable() item::item()
{ {
if(!gc_items) gc_items = new std::set<garbage_collectable*>; if(!gc_items) gc_items = new std::set<item*>;
gc_items->insert(this); gc_items->insert(this);
root_count = 1; root_count = 1;
} }
garbage_collectable::~garbage_collectable() item::~item()
{ {
gc_items->erase(this); gc_items->erase(this);
} }
void garbage_collectable::mark_root() void item::mark_root()
{ {
root_count++; root_count++;
} }
void garbage_collectable::unmark_root() void item::unmark_root()
{ {
if(root_count) root_count--; if(root_count) root_count--;
} }
void garbage_collectable::do_gc() void item::do_gc()
{ {
if(!gc_items) return; if(!gc_items) return;
for(auto i : *gc_items) for(auto i : *gc_items)
@ -50,7 +52,7 @@ void garbage_collectable::do_gc()
} }
} }
void garbage_collectable::mark() void item::mark()
{ {
bool was_reachable = reachable; bool was_reachable = reachable;
reachable = true; reachable = true;
@ -58,3 +60,4 @@ void garbage_collectable::mark()
trace(); trace();
} }
} }
}

View file

@ -30,7 +30,7 @@ mathexpr::mathexpr(typeinfo* _type)
fn = (operinfo*)0xDEADBEEF; fn = (operinfo*)0xDEADBEEF;
} }
mathexpr::mathexpr(typeinfo* _type, gcroot_pointer<mathexpr> fwd) mathexpr::mathexpr(typeinfo* _type, GC::pointer<mathexpr> fwd)
: type(*_type) : type(*_type)
{ {
owns_operator = false; owns_operator = false;
@ -58,8 +58,7 @@ mathexpr::mathexpr(typeinfo* _type, const std::string& _val, bool string)
fn = NULL; fn = NULL;
} }
mathexpr::mathexpr(typeinfo* _type, operinfo* _fn, std::vector<gcroot_pointer<mathexpr>> _args, mathexpr::mathexpr(typeinfo* _type, operinfo* _fn, std::vector<GC::pointer<mathexpr>> _args, bool _owns_operator)
bool _owns_operator)
: type(*_type), fn(_fn), owns_operator(_owns_operator) : type(*_type), fn(_fn), owns_operator(_owns_operator)
{ {
try { try {
@ -354,18 +353,18 @@ namespace
struct expr_or_op struct expr_or_op
{ {
expr_or_op(gcroot_pointer<mathexpr> e) : expr(e), typei(NULL) {} expr_or_op(GC::pointer<mathexpr> e) : expr(e), typei(NULL) {}
expr_or_op(std::string o) : op(o), typei(NULL) {} expr_or_op(std::string o) : op(o), typei(NULL) {}
gcroot_pointer<mathexpr> expr; GC::pointer<mathexpr> expr;
std::string op; std::string op;
operinfo* typei; operinfo* typei;
}; };
gcroot_pointer<mathexpr> parse_rec(typeinfo& _type, std::vector<expr_or_op>& operands, GC::pointer<mathexpr> parse_rec(typeinfo& _type, std::vector<expr_or_op>& operands,
size_t first, size_t last) size_t first, size_t last)
{ {
if(operands.empty()) if(operands.empty())
return gcroot_pointer<mathexpr>(gcroot_pointer_object_tag(), &_type); return GC::pointer<mathexpr>(GC::obj_tag(), &_type);
if(last - first > 1) { if(last - first > 1) {
//Find the highest percedence operator. //Find the highest percedence operator.
size_t best = last; size_t best = last;
@ -387,29 +386,29 @@ namespace
size_t j = first; size_t j = first;
while(operands[j].typei) while(operands[j].typei)
j++; j++;
std::vector<gcroot_pointer<mathexpr>> args; std::vector<GC::pointer<mathexpr>> args;
args.push_back(parse_rec(_type, operands, first + 1, j + 1)); args.push_back(parse_rec(_type, operands, first + 1, j + 1));
return gcroot_pointer<mathexpr>(gcroot_pointer_object_tag(), &_type, return GC::pointer<mathexpr>(GC::obj_tag(), &_type,
operands[best].typei, args); operands[best].typei, args);
} else { } else {
//Binary operator. //Binary operator.
std::vector<gcroot_pointer<mathexpr>> args; std::vector<GC::pointer<mathexpr>> args;
args.push_back(parse_rec(_type, operands, first, best)); args.push_back(parse_rec(_type, operands, first, best));
args.push_back(parse_rec(_type, operands, best + 1, last)); args.push_back(parse_rec(_type, operands, best + 1, last));
return gcroot_pointer<mathexpr>(gcroot_pointer_object_tag(), &_type, return GC::pointer<mathexpr>(GC::obj_tag(), &_type,
operands[best].typei, args); operands[best].typei, args);
} }
} }
return operands[first].expr; return operands[first].expr;
} }
gcroot_pointer<mathexpr> parse_rec(typeinfo& _type, std::vector<subexpression>& ss, GC::pointer<mathexpr> parse_rec(typeinfo& _type, std::vector<subexpression>& ss,
std::set<operinfo*>& operations, std::set<operinfo*>& operations,
std::function<gcroot_pointer<mathexpr>(const std::string&)> vars, size_t first, size_t last) std::function<GC::pointer<mathexpr>(const std::string&)> vars, size_t first, size_t last)
{ {
operations_set opset(operations); operations_set opset(operations);
std::vector<expr_or_op> operands; std::vector<expr_or_op> operands;
std::vector<gcroot_pointer<mathexpr>> args; std::vector<GC::pointer<mathexpr>> args;
operinfo* fn; operinfo* fn;
for(size_t i = first; i < last; i++) { for(size_t i = first; i < last; i++) {
size_t l = find_last_in_sub(ss, i); size_t l = find_last_in_sub(ss, i);
@ -419,16 +418,16 @@ namespace
operands.push_back(parse_rec(_type, ss, operations, vars, i + 1, l)); operands.push_back(parse_rec(_type, ss, operations, vars, i + 1, l));
break; break;
case TT_VALUE: case TT_VALUE:
operands.push_back(gcroot_pointer<mathexpr>(gcroot_pointer_object_tag(), &_type, operands.push_back(GC::pointer<mathexpr>(GC::obj_tag(), &_type,
ss[i].string, false)); ss[i].string, false));
break; break;
case TT_STRING: case TT_STRING:
operands.push_back(gcroot_pointer<mathexpr>(gcroot_pointer_object_tag(), &_type, operands.push_back(GC::pointer<mathexpr>(GC::obj_tag(), &_type,
ss[i].string, true)); ss[i].string, true));
break; break;
case TT_VARIABLE: case TT_VARIABLE:
//We have to warp this is identify transform to make the evaluation lazy. //We have to warp this is identify transform to make the evaluation lazy.
operands.push_back(gcroot_pointer<mathexpr>(gcroot_pointer_object_tag(), &_type, operands.push_back(GC::pointer<mathexpr>(GC::obj_tag(), &_type,
vars(ss[i].string))); vars(ss[i].string)));
break; break;
case TT_FUNCTION: case TT_FUNCTION:
@ -442,7 +441,7 @@ namespace
else else
i = k; i = k;
} }
operands.push_back(gcroot_pointer<mathexpr>(gcroot_pointer_object_tag(), &_type, fn, operands.push_back(GC::pointer<mathexpr>(GC::obj_tag(), &_type, fn,
args)); args));
args.clear(); args.clear();
break; break;
@ -462,8 +461,8 @@ namespace
if(!(bool)i.expr) { if(!(bool)i.expr) {
auto fn = opset.find_operator(i.op, 0); auto fn = opset.find_operator(i.op, 0);
if(fn) if(fn)
i.expr = gcroot_pointer<mathexpr>(gcroot_pointer_object_tag(), &_type, fn, i.expr = GC::pointer<mathexpr>(GC::obj_tag(), &_type, fn,
std::vector<gcroot_pointer<mathexpr>>()); std::vector<GC::pointer<mathexpr>>());
} }
} }
//Check that there aren't two consequtive subexpressions and mark operators. //Check that there aren't two consequtive subexpressions and mark operators.
@ -615,8 +614,8 @@ namespace
} }
} }
gcroot_pointer<mathexpr> mathexpr::parse(typeinfo& _type, const std::string& expr, GC::pointer<mathexpr> mathexpr::parse(typeinfo& _type, const std::string& expr,
std::function<gcroot_pointer<mathexpr>(const std::string&)> vars) std::function<GC::pointer<mathexpr>(const std::string&)> vars)
{ {
if(expr == "") if(expr == "")
throw std::runtime_error("Empty expression"); throw std::runtime_error("Empty expression");

View file

@ -230,7 +230,7 @@ void item::show(const std::string& n)
set::~set() set::~set()
{ {
roots.clear(); roots.clear();
garbage_collectable::do_gc(); GC::item::do_gc();
} }
void set::reset() void set::reset()
@ -284,7 +284,7 @@ void set::destroy(const std::string& name)
if(!roots.count(name)) if(!roots.count(name))
return; return;
roots.erase(name); roots.erase(name);
garbage_collectable::do_gc(); GC::item::do_gc();
} }
const std::string& set::get_longest_name(std::function<size_t(const std::string& n)> rate) const std::string& set::get_longest_name(std::function<size_t(const std::string& n)> rate)