changed entry_finalizer scheme to use objects, not just function pointers

This commit is contained in:
John Wiegley 2004-09-24 04:10:39 -04:00
parent c715528f2f
commit 4f56735dfa
6 changed files with 72 additions and 64 deletions

View file

@ -27,29 +27,4 @@ void automated_transaction_t::extend_entry(entry_t& entry)
} }
} }
automated_transactions_t * current_auto_xacts = NULL;
bool handle_auto_xacts(entry_t& entry)
{
if (current_auto_xacts &&
! current_auto_xacts->automated_transactions.empty())
current_auto_xacts->extend_entry(entry);
return true;
}
} // namespace ledger } // namespace ledger
#ifdef USE_BOOST_PYTHON
#include <boost/python.hpp>
#include <Python.h>
using namespace boost::python;
using namespace ledger;
void export_autoxact() {
def("handle_auto_xacts", handle_auto_xacts);
}
#endif // USE_BOOST_PYTHON

View file

@ -88,9 +88,14 @@ public:
} }
}; };
extern automated_transactions_t * current_auto_xacts; struct autoxact_finalizer_t : public entry_finalizer_t {
automated_transactions_t auto_xacts;
bool handle_auto_xacts(entry_t& entry); virtual bool operator()(entry_t& entry) {
if (! auto_xacts.automated_transactions.empty())
auto_xacts.extend_entry(entry);
return true;
}
};
} // namespace ledger } // namespace ledger

View file

@ -360,6 +360,7 @@ journal_t::~journal_t()
{ {
DEBUG_PRINT("ledger.memory.dtors", "dtor journal_t"); DEBUG_PRINT("ledger.memory.dtors", "dtor journal_t");
delete default_finalizer;
delete master; delete master;
// Don't bother unhooking each entry's transactions from the // Don't bother unhooking each entry's transactions from the
@ -574,27 +575,42 @@ account_t * py_find_account_2(journal_t& journal, const std::string& name,
return journal.find_account(name, auto_create); return journal.find_account(name, auto_create);
} }
#if 0 struct py_entry_finalizer_t : public entry_finalizer_t {
object pyobj;
py_entry_finalizer_t() {}
py_entry_finalizer_t(object obj) : pyobj(obj) {}
py_entry_finalizer_t(const py_entry_finalizer_t& other)
: pyobj(other.pyobj) {}
virtual bool operator()(entry_t& entry) {
return call<bool>(pyobj.ptr(), entry);
}
};
void py_add_entry_finalize_hook(journal_t& journal, object x) std::list<py_entry_finalizer_t> py_finalizers;
void py_add_entry_finalizer(journal_t& journal, object x)
{ {
add_hook(journal.entry_finalize_hooks, py_finalizers.push_back(py_entry_finalizer_t(x));
extract<journal_t::entry_finalize_hook_t>(x)); add_hook<entry_finalizer_t *>(journal.entry_finalize_hooks,
&py_finalizers.back());
} }
void py_remove_entry_finalize_hook(journal_t& journal, object x) void py_remove_entry_finalizer(journal_t& journal, object x)
{ {
remove_hook(journal.entry_finalize_hooks, for (std::list<py_entry_finalizer_t>::iterator i = py_finalizers.begin();
extract<journal_t::entry_finalize_hook_t>(x)); i != py_finalizers.end();
i++)
if ((*i).pyobj == x) {
remove_hook<entry_finalizer_t *>(journal.entry_finalize_hooks, &(*i));
return;
}
} }
void py_run_entry_finalize_hooks(journal_t& journal, entry_t& entry) void py_run_entry_finalizers(journal_t& journal, entry_t& entry)
{ {
run_hooks(journal.entry_finalize_hooks, entry); run_hooks(journal.entry_finalize_hooks, entry);
} }
#endif
#define EXC_TRANSLATOR(type) \ #define EXC_TRANSLATOR(type) \
void exc_translate_ ## type(const type& err) { \ void exc_translate_ ## type(const type& err) { \
PyErr_SetString(PyExc_RuntimeError, err.what()); \ PyErr_SetString(PyExc_RuntimeError, err.what()); \
@ -682,11 +698,9 @@ void export_journal()
.def("add_entry", &journal_t::add_entry) .def("add_entry", &journal_t::add_entry)
.def("remove_entry", &journal_t::remove_entry) .def("remove_entry", &journal_t::remove_entry)
#if 0 .def("add_entry_finalizer", py_add_entry_finalizer)
.def("add_entry_finalize_hook", py_add_entry_finalize_hook) .def("remove_entry_finalizer", py_remove_entry_finalizer)
.def("remove_entry_finalize_hook", py_remove_entry_finalize_hook) .def("run_entry_finalizers", py_run_entry_finalizers)
.def("run_entry_finalize_hooks", py_run_entry_finalize_hooks)
#endif
.def("valid", &journal_t::valid) .def("valid", &journal_t::valid)
; ;

View file

