2.5 Branch: added WM_report and WM_reportf functions for reporting
authorBrecht Van Lommel <brechtvanlommel@pandora.be>
Fri, 3 Oct 2008 18:03:30 +0000 (18:03 +0000)
committerBrecht Van Lommel <brechtvanlommel@pandora.be>
Fri, 3 Oct 2008 18:03:30 +0000 (18:03 +0000)
information, warnings and errors.

source/blender/blenloader/intern/readfile.c
source/blender/makesdna/DNA_windowmanager_types.h
source/blender/windowmanager/WM_api.h
source/blender/windowmanager/WM_types.h
source/blender/windowmanager/intern/wm.c
source/blender/windowmanager/intern/wm_report.c [new file with mode: 0644]
source/blender/windowmanager/wm.h

index 13b2179e778a65eb59250e2cd6961ed8858adbd9..f5abbc7bfab59ad644b608e2b99aff5f379359b7 100644 (file)
@@ -3509,6 +3509,7 @@ static void direct_link_windowmanager(FileData *fd, wmWindowManager *wm)
        wm->screenkeymap.first= wm->screenkeymap.last= NULL;
        
        wm->queue.first= wm->queue.last= NULL;
+       wm->reports.first= wm->reports.last= NULL;
        
        wm->windrawable= NULL;
        wm->initialized= 0;
