wip - file_service
This commit is contained in:
@@ -85,7 +85,8 @@ void Engine::firePS2()
|
||||
SifInitRpc(0);
|
||||
srand(time(NULL));
|
||||
VU1::uploadProgram(0, &VU1Draw3D_CodeStart, &VU1Draw3D_CodeEnd);
|
||||
audio.startThread();
|
||||
fileService.startThread();
|
||||
audio.startThread(&fileService);
|
||||
isInitialized = 0;
|
||||
mainThreadId = GetThreadId();
|
||||
}
|
||||
|
||||
@@ -19,6 +19,7 @@
|
||||
#include "modules/timer.hpp"
|
||||
#include "modules/pad.hpp"
|
||||
#include "modules/audio.hpp"
|
||||
#include "modules/file_service.hpp"
|
||||
|
||||
class Engine
|
||||
{
|
||||
@@ -31,6 +32,7 @@ public:
|
||||
void init(Game *t_game, u32 t_gifPacketSize);
|
||||
void setDefaultScreen();
|
||||
Renderer *renderer;
|
||||
FileService fileService;
|
||||
Audio audio;
|
||||
ScreenSettings screen;
|
||||
Pad pad;
|
||||
|
||||
@@ -12,6 +12,7 @@
|
||||
#define _TYRA_AUDIO_
|
||||
|
||||
#include "../models/audio_listener.hpp"
|
||||
#include "./file_service.hpp"
|
||||
#include <tamtypes.h>
|
||||
#include <stdio.h>
|
||||
#include <audsrv.h>
|
||||
@@ -120,17 +121,15 @@ public:
|
||||
* Do not call this method unless you know what you do.
|
||||
* Should be called by engine.
|
||||
*/
|
||||
void startThread();
|
||||
void startThread(FileService *t_fileService);
|
||||
|
||||
private:
|
||||
u8 songLoaded, volume, realVolume, songPlaying, songInLoop, songFinished;
|
||||
std::vector<AudioListenerRef> songListeners;
|
||||
FILE *wav;
|
||||
audsrv_fmt_t format;
|
||||
// we have some sema problems here (sound freezing)
|
||||
// this probably should be changed to smth like this:
|
||||
// this thread (A) : play next chunks
|
||||
// other thread (B) : load chunks (fread()) for thread A
|
||||
FileService *fileService;
|
||||
|
||||
char wavChunk[2 * 1024] __attribute__((aligned(16)));
|
||||
s32 chunkReadStatus;
|
||||
|
||||
@@ -150,7 +149,7 @@ private:
|
||||
void loadModules();
|
||||
void initAUDSRV();
|
||||
void threadLoop();
|
||||
static void audioThread();
|
||||
static void mainThread();
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
@@ -0,0 +1,115 @@
|
||||
/*
|
||||
# ______ ____ ___
|
||||
# | \/ ____| |___|
|
||||
# | | | \ | |
|
||||
#-----------------------------------------------------------------------
|
||||
# Copyright 2020, tyra - https://github.com/h4570/tyra
|
||||
# Licenced under Apache License 2.0
|
||||
# Sandro Sobczyński <sandro.sobczynski@gmail.com>
|
||||
*/
|
||||
|
||||
#ifndef _TYRA_FILE_SERVICE_
|
||||
#define _TYRA_FILE_SERVICE_
|
||||
|
||||
#include <tamtypes.h>
|
||||
#include <stdio.h>
|
||||
#include <kernel.h>
|
||||
#include <vector>
|
||||
|
||||
enum FileServiceTaskType
|
||||
{
|
||||
ReadChunk = 0
|
||||
};
|
||||
|
||||
struct FileServiceTask
|
||||
{
|
||||
FileServiceTaskType type;
|
||||
|
||||
u32 id;
|
||||
|
||||
/**
|
||||
* Used by types:
|
||||
* - ReadChunk
|
||||
*/
|
||||
FILE *file;
|
||||
|
||||
/**
|
||||
* Used by types:
|
||||
* - ReadChunk
|
||||
*/
|
||||
s32 readStatus;
|
||||
|
||||
/**
|
||||
* Used by types:
|
||||
* - ReadChunk
|
||||
*/
|
||||
void *destination;
|
||||
|
||||
/**
|
||||
* Used by types:
|
||||
* - ReadChunk
|
||||
*/
|
||||
u32 size;
|
||||
|
||||
/**
|
||||
* Used by types:
|
||||
* - ReadChunk
|
||||
*/
|
||||
u32 n;
|
||||
};
|
||||
|
||||
/** Class responsible for background, non-blocking file loading playing. */
|
||||
class FileService
|
||||
{
|
||||
|
||||
public:
|
||||
/** Constructor is called by the engine. */
|
||||
FileService();
|
||||
~FileService();
|
||||
|
||||
/**
|
||||
* Add task to read next chunk. ( fread() )
|
||||
* @returns Task id
|
||||
*/
|
||||
u32 addReadChunk(FILE *t_file, void *t_destination, const u32 &t_size, const u32 &t_n);
|
||||
|
||||
/**
|
||||
* Check if given task was done.
|
||||
* When task is done, this method will return read status.
|
||||
* After this, task is removed from file service, so this method
|
||||
* will return something once per task.
|
||||
* @returns Read status (ex. result of fread()). -2137 if task is not done.
|
||||
*/
|
||||
s32 isTaskDone(const u32 &t_taskId);
|
||||
|
||||
/**
|
||||
* Start file service thread.
|
||||
* Do not call this method unless you know what you do.
|
||||
* Should be called by engine.
|
||||
*/
|
||||
void startThread();
|
||||
|
||||
std::vector<FileServiceTask> tasks;
|
||||
|
||||
private:
|
||||
/** Remove task by index */
|
||||
void removeByIndex(const u32 &t_index) { tasks.erase(tasks.begin() + t_index); }
|
||||
|
||||
/** Remove task by id */
|
||||
const void removeById(const u32 &t_taskId);
|
||||
|
||||
/**
|
||||
* Get index of task.
|
||||
* @returns Index of task. -1 if not found.
|
||||
*/
|
||||
const s32 getIndexOf(const u32 &t_taskId);
|
||||
|
||||
u8 threadStack[8 * 1024] __attribute__((aligned(16)));
|
||||
u32 getThreadStackSize() { return 8 * 1024; }
|
||||
ee_thread_t thread;
|
||||
int threadId;
|
||||
void threadLoop();
|
||||
static void mainThread();
|
||||
};
|
||||
|
||||
#endif
|
||||
@@ -157,11 +157,12 @@ void Audio::playADPCM(audsrv_adpcm_t *t_adpcm, const s8 &t_ch)
|
||||
|
||||
// Other
|
||||
|
||||
void Audio::startThread()
|
||||
void Audio::startThread(FileService *t_fileService)
|
||||
{
|
||||
PRINT_LOG("Creating audio thread");
|
||||
fileService = t_fileService;
|
||||
extern void *_gp;
|
||||
thread.func = (void *)Audio::audioThread;
|
||||
thread.func = (void *)Audio::mainThread;
|
||||
thread.stack = threadStack;
|
||||
thread.stack_size = getThreadStackSize();
|
||||
thread.gp_reg = (void *)&_gp;
|
||||
@@ -293,7 +294,7 @@ void Audio::initAUDSRV()
|
||||
* Do not call this function.
|
||||
* This is a audio thread, runned by engine
|
||||
*/
|
||||
void Audio::audioThread()
|
||||
void Audio::mainThread()
|
||||
{
|
||||
while (true)
|
||||
audioRef->threadLoop();
|
||||
|
||||
@@ -0,0 +1,117 @@
|
||||
/*
|
||||
# ______ ____ ___
|
||||
# | \/ ____| |___|
|
||||
# | | | \ | |
|
||||
#-----------------------------------------------------------------------
|
||||
# Copyright 2020, tyra - https://github.com/h4570/tyra
|
||||
# Licenced under Apache License 2.0
|
||||
# Sandro Sobczyński <sandro.sobczynski@gmail.com>
|
||||
*/
|
||||
|
||||
#include "../include/modules/file_service.hpp"
|
||||
#include "../include/utils/string.hpp"
|
||||
#include "../include/utils/debug.hpp"
|
||||
#include <cstdlib>
|
||||
|
||||
// ----
|
||||
// Constructors/Destructors
|
||||
// ----
|
||||
|
||||
FileService *fsRef;
|
||||
|
||||
FileService::FileService() {}
|
||||
|
||||
FileService::~FileService() {}
|
||||
|
||||
// ----
|
||||
// Methods
|
||||
// ----
|
||||
|
||||
u32 FileService::addReadChunk(FILE *t_file, void *t_destination, const u32 &t_size, const u32 &t_n)
|
||||
{
|
||||
FileServiceTask task;
|
||||
task.id = rand() % 1000000;
|
||||
task.file = t_file;
|
||||
task.destination = t_destination;
|
||||
task.size = t_size;
|
||||
task.n = t_n;
|
||||
task.readStatus = -2137;
|
||||
tasks.push_back(task);
|
||||
return task.id;
|
||||
}
|
||||
|
||||
s32 FileService::isTaskDone(const u32 &t_taskId)
|
||||
{
|
||||
s32 taskIndex = getIndexOf(t_taskId);
|
||||
if (taskIndex == -1)
|
||||
PRINT_ERR("Task was not found!");
|
||||
s32 result = tasks[taskIndex].readStatus;
|
||||
if (result != -2137)
|
||||
removeByIndex(taskIndex);
|
||||
return result;
|
||||
}
|
||||
|
||||
const void FileService::removeById(const u32 &t_taskId)
|
||||
{
|
||||
s32 index = getIndexOf(t_taskId);
|
||||
if (index != -1)
|
||||
removeByIndex(index);
|
||||
else
|
||||
PRINT_ERR("Cant remove task, because it was not found!");
|
||||
}
|
||||
|
||||
const s32 FileService::getIndexOf(const u32 &t_taskId)
|
||||
{
|
||||
for (u32 i = 0; i < tasks.size(); i++)
|
||||
if (tasks[i].id == t_taskId)
|
||||
return i;
|
||||
return -1;
|
||||
};
|
||||
|
||||
// Other
|
||||
|
||||
void FileService::startThread()
|
||||
{
|
||||
PRINT_LOG("Creating file service thread");
|
||||
extern void *_gp;
|
||||
thread.func = (void *)FileService::mainThread;
|
||||
thread.stack = threadStack;
|
||||
thread.stack_size = getThreadStackSize();
|
||||
thread.gp_reg = (void *)&_gp;
|
||||
thread.initial_priority = 0x12;
|
||||
if ((threadId = CreateThread(&thread)) < 0)
|
||||
PRINT_ERR("Create audio thread failed!");
|
||||
PRINT_LOG("File service created");
|
||||
StartThread(threadId, NULL);
|
||||
PRINT_LOG("File service started");
|
||||
}
|
||||
|
||||
/** Main thread loop */
|
||||
void FileService::threadLoop()
|
||||
{
|
||||
// This will cause an error
|
||||
// printf("\n\n\n\n\nsize:%d\n", tasks.size());
|
||||
// for (size_t i = 0; i < tasks.size(); i++)
|
||||
// {
|
||||
// switch (tasks[i].type)
|
||||
// {
|
||||
// case ReadChunk:
|
||||
// tasks[i].readStatus = fread(tasks[i].destination, tasks[i].n, tasks[i].size, tasks[i].file);
|
||||
// break;
|
||||
|
||||
// default:
|
||||
// break;
|
||||
// }
|
||||
// }
|
||||
SleepThread();
|
||||
}
|
||||
|
||||
/**
|
||||
* Do not call this function.
|
||||
* This is an file service thread, runned by engine
|
||||
*/
|
||||
void FileService::mainThread()
|
||||
{
|
||||
while (true)
|
||||
fsRef->threadLoop();
|
||||
}
|
||||
@@ -11,6 +11,7 @@ EE_OBJS = \
|
||||
../../engine/models/mesh_texture.o \
|
||||
../../engine/modules/audio.o \
|
||||
../../engine/modules/camera_base.o \
|
||||
../../engine/modules/file_service.o \
|
||||
../../engine/modules/gif_sender.o \
|
||||
../../engine/modules/light.o \
|
||||
../../engine/modules/pad.o \
|
||||
|
||||
Reference in New Issue
Block a user