#include "arc/console/buffer/line.h" #include "arc/console/view.h" #include "arc/std/string.h" #include "arc/std/vector.h" #include #include struct ARC_ConsoleLineBuffer { ARC_Vector *bufferLines; }; void ARC_ConsoleLineBuffer_Create(ARC_ConsoleLineBuffer **buffer){ *buffer = (ARC_ConsoleLineBuffer *)malloc(sizeof(ARC_ConsoleLineBuffer)); ARC_Vector_Create(&((*buffer)->bufferLines)); //add first line to vector ARC_Vector_Add((*buffer)->bufferLines, NULL); } void ARC_ConsoleLineBuffer_Destroy(ARC_ConsoleLineBuffer *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_ConsoleLineBuffer_Clear(ARC_ConsoleLineBuffer *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_ConsoleLineBuffer_Render(ARC_ConsoleLineBuffer *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_ConsoleLineBuffer_RenderSection(ARC_ConsoleLineBuffer *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_ConsoleLineBuffer_AddChar(ARC_ConsoleLineBuffer *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_ConsoleLineBuffer_AddString(ARC_ConsoleLineBuffer *buffer, ARC_String *string){ //TODO: this in a more efficient way for(uint64_t i = 0; i < string->length; i++){ ARC_ConsoleLineBuffer_AddChar(buffer, string->data[i]); } } void ARC_ConsoleLineBuffer_AddCString(ARC_ConsoleLineBuffer *buffer, char *cstring, uint64_t length){ //TODO: this in a more efficient way for(uint64_t i = 0; i < length; i++){ ARC_ConsoleLineBuffer_AddChar(buffer, cstring[i]); } } void ARC_ConsoleLineBuffer_AddCStringWithStrlen(ARC_ConsoleLineBuffer *buffer, char *cstring){ //TODO: this in a more efficient way for(uint64_t i = 0; i < strlen(cstring); i++){ ARC_ConsoleLineBuffer_AddChar(buffer, cstring[i]); } } uint32_t ARC_ConsoleLineBuffer_GetLineNumbers(ARC_ConsoleLineBuffer *buffer){ return ARC_Vector_Size(buffer->bufferLines); }