@ -174,25 +174,40 @@ class account_t
std::ostream& operator<<(std::ostream& out, const account_t& account); std::ostream& operator<<(std::ostream& out, const account_t& account);
struct entry_finalizer_t {
virtual ~entry_finalizer_t() {}
virtual bool operator()(entry_t& entry) = 0;
};
struct func_finalizer_t : public entry_finalizer_t {
typedef bool (*func_t)(entry_t& entry);
func_t func;
func_finalizer_t(func_t _func) : func(_func) {}
func_finalizer_t(const func_finalizer_t& other) : func(other.func) {}
virtual bool operator()(entry_t& entry) {
return func(entry);
}
};
template <typename T> template <typename T>
void add_hook(std::list<T>& list, T func, const bool prepend = false) { void add_hook(std::list<T>& list, T obj, const bool prepend = false) {
if (prepend) if (prepend)
list.push_front(func); list.push_front(obj);
else else
list.push_back(func); list.push_back(obj);
} }
template <typename T> template <typename T>
void remove_hook(std::list<T>& list, T func) { void remove_hook(std::list<T>& list, T obj) {
list.remove(func); list.remove(obj);
} }
template <typename T, typename Data> template <typename T, typename Data>
bool run_hooks(std::list<T>& list, Data& entry) { bool run_hooks(std::list<T>& list, Data& item) {
for (typename std::list<T>::const_iterator i = list.begin(); for (typename std::list<T>::const_iterator i = list.begin();
i != list.end(); i != list.end();
i++) i++)
if (! (*i)(entry)) if (! (*(*i))(item))
return false; return false;
return true; return true;
} }
@ -212,14 +227,14 @@ class journal_t
mutable accounts_map accounts_cache; mutable accounts_map accounts_cache;
typedef bool (*entry_finalize_hook_t)(entry_t& entry); std::list<entry_finalizer_t *> entry_finalize_hooks;
entry_finalizer_t * default_finalizer;
std::list<entry_finalize_hook_t> entry_finalize_hooks;
journal_t() { journal_t() {
master = new account_t(NULL, ""); master = new account_t(NULL, "");
item_pool = item_pool_end = NULL; item_pool = item_pool_end = NULL;
add_hook(entry_finalize_hooks, finalize_entry); default_finalizer = new func_finalizer_t(finalize_entry);
add_hook(entry_finalize_hooks, default_finalizer);
} }
~journal_t(); ~journal_t();

View file

@ -28,7 +28,6 @@ void export_walk();
void export_format(); void export_format();
void export_valexpr(); void export_valexpr();
void export_datetime(); void export_datetime();
void export_autoxact();
void export_derive(); void export_derive();
void initialize_ledger_for_python() void initialize_ledger_for_python()
@ -50,7 +49,6 @@ void initialize_ledger_for_python()
export_format(); export_format();
export_valexpr(); export_valexpr();
export_datetime(); export_datetime();
export_autoxact();
export_derive(); export_derive();
module_initialized = true; module_initialized = true;

View file

@ -231,9 +231,7 @@ unsigned int textual_parser_t::parse(std::istream& in,
commodity_t * time_commodity = NULL; commodity_t * time_commodity = NULL;
std::deque<account_t *> account_stack; std::deque<account_t *> account_stack;
automated_transactions_t auto_xacts; autoxact_finalizer_t autoxact_finalizer;
current_auto_xacts = &auto_xacts;
if (! master) if (! master)
master = journal->master; master = journal->master;
@ -433,10 +431,12 @@ unsigned int textual_parser_t::parse(std::istream& in,
case '=': // automated transactions case '=': // automated transactions
if (! added_autoxact_hook) { if (! added_autoxact_hook) {
add_hook(journal->entry_finalize_hooks, handle_auto_xacts); add_hook<entry_finalizer_t *>(journal->entry_finalize_hooks,
&autoxact_finalizer);
added_autoxact_hook = true; added_autoxact_hook = true;
} }
parse_automated_transactions(in, account_stack.front(), auto_xacts); parse_automated_transactions(in, account_stack.front(),
autoxact_finalizer.auto_xacts);
break; break;
case '!': { // directive case '!': { // directive
@ -449,8 +449,6 @@ unsigned int textual_parser_t::parse(std::istream& in,
push_var<unsigned int> save_linenum(linenum); push_var<unsigned int> save_linenum(linenum);
push_var<std::string> save_path(path); push_var<std::string> save_path(path);
push_var<automated_transactions_t *>
save_current_auto_xacts(current_auto_xacts);
count += parse_journal_file(skip_ws(line), journal, count += parse_journal_file(skip_ws(line), journal,
account_stack.front()); account_stack.front());
@ -496,6 +494,9 @@ unsigned int textual_parser_t::parse(std::istream& in,
} }
done: done:
if (added_autoxact_hook)
remove_hook<entry_finalizer_t *>(journal->entry_finalize_hooks,
&autoxact_finalizer);
if (time_commodity) { if (time_commodity) {
time_commodity->precision = 2; time_commodity->precision = 2;
time_commodity->flags |= COMMODITY_STYLE_NOMARKET; time_commodity->flags |= COMMODITY_STYLE_NOMARKET;