Skip to content

Commit e824328

Browse files
committed
Init release
1 parent 8c19e05 commit e824328

10 files changed

Lines changed: 631 additions & 1 deletion

File tree

.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -39,3 +39,4 @@
3939

4040
# debug information files
4141
*.dwo
42+
build-ninja/

CMakeLists.txt

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
cmake_minimum_required(VERSION 3.20)
2+
project(app LANGUAGES CXX)
3+
4+
set(CMAKE_CXX_STANDARD 20)
5+
set(CMAKE_CXX_STANDARD_REQUIRED ON)
6+
7+
add_library(app INTERFACE)
8+
add_library(app::app ALIAS app)
9+
10+
target_include_directories(app INTERFACE
11+
$<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/include>
12+
$<INSTALL_INTERFACE:include>
13+
)
14+
15+
if (MSVC)
16+
target_compile_options(app INTERFACE /W4 /permissive-)
17+
else()
18+
target_compile_options(app INTERFACE -Wall -Wextra -Wpedantic)
19+
endif()
20+
21+
include(CTest)
22+
enable_testing()
23+
24+
add_executable(app_basic_test tests/test_basic.cpp)
25+
target_link_libraries(app_basic_test PRIVATE app::app)
26+
add_test(NAME app.basic COMMAND app_basic_test)

CMakePresets.json

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
{
2+
"version": 6,
3+
"configurePresets": [
4+
{
5+
"name": "dev-ninja",
6+
"displayName": "Dev (Ninja, Debug)",
7+
"generator": "Ninja",
8+
"binaryDir": "build-ninja",
9+
"cacheVariables": {
10+
"CMAKE_BUILD_TYPE": "Debug",
11+
"CMAKE_EXPORT_COMPILE_COMMANDS": "ON"
12+
}
13+
},
14+
{
15+
"name": "release",
16+
"displayName": "Release (Ninja, Release)",
17+
"generator": "Ninja",
18+
"binaryDir": "build-release",
19+
"cacheVariables": {
20+
"CMAKE_BUILD_TYPE": "Release",
21+
"CMAKE_EXPORT_COMPILE_COMMANDS": "ON"
22+
}
23+
},
24+
{
25+
"name": "dev-msvc",
26+
"displayName": "Dev (MSVC, Release)",
27+
"generator": "Visual Studio 17 2022",
28+
"architecture": { "value": "x64" },
29+
"binaryDir": "build-msvc",
30+
"cacheVariables": {
31+
"CMAKE_CONFIGURATION_TYPES": "Release"
32+
}
33+
}
34+
],
35+
"buildPresets": [
36+
{ "name": "build-ninja", "displayName": "Build (ALL, Ninja Debug)", "configurePreset": "dev-ninja" },
37+
{ "name": "build-release", "displayName": "Build (ALL, Ninja Release)", "configurePreset": "release" },
38+
{ "name": "build-msvc", "displayName": "Build (ALL, MSVC)", "configurePreset": "dev-msvc", "configuration": "Release" }
39+
]
40+
}

README.md

