#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); }