Fixed CSV Parsing on tools

This commit is contained in:
2023-01-28 21:01:30 -08:00
parent fcaeebd316
commit d14e063ba6
17 changed files with 347 additions and 19 deletions

View File

@ -29,4 +29,5 @@ scene.22.1,"King Fight"
scene.23.1,"Post King Fight, angry he leaves, town rallies around you"
scene.24.1,"Go to one of the kingsmen who's working with the big bad, he's worried that the townspeople know more than they let on."
unknown3,"Something here has to bring the big bad to town."
test.1,"Test"
test.1,"Test "
test.2,"Test*"
1 undefined UNDEFINED
29 scene.23.1 Post King Fight, angry he leaves, town rallies around you
30 scene.24.1 Go to one of the kingsmen who's working with the big bad, he's worried that the townspeople know more than they let on.
31 unknown3 Something here has to bring the big bad to town.
32 test.1 Test Test
33 test.2 Test*

View File

@ -7,6 +7,7 @@
#include "scene/Scene.hpp"
#include "ui/UIComponent.hpp"
#include "game/DawnGame.hpp"
#include "ui/UIMenu.hpp"
using namespace Dawn;
@ -26,6 +27,12 @@ void UICanvas::onRenderTargetResize(float_t w, float_t h){
}
}
void UICanvas::onSceneUpdate() {
if(this->currentMenu != nullptr) {
this->currentMenu->onTick();
}
}
void UICanvas::setCamera(Camera *camera) {
assertTrue(camera != this->camera);
@ -58,11 +65,23 @@ float_t UICanvas::getHeight() {
return this->camera->getRenderTarget()->getHeight();
}
struct UIMenu * UICanvas::getCurrentMenu() {
return this->currentMenu;
}
void UICanvas::setCurrentMenu(struct UIMenu *menu) {
if(this->currentMenu != nullptr) this->currentMenu->onInactive();
this->currentMenu = menu;
if(menu != nullptr) menu->onActive();
}
void UICanvas::onStart() {
if(this->camera == nullptr) {
auto camera = this->getScene()->findComponent<Camera>();
this->setCamera(camera);
}
this->getScene()->eventSceneUpdate.addListener(this, &UICanvas::onSceneUpdate);
}
void UICanvas::onDispose() {
@ -71,6 +90,8 @@ void UICanvas::onDispose() {
this, &UICanvas::onRenderTargetResize
);
}
this->getScene()->eventSceneUpdate.removeListener(this, &UICanvas::onSceneUpdate);
auto it = this->children.begin();
while(it != this->children.end()) {

View File

@ -16,12 +16,15 @@ namespace Dawn {
};
class UIComponent;
struct UIMenu;
class UICanvas : public SceneItemComponent {
protected:
Camera *camera = nullptr;
struct UIMenu *currentMenu = nullptr;
void onRenderTargetResize(float_t w, float_t h);
void onSceneUpdate();
public:
/**
@ -33,7 +36,7 @@ namespace Dawn {
*/
static UICanvas * create(Scene *scene);
//
//======================================================================//
std::vector<UIComponent*> children;
UIDrawType drawType = UI_DRAW_TYPE_WORLD_CAMERA_RELATIVE;
@ -64,6 +67,12 @@ namespace Dawn {
return item;
}
/**
* Find a UI Element attached to this canvas.
*
* @tparam Type of the UI item to find.
* @return Pointer to first matching element of type T.
*/
template<class T>
T * findElement() {
auto it = this->children.begin();
@ -90,6 +99,20 @@ namespace Dawn {
*/
float_t getHeight();
/**
* Returns the currently active menu for this UI Canvas.
*
* @return The currently active menu, or nullptr if there is none.
*/
struct UIMenu * getCurrentMenu();
/**
* Sets the currently active menu, and ticks it appropriately.
*
* @param menu Menu to set as the current active menu.
*/
void setCurrentMenu(struct UIMenu *menu);
void onStart() override;
void onDispose() override;
};

View File

@ -12,4 +12,5 @@ target_sources(${DAWN_TARGET_NAME}
UISprite.cpp
UIEmpty.cpp
UIGrid.cpp
UIMenu.cpp
)

View File

@ -91,9 +91,7 @@ void UIComponent::updatePositions() {
}
// Fire event
eventAlignmentUpdated.invoke(
this->width, this->height, this->relativeX, this->relativeY
);
eventAlignmentUpdated.invoke(this);
}
float_t UIComponent::getWidth() {

View File

@ -38,7 +38,7 @@ namespace Dawn {
UIComponent *parent = nullptr;
// Events
Event<float_t, float_t, float_t, float_t> eventAlignmentUpdated;
Event<UIComponent*> eventAlignmentUpdated;
// I currently don't support rotation or scale. Not because I can't but
// because it's basically un-necessary. Unity does support rotation but

View File

@ -36,7 +36,18 @@ std::vector<struct ShaderPassItem> UIGrid::getSelfPassItems(
return std::vector<struct ShaderPassItem>();
}
void UIGrid::onChildAligned(UIComponent *child) {
assertNotNull(child);
assertMapHasKey(this->gridChildren, child);
this->alignChild(child, this->gridChildren[child]);
}
void UIGrid::alignChild(UIComponent *child, struct UIGridPosition pos) {
assertNotNull(child);
// Remove event listener
child->eventAlignmentUpdated.addListener(this, &UIGrid::onChildAligned);
float_t gridX = (this->sizeCol * pos.x) + (this->gutterX * pos.x);
float_t gridY = (this->sizeRow * pos.y) + (this->gutterY * pos.y);
@ -68,6 +79,9 @@ void UIGrid::alignChild(UIComponent *child, struct UIGridPosition pos) {
glm::vec4(gridX + x, gridY + y, sizeX, sizeY),
0.0f
);
// Re-Add event listener
child->eventAlignmentUpdated.addListener(this, &UIGrid::onChildAligned);
}
void UIGrid::setGridSize(
@ -79,6 +93,8 @@ void UIGrid::setGridSize(
this->gutterX = gutterX;
this->gutterY = gutterY;
// TODO: Need to fix children here.
this->gridChildren.clear();
this->updatePositions();
}

View File

@ -33,6 +33,8 @@ namespace Dawn {
*/
void alignChild(UIComponent *child, struct UIGridPosition pos);
void onChildAligned(UIComponent *child);
protected:
void updatePositions() override;
std::vector<struct ShaderPassItem> getSelfPassItems(

96
src/dawn/ui/UIMenu.cpp Normal file
View File

@ -0,0 +1,96 @@
// Copyright (c) 2023 Dominic Masters
//
// This software is released under the MIT License.
// https://opensource.org/licenses/MIT
#include "UIMenu.hpp"
using namespace Dawn;
UIMenu::UIMenu(UICanvas *canvas, int32_t columns, int32_t rows) {
assertNotNull(canvas);
assertTrue(columns > 0);
assertTrue(rows > 0);
this->canvas = canvas;
this->rows = rows;
this->columns = columns;
this->items = (UIMenuItem**)memoryFillWithZero(sizeof(UIMenuItem*)*columns*rows);
}
void UIMenu::setSize(int32_t cols, int32_t rows) {
assertNotNull(this->items);
assertTrue(columns > 0);
assertTrue(rows > 0);
assertTrue(columns != this->columns);
assertTrue(rows != this->rows);
memoryFree(this->items);
this->items = (UIMenuItem**)memoryFillWithZero(sizeof(UIMenuItem*)*columns*rows);
}
UIMenuItem * UIMenu::getItem(int32_t x, int32_t y) {
return this->items[x * this->columns + y];
}
void UIMenu::setPosition(int32_t x, int32_t y) {
assertTrue(x >= 0 && x < this->columns);
assertTrue(y >= 0 && y < this->rows);
UIMenuItem *item;
if(this->x != -1) {
assertTrue(this->y != -1);
item = this->getItem(this->x, this->y);
if(item != nullptr) {
item->onItemOff();
}
}
this->eventCursorChange.invoke(this->x, this->y, x, y);
this->x = x;
this->y = y;
item = this->getItem(x, y);
if(item != nullptr && item->canBeOvered()) {
item->onItemOver();
}
}
void UIMenu::moveRelative(int32_t x, int32_t y) {
int32_t x2 = this->x + x;
if(x2 < 0 || x2 >= this->columns) return;
int32_t y2 = this->y + y;
if(y2 < 0 || y2 >= this->rows) return;
this->setPosition(x2, y2);
}
void UIMenu::setItem(int32_t x, int32_t y, UIMenuItem *item) {
assertTrue(x >= 0);
assertTrue(y >= 0);
assertTrue(x < this->columns);
assertTrue(y < this->rows);
assertNotNull(item);
assertNotNull(this->items);
assertNull(this->getItem(x, y));
this->items[x * this->columns + y] = item;
}
void UIMenu::onInactive() {
this->eventMenuInactive.invoke();
}
void UIMenu::onActive() {
this->eventMenuActive.invoke();
}
void UIMenu::onTick() {
std::cout << "Tick menu" << std::endl;
}
UIMenu::~UIMenu() {
if(this->canvas->getCurrentMenu() == this) {
this->canvas->setCurrentMenu(nullptr);
}
memoryFree(this->items);
}

125
src/dawn/ui/UIMenu.hpp Normal file
View File

@ -0,0 +1,125 @@
// Copyright (c) 2023 Dominic Masters
//
// This software is released under the MIT License.
// https://opensource.org/licenses/MIT
#pragma once
#include "event/Event.hpp"
#include "ui/UIComponent.hpp"
#include "util/memory.hpp"
namespace Dawn {
class UIMenuItem {
public:
/**
* Called when the item is selected (Accepted) on.
*/
virtual void onItemSelected() = 0;
/**
* Called when either the mouse or the user controller input is removed
* off this item.
*/
virtual void onItemOver() = 0;
/**
* Called when either the mouth or the user controller input is put over
* this item.
*/
virtual void onItemOff() = 0;
/**
* Returns whether the UI item can be hovered overed or not.
* @return Whether it can be overed or not.
*/
virtual bool_t canBeOvered() = 0;
/**
* Returns whether or not the item can be selected or not.
* @return Whether it can be selected or not.
*/
virtual bool_t canBeSelected() = 0;
};
struct UIMenu {
private:
UICanvas *canvas;
int32_t x = -1;
int32_t y = -1;
int32_t rows = 1;
int32_t columns = 1;
UIMenuItem **items = nullptr;
protected:
/** Invoked by UICanvas when this menu has been made inactive. */
void onInactive();
/** Invoked by UICanvas when this menu has been made active. */
void onActive();
/** Invoked by UICanvas every tick this menu is active. */
void onTick();
public:
Event<> eventMenuActive;
Event<> eventMenuInactive;
Event<int32_t, int32_t, int32_t, int32_t> eventCursorChange;
Event<UIMenuItem*> eventItemSelected;
/**
* Construct a new UI Menu Host.
*
* @param canvas Canvas that this menu belongs to.
* @param columns Iniitial size of the menu X axis.
* @param rows Initial size of the menu Y axis.
*/
UIMenu(UICanvas *canvas, int32_t columns, int32_t rows);
/**
* Sets the size of the UI Menu.
*
* @param columns How many columns in the menu.
* @param rows How many rows in the menu.
*/
void setSize(int32_t columns, int32_t rows);
/**
* Returns the UI Item at the given position.
*
* @param x X coordinate of the item to get.
* @param y Y coordinate of the item to get.
* @return The pointer to the menu item, or null if invalid.
*/
UIMenuItem * getItem(int32_t x, int32_t y);
/**
* Sets the position of the cursor in the grid.
*
* @param x X position of the cursor.
* @param y Y position of the cursor.
*/
void setPosition(int32_t x, int32_t y);
/**
* Move the cursor relative to the current position.
*
* @param x X position to move relative.
* @param y Y position to move relative.
*/
void moveRelative(int32_t x, int32_t y);
/**
* Adds/Sets an item onto the menu.
*
* @param x X coordinate to set the item.
* @param y Y coordinate to set the item.
* @param item Item to set.
*/
void setItem(int32_t x, int32_t y, UIMenuItem *item);
/**
* Cleans up the menu items, doesn't free the children themselves.
*/
~UIMenu();
friend class UICanvas;
};
}

View File

@ -20,6 +20,17 @@ static inline void * memoryAllocate(const size_t size) {
return (void *)malloc(size);
}
/**
* Allocate space in memory, where all values are set to 0 (in binary space).
*
* @param size Size of the array.
* @return Pointer to the space in memory to use.
*/
static inline void * memoryFillWithZero(const size_t size) {
return (void *)calloc(1, size);
}
/**
* Free some previously allocated memory space.
* @param pointer Pointer in memory to free.

View File

@ -30,7 +30,6 @@ set(DIR_GAME_ASSETS games/pokergame)
tool_texture(texture_test texture_test.png)
tool_language(language_en ${DIR_GAME_ASSETS}/locale/en.csv)
tool_language(language_jp ${DIR_GAME_ASSETS}/locale/jp.csv)
tool_tileset(tileset_death texture_death ${DIR_GAME_ASSETS}/characters/death/sheet.png 1 3)
@ -40,7 +39,6 @@ tool_audio(audio_test borrowed/sample_short.wav)
add_dependencies(${DAWN_TARGET_NAME}
language_en
language_jp
tileset_death

View File

@ -46,6 +46,8 @@ void TestUIScene::stage() {
auto grid = this->canvas->addElement<UIGrid>();
grid->setTransform(UI_COMPONENT_ALIGN_STRETCH, UI_COMPONENT_ALIGN_STRETCH, glm::vec4(0, 0, 0, 0), 0);
grid->setGridSize(4, 4, 8, 8);
auto menu = new UIMenu(this->canvas, grid->getColumns(), grid->getRows());
for(int32_t x = 0; x < grid->getColumns(); x++) {
for(int32_t y = 0; y < grid->getRows(); y++) {
@ -54,6 +56,15 @@ void TestUIScene::stage() {
label->setText("test.1");
label->setFontSize(24);
grid->addToGrid(label, x, y, UI_COMPONENT_ALIGN_END, UI_COMPONENT_ALIGN_END);
auto menuItem = new TestMenuItem;
menuItem->label = label;
menu->setItem(x, y, menuItem);
}
menu->setPosition(0, 0);
this->canvas->setCurrentMenu(menu);
}
this->canvas->setCurrentMenu(menu);
}

View File

@ -12,8 +12,33 @@
#include "ui/UIGrid.hpp"
#include "ui/UISprite.hpp"
#include "prefabs/SimpleSpinningCubePrefab.hpp"
#include "ui/UIMenu.hpp"
namespace Dawn {
class TestMenuItem : public UIMenuItem {
public:
UILabel *label;
void onItemSelected() {
}
void onItemOver() {
this->label->setText("test.2");
}
void onItemOff() {
this->label->setText("test.1");
}
bool_t canBeOvered() {
return true;
}
bool_t canBeSelected() {
return true;
}
};
class TestUIScene : public Scene {
private:
Camera *camera = nullptr;

View File

@ -56,23 +56,22 @@ int main(int argc, char *argv[]) {
size_t readSize = fread(buffer, 1, fileSize, file);
fclose(file);
if(readSize < fileSize) {
free(buffer);
printf("Failed to read all data from CSV\n");
free(buffer);
return 1;
}
buffer[fileSize] = '\0';
csvParse(buffer, &csv);
free(buffer);
printf("Parsed\n");
// Prepare output file for writing.
sprintf(path, "%s.language", out);
fileMkdirp(path);
file = fopen(path, "wb");
if(file == NULL) {
csvDispose(&csv);
printf("Failed to create output language file\n");
csvDispose(&csv);
return 1;
}
@ -85,14 +84,13 @@ int main(int argc, char *argv[]) {
csvDispose(&csv);
return 1;
}
char *key = csvGetCell(&csv, y, 0);
char *value = csvGetCell(&csv, y, 1);
// 23/01/14 - Replace \r in CSV.
stringRemoveAll(key, '\r');
stringRemoveAll(value, '\r');
if(strlen(key) <= 0 || strlen(value) <= 0) {
printf("Failed to parse language. Line %i has an invalid string\n", y);
fclose(file);

View File

@ -8,7 +8,7 @@
#include "csv.h"
char * csvGetCell(csv_t *csv, int32_t row, int32_t cell) {
return csv->rows[(row * CSV_ROW_COUNT_MAX) + cell];
return csv->rows[(row * CSV_COLUMN_COUNT_MAX) + cell];
}
void csvParse(char *string, csv_t *csv) {
@ -18,9 +18,9 @@ void csvParse(char *string, csv_t *csv) {
int32_t rowCellCount;
length = strlen(string);
csv->buffer = malloc(sizeof(char) * length * 2);
csv->buffer = malloc(sizeof(char) * (length+1) * CSV_COLUMN_COUNT_MAX * CSV_ROW_COUNT_MAX);
csv->cellCounts = malloc(sizeof(int32_t) * CSV_ROW_COUNT_MAX);
csv->rows = malloc(sizeof(char *) * 32 * CSV_ROW_COUNT_MAX);
csv->rows = malloc(sizeof(char*) * CSV_ROW_COUNT_MAX * CSV_COLUMN_COUNT_MAX);
i = 0;
j = 0;
@ -35,7 +35,7 @@ void csvParse(char *string, csv_t *csv) {
case CSV_PARSE_STATE_FIND_CELL:
if(c == '"') {
state = CSV_PARSE_STATE_PARSE_CELL_WITH_QUOTES;
csv->rows[(csv->rowCount * CSV_ROW_COUNT_MAX) + rowCellCount] = csv->buffer + j;
csv->rows[(csv->rowCount * CSV_COLUMN_COUNT_MAX) + rowCellCount] = csv->buffer + j;
rowCellCount++;
continue;
} else if(c == '\r' || c == '\n') {
@ -43,13 +43,13 @@ void csvParse(char *string, csv_t *csv) {
state = CSV_PARSE_STATE_LINE_END;
continue;
} else if(c == ',') {
csv->rows[(csv->rowCount * CSV_ROW_COUNT_MAX) + rowCellCount] = csv->buffer + j;
csv->rows[(csv->rowCount * CSV_COLUMN_COUNT_MAX) + rowCellCount] = csv->buffer + j;
csv->buffer[j++] = '\0';
rowCellCount++;
continue;
} else {
state = CSV_PARSE_STATE_PARSE_CELL;
csv->rows[(csv->rowCount * CSV_ROW_COUNT_MAX) + rowCellCount] = csv->buffer + j;
csv->rows[(csv->rowCount * CSV_COLUMN_COUNT_MAX) + rowCellCount] = csv->buffer + j;
csv->buffer[j++] = c;
rowCellCount++;
continue;
@ -104,6 +104,7 @@ void csvParse(char *string, csv_t *csv) {
free(NULL);
}
}
csv->buffer[j++] = '\0';
if(rowCellCount != 0) {

View File

@ -10,6 +10,7 @@
#include "string.h"
#define CSV_ROW_COUNT_MAX 128
#define CSV_COLUMN_COUNT_MAX 16
typedef enum {
CSV_PARSE_STATE_FIND_CELL,//0