Skylark: Grouped library handlers: SkylarkPack

git-svn-id: svn://ultimatepp.org/upp/trunk@5342 f0d560ea-af0d-0410-9eb7-867de7ffcac7
This commit is contained in:
cxl 2012-09-09 18:28:10 +00:00
parent 297ebcebce
commit 2da95c05e1
5 changed files with 107 additions and 32 deletions

View file

@ -89,6 +89,8 @@ One<Exe> Compiler::Prim()
if(p.Char('@'))
id = "@";
id << p.ReadId();
while(p.Char(':'))
id << ':' << p.ReadId();
int n = var.Find(id);
if(p.Char('(')) {
Value (*f)(const Vector<Value>&, const Renderer *) = functions().Get(id, NULL);

View file

@ -1,9 +1,17 @@
#include "Skylark.h"
#define LLOG(x) //DLOG(x)
#define LDUMP(x) //DDUMP(x)
#define LDUMPC(x) //DDUMPC(x)
#define LDUMPM(x) //DDUMPM(x)
#if 0
#define LLOG(x) DLOG(x)
#define LDUMP(x) DDUMP(x)
#define LDUMPC(x) DDUMPC(x)
#define LDUMPM(x) DDUMPM(x)
#else
#define LLOG(x)
#define LDUMP(x)
#define LDUMPC(x)
#define LDUMPM(x)
#endif
#define LTIMING(x) //RTIMING(x)
namespace Upp {
@ -49,10 +57,15 @@ void DumpDispatchMap()
String sub;
for(int j = 0; j < DispatchMap[i].subnode.GetCount(); j++)
sub << DispatchMap[i].subnode.GetKey(j) << "->" << DispatchMap[i].subnode[j] << ", ";
LLOG(i << " " << (bool)DispatchMap[i].view << ": " << sub);
LLOG(i << " " << (bool)DispatchMap[i].handler << ": " << sub);
}
}
String SkylarkAppendPath__(const String& path_prefix, const String& path)
{
return path_prefix.GetCount() ? path_prefix + '/' + path : path;
}
Vector<String> *GetUrlViewLinkParts(const String& id)
{
int q = sLinkMap().Find(id);
@ -61,9 +74,8 @@ Vector<String> *GetUrlViewLinkParts(const String& id)
return &sLinkMap()[q];
}
String MakeLink(void (*view)(Http&), const Vector<Value>& arg)
String MakeLink0(int q, const Vector<Value>& arg)
{
int q = sHandlerIndex().Find((uintptr_t)view);
if(q < 0)
throw Exc("Invalid view");
if(q < 0)
@ -73,13 +85,18 @@ String MakeLink(void (*view)(Http&), const Vector<Value>& arg)
return out;
}
String MakeLink(const HandlerId& id, const Vector<Value>& arg)
{
return MakeLink0(id.handler ? sHandlerIndex().Find((uintptr_t)id.handler) : sLinkMap().Find(id.id), arg);
}
void RegisterView0(void (*fn)(Http&), Callback1<Http&> cb, const char *id, String path, bool primary)
{
LLOG("RegisterView " << path);
LLOG("RegisterView " << id << " -> " << path);
ASSERT_(sLinkMap().Find(id) < 0, "duplicate handler id " + String(id));
Vector<String>& linkpart = sLinkMap().GetAdd(id);
ASSERT_(!fn || sHandlerIndex().Find((uintptr_t)fn) < 0, "duplicate view function registration " + String(id));
sHandlerIndex().FindAdd((uintptr_t)fn);
sHandlerIndex().Add((uintptr_t)fn);
Vector<DispatchNode>& DispatchMap = sDispatchMap();
int method = DispatchNode::GET;
bool post_raw = false;
@ -142,6 +159,8 @@ struct HandlerData { // temporary storage of handlers until FinalizeViews call
Callback1<Http&> cb;
String id;
String path;
HandlerData() { fn = NULL; }
};
static Array<HandlerData>& sHandlerData()
@ -342,7 +361,7 @@ void Http::Dispatch(TcpSocket& socket)
var.GetAdd(".__lang__") = lang;
var.GetAdd(".language") = ToLower(LNGAsText(lang));
handlerid = bd.id;
LDUMP(viewid);
LDUMP(handlerid);
bd.handler(*this);
if(session_dirty)
SaveSession();

View file

@ -309,33 +309,33 @@ Http& Http::RenderResult(const char *template_name)
return *this;
}
Http& Http::Redirect(void (*view)(Http&), const Vector<Value>& arg)
Http& Http::Redirect(const HandlerId& handler, const Vector<Value>& arg)
{
Redirect(MakeLink(view, arg));
Redirect(MakeLink(handler, arg));
return *this;
}
Http& Http::Redirect(void (*view)(Http&))
Http& Http::Redirect(const HandlerId& handler)
{
Vector<Value> arg;
Redirect(view, arg);
Redirect(handler, arg);
return *this;
}
Http& Http::Redirect(void (*view)(Http&), const Value& v1)
Http& Http::Redirect(const HandlerId& handler, const Value& v1)
{
Vector<Value> arg;
arg.Add(v1);
Redirect(view, arg);
Redirect(handler, arg);
return *this;
}
Http& Http::Redirect(void (*view)(Http&), const Value& v1, const Value& v2)
Http& Http::Redirect(const HandlerId& handler, const Value& v1, const Value& v2)
{
Vector<Value> arg;
arg.Add(v1);
arg.Add(v2);
Redirect(view, arg);
Redirect(handler, arg);
return *this;
}

