create new project
This commit is contained in:
parent
e55f035f80
commit
53612d9456
1
.gitignore
vendored
Normal file
1
.gitignore
vendored
Normal file
@ -0,0 +1 @@
|
||||
/build*/
|
53
CMakeLists.txt
Normal file
53
CMakeLists.txt
Normal file
@ -0,0 +1,53 @@
|
||||
cmake_minimum_required(VERSION 3.27)
|
||||
|
||||
project(nf7 C)
|
||||
|
||||
set(CMAKE_C_STANDARD 23)
|
||||
set(CMAKE_C_STANDARD_REQUIRED ON)
|
||||
set(CMAKE_EXPORT_COMPILE_COMMANDS ON)
|
||||
|
||||
include(tool/meta.cmake)
|
||||
|
||||
# ---- thirdparty import
|
||||
add_subdirectory(thirdparty EXCLUDE_FROM_ALL)
|
||||
|
||||
# ---- generation
|
||||
include(tool/meta.cmake)
|
||||
|
||||
# ---- common config
|
||||
add_library(nf7config INTERFACE)
|
||||
target_include_directories(nf7config
|
||||
INTERFACE
|
||||
${PROJECT_SOURCE_DIR}
|
||||
${NF7_GENERATED_DIR}
|
||||
)
|
||||
target_compile_options(nf7config INTERFACE
|
||||
$<$<CXX_COMPILER_ID:MSVC>:
|
||||
/W4
|
||||
$<$<CONFIG:Debug>:/WX>
|
||||
>
|
||||
$<$<NOT:$<CXX_COMPILER_ID:MSVC>>:
|
||||
-Wall -Wextra -Wpedantic
|
||||
$<$<CONFIG:Debug>:-Werror>
|
||||
>
|
||||
)
|
||||
|
||||
# ---- util library
|
||||
add_subdirectory(util)
|
||||
|
||||
# ---- interface library
|
||||
add_library(nf7if INTERFACE)
|
||||
target_sources(nf7if INTERFACE nf7.h)
|
||||
target_link_libraries(nf7if INTERFACE nf7config nf7util uv)
|
||||
|
||||
# ---- core library
|
||||
add_subdirectory(core)
|
||||
|
||||
# ---- main executable
|
||||
add_executable(nf7)
|
||||
target_sources(nf7 PRIVATE main.c)
|
||||
target_link_libraries(nf7
|
||||
PRIVATE
|
||||
nf7if
|
||||
nf7core
|
||||
)
|
19
README.md
Normal file
19
README.md
Normal file
@ -0,0 +1,19 @@
|
||||
Nf7
|
||||
====
|
||||
|
||||
Nf7 is an abstraction layer for Media-programming.
|
||||
The goal is to allow creative activities on any platforms without any differences.
|
||||
|
||||
**UNDER REFACTORING:** Please checkout tag v0.4.1 to see a codebase which works.
|
||||
|
||||
## Build
|
||||
|
||||
```bash
|
||||
$ cmake -B build
|
||||
$ cmake --build build -j4
|
||||
```
|
||||
|
||||
## License
|
||||
|
||||
WTFPLv2
|
||||
|
19
core/CMakeLists.txt
Normal file
19
core/CMakeLists.txt
Normal file
@ -0,0 +1,19 @@
|
||||
# ---- basic modules
|
||||
set(MODS
|
||||
sdl2
|
||||
)
|
||||
|
||||
# ---- core library
|
||||
add_library(nf7core)
|
||||
target_link_libraries(nf7core PRIVATE nf7if)
|
||||
|
||||
foreach(name IN LISTS MODS)
|
||||
add_subdirectory(${name})
|
||||
target_link_libraries(nf7core PRIVATE nf7core_${name})
|
||||
endforeach()
|
||||
|
||||
# ---- generate all.h
|
||||
target_meta_source(nf7core
|
||||
PRIVATE all.c.sh
|
||||
ARGS ${MODS}
|
||||
)
|
25
core/all.c.sh
Executable file
25
core/all.c.sh
Executable file
@ -0,0 +1,25 @@
|
||||
#!/bin/bash
|
||||
|
||||
echo "#include \"core/all.h\""
|
||||
echo
|
||||
echo "#include <assert.h>"
|
||||
echo
|
||||
echo "const uint32_t NF7_CORE_MAX_MODS = UINT32_C($#);"
|
||||
echo
|
||||
echo "uint32_t nf7_core_new(const struct nf7* nf7, struct nf7_mod** mods) {"
|
||||
echo " assert(nullptr != nf7);"
|
||||
echo " assert(nullptr != mods);"
|
||||
echo
|
||||
echo " uint32_t i = 0;"
|
||||
echo
|
||||
for name in $@; do
|
||||
echo " extern struct nf7_mod* nf7_core_${name}_new(const struct nf7*);"
|
||||
echo " mods[i] = nf7_core_${name}_new(nf7);"
|
||||
echo " if (nullptr != mods[i]) {"
|
||||
echo " assert(nullptr != mods[i]->meta);"
|
||||
echo " ++i;"
|
||||
echo " }"
|
||||
echo
|
||||
done
|
||||
echo " return i;"
|
||||
echo "}"
|
20
core/all.h
Normal file
20
core/all.h
Normal file
@ -0,0 +1,20 @@
|
||||
#pragma once
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
#include "nf7.h"
|
||||
|
||||
|
||||
// A maximum number of modules which nf7core may provide.
|
||||
extern const uint32_t NF7_CORE_MAX_MODS;
|
||||
|
||||
|
||||
// Initializes all modules and returns their instances.
|
||||
uint32_t nf7_core_new(const struct nf7* nf7, struct nf7_mod** mods);
|
||||
// PRECONDS:
|
||||
// - `nf7` is a valid pointer
|
||||
// - `mods` is a valid pointer
|
||||
// to memory large enough to keep `NF7_CORE_MAX_MODS` pointers
|
||||
// POSTCONDS:
|
||||
// - When x is lower than the return value,
|
||||
// mods[x] is a valid pointer to an initialized module
|
12
core/sdl2/CMakeLists.txt
Normal file
12
core/sdl2/CMakeLists.txt
Normal file
@ -0,0 +1,12 @@
|
||||
add_library(nf7core_sdl2)
|
||||
target_sources(nf7core_sdl2
|
||||
PRIVATE
|
||||
mod.c
|
||||
)
|
||||
target_link_libraries(nf7core_sdl2
|
||||
PRIVATE
|
||||
nf7if
|
||||
nf7util
|
||||
OpenGL
|
||||
SDL2
|
||||
)
|
43
core/sdl2/mod.c
Normal file
43
core/sdl2/mod.c
Normal file
@ -0,0 +1,43 @@
|
||||
// No copyright
|
||||
#include "core/sdl2/mod.h"
|
||||
|
||||
#include <assert.h>
|
||||
#include <stdio.h>
|
||||
|
||||
#include "nf7.h"
|
||||
|
||||
#include "util/malloc.h"
|
||||
|
||||
|
||||
struct nf7_mod* nf7_core_sdl2_new(const struct nf7* nf7) {
|
||||
assert(nullptr != nf7);
|
||||
|
||||
struct nf7_core_sdl2* this = nf7_util_malloc_new(nf7->malloc, sizeof(*this));
|
||||
if (nullptr == this) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
*this = (struct nf7_core_sdl2) {
|
||||
.meta = &nf7_core_sdl2,
|
||||
.nf7 = nf7,
|
||||
.malloc = nf7->malloc,
|
||||
.uv = nf7->uv,
|
||||
};
|
||||
return (struct nf7_mod*) this;
|
||||
}
|
||||
|
||||
static void del_(struct nf7_mod* this_) {
|
||||
struct nf7_core_sdl2* this = (struct nf7_core_sdl2*) this_;
|
||||
assert(nullptr != this);
|
||||
|
||||
nf7_util_malloc_del(this->malloc, this);
|
||||
}
|
||||
|
||||
|
||||
const struct nf7_mod_meta nf7_core_sdl2 = {
|
||||
.name = (const uint8_t*) "nf7core_sdl2",
|
||||
.desc = (const uint8_t*) "provides SDL2 features",
|
||||
.ver = 0,
|
||||
|
||||
.delete = del_,
|
||||
};
|
21
core/sdl2/mod.h
Normal file
21
core/sdl2/mod.h
Normal file
@ -0,0 +1,21 @@
|
||||
// No copyright
|
||||
#pragma once
|
||||
|
||||
#include <SDL.h>
|
||||
#include <uv.h>
|
||||
|
||||
#include "nf7.h"
|
||||
|
||||
#include "util/malloc.h"
|
||||
|
||||
|
||||
extern const struct nf7_mod_meta nf7_core_sdl2;
|
||||
|
||||
struct nf7_core_sdl2 {
|
||||
const struct nf7_mod_meta* meta;
|
||||
|
||||
const struct nf7* nf7;
|
||||
struct nf7_util_malloc* malloc;
|
||||
uv_loop_t* uv;
|
||||
SDL_Window* win;
|
||||
};
|
59
main.c
Normal file
59
main.c
Normal file
@ -0,0 +1,59 @@
|
||||
// No copyright
|
||||
#include <stdatomic.h>
|
||||
#include <stdbool.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#include <uv.h>
|
||||
|
||||
#include "nf7.h"
|
||||
|
||||
#include "core/all.h"
|
||||
|
||||
|
||||
static void cb_close_all_handles_(uv_handle_t*, void*);
|
||||
|
||||
|
||||
int main(int argc, char** argv) {
|
||||
// init loop
|
||||
uv_loop_t uv;
|
||||
if (0 != uv_loop_init(&uv)) {
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
struct nf7 nf7 = {
|
||||
.ver = 0,
|
||||
.argc = argc,
|
||||
.argv = (const char* const*) argv,
|
||||
.uv = &uv,
|
||||
};
|
||||
|
||||
// load modules
|
||||
struct nf7_mod* nf7_mods[NF7_CORE_MAX_MODS];
|
||||
nf7.mods.n = nf7_core_new(&nf7, nf7_mods);
|
||||
nf7.mods.ptr = nf7_mods;
|
||||
|
||||
// main loop
|
||||
if (0 != uv_run(&uv, UV_RUN_DEFAULT)) {
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
|
||||
// destroy modules
|
||||
for (uint32_t i = 0; i < nf7.mods.n; ++i) {
|
||||
struct nf7_mod* mod = nf7.mods.ptr[i];
|
||||
if (nullptr != mod->meta->delete) {
|
||||
mod->meta->delete(mod);
|
||||
}
|
||||
}
|
||||
|
||||
// teardown loop
|
||||
uv_walk(&uv, cb_close_all_handles_, nullptr);
|
||||
uv_run(&uv, UV_RUN_DEFAULT);
|
||||
if (0 != uv_loop_close(&uv)) {
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
return EXIT_SUCCESS;
|
||||
}
|
||||
|
||||
static void cb_close_all_handles_(uv_handle_t* handle, void*) {
|
||||
uv_close(handle, nullptr);
|
||||
}
|
42
nf7.h
Normal file
42
nf7.h
Normal file
@ -0,0 +1,42 @@
|
||||
// No copyright
|
||||
#pragma once
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
#include <uv.h>
|
||||
|
||||
#include "util/malloc.h"
|
||||
|
||||
|
||||
struct nf7;
|
||||
struct nf7_mod;
|
||||
struct nf7_mod_meta;
|
||||
|
||||
|
||||
struct nf7 {
|
||||
uint32_t ver;
|
||||
|
||||
uint32_t argc;
|
||||
const char* const* argv;
|
||||
|
||||
uv_loop_t* uv;
|
||||
struct nf7_util_malloc* malloc;
|
||||
|
||||
struct {
|
||||
uint32_t n;
|
||||
struct nf7_mod** ptr;
|
||||
} mods;
|
||||
};
|
||||
|
||||
struct nf7_mod {
|
||||
const struct nf7_mod_meta* meta;
|
||||
};
|
||||
|
||||
struct nf7_mod_meta {
|
||||
const uint8_t* name;
|
||||
const uint8_t* desc;
|
||||
uint32_t ver;
|
||||
|
||||
void (*delete)(struct nf7_mod*);
|
||||
void (*push_lua)(struct nf7_mod*);
|
||||
};
|
18
thirdparty/CMakeLists.txt
vendored
Normal file
18
thirdparty/CMakeLists.txt
vendored
Normal file
@ -0,0 +1,18 @@
|
||||
include(FetchContent)
|
||||
|
||||
|
||||
# ---- libuv (MIT)
|
||||
FetchContent_Declare(
|
||||
libuv
|
||||
GIT_REPOSITORY https://github.com/libuv/libuv.git
|
||||
GIT_TAG v1.47.0
|
||||
)
|
||||
FetchContent_MakeAvailable(libuv)
|
||||
|
||||
# ---- OpenGL
|
||||
find_package(OpenGL REQUIRED GLOBAL)
|
||||
add_library(OpenGL ALIAS OpenGL::GL)
|
||||
|
||||
# ---- SDL2 (zlib)
|
||||
find_package(SDL2 REQUIRED GLOBAL)
|
||||
add_library(SDL2 ALIAS SDL2::SDL2)
|
44
tool/meta.cmake
Normal file
44
tool/meta.cmake
Normal file
@ -0,0 +1,44 @@
|
||||
# No copyright
|
||||
|
||||
# This function adds a custom command to execute ${args_src} and adds its output
|
||||
# to sources of ${args_target} with a scope ${args_scope}
|
||||
function(target_meta_source args_target args_scope args_src)
|
||||
cmake_parse_arguments(args
|
||||
""
|
||||
""
|
||||
"ARGS;DEPENDS"
|
||||
${ARGN}
|
||||
)
|
||||
|
||||
if (IS_ABSOLUTE "${args_src}")
|
||||
set(src_abs "${args_src}")
|
||||
else()
|
||||
if (EXISTS "${CMAKE_CURRENT_SOURCE_DIR}/${args_src}")
|
||||
set(src_abs "${CMAKE_CURRENT_SOURCE_DIR}/${args_src}")
|
||||
elseif(EXISTS "${CMAKE_CURRENT_BINARY_DIR}/${args_src}")
|
||||
set(src_abs "${CMAKE_CURRENT_BINARY_DIR}/${args_src}")
|
||||
else()
|
||||
message(FATAL_ERROR "no source file found: ${args_src}")
|
||||
endif()
|
||||
endif()
|
||||
|
||||
get_filename_component(src_ext "${src_abs}" LAST_EXT)
|
||||
get_filename_component(src_name "${src_abs}" NAME)
|
||||
string(REGEX REPLACE "${src_ext}$" "" dst_name "${src_name}")
|
||||
|
||||
get_filename_component(src_dir_abs "${src_abs}" DIRECTORY)
|
||||
string(REGEX REPLACE "^${CMAKE_SOURCE_DIR}/" "" src_dir "${src_dir_abs}")
|
||||
|
||||
set(dst_dir_abs "${CMAKE_BINARY_DIR}/generated/${src_dir}")
|
||||
file(MAKE_DIRECTORY "${dst_dir_abs}")
|
||||
set(dst_abs "${dst_dir_abs}/${dst_name}")
|
||||
|
||||
add_custom_command(
|
||||
COMMAND "${src_abs}" ${args_ARGS} > "${dst_abs}"
|
||||
OUTPUT "${dst_abs}"
|
||||
DEPENDS ${args_DEPENDS}
|
||||
WORKING_DIRECTORY "${src_dir_abs}"
|
||||
VERBATIM
|
||||
)
|
||||
target_sources(${args_target} ${args_scope} "${dst_abs}")
|
||||
endfunction()
|
8
util/CMakeLists.txt
Normal file
8
util/CMakeLists.txt
Normal file
@ -0,0 +1,8 @@
|
||||
add_library(nf7util)
|
||||
target_sources(nf7util
|
||||
PRIVATE
|
||||
malloc.c
|
||||
PUBLIC
|
||||
malloc.h
|
||||
)
|
||||
target_link_libraries(nf7util PRIVATE nf7config)
|
43
util/malloc.c
Normal file
43
util/malloc.c
Normal file
@ -0,0 +1,43 @@
|
||||
// No copyright
|
||||
#include "util/malloc.h"
|
||||
|
||||
#include <assert.h>
|
||||
|
||||
|
||||
void* nf7_util_malloc_stack_new(struct nf7_util_malloc_stack* const this, const uint64_t n) {
|
||||
assert(nullptr != this);
|
||||
|
||||
if (this->end < this->tail + n) {
|
||||
const uint64_t tail = this->tail - this->begin;
|
||||
const uint64_t size = tail + n;
|
||||
|
||||
uint8_t* const ptr = nf7_util_malloc_renew(this->malloc, this->begin, size);
|
||||
if (nullptr == ptr) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
this->begin = ptr;
|
||||
// this->head = ptr + head; // unnecessary 'cause it'll be filled before return
|
||||
this->tail = ptr + tail;
|
||||
this->end = ptr + size;
|
||||
}
|
||||
|
||||
this->head = this->tail;
|
||||
this->tail += n;
|
||||
return this->head;
|
||||
}
|
||||
|
||||
void nf7_util_malloc_stack_del(struct nf7_util_malloc_stack* const this, void* const ptr) {
|
||||
assert(nullptr != this);
|
||||
assert(0 < this->refcnt);
|
||||
|
||||
if (--this->refcnt == 0) {
|
||||
this->head = this->begin;
|
||||
this->tail = this->begin;
|
||||
return;
|
||||
}
|
||||
if (this->head == ptr) {
|
||||
this->tail = this->head;
|
||||
return;
|
||||
}
|
||||
}
|
38
util/malloc.h
Normal file
38
util/malloc.h
Normal file
@ -0,0 +1,38 @@
|
||||
// No copyright
|
||||
#pragma once
|
||||
|
||||
#include <stdlib.h>
|
||||
|
||||
|
||||
// ---- General Purpose Memory Allocator
|
||||
// The current implementation is just a wrap of malloc/free.
|
||||
struct nf7_util_malloc { uint8_t dummy_; };
|
||||
|
||||
static inline void* nf7_util_malloc_new(struct nf7_util_malloc*, uint64_t n) {
|
||||
return n > 0? calloc(n, 1): nullptr;
|
||||
}
|
||||
static inline void nf7_util_malloc_del(struct nf7_util_malloc*, void* ptr) {
|
||||
if (nullptr != ptr) { free(ptr); }
|
||||
}
|
||||
static inline void* nf7_util_malloc_renew(struct nf7_util_malloc* this, void* ptr, uint64_t n) {
|
||||
if (n > 0) {
|
||||
return nullptr != ptr? realloc(ptr, n): malloc(n);
|
||||
} else {
|
||||
nf7_util_malloc_del(this, ptr);
|
||||
return nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// ---- Stack Allocator
|
||||
struct nf7_util_malloc_stack {
|
||||
struct nf7_util_malloc* malloc;
|
||||
|
||||
uint8_t* begin;
|
||||
uint8_t* end;
|
||||
uint8_t* head;
|
||||
uint8_t* tail;
|
||||
uint64_t refcnt;
|
||||
};
|
||||
|
||||
void* nf7_util_malloc_stack_new(struct nf7_util_malloc_stack* this, uint64_t n);
|
Loading…
x
Reference in New Issue
Block a user