index 788f9f71e562b597eac5018db4961454a5ccbf92..99334d705dc881327a9f2c86e14b00c59e913dbd 100644 (file)
@@ -61,6 +61,8 @@ typedef struct wmWindowManager {
        ListBase operators;             /* operator registry */
        
        ListBase queue;                 /* refresh/redraw wmNotifier structs */
+
+       ListBase reports;               /* information and error reports */
        
        /* custom keymaps */
        ListBase windowkeymap;
index 6b020a07fb94fa5ad6f78a63c397fff2f39eff6a..2f450c9bbd731d4c23c70074299c626f9211d3f4 100644 (file)
@@ -150,6 +150,10 @@ void WM_gesture_update(struct bContext *C, struct wmGesture *from);
 void WM_gesture_end(struct bContext *C, int type);
 void WM_gesture_free(wmWindow *win);
 
+                       /* Reporting information and errors */
+void WM_report(struct bContext *C, int type, const char *message);
+void WM_reportf(struct bContext *C, int type, const char *format, ...);
+
                        /* OpenGL wrappers, mimicing opengl syntax */
 void           wmLoadMatrix            (wmWindow *win, float mat[][4]);
 void           wmGetMatrix                     (wmWindow *win, float mat[][4]);
index a0d1bc58ecb37db13ddd9b5bcdf66628afd45724..a85988b6a09d3b07cfec77b068c4554fc13c989d 100644 (file)
@@ -138,6 +138,25 @@ typedef struct wmBorderSelect {
        short x2, y2;
 } wmBorderSelect;
 
+/* ****************** Messages ********************* */
+
+enum {
+       WM_LOG_DEBUG                            = 0,
+       WM_LOG_INFO                                     = 1000,
+       WM_LOG_WARNING                          = 2000,
+       WM_ERROR_UNDEFINED                      = 3000,
+       WM_ERROR_INVALID_INPUT          = 3001,
+       WM_ERROR_INVALID_CONTEXT        = 3002,
+       WM_ERROR_OUT_OF_MEMORY          = 3003
+};
+
+typedef struct wmReport {
+       struct wmReport *next, *prev;
+       int type;
+       const char *typestr;
+       char *message;
+} wmReport;
+
 /* *************** migrated stuff, clean later? ******************************** */
 
 typedef struct RecentFile {
index 9727aa0f4ca060c03b04b6325bc3b7dd0c937b2b..87a3ce790f94dc2822ee66758b1fde63982f0ef5 100644 (file)
@@ -43,6 +43,7 @@
 #include "wm_window.h"
 #include "wm_event_system.h"
 #include "wm_event_types.h"
+#include "wm.h"
 
 #include "ED_screen.h"
 
@@ -130,6 +131,7 @@ void wm_close_and_free(bContext *C, wmWindowManager *wm)
 {
        wmWindow *win;
        wmOperator *op;
+       wmReport *report;
        
        while((win= wm->windows.first)) {
                BLI_remlink(&wm->windows, win);
@@ -141,6 +143,11 @@ void wm_close_and_free(bContext *C, wmWindowManager *wm)
                wm_operator_free(op);
        }
 
+       while((report= wm->reports.first)) {
+               BLI_remlink(&wm->reports, report);
+               wm_report_free(report);
+       }
+
        BLI_freelistN(&wm->timekeymap);
        BLI_freelistN(&wm->windowkeymap);
        BLI_freelistN(&wm->screenkeymap);
diff --git a/source/blender/windowmanager/intern/wm_report.c b/source/blender/windowmanager/intern/wm_report.c
new file mode 100644 (file)
index 0000000..3be991e
--- /dev/null
@@ -0,0 +1,134 @@
+
+#include "MEM_guardedalloc.h"
+
+#include "DNA_windowmanager_types.h"
+
+#include "BLI_blenlib.h"
+
+#include "BKE_global.h"
+
+#include "WM_api.h"
+#include "WM_types.h"
+
+#include <stdarg.h>
+#include <stdio.h>
+#include <string.h>
+
+#ifdef _WIN32
+#ifndef vsnprintf
+#define vsnprintf _vsnprintf
+#endif
+#endif
+
+static int wmReportLevel= WM_LOG_INFO;
+static int wmReportPrint= 0;
+
+static const char *wm_report_type_str(int type)
+{
+       switch(type) {
+               case WM_LOG_DEBUG: return "Debug";
+               case WM_LOG_INFO: return "Info";
+               case WM_LOG_WARNING: return "Warning";
+               case WM_ERROR_UNDEFINED: return "Error";
+               case WM_ERROR_INVALID_INPUT: return "Invalid Input Error";
+               case WM_ERROR_INVALID_CONTEXT: return "Invalid Context Error";
+               case WM_ERROR_OUT_OF_MEMORY: return "Out Of Memory Error";
+               default: return "Undefined Type";
+       }
+}
+
+static void wm_print_report(wmReport *report)
+{
+       printf("%s: %s\n", report->typestr, report->message);
+       fflush(stdout); /* this ensures the message is printed before a crash */
+}
+
+void WM_report(bContext *C, int type, const char *message)
+{
+       wmReport *report;
+       int len;
+
+       if(!C->wm) {
+               fprintf(stderr, "WM_report: can't report without windowmanager.\n");
+               return;
+       }
+       if(type < wmReportLevel)
+               return;
+
+       report= MEM_callocN(sizeof(wmReport), "wmReport");
+       report->type= type;
+       report->typestr= wm_report_type_str(type);
+
+       len= strlen(message);
+       report->message= MEM_callocN(sizeof(char)*(len+1), "wmReportMessage");
+       memcpy(report->message, message, sizeof(char)*(len+1));
+
+       if(wmReportPrint)
+               wm_print_report(report);
+       
+       BLI_addtail(&C->wm->reports, report);
+}
+
+void WM_reportf(bContext *C, int type, const char *format, ...)
+{
+       wmReport *report;
+       va_list args;
+       char *message;
+       int len= 256, maxlen= 65536, retval;
+
+       if(!C->wm) {
+               fprintf(stderr, "WM_report: can't report without windowmanager.\n");
+               return;
+       }
+       if(type < wmReportLevel)
+               return;
+
+       while(1) {
+               message= MEM_callocN(sizeof(char)*len+1, "wmReportMessage");
+
+               va_start(args, format);
+               retval= vsnprintf(message, len, format, args);
+               va_end(args);
+
+               if(retval == -1) {
+                       /* -1 means not enough space, but on windows it may also mean
+                        * there is a formatting error, so we impose a maximum length */
+                       MEM_freeN(message);
+                       message= NULL;
+
+                       len *= 2;
+                       if(len > maxlen) {
+                               fprintf(stderr, "WM_report message too long or format error.\n");
+                               break;
+                       }
+               }
+               else if(retval > len) {
+                       /* in C99 the actual length required is returned */
+                       MEM_freeN(message);
+                       message= NULL;
+
+                       len= retval;
+               }
+               else
+                       break;
+       }
+
+       if(message) {
+               report= MEM_callocN(sizeof(wmReport), "wmReport");
+               report->type= type;
+               report->typestr= wm_report_type_str(type);
+               report->message= message;
+
+               if(wmReportPrint)
+                       wm_print_report(report);
+
+               BLI_addtail(&C->wm->reports, report);
+       }
+}
+
+void wm_report_free(wmReport *report)
+{
+       MEM_freeN(report->message);
+       MEM_freeN(report);
+}
+
index c381ac269d966a878d9d09cbf3b0830c101e3b75..739b0266c78588be13d7e7567bb5482b60771630 100644 (file)
@@ -38,6 +38,8 @@ void          wm_operator_free(wmOperator *op);
                        /* register to windowmanager for redo or macro */
 void           wm_operator_register(wmWindowManager *wm, wmOperator *op);
 
+extern void wm_report_free(wmReport *report);
+
 /* wm_operator.c, for init/exit */
 void wm_operatortype_free(void);
 void wm_operatortype_init(void);