mirror of
https://github.com/ultimatepp/ultimatepp.git
synced 2026-05-15 22:02:49 -06:00
373 lines
14 KiB
C++
373 lines
14 KiB
C++
#include <Core/Core.h>
|
|
|
|
using namespace Upp;
|
|
|
|
String If(String s, String txt)
|
|
{
|
|
return IsNull(s) ? String() : txt;
|
|
}
|
|
|
|
void CallbackGen(String name, String rettype, int n, String extension, String atest = Null)
|
|
{
|
|
LOG("// -----------------------------------------------------------");
|
|
String classdef, classlist, paramdef, paramlist;
|
|
for(int i = 1; i <= n; i++) {
|
|
if(i > 1) {
|
|
classdef << ", ";
|
|
classlist << ", ";
|
|
paramdef << ", ";
|
|
paramlist << ", ";
|
|
}
|
|
classdef << Format("class P%d", i);
|
|
classlist << Format("P%d", i);
|
|
paramdef << Format("P%d p%d", i, i);
|
|
paramlist << Format("p%d", i);
|
|
}
|
|
String cl_list = If(classlist, "<" + classlist + ">");
|
|
String cl_temp = String("template <class OBJECT, class METHOD") << If(classdef, ", " + classdef) << ">";
|
|
String return_ = rettype == "void" ? "" : "return ";
|
|
String name_cl = name + cl_list;
|
|
LOG("");
|
|
if(!IsNull(classdef))
|
|
LOG("template <" << classdef << ">");
|
|
LOG("struct " << name << "Action {");
|
|
LOGBEGIN();
|
|
LOG("Atomic count;");
|
|
LOG("");
|
|
LOG("virtual " << rettype << " Execute(" + paramdef + ") = 0;");
|
|
LOG("virtual bool IsValid() const { return true; }");
|
|
// LOG("virtual bool IsEqual(const " << name << "Action *other) const = 0;");
|
|
// LOG("virtual unsigned GetHashValue() const = 0;");
|
|
LOG("");
|
|
LOG(name << "Action() { count = 1; }");
|
|
LOG("virtual ~" << name << "Action() {}");
|
|
LOGEND();
|
|
LOG("};");
|
|
LOG("");
|
|
|
|
LOG(cl_temp);
|
|
LOG("struct " << name << "MethodActionPte : public " << name << "Action" << cl_list + " {");
|
|
LOGBEGIN();
|
|
LOG("Ptr<OBJECT> object;");
|
|
LOG("METHOD method;");
|
|
LOG("");
|
|
if(rettype == "void")
|
|
LOG(rettype << " Execute(" << paramdef << ") { if(object) (object->*method)(" << paramlist << "); }");
|
|
else
|
|
LOG(rettype << " Execute(" << paramdef << ") { return object ? (object->*method)(" << paramlist << ") : false; }");
|
|
LOG("bool IsValid() const { return object; }");
|
|
// LOG("bool IsEqual(const " << name << "Action" << cl_list << " *other) const {");
|
|
// LOGBEGIN();
|
|
// LOG("const " << name << "MethodActionPte *q = dynamic_cast<const " << name <<
|
|
// "MethodActionPte *>(other);");
|
|
// LOG("return q ? q->object == object && q->method == method : false;");
|
|
// LOGEND();
|
|
// LOG("}");
|
|
// LOG("unsigned GetHashValue() const {");
|
|
// LOG("\treturn (unsigned)(uintptr_t)~object ^ (unsigned)brutal_cast<uintptr_t>(method);");
|
|
// LOG("}");
|
|
LOG("");
|
|
LOG(name << "MethodActionPte(OBJECT *object, METHOD method) "
|
|
": object(object), method(method) {}");
|
|
LOGEND();
|
|
LOG("};");
|
|
LOG("");
|
|
|
|
LOG(cl_temp);
|
|
LOG("struct " << name << "MethodAction : public " << name << "Action" << cl_list + " {");
|
|
LOGBEGIN();
|
|
LOG("OBJECT *object;");
|
|
LOG("METHOD method;");
|
|
LOG("");
|
|
LOG(rettype << " Execute(" << paramdef << ") { " <<
|
|
return_ << "(object->*method)(" << paramlist << "); }");
|
|
/* LOG("bool IsEqual(const " << name << "Action" << cl_list << " *other) const {");
|
|
LOGBEGIN();
|
|
LOG("const " << name << "MethodAction *q = dynamic_cast<const " << name <<
|
|
"MethodAction *>(other);");
|
|
LOG("return q ? q->object == object && q->method == method : false;");
|
|
LOGEND();
|
|
LOG("}");
|
|
LOG("unsigned GetHashValue() const {");
|
|
LOG("\treturn (unsigned)(uintptr_t)object ^ (unsigned)brutal_cast<uintptr_t>(method);");
|
|
LOG("}");
|
|
*/ LOG("");
|
|
LOG(name << "MethodAction(OBJECT *object, METHOD method) "
|
|
": object(object), method(method) {}");
|
|
LOGEND();
|
|
LOG("};");
|
|
LOG("");
|
|
|
|
if(!IsNull(classdef))
|
|
LOG("template <" << classdef << ">");
|
|
LOG("struct " << name << "FnAction : public " << name << "Action" << cl_list << " {");
|
|
LOGBEGIN();
|
|
LOG(rettype << " (*fn)(" << paramdef << ");");
|
|
LOG("");
|
|
LOG(rettype << " Execute(" << paramdef << ") { " << return_ << "(*fn)(" <<
|
|
paramlist << "); }");
|
|
/* LOG("bool IsEqual(const " << name << "Action" << cl_list << " *other) const {");
|
|
LOGBEGIN();
|
|
LOG("const " << name << "FnAction *q = dynamic_cast<const " << name <<
|
|
"FnAction *>(other);");
|
|
LOG("return q ? q->fn == fn : false;");
|
|
LOGEND();
|
|
LOG("}");
|
|
LOG("unsigned GetHashValue() const {");
|
|
LOG("\treturn (unsigned)(uintptr_t)fn;");
|
|
LOG("}");
|
|
*/ LOG("");
|
|
LOG(name << "FnAction(" << rettype << " (*fn)(" << paramdef << ")) : fn(fn) {}");
|
|
LOGEND();
|
|
LOG("};");
|
|
LOG("");
|
|
|
|
if(!IsNull(classdef))
|
|
LOG("template <" << classdef << ">");
|
|
LOG("class " << name << " : Moveable< " << name_cl << " > {");
|
|
LOGBEGIN();
|
|
LOG(name << "Action" << cl_list << " *action;");
|
|
LOG("");
|
|
LOG("void Retain() const { if(action " << atest << ") AtomicInc(action->count); }");
|
|
LOG("void Release() { if(action " << atest << " && AtomicDec(action->count) == 0) delete action; }");
|
|
LOG("");
|
|
LOG("bool operator==(const " << name << "&);");
|
|
LOG("bool operator!=(const " << name << "&);");
|
|
LOG("");
|
|
LOGEND();
|
|
LOG("public:");
|
|
LOGBEGIN();
|
|
LOG("typedef " << name << " CLASSNAME;");
|
|
LOG("");
|
|
LOG(name << "& operator=(const " << name << "& c);");
|
|
LOG(name << "(const " << name << "& c);");
|
|
LOG("void Clear() { Release(); action = NULL; }");
|
|
LOG("");
|
|
// LOG("unsigned GetHashValue() const { return action->GetHashValue(); }");
|
|
LOG("");
|
|
LOG(extension);
|
|
LOG("");
|
|
LOG("explicit " << name << "(" << name << "Action " << cl_list <<
|
|
" *newaction) { action = newaction; }");
|
|
// LOG(name << "& operator=(" << name << "Action" << cl_list <<
|
|
// " *newaction) { action = newaction; return *this; }");
|
|
LOG(name << "() { action = NULL; }");
|
|
LOG(name << "(_CNULL) { action = NULL; }");
|
|
LOG("~" << name << "();");
|
|
LOG("");
|
|
LOG("static " << name << " Empty() { return CNULL; }");
|
|
LOG("");
|
|
// LOG("friend bool operator==(const " << name << "& a, const " << name << "& b)");
|
|
// LOG("\t{ return a.action ? a.action->IsEqual(b.action) : !b.action; }");
|
|
// LOG("friend bool operator!=(const " << name << "& a, const " << name << " & b)");
|
|
// LOG("\t{ return !(a == b); }");
|
|
LOGEND();
|
|
LOG("};");
|
|
LOG("");
|
|
|
|
LOG(cl_temp);
|
|
LOG(name_cl << " pteback(OBJECT *object, " << rettype <<
|
|
" (METHOD::*method)(" << paramdef << ")) {");
|
|
LOG("\treturn " << name_cl <<
|
|
"(new " << name << "MethodActionPte<OBJECT, " << rettype << " (METHOD::*)(" <<
|
|
paramdef << ")" << If(classlist, ", " + classlist) << ">(object, method));");
|
|
LOG("}");
|
|
LOG("");
|
|
|
|
LOG(cl_temp);
|
|
LOG(name_cl << " callback(OBJECT *object, " << rettype <<
|
|
" (METHOD::*method)(" << paramdef << ")) {");
|
|
LOG("\treturn " << name_cl <<
|
|
"(new " << name << "MethodAction<OBJECT, " << rettype << " (METHOD::*)(" <<
|
|
paramdef << ")" << If(classlist, ", " + classlist) << ">(object, method));");
|
|
LOG("}");
|
|
LOG("");
|
|
|
|
LOG(cl_temp);
|
|
LOG(name_cl << " callback(const OBJECT *object, " << rettype <<
|
|
" (METHOD::*method)(" << paramdef << ") const) {");
|
|
LOG("\treturn " << name_cl <<
|
|
"(new " << name << "MethodAction<const OBJECT, " << rettype << " (METHOD::*)("
|
|
<< paramdef << ") const" << If(classlist, ", " + classlist) << ">(object, method));");
|
|
LOG("}");
|
|
LOG("");
|
|
|
|
if(!IsNull(classdef))
|
|
LOG("template <" << classdef << ">");
|
|
LOG("inline " << name_cl << " callback(" << rettype << " (*fn)(" << paramdef << ")) {");
|
|
LOG("\treturn " << name_cl << "(new " << name << "FnAction " << cl_list << "(fn));");
|
|
LOG("}");
|
|
LOG("");
|
|
|
|
|
|
if(!IsNull(classdef))
|
|
LOG("template <" << classdef << ">");
|
|
LOG("struct " << name << "ForkAction : public " << name << "Action" << cl_list << " {");
|
|
LOGBEGIN();
|
|
LOG(name_cl << " cb1, cb2;");
|
|
LOG("");
|
|
LOG(rettype << " Execute(" << paramdef << ") { cb1(" << paramlist <<
|
|
"); " << return_ << "cb2(" << paramlist << "); }");
|
|
// LOG("bool IsEqual(const " << name << "Action " << cl_list << " *other) const {");
|
|
// LOG("\tconst " << name << "ForkAction *q = dynamic_cast<const " << name
|
|
// << "ForkAction *>(other);");
|
|
// LOG("\treturn q ? q->cb1 == cb1 && q->cb2 == cb2 : false;");
|
|
// LOG("}");
|
|
// LOG("unsigned GetHashValue() const {");
|
|
// LOG("\treturn ::GetHashValue(cb1) ^ ::GetHashValue(cb2);");
|
|
// LOG("}");
|
|
LOG("");
|
|
LOG(name << "ForkAction(" << name_cl << " cb1, " << name_cl << " cb2)"
|
|
"\n\t : cb1(cb1), cb2(cb2) {}");
|
|
LOGEND();
|
|
LOG("};");
|
|
LOG("");
|
|
|
|
if(!IsNull(classdef))
|
|
LOG("template <" << classdef << ">");
|
|
LOG("inline " << name_cl << " Proxy(" << name_cl << "& cb)");
|
|
LOG("{");
|
|
LOG("\treturn callback(&cb, &" << name_cl << "::Execute);");
|
|
LOG("}");
|
|
LOG("");
|
|
|
|
if(IsNull(classdef)) {
|
|
LOG(name_cl << " callback(" << name_cl << " cb1, " << name_cl << " cb2);");
|
|
LOG(name_cl << "& operator<<(" << name_cl << "& a, " << name_cl << " b);");
|
|
LOG("");
|
|
LOG("#endif");
|
|
LOG("#ifdef CPP_PART__");
|
|
LOG("");
|
|
}
|
|
|
|
if(!IsNull(classdef))
|
|
LOG("template <" << classdef << ">");
|
|
LOG(name_cl << " callback(" << name_cl << " cb1, " << name_cl << " cb2)");
|
|
LOG("{");
|
|
LOG("\treturn " << name_cl << "(new " << name << "ForkAction " << cl_list << "(cb1, cb2));");
|
|
LOG("}");
|
|
LOG("");
|
|
|
|
if(!IsNull(classdef))
|
|
LOG("template <" << classdef << ">");
|
|
LOG(name_cl << "& operator<<(" << name_cl << "& a, " << name_cl << " b)");
|
|
LOG("{");
|
|
LOG("\tif(a)");
|
|
LOG("\t\ta = callback(a, b);");
|
|
LOG("\telse");
|
|
LOG("\t\ta = b;");
|
|
LOG("\treturn a;");
|
|
LOG("}");
|
|
LOG("");
|
|
|
|
if(!IsNull(classdef))
|
|
LOG("template <" << classdef << ">");
|
|
LOG(name_cl << "& " << name_cl << "::operator=(const " << name << "& c)");
|
|
LOG("{");
|
|
LOG("\tc.Retain();");
|
|
LOG("\tRelease();");
|
|
LOG("\taction = c.action;");
|
|
LOG("\treturn *this;");
|
|
LOG("}");
|
|
LOG("");
|
|
if(!IsNull(classdef))
|
|
LOG("template <" << classdef << ">");
|
|
LOG(name_cl << "::" << name << "(const " << name << "& c)");
|
|
LOG("{");
|
|
LOG("\taction = c.action;");
|
|
LOG("\tRetain();");
|
|
LOG("}");
|
|
LOG("");
|
|
if(!IsNull(classdef))
|
|
LOG("template <" << classdef << ">");
|
|
LOG(name_cl << "::~" << name << "()");
|
|
LOG("{");
|
|
LOG("\tRelease();");
|
|
LOG("}");
|
|
LOG("");
|
|
if(IsNull(classdef)) {
|
|
LOG("#endif");
|
|
LOG("#ifndef CPP_PART__");
|
|
LOG("");
|
|
}
|
|
};
|
|
|
|
CONSOLE_APP_MAIN
|
|
{
|
|
LOG("#ifndef CPP_PART__");
|
|
LOG("");
|
|
|
|
CallbackGen("Callback", "void", 0,
|
|
"operator bool() const { return action && action->IsValid(); }\n"
|
|
"void Execute() const;\n"
|
|
"void operator()() const { Execute(); }"
|
|
);
|
|
CallbackGen("Callback1", "void", 1,
|
|
"operator bool() const { return action && action->IsValid(); }\n"
|
|
"void Execute(P1 p1) const { if(action) action->Execute(p1); }\n"
|
|
"void operator()(P1 p1) const { Execute(p1); }"
|
|
);
|
|
CallbackGen("Callback2", "void", 2,
|
|
"operator bool() const { return action && action->IsValid(); }\n"
|
|
"void Execute(P1 p1, P2 p2) const { if(action) action->Execute(p1, p2); }\n"
|
|
"void operator()(P1 p1, P2 p2) const { Execute(p1, p2); }"
|
|
);
|
|
CallbackGen("Callback3", "void", 3,
|
|
"operator bool() const { return action && action->IsValid(); }\n"
|
|
"void Execute(P1 p1, P2 p2, P3 p3) const { if(action) action->Execute(p1, p2, p3); }\n"
|
|
"void operator()(P1 p1, P2 p2, P3 p3) const { Execute(p1, p2, p3); }"
|
|
);
|
|
CallbackGen("Callback4", "void", 4,
|
|
"operator bool() const { return action && action->IsValid(); }\n"
|
|
"void Execute(P1 p1, P2 p2, P3 p3, P4 p4) const { if(action) action->Execute(p1, p2, p3, p4); }\n"
|
|
"void operator()(P1 p1, P2 p2, P3 p3, P4 p4) const { Execute(p1, p2, p3, p4); }"
|
|
);
|
|
|
|
CallbackGen("Gate", "bool", 0,
|
|
"operator bool() const { return (void *)action != (void *)1 && action && action->IsValid(); }\n"
|
|
"bool Execute() const;\n"
|
|
"bool operator()() const { return Execute(); }\n"
|
|
"void ClearTrue() { Clear(); action = (GateAction *)1; }\n"
|
|
"void ClearFalse() { Clear(); }\n\n"
|
|
"Gate(bool b) { action = (GateAction *)(int)b; }",
|
|
"&& (void *)action != (void *)1"
|
|
);
|
|
CallbackGen("Gate1", "bool", 1,
|
|
"operator bool() const { return (void *)action != (void *)1 && action && action->IsValid(); }\n"
|
|
"bool Execute(P1 p1) const;\n"
|
|
"bool operator()(P1 p1) const { return Execute(p1); }\n"
|
|
"void ClearTrue() { Clear(); action = (Gate1Action<P1> *)1; }\n"
|
|
"void ClearFalse() { Clear(); }\n\n"
|
|
"Gate1(bool b) { action = (Gate1Action<P1> *)(uintptr_t)b; }",
|
|
"&& (void *)action != (void *)1"
|
|
);
|
|
CallbackGen("Gate2", "bool", 2,
|
|
"operator bool() const { return (void *)action != (void *)1 && action && action->IsValid(); }\n"
|
|
"bool Execute(P1 p1, P2 p2) const;\n"
|
|
"bool operator()(P1 p1, P2 p2) const { return Execute(p1, p2); }\n"
|
|
"void ClearTrue() { Clear(); action = (Gate2Action<P1, P2> *)1; }\n"
|
|
"void ClearFalse() { Clear(); }\n\n"
|
|
"Gate2(bool b) { action = (Gate2Action<P1, P2> *)(uintptr_t)b; }",
|
|
"&& (void *)action != (void *)1"
|
|
);
|
|
CallbackGen("Gate3", "bool", 3,
|
|
"operator bool() const { return (void *)action != (void *)1 && action && action->IsValid(); }\n"
|
|
"bool Execute(P1 p1, P2 p2, P3 p3) const;\n"
|
|
"bool operator()(P1 p1, P2 p2, P3 p3) const { return Execute(p1, p2, p3); }\n"
|
|
"void ClearTrue() { Clear(); action = (Gate3Action<P1, P2, P3> *)1; }\n"
|
|
"void ClearFalse() { Clear(); }\n\n"
|
|
"Gate3(bool b) { action = (Gate3Action<P1, P2, P3> *)(uintptr_t)b; }",
|
|
"&& (void *)action != (void *)1"
|
|
);
|
|
CallbackGen("Gate4", "bool", 4,
|
|
"operator bool() const { return (void *)action != (void *)1 && action && action->IsValid(); }\n"
|
|
"bool Execute(P1 p1, P2 p2, P3 p3, P4 p4) const;\n"
|
|
"bool operator()(P1 p1, P2 p2, P3 p3, P4 p4) const { return Execute(p1, p2, p3, p4); }\n"
|
|
"void ClearTrue() { Clear(); action = (Gate4Action<P1, P2, P3, P4> *)1; }\n"
|
|
"void ClearFalse() { Clear(); }\n\n"
|
|
"Gate4(bool b) { action = (Gate4Action<P1, P2, P3, P4> *)(uintptr_t)b; }",
|
|
"&& (void *)action != (void *)1"
|
|
);
|
|
LOG("");
|
|
LOG("#endif");
|
|
}
|