Lines changed: 220 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,221 @@
11
# app
2-
Core application scaffold for Vix-based projects. Provides the minimal runtime structure, lifecycle hooks, configuration loading, and bootstrap logic to build any Vix application.
2+
3+
Base application lifecycle kit for modern C++.
4+
5+
`app` provides a minimal, deterministic application runtime foundation designed for Vix application scaffolding.
6+
7+
- Explicit start / stop lifecycle
8+
- Structured run loop
9+
- Graceful shutdown (SIGINT, SIGTERM)
10+
- Hook-based initialization and cleanup
11+
12+
Header-only. Standard library only. Zero external dependencies.
13+
14+
## Download
15+
16+
https://vixcpp.com/registry/pkg/vix/app
17+
18+
## Why app?
19+
20+
Every long-running C++ application eventually needs:
21+
22+
- Startup initialization
23+
- Graceful shutdown
24+
- Signal handling
25+
- Lifecycle structure
26+
- A main run loop
27+
- Clean separation between bootstrap and runtime
28+
29+
Most projects either:
30+
31+
- Put everything inside `main()`
32+
- Reimplement ad-hoc loops
33+
- Forget proper shutdown handling
34+
- Mix lifecycle and business logic
35+
36+
`app` provides:
37+
38+
- A minimal lifecycle base class
39+
- Explicit hooks (`on_start`, `on_stop`)
40+
- Customizable run loop
41+
- Safe stop signaling
42+
- Clean extension points
43+
44+
No logging system.
45+
No HTTP layer.
46+
No async runtime.
47+
48+
Just a deterministic application foundation.
49+
50+
## Installation
51+
52+
### Using Vix Registry
53+
54+
```bash
55+
vix add vix/app
56+
vix deps
57+
```
58+
59+
### Manual
60+
61+
```bash
62+
git clone https://github.com/vixcpp/app.git
63+
```
64+
65+
Add the `include/` directory to your project.
66+
67+
### Dependency
68+
69+
Requires C++17 or newer. No external dependencies.
70+
71+
## Quick examples
72+
73+
### Minimal application
74+
75+
```cpp
76+
#include <app/app.hpp>
77+
#include <iostream>
78+
79+
class MyApp : public vix::app::Application
80+
{
81+
protected:
82+
void loop_step() override
83+
{
84+
std::cout << "tick\n";
85+
stop(); // stop after one iteration
86+
}
87+
};
88+
89+
int main()
90+
{
91+
MyApp app;
92+
93+
app.on_start([] {
94+
std::cout << "starting\n";
95+
});
96+
97+
app.on_stop([] {
98+
std::cout << "stopping\n";
99+
});
100+
101+
app.run();
102+
}
103+
```
104+
105+
### Custom run loop
106+
107+
```cpp
108+
#include <app/app.hpp>
109+
#include <chrono>
110+
#include <iostream>
111+
#include <thread>
112+
113+
class CustomApp : public vix::app::Application
114+
{
115+
protected:
116+
void run_loop() override
117+
{
118+
for (int i = 0; i < 5 && is_running(); ++i)
119+
{
120+
std::cout << "step: " << i << "\n";
121+
std::this_thread::sleep_for(std::chrono::milliseconds(50));
122+
}
123+
stop();
124+
}
125+
};
126+
127+
int main()
128+
{
129+
CustomApp app;
130+
app.run();
131+
}
132+
```
133+
134+
## API overview
135+
136+
### `vix::app::Application`
137+
138+
- `Application::run()`
139+
- `Application::stop()`
140+
- `Application::is_running()`
141+
- `Application::on_start()`
142+
- `Application::on_stop()`
143+
144+
Protected extension points:
145+
146+
- `Application::run_loop()`
147+
- `Application::loop_step()`
148+
- `Application::tick_interval()`
149+
150+
## Lifecycle model
151+
152+
Execution order:
153+
154+
1. `run()`
155+
2. `on_start()` hook
156+
3. `run_loop()`
157+
4. `stop()` requested
158+
5. `on_stop()` hook
159+
6. exit
160+
161+
Signals handled:
162+
163+
- `SIGINT`
164+
- `SIGTERM`
165+
166+
Graceful shutdown is guaranteed if `stop()` is triggered.
167+
168+
## Complexity
169+
170+
All operations are constant time.
171+
172+
| Operation | Time complexity |
173+
|----------------|-----------------|
174+
| `run()` start | O(1) |
175+
| `stop()` | O(1) |
176+
| `is_running()` | O(1) |
177+
178+
The run loop complexity depends on user-defined behavior.
179+
180+
## Design principles
181+
182+
- Deterministic lifecycle
183+
- Explicit extension points
184+
- No hidden threads
185+
- No global state (except controlled signal pointer)
186+
- Minimal abstraction
187+
- Stable foundation for higher-level runtimes
188+
189+
This library provides primitives only.
190+
191+
If you need:
192+
193+
- HTTP server runtime
194+
- WebSocket handling
195+
- Async I/O engine
196+
- Microservice orchestration
197+
198+
Build them on top of this layer (`web_app`, `service_app`, `realtime_app`, etc.).
199+
200+
## Tests
201+
202+
Run:
203+
204+
```bash
205+
vix build
206+
vix test
207+
```
208+
209+
Tests verify:
210+
211+
- Lifecycle execution
212+
- Hook execution
213+
- Proper stop behavior
214+
- Loop iteration
215+
- Graceful termination
216+
217+
## License
218+
219+
MIT License\
220+
Copyright (c) Gaspard Kirira
221+

app.vix

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
version = 1
2+
3+
[app]
4+
kind = "project"
5+
dir = "."
6+
name = "app"
7+
entry = "tests/test_basic.cpp"
8+
9+
[build]
10+
preset = "dev-ninja"

examples/basic.cpp

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
#include <app/app.hpp>
2+
3+
#include <chrono>
4+
#include <iostream>
5+
#include <thread>
6+
7+
class MyApp : public vix::app::Application
8+
{
9+
protected:
10+
void loop_step() override
11+
{
12+
std::cout << "tick" << std::endl;
13+
std::this_thread::sleep_for(std::chrono::milliseconds(100));
14+
stop(); // stop after one tick for demo
15+
}
16+
};
17+
18+
int main()
19+
{
20+
MyApp app;
21+
22+
app.on_start([]
23+
{ std::cout << "starting..." << std::endl; });
24+
25+
app.on_stop([]
26+
{ std::cout << "stopping..." << std::endl; });
27+
28+
app.run();
29+
return 0;
30+
}

examples/custom_loop.cpp

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
#include <app/app.hpp>
2+
3+
#include <chrono>
4+
#include <iostream>
5+
#include <thread>
6+
7+
class CustomLoopApp : public vix::app::Application
8+
{
9+
protected:
10+
void run_loop() override
11+
{
12+
// Custom event loop style.
13+
for (int i = 0; i < 5 && is_running(); ++i)
14+
{
15+
std::cout << "custom loop step: " << i << std::endl;
16+
std::this_thread::sleep_for(std::chrono::milliseconds(50));
17+
}
18+
stop();
19+
}
20+
};
21+
22+
int main()
23+
{
24+
CustomLoopApp app;
25+
26+
app.on_start([]
27+
{ std::cout << "custom app start" << std::endl; });
28+
29+
app.on_stop([]
30+
{ std::cout << "custom app stop" << std::endl; });
31+
32+
app.run();
33+
return 0;
34+
}

0 commit comments

Comments
 (0)