View file

@ -1,16 +1,29 @@
void MakeLink(StringBuffer& out, const Vector<String>& part, const Vector<Value>& arg);
struct HandlerId {
void (*handler)(Http& http);
String id;
HandlerId(const char *id) : id(id) { handler = NULL; }
HandlerId(void (*handler)(Http& http)) : handler(handler) {}
HandlerId() { handler = NULL; }
};
class Renderer {
protected:
VectorMap<String, Value> var;
int lang;
Renderer& Link(const char *id, void (*view)(Http&), const Vector<Value>& arg);
Renderer& Link(const char *id, const HandlerId& handler, const Vector<Value>& arg);
const One<Exe>& GetTemplate(const char *template_name);
public:
Renderer& operator()(const char *id, const Value& v) { var.Add(id, v); return *this; }
Renderer& operator()(const ValueMap& map);
Renderer& operator()(const char *id, const HandlerId& handler);
Renderer& operator()(const char *id, const HandlerId& handler, const Value& arg1);
Renderer& operator()(const char *id, const HandlerId& handler, const Value& arg1, const Value& arg2);
Renderer& operator()(const char *id, void (*handler)(Http&));
Renderer& operator()(const char *id, void (*handler)(Http&), const Value& arg1);
Renderer& operator()(const char *id, void (*handler)(Http&), const Value& arg1, const Value& arg2);
@ -69,6 +82,9 @@ class Http : public Renderer {
public:
Http& operator()(const char *id, const Value& v) { var.Add(id, v); return *this; }
Http& operator()(const ValueMap& map) { Renderer::operator()(map); return *this; }
Http& operator()(const char *id, const HandlerId& handler) { Renderer::operator()(id, handler); return *this; }
Http& operator()(const char *id, const HandlerId& handler, const Value& arg1) { Renderer::operator()(id, handler, arg1); return *this; }
Http& operator()(const char *id, const HandlerId& handler, const Value& arg1, const Value& arg2) { Renderer::operator()(id, handler, arg1, arg2); return *this; }
Http& operator()(const char *id, void (*handler)(Http&)) { Renderer::operator()(id, handler); return *this; }
Http& operator()(const char *id, void (*handler)(Http&), const Value& arg1) { Renderer::operator()(id, handler, arg1); return *this; }
Http& operator()(const char *id, void (*handler)(Http&), const Value& arg1, const Value& arg2) { Renderer::operator()(id, handler, arg1, arg2); return *this; }
@ -119,10 +135,10 @@ public:
Http& RenderResult(const char *template_name);
Http& Redirect(const char *url, int code_ = 302) { code = code_; redirect = url; return *this; }
Http& Redirect(void (*handler)(Http&), const Vector<Value>& arg);
Http& Redirect(void (*handler)(Http&));
Http& Redirect(void (*handler)(Http&), const Value& v1);
Http& Redirect(void (*handler)(Http&), const Value& v1, const Value& v2);
Http& Redirect(const HandlerId& handler, const Vector<Value>& arg);
Http& Redirect(const HandlerId& handler);
Http& Redirect(const HandlerId& handler, const Value& v1);
Http& Redirect(const HandlerId& handler, const Value& v1, const Value& v2);
Http& Ux(const char *id, const String& text);
Http& UxRender(const char *id, const char *template_name);
@ -145,8 +161,31 @@ void RegisterHandler(Callback1<Http&> handler, const char *id, const char *path)
Vector<String> *GetUrlViewLinkParts(const String& id);
String MakeLink(void (*handler)(Http&), const Vector<Value>& arg);
String MakeLink(const HandlerId& id, const Vector<Value>& arg);
enum {
SESSION_FORMAT_BINARY, SESSION_FORMAT_JSON, SESSION_FORMAT_XML
};
struct SkylarkPack {
String instance_id;
String instance_path;
};
String SkylarkAppendPath__(const String& path_prefix, const String& path);
#define SKYLARK_USE(cls, id, path) \
static void cls##_##id##_##init(cls& id); \
INITBLOCK { \
static cls id; \
id.instance_id = #id; \
id.instance_path = path; \
cls##_##id##_##init(id); \
id.Use(); \
} \
static void cls##_##id##_##init(cls& id)
#define SKYLARK_METHOD(method, path) \
RegisterHandler(THISBACK(method), instance_id + ':' + #method, SkylarkAppendPath__(instance_path, path))
#define THISLINK(x) HandlerId(instance_id + ':' + #x)

View file

@ -14,25 +14,40 @@ Renderer& Renderer::operator()(const ValueMap& map)
return *this;
}
Renderer& Renderer::Link(const char *id, void (*view)(Http&), const Vector<Value>& arg)
Renderer& Renderer::Link(const char *id, const HandlerId& handler, const Vector<Value>& arg)
{
var.Add(id, Raw('\"' + MakeLink(view, arg) + '\"'));
var.Add(id, Raw('\"' + MakeLink(handler, arg) + '\"'));
return *this;
}
Renderer& Renderer::operator()(const char *id, void (*view)(Http&))
Renderer& Renderer::operator()(const char *id, const HandlerId& handler)
{
return Link(id, view, Vector<Value>());
return Link(id, handler, Vector<Value>());
}
Renderer& Renderer::operator()(const char *id, void (*view)(Http&), const Value& arg1)
Renderer& Renderer::operator()(const char *id, const HandlerId& handler, const Value& arg1)
{
return Link(id, view, Vector<Value>() << arg1);
return Link(id, handler, Vector<Value>() << arg1);
}
Renderer& Renderer::operator()(const char *id, void (*view)(Http&), const Value& arg1, const Value& arg2)
Renderer& Renderer::operator()(const char *id, const HandlerId& handler, const Value& arg1, const Value& arg2)
{
return Link(id, view, Vector<Value>() << arg1 << arg2);
return Link(id, handler, Vector<Value>() << arg1 << arg2);
}
Renderer& Renderer::operator()(const char *id, void (*handler)(Http&))
{
return operator()(id, HandlerId(handler));
}
Renderer& Renderer::operator()(const char *id, void (*handler)(Http&), const Value& arg1)
{
return operator()(id, HandlerId(handler), arg1);
}
Renderer& Renderer::operator()(const char *id, void (*handler)(Http&), const Value& arg1, const Value& arg2)
{
return operator()(id, HandlerId(handler), arg1, arg2);
}
Renderer& Renderer::SetLanguage(int lang_)