/* orxonox - the future of 3D-vertical-scrollers Copyright (C) 2004 orx This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2, or (at your option) any later version. ### File Specific: main-programmer: Benjamin Grauer co-programmer: ... */ //#define DEBUG_SPECIAL_MODULE DEBUG_MODULE_ #include "shell_buffer.h" #include "debug.h" #include "shell.h" #include "stdlibincl.h" using namespace std; /** * @brief standard constructor */ ShellBuffer::ShellBuffer () { ShellBuffer::singletonRef = this; this->shell = NULL; this->lineCount = 0; this->keepBufferArray[0] = '\0'; this->bufferArray[0] = '\0'; this->keepBuffer = false; this->setBufferSize(100); } ShellBuffer* ShellBuffer::singletonRef = NULL; SDL_mutex* ShellBuffer::bufferMutex = NULL; /** * @brief standard deconstructor */ ShellBuffer::~ShellBuffer () { if (this->shell != NULL) delete this->shell; this->flush(); if (ShellBuffer::bufferMutex != NULL) SDL_DestroyMutex(ShellBuffer::bufferMutex); ShellBuffer::bufferMutex = NULL; ShellBuffer::singletonRef = NULL; } /** * @brief registers the Shell to the Buffer * @param shell the Shell to register. */ void ShellBuffer::registerShell(Shell* shell) { if (this->shell == NULL) this->shell = shell; else PRINTF(1)("already registered a Shell to the ShellBuffer\n"); } /** * @brief unregisters the Shell from the Buffer * @param shell the Shell to unregister. */ void ShellBuffer::unregisterShell(Shell* shell) { if (this->shell == shell) this->shell = NULL; else PRINTF(1)("cannot unregister shell, because it is not registered to the ShellBuffer\n"); } /** * @brief deletes all the Buffers */ void ShellBuffer::flush() { this->buffer.clear(); } /** * @brief adds a new Line to the List of Buffers * @param line the Line as in the first argument in printf */ bool ShellBuffer::addBufferLineStatic(const char* line, ...) { va_list arguments; va_start(arguments, line); if (ShellBuffer::bufferMutex == NULL) ShellBuffer::bufferMutex = SDL_CreateMutex(); SDL_mutexP(ShellBuffer::bufferMutex); #if DEBUG < 3 if (ShellBuffer::singletonRef == NULL) #endif vprintf(line, arguments); #if DEBUG < 3 else #else if (ShellBuffer::singletonRef != NULL) #endif ShellBuffer::singletonRef->addBufferLine(line, arguments); SDL_mutexV(ShellBuffer::bufferMutex); return true; } /** * @brief add a Line to the List of Buffers * @param line * @param arguments * * This function Adds one line to the buffer. * and displays the line as the First Line of the display-buffer */ void ShellBuffer::addBufferLine(const char* line, va_list arguments) { char* inputEnd; char* newLineBegin; char* newLineEnd; // copy the output to the bufferArray vsprintf(this->bufferArray, line, arguments); // check if we have something left in the buffers // if so, append the new String to this one. if (unlikely(this->keepBuffer)) { strcat(this->keepBufferArray, this->bufferArray); inputEnd = this->keepBufferArray + strlen(this->bufferArray); newLineBegin = this->keepBufferArray; this->keepBuffer = false; } else { inputEnd = this->bufferArray + strlen(this->bufferArray); newLineBegin = this->bufferArray; } // adding all the new Lines while (newLineBegin < inputEnd) { newLineEnd = strchr(newLineBegin, '\n'); if (likely(newLineEnd != NULL && *newLineEnd == '\n')) *newLineEnd = '\0'; else { unsigned int len = strlen(newLineBegin); char* copyBuffer = new char[len+1]; strcpy(copyBuffer, newLineBegin); strncpy(this->keepBufferArray, copyBuffer, len); delete[] copyBuffer; this->keepBufferArray[len] = '\0'; this->keepBuffer = true; break; } this->lineCount++; this->buffer.push_back(newLineBegin); if (likely (this->shell != NULL) && unlikely (this->shell->isActive())) this->shell->printToDisplayBuffer(newLineBegin); if (this->buffer.size() > this->bufferSize) this->buffer.pop_front(); newLineBegin = newLineEnd+1; } } /** * displays some nice output from the Shell */ void ShellBuffer::debug() const { PRINT(3)("Debugging output to console (not this shell)\n"); list::const_iterator bufferLine; for (bufferLine = this->buffer.begin(); bufferLine != this->buffer.end(); bufferLine++) printf((*bufferLine).c_str()); }