// This file is a part of Framsticks SDK. http://www.framsticks.com/ // Copyright (C) 1999-2015 Maciej Komosinski and Szymon Ulatowski. // See LICENSE.txt for details. #ifndef _ERRMANAGER_H_ #define _ERRMANAGER_H_ #include #include #include #include class ErrorHandlerBase; class ErrorManager { friend class ErrorHandlerBase; SListTempl handlers; void send(int level, const char *o, const char *m, const char *bl, int w); public: int find(ErrorHandlerBase *r) { return handlers.find(r); } int add(ErrorHandlerBase *r); void remove(int i); void remove(ErrorHandlerBase *r); void removeAll(); void send(const char *o, const char *m, const char *bl, int w) { send(handlers.size() - 1, o, m, bl, w); } ~ErrorManager() { removeAll(); } }; extern THREAD_LOCAL_DECL(ErrorManager, errmgr_instance); //////////////////////////////////////// class ErrorHandlerBase { friend class ErrorManager; protected: ErrorManager* mgr; int options; public: enum HandlerOptions { DontBlock = 1, CannotBeBlocked = 2, DontEnable = 4, Paused = 8 }; void FMprintf(const char *o, const char *m, int w, const char *bl, ...); void send(const char *o, const char *m, const char *bl, int w); bool isEnabled() { return mgr ? 1 : 0; } void enable(); void disable(); bool isPaused() { return (options & Paused) != 0; } void pause(); void resume(); ErrorHandlerBase(int opts = 0) :mgr(0), options(opts) { if (!(options&DontEnable)) enable(); } virtual ~ErrorHandlerBase() { disable(); } virtual void handle(const char *o, const char *m, const char *bl, int w) {} }; /////////////////////////////////////////// class ErrorHandler : public ErrorHandlerBase { protected: int maxlevel, errcount, warncount, storlevel, storcount, infocount; SString msgs; public: void reset() { maxlevel = FMLV_INFO - 1; errcount = warncount = storcount = infocount = 0; msgs = 0; } enum Options2 { StoreFirstMessage = 16, StoreAllMessages = 32 }; int getErrorCount() { return errcount; } int getWarningCount() { return warncount; } int getInfoCount() { return infocount; } int getStoredCount() { return storcount; } int getErrorLevel() { return maxlevel; } const SString& getMessages() { return msgs; } ErrorHandler(int opts = 0, int store = FMLV_ERROR) :ErrorHandlerBase(opts), storlevel(store) { reset(); } void handle(const char *o, const char *m, const char *bl, int w); }; class ErrorRedirector : public ErrorHandlerBase { ErrorManager *other_mgr; public: ErrorRedirector(ErrorManager *om) :ErrorHandlerBase(), other_mgr(om) {} void handle(const char *o, const char *m, const char *bl, int w) { other_mgr->send(o, m, bl, w); } }; #endif