Make modules more restartable;

Except headset.  Screw you, headset.
This commit is contained in:
bjorn 2018-02-22 19:18:36 -08:00
parent 9d42d7737a
commit f5fa9a4e5c
18 changed files with 98 additions and 69 deletions

View File

@ -5,12 +5,9 @@
#include <stdlib.h>
static AudioState state;
static bool audioAlreadyInit = false;
void lovrAudioInit() {
if (audioAlreadyInit) { // During a reload, bring down the audio device then recreate it
lovrAudioDestroy();
}
if (state.initialized) return;
ALCdevice* device = alcOpenDevice(NULL);
lovrAssert(device, "Unable to open default audio device");
@ -35,18 +32,16 @@ void lovrAudioInit() {
quat_set(state.orientation, 0, 0, 0, -1);
vec3_set(state.position, 0, 0, 0);
vec3_set(state.velocity, 0, 0, 0);
if (!audioAlreadyInit) {
atexit(lovrAudioDestroy);
audioAlreadyInit = true;
}
state.initialized = true;
}
void lovrAudioDestroy() {
if (!state.initialized) return;
alcMakeContextCurrent(NULL);
alcDestroyContext(state.context);
alcCloseDevice(state.device);
vec_deinit(&state.sources);
memset(&state, 0, sizeof(AudioState));
}
void lovrAudioUpdate() {

View File

@ -8,6 +8,7 @@
#pragma once
typedef struct {
bool initialized;
ALCdevice* device;
ALCcontext* context;
vec_void_t sources;

View File

@ -3,23 +3,21 @@
#include <stdlib.h>
static EventState state;
bool eventAlreadyInit = false;
void lovrEventInit() {
if (eventAlreadyInit)
lovrEventDestroy();
if (state.initialized) return;
vec_init(&state.pumps);
vec_init(&state.events);
lovrEventAddPump(glfwPollEvents);
if (!eventAlreadyInit) {
atexit(lovrEventDestroy);
eventAlreadyInit = true;
}
atexit(lovrEventDestroy);
state.initialized = true;
}
void lovrEventDestroy() {
if (!state.initialized) return;
vec_deinit(&state.pumps);
vec_deinit(&state.events);
memset(&state, 0, sizeof(EventState));
}
void lovrEventAddPump(EventPump pump) {

View File

@ -68,6 +68,7 @@ typedef vec_t(EventPump) vec_pump_t;
typedef vec_t(Event) vec_event_t;
typedef struct {
bool initialized;
vec_pump_t pumps;
vec_event_t events;
} EventState;

View File

@ -20,12 +20,9 @@
static FilesystemState state;
bool filesystemAlreadyInit = false;
void lovrFilesystemInit(const char* arg0, const char* arg1) {
if (filesystemAlreadyInit) // Do not change settings during a reload, and don't try to initialize PhysFS twice
return;
filesystemAlreadyInit = true;
if (state.initialized) return;
state.initialized = true;
if (!PHYSFS_init(arg0)) {
lovrThrow("Could not initialize filesystem: %s", PHYSFS_getErrorByCode(PHYSFS_getLastErrorCode()));
@ -43,23 +40,22 @@ void lovrFilesystemInit(const char* arg0, const char* arg1) {
if (arg1) {
strncpy(state.source, arg1, LOVR_PATH_MAX);
if (!lovrFilesystemMount(state.source, NULL, 1)) {
goto mounted;
return;
}
}
free(state.source);
state.source = NULL;
}
mounted:
atexit(lovrFilesystemDestroy);
}
void lovrFilesystemDestroy() {
if (!state.initialized) return;
free(state.source);
free(state.savePathFull);
free(state.savePathRelative);
PHYSFS_deinit();
memset(&state, 0, sizeof(FilesystemState));
}
int lovrFilesystemCreateDirectory(const char* path) {

View File

@ -8,6 +8,7 @@
typedef int getDirectoryItemsCallback(void* userdata, const char* dir, const char* file);
typedef struct {
bool initialized;
char* source;
const char* identity;
char* savePathRelative;

View File

@ -40,6 +40,7 @@ void lovrGraphicsInit() {
}
void lovrGraphicsDestroy() {
if (!state.initialized) return;
lovrGraphicsSetShader(NULL);
lovrGraphicsSetFont(NULL);
for (int i = 0; i < DEFAULT_SHADER_COUNT; i++) {
@ -53,6 +54,7 @@ void lovrGraphicsDestroy() {
glDeleteBuffers(1, &state.streamIBO);
vec_deinit(&state.streamData);
vec_deinit(&state.streamIndices);
memset(&state, 0, sizeof(GraphicsState));
}
void lovrGraphicsReset() {
@ -185,15 +187,13 @@ void lovrGraphicsPrepare(Material* material, float* pose) {
lovrShaderBind(shader);
}
static bool graphicsAlreadyInit = false;
void lovrGraphicsCreateWindow(int w, int h, bool fullscreen, int msaa, const char* title, const char* icon) {
if (graphicsAlreadyInit) {
lovrAssert(!state.window, "Window is already created");
if (!state.initialized && (state.window = glfwGetCurrentContext()) != NULL) {
lovrGraphicsReset();
state.initialized = true;
return;
} else {
lovrAssert(!state.window, "Window is already created");
graphicsAlreadyInit = true;
}
#ifdef EMSCRIPTEN
@ -257,7 +257,7 @@ void lovrGraphicsCreateWindow(int w, int h, bool fullscreen, int msaa, const cha
vec_init(&state.streamData);
vec_init(&state.streamIndices);
lovrGraphicsReset();
atexit(lovrGraphicsDestroy);
state.initialized = true;
}
int lovrGraphicsGetWidth() {

View File

@ -95,6 +95,7 @@ typedef struct {
} GraphicsStats;
typedef struct {
bool initialized;
GLFWwindow* window;
Shader* defaultShaders[DEFAULT_SHADER_COUNT];
DefaultShader defaultShader;

View File

@ -1,4 +1,21 @@
#include "lovr.h"
#include "audio/audio.h"
#include "event/event.h"
#include "filesystem/filesystem.h"
#include "graphics/graphics.h"
#include "math/math.h"
#include "physics/physics.h"
#include "timer/timer.h"
void lovrDestroy() {
lovrAudioDestroy();
lovrEventDestroy();
lovrFilesystemDestroy();
lovrGraphicsDestroy();
lovrMathDestroy();
lovrPhysicsDestroy();
lovrTimerDestroy();
}
const char* lovrGetOS() {
#ifdef _WIN32

View File

@ -3,5 +3,6 @@
#define LOVR_VERSION_PATCH 1
#define LOVR_VERSION_ALIAS "Fluffy Cuttlefish"
void lovrDestroy();
const char* lovrGetOS();
void lovrGetVersion(int* major, int* minor, int* patch);

View File

@ -12,6 +12,7 @@
static int errorCount = 0;
static void destroy(int exitCode) {
lovrDestroy();
glfwTerminate();
exit(exitCode);
}
@ -131,6 +132,7 @@ int main(int argc, char** argv) {
int exitCode = 0;
int returnType = lua_type(L, -1);
if (returnType == LUA_TSTRING && 0 == strcmp("restart", lua_tostring(L, -1))) {
lovrDestroy();
continue;
}

View File

@ -3,27 +3,25 @@
#include <math.h>
#include <stdlib.h>
#include <time.h>
#include <stdbool.h>
static RandomGenerator* generator;
bool mathAlreadyInit = false;
static MathState state;
void lovrMathInit() {
generator = lovrRandomGeneratorCreate();
if (state.initialized) return;
state.generator = lovrRandomGeneratorCreate();
Seed seed = { .b64 = (uint64_t) time(0) };
lovrRandomGeneratorSetSeed(generator, seed);
if (!mathAlreadyInit) {
atexit(lovrMathDestroy);
mathAlreadyInit = true;
}
lovrRandomGeneratorSetSeed(state.generator, seed);
state.initialized = true;
}
void lovrMathDestroy() {
lovrRandomGeneratorDestroy(&generator->ref);
if (!state.initialized) return;
lovrRandomGeneratorDestroy(&state.generator->ref);
memset(&state, 0, sizeof(MathState));
}
RandomGenerator* lovrMathGetRandomGenerator() {
return generator;
return state.generator;
}
void lovrMathOrientationToDirection(float angle, float ax, float ay, float az, vec3 v) {

View File

@ -1,5 +1,6 @@
#include "lib/vec/vec.h"
#include "randomGenerator.h"
#include <stdbool.h>
#pragma once
@ -12,6 +13,11 @@ typedef float* quat;
typedef float* mat4;
typedef vec_t(mat4) vec_mat4_t;
typedef struct {
bool initialized;
RandomGenerator* generator;
} MathState;
void lovrMathInit();
void lovrMathDestroy();
RandomGenerator* lovrMathGetRandomGenerator();

View File

@ -1,6 +1,7 @@
#include "physics.h"
#include "math/quat.h"
#include <stdlib.h>
#include <stdbool.h>
static void defaultNearCallback(void* data, dGeomID a, dGeomID b) {
lovrWorldCollide((World*) data, dGeomGetData(a), dGeomGetData(b), -1, -1);
@ -28,19 +29,18 @@ static void raycastCallback(void* data, dGeomID a, dGeomID b) {
}
}
static bool odeAlreadyInit = false;
static bool initialized = false;
void lovrPhysicsInit() {
if (odeAlreadyInit)
return;
if (initialized) return;
dInitODE();
atexit(lovrPhysicsDestroy);
odeAlreadyInit = true;
initialized = true;
}
void lovrPhysicsDestroy() {
if (!initialized) return;
dCloseODE();
initialized = false;
}
World* lovrWorldCreate(float xg, float yg, float zg, bool allowSleep, const char** tags, int tagCount) {

View File

@ -6,12 +6,15 @@
static ThreadState state;
void lovrThreadInit() {
if (state.initialized) return;
map_init(&state.channels);
atexit(lovrThreadDeinit);
state.initialized = true;
}
void lovrThreadDeinit() {
if (!state.initialized) return;
map_deinit(&state.channels);
state.initialized = false;
}
Channel* lovrThreadGetChannel(const char* name) {

View File

@ -7,6 +7,7 @@
#pragma once
typedef struct {
bool initialized;
map_void_t channels;
} ThreadState;

View File

@ -2,17 +2,21 @@
#include "lib/glfw.h"
#include "util.h"
static TimerState timerState;
static TimerState state;
void lovrTimerInit() {
timerState.tickIndex = 0;
for (int i = 0; i < TICK_SAMPLES; i++) {
timerState.tickBuffer[i] = 0.;
}
if (state.initialized) return;
lovrTimerDestroy();
state.initialized = true;
}
void lovrTimerDestroy() {
if (!state.initialized) return;
memset(&state, 0, sizeof(TimerState));
}
double lovrTimerGetDelta() {
return timerState.dt;
return state.dt;
}
double lovrTimerGetTime() {
@ -20,26 +24,26 @@ double lovrTimerGetTime() {
}
double lovrTimerStep() {
timerState.lastTime = timerState.time;
timerState.time = glfwGetTime();
timerState.dt = timerState.time - timerState.lastTime;
timerState.tickSum -= timerState.tickBuffer[timerState.tickIndex];
timerState.tickSum += timerState.dt;
timerState.tickBuffer[timerState.tickIndex] = timerState.dt;
timerState.averageDelta = timerState.tickSum / TICK_SAMPLES;
timerState.fps = (int) (1 / (timerState.tickSum / TICK_SAMPLES) + .5);
if (++timerState.tickIndex == TICK_SAMPLES) {
timerState.tickIndex = 0;
state.lastTime = state.time;
state.time = glfwGetTime();
state.dt = state.time - state.lastTime;
state.tickSum -= state.tickBuffer[state.tickIndex];
state.tickSum += state.dt;
state.tickBuffer[state.tickIndex] = state.dt;
state.averageDelta = state.tickSum / TICK_SAMPLES;
state.fps = (int) (1 / (state.tickSum / TICK_SAMPLES) + .5);
if (++state.tickIndex == TICK_SAMPLES) {
state.tickIndex = 0;
}
return timerState.dt;
return state.dt;
}
double lovrTimerGetAverageDelta() {
return timerState.averageDelta;
return state.averageDelta;
}
int lovrTimerGetFPS() {
return timerState.fps;
return state.fps;
}
void lovrTimerSleep(double seconds) {

View File

@ -1,8 +1,11 @@
#include <stdbool.h>
#pragma once
#define TICK_SAMPLES 90
typedef struct {
bool initialized;
double lastTime;
double time;
double dt;
@ -14,6 +17,7 @@ typedef struct {
} TimerState;
void lovrTimerInit();
void lovrTimerDestroy();
double lovrTimerGetDelta();
double lovrTimerGetTime();
double lovrTimerStep();