Core: rudimentary Callback lambda support

git-svn-id: svn://ultimatepp.org/upp/trunk@7051 f0d560ea-af0d-0410-9eb7-867de7ffcac7
This commit is contained in:
cxl 2014-03-17 18:05:55 +00:00
parent d4b1ce6c48
commit c101d0da23
4 changed files with 178 additions and 3 deletions

View file

@ -1,4 +1,4 @@
description "Utility to generate (long and repetitive) callback C++ source files";
description "Utility to generate (long and repetitive) callback C++ source files\377";
uses
Core;

View file

@ -7,6 +7,12 @@ String If(String s, String txt)
return IsNull(s) ? String() : txt;
}
/*
#ifdef CPP_11
Callback& operator=(const std::function<void ()>& fn) { Release(); action = new LambdaCallbackAction(fn); return *this; }
#endif
*/
void CallbackGen(String name, String rettype, int n, String extension, String atest = Null)
{
LOG("// -----------------------------------------------------------");
@ -24,7 +30,7 @@ void CallbackGen(String name, String rettype, int n, String extension, String at
paramlist << Format("p%d", i);
}
String cl_list = If(classlist, "<" + classlist + ">");
String cl_temp = String("template <class OBJECT, class METHOD") << If(classdef, ", " + classdef) << ">";
String cl_temp = String("template <class OBJECT, class METHOD").Cat() << If(classdef, ", " + classdef) << ">";
String return_ = rettype == "void" ? "" : "return ";
String name_cl = name + cl_list;
LOG("");
@ -45,6 +51,24 @@ void CallbackGen(String name, String rettype, int n, String extension, String at
LOG("};");
LOG("");
LOG("#ifdef HAS_LAMBDA");
if(!IsNull(classdef))
LOG("template <" << classdef << ">");
LOG("struct Lambda" << name << " : public " << name << "Action" << cl_list + " {");
LOGBEGIN();
LOG("std::function<" << rettype << " (" << classlist << ")> fn;");
if(rettype == "void")
LOG("virtual void Execute(" << paramdef << ") { fn(" << paramlist << "); }");
else
LOG("virtual " << rettype << " Execute(" << paramdef << ") { return fn(" << paramlist << "); }");
LOG("");
LOG("Lambda" << name << "(std::function<" << rettype << " (" << classlist << ")> fn) : fn(fn) {}");
LOGEND();
LOG("};");
LOG("#endif");
LOG("");
#if 0
LOG(cl_temp);
LOG("struct " << name << "MethodActionPte : public " << name << "Action" << cl_list + " {");
LOGBEGIN();
@ -121,6 +145,7 @@ void CallbackGen(String name, String rettype, int n, String extension, String at
LOGEND();
LOG("};");
LOG("");
#endif
if(!IsNull(classdef))
LOG("template <" << classdef << ">");
@ -154,6 +179,13 @@ void CallbackGen(String name, String rettype, int n, String extension, String at
LOG(name << "() { action = NULL; }");
LOG(name << "(_CNULL) { action = NULL; }");
LOG("~" << name << "();");
LOGEND();
LOG("#ifdef HAS_LAMBDA");
LOGBEGIN();
LOG(name << "& operator=(std::function<" << rettype << " (" << classlist << ")> l) { Clear(); action = new Lambda" << name << "<" << classlist << ">(l); return *this; }");
LOGEND();
LOG("#endif");
LOGBEGIN();
LOG("");
LOG("static " << name << " Empty() { return CNULL; }");
LOG("");
@ -165,6 +197,7 @@ void CallbackGen(String name, String rettype, int n, String extension, String at
LOG("};");
LOG("");
#if 0
LOG(cl_temp);
LOG(name_cl << " pteback(OBJECT *object, " << rettype <<
" (METHOD::*method)(" << paramdef << ")) {");
@ -290,6 +323,7 @@ void CallbackGen(String name, String rettype, int n, String extension, String at
LOG("#ifndef CPP_PART__");
LOG("");
}
#endif
};
CONSOLE_APP_MAIN

View file

@ -1,5 +1,9 @@
// -----------------------------------------------------------
#ifdef CPP_11
#define HAS_LAMBDA 1
#endif
struct CallbackAction {
Atomic count;
@ -10,6 +14,15 @@ struct CallbackAction {
virtual ~CallbackAction() {}
};
#ifdef HAS_LAMBDA
struct LambdaCallback : CallbackAction {
std::function<void ()> fn;
virtual void Execute() { fn(); }
LambdaCallback(std::function<void ()> fn) : fn(fn) {}
};
#endif
class Callback : Moveable< Callback > {
CallbackAction *action;
@ -34,10 +47,13 @@ public:
explicit Callback(CallbackAction *newaction) { action = newaction; }
Callback() { action = NULL; }
Callback(_CNULL) { action = NULL; }
#ifdef HAS_LAMBDA
Callback& operator=(std::function<void ()> l) { Clear(); action = new LambdaCallback(l); return *this; }
#endif
~Callback();
static Callback Empty() { return CNULL; }
};
// -----------------------------------------------------------
@ -53,6 +69,16 @@ struct Callback1Action {
virtual ~Callback1Action() {}
};
#ifdef HAS_LAMBDA
template <class P1>
struct LambdaCallback1 : public Callback1Action<P1> {
std::function<void (P1)> fn;
virtual void Execute(P1 p1) { fn(p1); }
LambdaCallback1(std::function<void (P1)> fn) : fn(fn) {}
};
#endif
template <class P1>
class Callback1 : Moveable< Callback1<P1> > {
Callback1Action<P1> *action;
@ -79,6 +105,9 @@ public:
Callback1() { action = NULL; }
Callback1(_CNULL) { action = NULL; }
~Callback1();
#ifdef HAS_LAMBDA
Callback1& operator=(std::function<void (P1)> l) { Clear(); action = new LambdaCallback1<P1>(l); return *this; }
#endif
static Callback1 Empty() { return CNULL; }
@ -119,6 +148,16 @@ struct Callback2Action {
virtual ~Callback2Action() {}
};
#ifdef HAS_LAMBDA
template <class P1, class P2>
struct LambdaCallback2 : public Callback2Action<P1, P2> {
std::function<void (P1, P2)> fn;
virtual void Execute(P1 p1, P2 p2) { fn(p1, p2); }
LambdaCallback2(std::function<void (P1, P2)> fn) : fn(fn) {}
};
#endif
template <class P1, class P2>
class Callback2 : Moveable< Callback2<P1, P2> > {
Callback2Action<P1, P2> *action;
@ -144,6 +183,9 @@ public:
explicit Callback2(Callback2Action <P1, P2> *newaction) { action = newaction; }
Callback2() { action = NULL; }
Callback2(_CNULL) { action = NULL; }
#ifdef HAS_LAMBDA
Callback2& operator=(std::function<void (P1, P2)> l) { Clear(); action = new LambdaCallback2<P1, P2>(l); return *this; }
#endif
~Callback2();
static Callback2 Empty() { return CNULL; }
@ -185,6 +227,16 @@ struct Callback3Action {
virtual ~Callback3Action() {}
};
#ifdef HAS_LAMBDA
template <class P1, class P2, class P3>
struct LambdaCallback3 : public Callback3Action<P1, P2, P3> {
std::function<void (P1, P2, P3)> fn;
virtual void Execute(P1 p1, P2 p2, P3 p3) { fn(p1, p2, p3); }
LambdaCallback3(std::function<void (P1, P2, P3)> fn) : fn(fn) {}
};
#endif
template <class P1, class P2, class P3>
class Callback3 : Moveable< Callback3<P1, P2, P3> > {
Callback3Action<P1, P2, P3> *action;
@ -210,6 +262,9 @@ public:
explicit Callback3(Callback3Action <P1, P2, P3> *newaction) { action = newaction; }
Callback3() { action = NULL; }
Callback3(_CNULL) { action = NULL; }
#ifdef HAS_LAMBDA
Callback3& operator=(std::function<void (P1, P2, P3)> l) { Clear(); action = new LambdaCallback3<P1, P2, P3>(l); return *this; }
#endif
~Callback3();
static Callback3 Empty() { return CNULL; }
@ -251,6 +306,16 @@ struct Callback4Action {
virtual ~Callback4Action() {}
};
#ifdef HAS_LAMBDA
template <class P1, class P2, class P3, class P4>
struct LambdaCallback4 : public Callback4Action<P1, P2, P3, P4> {
std::function<void (P1, P2, P3, P4)> fn;
virtual void Execute(P1 p1, P2 p2, P3 p3, P4 p4) { fn(p1, p2, p3, p4); }
LambdaCallback4(std::function<void (P1, P2, P3, P4)> fn) : fn(fn) {}
};
#endif
template <class P1, class P2, class P3, class P4>
class Callback4 : Moveable< Callback4<P1, P2, P3, P4> > {
Callback4Action<P1, P2, P3, P4> *action;
@ -276,6 +341,9 @@ public:
explicit Callback4(Callback4Action <P1, P2, P3, P4> *newaction) { action = newaction; }
Callback4() { action = NULL; }
Callback4(_CNULL) { action = NULL; }
#ifdef HAS_LAMBDA
Callback4& operator=(std::function<void (P1, P2, P3, P4)> l) { Clear(); action = new LambdaCallback4<P1, P2, P3, P4>(l); return *this; }
#endif
~Callback4();
static Callback4 Empty() { return CNULL; }
@ -316,6 +384,15 @@ struct GateAction {
virtual ~GateAction() {}
};
#ifdef HAS_LAMBDA
struct LambdaGate : public GateAction {
std::function<bool ()> fn;
virtual bool Execute() { return fn(); }
LambdaGate(std::function<bool ()> fn) : fn(fn) {}
};
#endif
class Gate : Moveable< Gate > {
GateAction *action;
@ -346,6 +423,9 @@ public:
explicit Gate(GateAction *newaction) { action = newaction; }
Gate() { action = NULL; }
Gate(_CNULL) { action = NULL; }
#ifdef HAS_LAMBDA
Gate& operator=(std::function<bool ()> l) { Clear(); action = new LambdaGate(l); return *this; }
#endif
~Gate();
static Gate Empty() { return CNULL; }
@ -365,6 +445,16 @@ struct Gate1Action {
virtual ~Gate1Action() {}
};
#ifdef HAS_LAMBDA
template <class P1>
struct LambdaGate1 : public Gate1Action<P1> {
std::function<bool (P1)> fn;
virtual bool Execute(P1 p1) { return fn(p1); }
LambdaGate1(std::function<bool (P1)> fn) : fn(fn) {}
};
#endif
template <class P1>
class Gate1 : Moveable< Gate1<P1> > {
Gate1Action<P1> *action;
@ -397,6 +487,9 @@ public:
explicit Gate1(Gate1Action <P1> *newaction) { action = newaction; }
Gate1() { action = NULL; }
Gate1(_CNULL) { action = NULL; }
#ifdef HAS_LAMBDA
Gate1& operator=(std::function<bool (P1)> l) { Clear(); action = new LambdaGate1<P1>(l); return *this; }
#endif
~Gate1();
static Gate1 Empty() { return CNULL; }
@ -438,6 +531,16 @@ struct Gate2Action {
virtual ~Gate2Action() {}
};
#ifdef HAS_LAMBDA
template <class P1, class P2>
struct LambdaGate2 : public Gate2Action<P1, P2> {
std::function<bool (P1, P2)> fn;
virtual bool Execute(P1 p1, P2 p2) { return fn(p1, p2); }
LambdaGate2(std::function<bool (P1, P2)> fn) : fn(fn) {}
};
#endif
template <class P1, class P2>
class Gate2 : Moveable< Gate2<P1, P2> > {
Gate2Action<P1, P2> *action;
@ -469,6 +572,9 @@ public:
explicit Gate2(Gate2Action <P1, P2> *newaction) { action = newaction; }
Gate2() { action = NULL; }
Gate2(_CNULL) { action = NULL; }
#ifdef HAS_LAMBDA
Gate2& operator=(std::function<bool (P1, P2)> l) { Clear(); action = new LambdaGate2<P1, P2>(l); return *this; }
#endif
~Gate2();
static Gate2 Empty() { return CNULL; }
@ -510,6 +616,16 @@ struct Gate3Action {
virtual ~Gate3Action() {}
};
#ifdef HAS_LAMBDA
template <class P1, class P2, class P3>
struct LambdaGate3 : public Gate3Action<P1, P2, P3> {
std::function<bool (P1, P2, P3)> fn;
virtual bool Execute(P1 p1, P2 p2, P3 p3) { return fn(p1, p2, p3); }
LambdaGate3(std::function<bool (P1, P2, P3)> fn) : fn(fn) {}
};
#endif
template <class P1, class P2, class P3>
class Gate3 : Moveable< Gate3<P1, P2, P3> > {
Gate3Action<P1, P2, P3> *action;
@ -541,6 +657,9 @@ public:
explicit Gate3(Gate3Action <P1, P2, P3> *newaction) { action = newaction; }
Gate3() { action = NULL; }
Gate3(_CNULL) { action = NULL; }
#ifdef HAS_LAMBDA
Gate3& operator=(std::function<bool (P1, P2, P3)> l) { Clear(); action = new LambdaGate3<P1, P2, P3>(l); return *this; }
#endif
~Gate3();
static Gate3 Empty() { return CNULL; }
@ -582,6 +701,16 @@ struct Gate4Action {
virtual ~Gate4Action() {}
};
#ifdef HAS_LAMBDA
template <class P1, class P2, class P3, class P4>
struct LambdaGate4 : public Gate4Action<P1, P2, P3, P4> {
std::function<bool (P1, P2, P3, P4)> fn;
virtual bool Execute(P1 p1, P2 p2, P3 p3, P4 p4) { return fn(p1, p2, p3, p4); }
LambdaGate4(std::function<bool (P1, P2, P3, P4)> fn) : fn(fn) {}
};
#endif
template <class P1, class P2, class P3, class P4>
class Gate4 : Moveable< Gate4<P1, P2, P3, P4> > {
Gate4Action<P1, P2, P3, P4> *action;
@ -613,6 +742,9 @@ public:
explicit Gate4(Gate4Action <P1, P2, P3, P4> *newaction) { action = newaction; }
Gate4() { action = NULL; }
Gate4(_CNULL) { action = NULL; }
#ifdef HAS_LAMBDA
Gate4& operator=(std::function<bool (P1, P2, P3, P4)> l) { Clear(); action = new LambdaGate4<P1, P2, P3, P4>(l); return *this; }
#endif
~Gate4();
static Gate4 Empty() { return CNULL; }

View file

@ -15,6 +15,8 @@ topic "Callbacks";
pointers. Each Callback represents some kind of action (usually
calling a certain function or a certain object method) that can
be invoked at any time.&]
[s9; If you are happy enough to be able to use C`+`+11, you can also
assign C`+`+ lambda to Callback.&]
[s9; There are several basic callback types, depending on number
of parameters passed and return value. In order to keep description
of callbacks short, all these types are described in a single
@ -84,6 +86,13 @@ Callback takes over its ownership.&]
[s0;:Callback1`:`:Callback1`(`):%- [%%*/@(128.0.255) CallbackType]()&]
[s2; Creates an empty callback.&]
[s3; &]
[s4;%- &]
[s5;:Callback1`:`:operator`=`(function`<void`(P1`)`>`):%- [_^Callback1^ Callback1][@(0.0.255) `&
]_[* operator`=](std`::function<[@(0.0.255) void]_([%%*/@(128.0.255) arguments])>_[*@3 lam
bda])&]
[s6;%- Only in C`+`+ 11&]
[s2; Assigns C`+`+11 lambda to callback.&]
[s3; &]
[s4; &]
[s0;:Callback1`:`:Callback1`(const Callback1`&`):%- [%%*/@(128.0.255) CallbackType](con
st_[%%*/@(128.0.255) CallbackType]`&_[*@3 c])&]