diff --git a/include/arc/console/buffer.h b/include/arc/console/buffer.h new file mode 100644 index 0000000..fe8b09d --- /dev/null +++ b/include/arc/console/buffer.h @@ -0,0 +1,102 @@ +#ifndef ARC_CONSOLE_LINE_BUFFER_H_ +#define ARC_CONSOLE_LINE_BUFFER_H_ + +#ifdef __cplusplus +extern "C" { +#endif + +#include +#include "arc/console/view.h" +#include "arc/std/string.h" + +/** + * @brief +*/ +typedef struct ARC_ConsoleBuffer ARC_ConsoleBuffer; + +/** + * @brief creates ARC_ConsoleBuffer type + * + * @param buffer ARC_ConsoleBuffer to create +*/ +void ARC_ConsoleBuffer_Create(ARC_ConsoleBuffer **buffer); + +/** + * @brief destroys ARC_ConsoleBuffer type + * + * @param buffer ARC_ConsoleBuffer to destroy +*/ +void ARC_ConsoleBuffer_Destroy(ARC_ConsoleBuffer *buffer); + +/** + * @brief clears the contents of a ARC_ConsoleBuffer + * + * @param buffer ARC_ConsoleBuffer to clear +*/ +void ARC_ConsoleBuffer_Clear(ARC_ConsoleBuffer *buffer); + +/** + * @brief renders a buffer to a ARC_ConsoleView + * + * @param buffer ARC_ConsoleBuffer to render + * @param view ARC_ConsoleView to render the buffer contents to +*/ +void ARC_ConsoleBuffer_Render(ARC_ConsoleBuffer *buffer, ARC_ConsoleView *view); + +/** + * @brief renders a section of buffer to a ARC_ConsoleView + * + * @param buffer ARC_ConsoleBuffer to render + * @param view ARC_ConsoleView to render the buffer contents to + * @param startIndex start index of buffer to render + * @param lines the number of lines of buffer to render +*/ +void ARC_ConsoleBuffer_RenderSection(ARC_ConsoleBuffer *buffer, ARC_ConsoleView *view, uint32_t startIndex, uint32_t lines); + +/** + * @brief adds a character to the buffer + * + * @param buffer ARC_ConsoleBuffer to add character to + * @param character char to add to ARC_ConsoleBuffer +*/ +void ARC_ConsoleBuffer_AddChar(ARC_ConsoleBuffer *buffer, char character); + +/** + * @brief adds an ARC_String to the buffer + * + * @param buffer ARC_ConsoleBuffer to add character to + * @param string ARC_String to add to ARC_ConsoleBuffer +*/ +void ARC_ConsoleBuffer_AddString(ARC_ConsoleBuffer *buffer, ARC_String *string); + +/** + * @brief adds a cstring to the buffer + * + * @param buffer ARC_ConsoleBuffer to add character to + * @param string cstring to add to ARC_ConsoleBuffer + * @param length the length of the c string to add +*/ +void ARC_ConsoleBuffer_AddCString(ARC_ConsoleBuffer *buffer, char *cstring, uint64_t length); + +/** + * @brief adds a cstring to the buffer with the cstrings string length + * + * @param buffer ARC_ConsoleBuffer to add character to + * @param string cstring to add to ARC_ConsoleBuffer +*/ +void ARC_ConsoleBuffer_AddCStringWithStrlen(ARC_ConsoleBuffer *buffer, char *cstring); + +/** + * @brief gets the number of lines from a console line buffer + * + * @param buffer ARC_ConsoleBuffer get number of lines from + * + * @return the number of lines within an ARC_ConsoleBuffer +*/ +uint32_t ARC_ConsoleBuffer_GetLineNumbers(ARC_ConsoleBuffer *buffer); + +#ifdef __cplusplus +} +#endif + +#endif //!ARC_CONSOLE_LINE_BUFFER_H_ diff --git a/packages/console/ncurses/buffer.c b/packages/console/ncurses/buffer.c new file mode 100644 index 0000000..f7aec83 --- /dev/null +++ b/packages/console/ncurses/buffer.c @@ -0,0 +1,147 @@ +#include "arc/console/buffer.h" + +#include "arc/console/view.h" +#include "arc/std/string.h" +#include "arc/std/vector.h" +#include +#include + +struct ARC_ConsoleBuffer { + ARC_Vector *bufferLines; +}; + +void ARC_ConsoleBuffer_Create(ARC_ConsoleBuffer **buffer){ + *buffer = (ARC_ConsoleBuffer *)malloc(sizeof(ARC_ConsoleBuffer)); + + ARC_Vector_Create(&((*buffer)->bufferLines)); + + //add first line to vector + ARC_Vector_Add((*buffer)->bufferLines, NULL); +} + +void ARC_ConsoleBuffer_Destroy(ARC_ConsoleBuffer *buffer){ + for(uint32_t i = 0; i < ARC_Vector_Size(buffer->bufferLines); i++){ + ARC_String *bufferLine = (ARC_String *)ARC_Vector_Get(buffer->bufferLines, i); + + if(bufferLine != NULL){ + ARC_String_Destroy(bufferLine); + } + } + + ARC_Vector_Destroy(buffer->bufferLines); + free(buffer); +} + +void ARC_ConsoleBuffer_Clear(ARC_ConsoleBuffer *buffer){ + for(uint32_t i = 0; i < ARC_Vector_Size(buffer->bufferLines); i++){ + ARC_String *bufferLine = (ARC_String *)ARC_Vector_Get(buffer->bufferLines, i); + + if(bufferLine != NULL){ + ARC_String_Destroy(bufferLine); + } + } + + ARC_Vector_Destroy(buffer->bufferLines); + ARC_Vector_Create(&(buffer->bufferLines)); + + //add first line to vector + ARC_Vector_Add(buffer->bufferLines, NULL); +} + +void ARC_ConsoleBuffer_Render(ARC_ConsoleBuffer *buffer, ARC_ConsoleView *view){ + ARC_Rect viewBounds = ARC_ConsoleView_GetBounds(view); + + uint32_t bufferStartIndex = 0; + if(ARC_Vector_Size(buffer->bufferLines) > (uint32_t)viewBounds.h){ + bufferStartIndex = ARC_Vector_Size(buffer->bufferLines) - viewBounds.h; + } + + for(uint32_t i = 0; i < (uint32_t)viewBounds.h; i++){ + if(i + bufferStartIndex > ARC_Vector_Size(buffer->bufferLines)){ + break; + } + + ARC_String *bufferLine = (ARC_String *)ARC_Vector_Get(buffer->bufferLines, i + bufferStartIndex); + if(bufferLine == NULL){ + continue; + } + + ARC_ConsoleView_RenderStringAt(view, bufferLine, (ARC_Point){ 0, i }); + } +} + +void ARC_ConsoleBuffer_RenderSection(ARC_ConsoleBuffer *buffer, ARC_ConsoleView *view, uint32_t startIndex, uint32_t lines){ + ARC_Rect viewBounds = ARC_ConsoleView_GetBounds(view); + + for(uint32_t i = 0; i < lines; i++){ + if(i + startIndex >= ARC_Vector_Size(buffer->bufferLines)){ + break; + } + + if(i >= (uint32_t)viewBounds.h){ + break; + } + + ARC_String *bufferLine = (ARC_String *)ARC_Vector_Get(buffer->bufferLines, i + startIndex); + if(bufferLine == NULL){ + continue; + } + + ARC_ConsoleView_RenderStringAt(view, bufferLine, (ARC_Point){ 0, i }); + } +} + +void ARC_ConsoleBuffer_AddChar(ARC_ConsoleBuffer *buffer, char character){ + if(character == '\n'){ + ARC_Vector_Add(buffer->bufferLines, (void *)NULL); + return; + } + + //get the last line and add a char to it + ARC_String *bufferLine = (ARC_String *)ARC_Vector_Get(buffer->bufferLines, ARC_Vector_Size(buffer->bufferLines) - 1); + ARC_Vector_RemoveIndex(buffer->bufferLines, ARC_Vector_Size(buffer->bufferLines) - 1); + + if(bufferLine == NULL){ + ARC_String_Create(&bufferLine, &character, 1); + ARC_Vector_Add(buffer->bufferLines, (void *)bufferLine); + return; + } + + //add char to the end of the bufferline + ARC_String *nextChar; + ARC_String_Create(&nextChar, &character, 1); + + ARC_String *tempBufferLine = bufferLine; + ARC_String_Merge(&bufferLine, tempBufferLine, nextChar); + + ARC_String_Destroy(tempBufferLine); + ARC_String_Destroy(nextChar); + + //add buffer line back to the bufferLines + ARC_Vector_Add(buffer->bufferLines, (void *)bufferLine); +} + +void ARC_ConsoleBuffer_AddString(ARC_ConsoleBuffer *buffer, ARC_String *string){ + //TODO: this in a more efficient way + for(uint64_t i = 0; i < string->length; i++){ + ARC_ConsoleBuffer_AddChar(buffer, string->data[i]); + } +} + +void ARC_ConsoleBuffer_AddCString(ARC_ConsoleBuffer *buffer, char *cstring, uint64_t length){ + //TODO: this in a more efficient way + for(uint64_t i = 0; i < length; i++){ + ARC_ConsoleBuffer_AddChar(buffer, cstring[i]); + } +} + +void ARC_ConsoleBuffer_AddCStringWithStrlen(ARC_ConsoleBuffer *buffer, char *cstring){ + //TODO: this in a more efficient way + for(uint64_t i = 0; i < strlen(cstring); i++){ + ARC_ConsoleBuffer_AddChar(buffer, cstring[i]); + } +} + +uint32_t ARC_ConsoleBuffer_GetLineNumbers(ARC_ConsoleBuffer *buffer){ + return ARC_Vector_Size(buffer->bufferLines); +}