From e39eebff26a38db41f5a83c75dbc59ed6b220eae Mon Sep 17 00:00:00 2001 From: Kearwood Gilbert Date: Sat, 14 Dec 2013 16:06:44 -0800 Subject: [PATCH] Implemented logging callbacks for client applications that would like to implement their own GUI --HG-- branch : nfb --- KREngine/kraken/KRAnimationAttribute.cpp | 2 +- KREngine/kraken/KRContext.cpp | 37 ++++++++++++++++++++++-- KREngine/kraken/KRContext.h | 16 ++++++++++ KREngine/kraken/KRDataBlock.cpp | 17 ++++++----- KREngine/kraken/KRHitInfo.cpp | 3 +- KREngine/kraken/KRMaterialManager.cpp | 2 +- KREngine/kraken/KRMesh.cpp | 4 +-- KREngine/kraken/KRMeshManager.cpp | 6 ++-- KREngine/kraken/KRShader.cpp | 24 ++++++++------- KREngine/kraken/KRShaderManager.cpp | 6 ++-- 10 files changed, 85 insertions(+), 32 deletions(-) diff --git a/KREngine/kraken/KRAnimationAttribute.cpp b/KREngine/kraken/KRAnimationAttribute.cpp index 9133f6a..f2ecebe 100644 --- a/KREngine/kraken/KRAnimationAttribute.cpp +++ b/KREngine/kraken/KRAnimationAttribute.cpp @@ -256,7 +256,7 @@ KRNode *KRAnimationAttribute::getTarget() m_target = getContext().getSceneManager()->getFirstScene()->getRootNode()->find(m_target_name); // FINDME, HACK! - This won't work with multiple scenes in a context; we should move the animations out of KRAnimationManager and attach them to the parent nodes of the animated KRNode's } if(m_target == NULL) { - fprintf(stderr, "Kraken - Animation attribute could not find object: %s\n", m_target_name.c_str()); + KRContext::Log(KRContext::LOG_LEVEL_ERROR, "Kraken - Animation attribute could not find object: %s", m_target_name.c_str()); } return m_target; } diff --git a/KREngine/kraken/KRContext.cpp b/KREngine/kraken/KRContext.cpp index a26e398..c11dbb1 100644 --- a/KREngine/kraken/KRContext.cpp +++ b/KREngine/kraken/KRContext.cpp @@ -25,6 +25,9 @@ const char *KRContext::extension_names[KRENGINE_NUM_EXTENSIONS] = { "GL_EXT_texture_storage" }; +KRContext::log_callback *KRContext::s_log_callback = NULL; +void *KRContext::s_log_callback_user_data = NULL; + KRContext::KRContext() { m_streamingEnabled = false; mach_timebase_info(&m_timebase_info); @@ -44,6 +47,8 @@ KRContext::KRContext() { m_pSoundManager = new KRAudioManager(*this); m_pUnknownManager = new KRUnknownManager(*this); m_streamingEnabled = true; + + } KRContext::~KRContext() { @@ -100,6 +105,32 @@ KRContext::~KRContext() { } } +void KRContext::SetLogCallback(log_callback *log_callback, void *user_data) +{ + s_log_callback = log_callback; + s_log_callback_user_data = user_data; +} + +void KRContext::Log(log_level level, const std::string &message_format, ...) +{ + va_list args; + va_start(args, message_format); + + if(s_log_callback) { + const int LOG_BUFFER_SIZE = 32768; + char log_buffer[LOG_BUFFER_SIZE]; + snprintf(log_buffer, LOG_BUFFER_SIZE, message_format.c_str(), args); + s_log_callback(s_log_callback_user_data, std::string(log_buffer), level); + } else { + FILE *out_file = level == LOG_LEVEL_INFORMATION ? stdout : stderr; + fprintf(out_file, "Kraken - INFO: "); + fprintf(out_file, message_format.c_str(), args); + fprintf(out_file, "\n"); + } + + va_end(args); +} + KRBundleManager *KRContext::getBundleManager() { return m_pBundleManager; } @@ -220,7 +251,7 @@ void KRContext::loadResource(std::string path) { if(data->load(path)) { loadResource(path, data); } else { - fprintf(stderr, "KRContext::loadResource - Failed to open file: %s\n", path.c_str()); + KRContext::Log(KRContext::LOG_LEVEL_ERROR, "KRContext::loadResource - Failed to open file: %s", path.c_str()); delete data; } } @@ -291,9 +322,9 @@ void KRContext::getMemoryStats(long &free_memory) vm_statistics_data_t vm_stat; int total_ram = 256 * 1024 * 1024; if(host_page_size(host_port, &pagesize) != KERN_SUCCESS) { - fprintf(stderr, "ERROR: Could not get VM page size.\n"); + KRContext::Log(KRContext::LOG_LEVEL_ERROR, "Could not get VM page size."); } else if(host_statistics(host_port, HOST_VM_INFO, (host_info_t)&vm_stat, &host_size) != KERN_SUCCESS) { - fprintf(stderr, "ERROR: Could not get VM stats.\n"); + KRContext::Log(KRContext::LOG_LEVEL_ERROR, "Could not get VM stats."); } else { total_ram = (vm_stat.wire_count + vm_stat.active_count + vm_stat.inactive_count + vm_stat.free_count) * pagesize; diff --git a/KREngine/kraken/KRContext.h b/KREngine/kraken/KRContext.h index c75f846..4f91d40 100644 --- a/KREngine/kraken/KRContext.h +++ b/KREngine/kraken/KRContext.h @@ -77,6 +77,18 @@ public: void getMemoryStats(long &free_memory); + typedef enum { + LOG_LEVEL_INFORMATION, + LOG_LEVEL_WARNING, + LOG_LEVEL_ERROR + } log_level; + + typedef void log_callback(void *userdata, const std::string &message, log_level level); + + static void SetLogCallback(log_callback *log_callback, void *user_data); + static void Log(log_level level, const std::string &message_format, ...); + + private: KRBundleManager *m_pBundleManager; KRSceneManager *m_pSceneManager; @@ -98,6 +110,10 @@ private: mach_timebase_info_data_t m_timebase_info; std::atomic m_streamingEnabled; + + + static log_callback *s_log_callback; + static void *s_log_callback_user_data; }; #endif diff --git a/KREngine/kraken/KRDataBlock.cpp b/KREngine/kraken/KRDataBlock.cpp index cfc2421..1a32081 100644 --- a/KREngine/kraken/KRDataBlock.cpp +++ b/KREngine/kraken/KRDataBlock.cpp @@ -32,6 +32,7 @@ #include "KRDataBlock.h" #include "KREngine-common.h" #include "KRResource.h" +#include "KRContext.h" #include @@ -311,28 +312,28 @@ void KRDataBlock::lock() int iError = errno; switch(iError) { case EACCES: - fprintf(stderr, "mmap failed with EACCES\n"); + KRContext::Log(KRContext::LOG_LEVEL_ERROR, "mmap failed with EACCES"); break; case EBADF: - fprintf(stderr, "mmap failed with EBADF\n"); + KRContext::Log(KRContext::LOG_LEVEL_ERROR, "mmap failed with EBADF"); break; case EMFILE: - fprintf(stderr, "mmap failed with EMFILE\n"); + KRContext::Log(KRContext::LOG_LEVEL_ERROR, "mmap failed with EMFILE"); break; case EINVAL: - fprintf(stderr, "mmap failed with EINVAL\n"); + KRContext::Log(KRContext::LOG_LEVEL_ERROR, "mmap failed with EINVAL"); break; case ENOMEM: - fprintf(stderr, "mmap failed with ENOMEM\n"); + KRContext::Log(KRContext::LOG_LEVEL_ERROR, "mmap failed with ENOMEM"); break; case ENXIO: - fprintf(stderr, "mmap failed with ENXIO\n"); + KRContext::Log(KRContext::LOG_LEVEL_ERROR, "mmap failed with ENXIO"); break; case EOVERFLOW: - fprintf(stderr, "mmap failed with EOVERFLOW\n"); + KRContext::Log(KRContext::LOG_LEVEL_ERROR, "mmap failed with EOVERFLOW"); break; default: - fprintf(stderr, "mmap failed with errno: %i\n", iError); + KRContext::Log(KRContext::LOG_LEVEL_ERROR, "mmap failed with errno: %i", iError); break; } assert(false); // mmap() failed. diff --git a/KREngine/kraken/KRHitInfo.cpp b/KREngine/kraken/KRHitInfo.cpp index 3e0d048..724dfb0 100644 --- a/KREngine/kraken/KRHitInfo.cpp +++ b/KREngine/kraken/KRHitInfo.cpp @@ -30,6 +30,7 @@ // #include "KRHitInfo.h" +#include "KRContext.h" KRHitInfo::KRHitInfo() { @@ -42,7 +43,7 @@ KRHitInfo::KRHitInfo(const KRVector3 &position, const KRVector3 &normal, KRNode { m_position = position; if(m_position == KRVector3::Zero()) { - fprintf(stderr, "Zero position hitinfo\n"); + KRContext::Log(KRContext::LOG_LEVEL_ERROR, "Zero position hitinfo"); } m_normal = normal; m_node = node; diff --git a/KREngine/kraken/KRMaterialManager.cpp b/KREngine/kraken/KRMaterialManager.cpp index 8b7deaa..cab3a97 100644 --- a/KREngine/kraken/KRMaterialManager.cpp +++ b/KREngine/kraken/KRMaterialManager.cpp @@ -80,7 +80,7 @@ KRMaterial *KRMaterialManager::getMaterial(const std::string &name) { unordered_map::iterator itr = m_materials.find(lowerName); if(itr == m_materials.end()) { - fprintf(stderr, "Material not found: %s\n", name.c_str()); + KRContext::Log(KRContext::LOG_LEVEL_WARNING, "Material not found: %s", name.c_str()); // Not found return NULL; } else { diff --git a/KREngine/kraken/KRMesh.cpp b/KREngine/kraken/KRMesh.cpp index 2cf0c2f..f379f27 100644 --- a/KREngine/kraken/KRMesh.cpp +++ b/KREngine/kraken/KRMesh.cpp @@ -175,7 +175,7 @@ void KRMesh::render(const std::string &object_name, KRCamera *pCamera, std::vect if(pMaterial) { m_uniqueMaterials.insert(pMaterial); } else { - fprintf(stderr, "Missing material: %s\n", szMaterialName); + KRContext::Log(KRContext::LOG_LEVEL_WARNING, "Missing material: %s", szMaterialName); } } @@ -1301,7 +1301,7 @@ void KRMesh::convertToIndexed() delete szKey; - fprintf(stderr, "Convert to indexed, before: %i after: %i \(%.2f%% saving)\n", getHeader()->vertex_count, mi.vertices.size(), ((float)getHeader()->vertex_count - (float)mi.vertices.size()) / (float)getHeader()->vertex_count * 100.0f); + KRContext::Log(KRContext::LOG_LEVEL_INFORMATION, "Convert to indexed, before: %i after: %i \(%.2f%% saving)", getHeader()->vertex_count, mi.vertices.size(), ((float)getHeader()->vertex_count - (float)mi.vertices.size()) / (float)getHeader()->vertex_count * 100.0f); mi.format = KRENGINE_MODEL_FORMAT_INDEXED_TRIANGLES; diff --git a/KREngine/kraken/KRMeshManager.cpp b/KREngine/kraken/KRMeshManager.cpp index 9247ae1..68b5c53 100644 --- a/KREngine/kraken/KRMeshManager.cpp +++ b/KREngine/kraken/KRMeshManager.cpp @@ -129,7 +129,7 @@ std::vector KRMeshManager::getModel(const char *szName) { std::sort(matching_models.begin(), matching_models.end(), KRMesh::lod_sort_predicate); if(matching_models.size() == 0) { - fprintf(stderr, "ERROR: Model not found: %s\n", lowerName.c_str()); + KRContext::Log(KRContext::LOG_LEVEL_INFORMATION, "Model not found: %s", lowerName.c_str()); } return matching_models; @@ -159,7 +159,7 @@ void KRMeshManager::releaseVBO(KRDataBlock &data) vbo_info_type vbo_to_release; if(m_vbosActive.find(&data) != m_vbosActive.end()) { - fprintf(stderr, "glFinish called due to releasing a VBO that is active in the current frame.\n"); + KRContext::Log(KRContext::LOG_LEVEL_WARNING, "glFinish called due to releasing a VBO that is active in the current frame."); GLDEBUG(glFinish()); // The VBO is active @@ -219,7 +219,7 @@ void KRMeshManager::bindVBO(KRDataBlock &data, KRDataBlock &index_data, int vert while(m_vbosPool.size() + m_vbosActive.size() + 1 >= KRContext::KRENGINE_MAX_VBO_HANDLES || m_vboMemUsed + data.getSize() + index_data.getSize() >= KRContext::KRENGINE_MAX_VBO_MEM) { if(m_vbosPool.empty()) { - fprintf(stderr, "flushBuffers due to VBO exhaustion...\n"); + KRContext::Log(KRContext::LOG_LEVEL_WARNING, "flushBuffers due to VBO exhaustion..."); m_pContext->rotateBuffers(false); } unordered_map::iterator first_itr = m_vbosPool.begin(); diff --git a/KREngine/kraken/KRShader.cpp b/KREngine/kraken/KRShader.cpp index bdb2cef..b1423e0 100644 --- a/KREngine/kraken/KRShader.cpp +++ b/KREngine/kraken/KRShader.cpp @@ -129,10 +129,11 @@ KRShader::KRShader(KRContext &context, char *szKey, std::string options, std::st GLint logLength; GLDEBUG(glGetShaderiv(vertexShader, GL_INFO_LOG_LENGTH, &logLength)); if (logLength > 0) { - GLchar *log = (GLchar *)malloc(logLength); + GLchar *log = (GLchar *)malloc(logLength + 1); assert(log != NULL); GLDEBUG(glGetShaderInfoLog(vertexShader, logLength, &logLength, log)); - fprintf(stderr, "KREngine - Failed to compile vertex shader: %s\nShader compile log:\n%s", szKey, log); + log[logLength] = '\0'; + KRContext::Log(KRContext::LOG_LEVEL_ERROR, "KREngine - Failed to compile vertex shader: %s\nShader compile log:\n%s", szKey, log); free(log); } @@ -145,10 +146,11 @@ KRShader::KRShader(KRContext &context, char *szKey, std::string options, std::st // Report any compile issues to stderr GLDEBUG(glGetShaderiv(fragShader, GL_INFO_LOG_LENGTH, &logLength)); if (logLength > 0) { - GLchar *log = (GLchar *)malloc(logLength); + GLchar *log = (GLchar *)malloc(logLength + 1); assert(log != NULL); GLDEBUG(glGetShaderInfoLog(fragShader, logLength, &logLength, log)); - fprintf(stderr, "KREngine - Failed to compile fragment shader: %s\nShader compile log:\n%s", szKey, log); + log[logLength] = '\0'; + KRContext::Log(KRContext::LOG_LEVEL_ERROR, "KREngine - Failed to compile fragment shader: %s\nShader compile log:\n%s", szKey, log); free(log); } @@ -176,15 +178,16 @@ KRShader::KRShader(KRContext &context, char *szKey, std::string options, std::st if(link_success != GL_TRUE) { // Report any linking issues to stderr - fprintf(stderr, "KREngine - Failed to link shader program: %s\n", szKey); + KRContext::Log(KRContext::LOG_LEVEL_ERROR, "KREngine - Failed to link shader program: %s", szKey); GLDEBUG(glGetProgramiv(m_iProgram, GL_INFO_LOG_LENGTH, &logLength)); if (logLength > 0) { - GLchar *log = (GLchar *)malloc(logLength); + GLchar *log = (GLchar *)malloc(logLength + 1); assert(log != NULL); GLDEBUG(glGetProgramInfoLog(m_iProgram, logLength, &logLength, log)); - fprintf(stderr, "Program link log:\n%s", log); + log[logLength] = '\0'; + KRContext::Log(KRContext::LOG_LEVEL_ERROR, "Program link log:\n%s", log); free(log); } GLDEBUG(glDeleteProgram(m_iProgram)); @@ -557,14 +560,15 @@ bool KRShader::bind(KRCamera &camera, const KRViewport &viewport, const KRMat4 & GLDEBUG(glValidateProgram(m_iProgram)); GLDEBUG(glGetProgramiv(m_iProgram, GL_VALIDATE_STATUS, &validate_status)); if(validate_status != GL_TRUE) { - fprintf(stderr, "KREngine - Failed to validate shader program: %s\n", m_szKey); + KRContext::Log(KRContext::LOG_LEVEL_ERROR, "KREngine - Failed to validate shader program: %s", m_szKey); GLDEBUG(glGetProgramiv(m_iProgram, GL_INFO_LOG_LENGTH, &logLength)); if (logLength > 0) { - GLchar *log = (GLchar *)malloc(logLength); + GLchar *log = (GLchar *)malloc(logLength + 1); assert(log != NULL); GLDEBUG(glGetProgramInfoLog(m_iProgram, logLength, &logLength, log)); - fprintf(stderr, "Program validate log:\n%s", log); + log[logLength] = '\0'; + KRContext::Log(KRContext::LOG_LEVEL_ERROR, "Program validate log:\n%s", log); free(log); } diff --git a/KREngine/kraken/KRShaderManager.cpp b/KREngine/kraken/KRShaderManager.cpp index 0cbe5d2..664cb1e 100644 --- a/KREngine/kraken/KRShaderManager.cpp +++ b/KREngine/kraken/KRShaderManager.cpp @@ -126,7 +126,7 @@ KRShader *KRShaderManager::getShader(const std::string &shader_name, KRCamera *p std::map > , KRShader *>::iterator itr = m_shaders.begin(); delete (*itr).second; m_shaders.erase(itr); - fprintf(stderr, "Swapping shaders...\n"); + KRContext::Log(KRContext::LOG_LEVEL_INFORMATION, "Swapping shaders...\n"); } @@ -224,10 +224,10 @@ KRShader *KRShaderManager::getShader(const std::string &shader_name, KRCamera *p std::string fragShaderSource = m_fragShaderSource[platform_shader_name]; if(vertShaderSource.length() == 0) { - fprintf(stderr, "ERROR: Vertex Shader Missing: %s\n", platform_shader_name.c_str()); + KRContext::Log(KRContext::LOG_LEVEL_ERROR, "Vertex Shader Missing: %s", platform_shader_name.c_str()); } if(fragShaderSource.length() == 0) { - fprintf(stderr, "ERROR: Fragment Shader Missing: %s\n", platform_shader_name.c_str()); + KRContext::Log(KRContext::LOG_LEVEL_ERROR, "Fragment Shader Missing: %s", platform_shader_name.c_str()); } char szKey[256];