Restructing the source layout to make it nicer.

This commit is contained in:
Zed A. Shaw 2024-09-10 21:17:15 -04:00
parent fff182b457
commit cc3bb171e1
14 changed files with 166 additions and 33 deletions

33
scratchpad/audiotest.cpp Normal file
View file

@ -0,0 +1,33 @@
#include <SFML/Audio.hpp>
#include <thread> // for sleep_for
#include <iostream>
#include <fmt/core.h>
#include <chrono>
int main(int argc, char *argv[]) {
sf::SoundBuffer buffer;
sf::Sound sound;
if(argc != 2) {
fmt::println("USAGE: audiotest [FILE]");
return 0;
}
const char *in_file = argv[1];
if(!buffer.loadFromFile(in_file)) {
fmt::println("Failed to load {}", in_file);
return 0;
}
sound.setBuffer(buffer);
fmt::println("Playing {}. Hit ctrl-c to exit.", in_file);
sound.play();
while(sound.getStatus() != sf::SoundSource::Status::Stopped) {
std::this_thread::sleep_for(std::chrono::milliseconds(100));
}
return 0;
}

48
scratchpad/badref.cpp Normal file
View file

@ -0,0 +1,48 @@
#include <string>
#include <memory>
#include <iostream>
using std::string, std::unique_ptr,
std::shared_ptr, std::make_unique;
class BadRef {
string &name;
public:
BadRef(string &name) : name(name) {}
void set_name(string &n) {
name = n;
}
};
class GoodRef {
string *name;
public:
/*
* After calling, name is owned.
*/
GoodRef(string *n) : name(n) {}
void print() {
std::cout << "My name is " << *name << std::endl;
}
};
int main() {
string my_name = "Zed";
string your_name = "Alex";
string &ref_test = my_name;
string *ptr_name = new string("Pointer");
ref_test = your_name;
auto br = BadRef(my_name);
br.set_name(your_name);
auto gr = GoodRef(ptr_name);
gr.print();
return 0;
}

52
scratchpad/corotest.cpp Normal file
View file

@ -0,0 +1,52 @@
#include "../coro.hpp"
#include <coroutine>
#include <vector>
#include <iostream>
using std::cout, std::endl;
Task<unsigned> task_test()
{
co_await Pass{};
for (unsigned i = 0; i < 3; ++i)
co_yield i;
co_return 1000;
}
int main()
{
const int task_count = 4;
std::vector<Task<unsigned>> tasks;
for(int i = 0; i < task_count; i++) {
auto t = task_test();
tasks.push_back(std::move(t));
}
int done_count = 0;
while(done_count < task_count) {
for(int i = 0; i < task_count; i++) {
Task<unsigned> &t = tasks[i];
if(t.done()) {
// remove it from the tasks
// this cause crash I think?
t.destroy();
done_count++;
} else {
auto res = t();
if(t.state() == AWAIT) {
cout << "AWAIT! " << t.state() << endl;
} else if(t.state() != YIELD) {
cout << "NOT YIELD: " << t.state() << endl;
} else {
cout << "T# " << i << " result "
<< res << " STATE " << t.state() << endl;
}
}
}
}
}

48
scratchpad/fsmtest.cpp Normal file
View file

@ -0,0 +1,48 @@
#include <fmt/core.h>
#include "../fsm.hpp"
using namespace fmt;
enum MyState {
START, RUNNING, END
};
enum MyEvent {
STARTED, PUSH, QUIT
};
class MyFSM : DeadSimpleFSM<MyState, MyEvent> {
public:
void event(MyEvent ev) override {
switch(_state) {
FSM_STATE(START, start, ev);
FSM_STATE(RUNNING, push, ev);
FSM_STATE(END, quit, ev);
}
}
void start(MyEvent ev) {
println("<<< START");
state(RUNNING);
}
void push(MyEvent ev) {
println("<<< RUN");
state(RUNNING);
}
void quit(MyEvent ev) {
println("<<< STOP");
state(END);
}
};
int main() {
MyFSM fsm;
fsm.event(STARTED);
fsm.event(PUSH);
fsm.event(PUSH);
fsm.event(PUSH);
fsm.event(QUIT);
}

View file

@ -0,0 +1,85 @@
#include <stdlib.h> // for EXIT_SUCCESS
#include <chrono> // for milliseconds
#include <thread> // for sleep_for, thread
#include <fmt/core.h>
#include <ftxui/component/event.hpp> // for Event
#include <ftxui/component/mouse.hpp> // for ftxui
#include <ftxui/dom/elements.hpp> // for text, separator, Element, operator|, vbox, border
#include <memory> // for allocator, shared_ptr
#include <string> // for operator+, to_string
#include <thread> // for sleep_for
#include <ftxui/component/component.hpp> // for CatchEvent, Renderer, operator|=
#include <ftxui/component/loop.hpp> // for Loop
#include <ftxui/component/screen_interactive.hpp> // for ScreenInteractive
using namespace ftxui;
ButtonOption Style() {
auto option = ButtonOption::Animated();
option.transform = [](const EntryState& s) {
auto element = text(s.label);
if (s.focused) {
element |= bold;
}
return element | center | borderEmpty | flex;
};
return option;
}
int main() {
auto screen = ScreenInteractive::Fullscreen();
// Create a component counting the number of frames drawn and event handled.
int custom_loop_count = 0;
int frame_count = 0;
int event_count = 0;
int hp = 100;
int row = 0;
auto hit_button = Button("Hit", [&] { hp -= 1; }, Style());
auto hard_button = Button("Hard", [&] { hp -= 10; }, Style());
auto heal_button = Button("Heal", [&] { hp += 10; }, Style());
auto buttons = Container::Horizontal({
hit_button, hard_button, heal_button}, &row);
auto component = Renderer(buttons, [&] {
frame_count++;
return vbox({
paragraph("I'm baby mustache hammock squid, stumptown echo park lumbersexual PBR&B glossier iceland pabst irony mlkshk skateboard migas kombucha. Lyft meggings organic tacos. IPhone microdosing bodega boys, fit locavore jawn cloud bread neutral milk hotel trust fund live-edge selfies portland lyft vice. Pug swag af slow-carb."),
separator(),
paragraph(fmt::format("HP {} frames {} events {} custom {}",
hp, frame_count, event_count, custom_loop_count)),
separator(),
hbox({
text("HP"),
gauge(hp / 100.0f),
}),
separator(),
buttons->Render(),
}) |
border;
});
component |= CatchEvent([&](Event) -> bool {
event_count++;
return false;
});
Loop loop(&screen, component);
std::atomic<bool> refresh_ui_continue = true;
std::thread refresh_ui([&] {
while(refresh_ui_continue) {
screen.Post(Event::Custom);
std::this_thread::sleep_for(std::chrono::milliseconds(10));
}
});
screen.Loop(component);
refresh_ui_continue = false;
refresh_ui.join();
return EXIT_SUCCESS;
}

91
scratchpad/ftxtest.cpp Normal file
View file

@ -0,0 +1,91 @@
#include <stdlib.h> // for EXIT_SUCCESS
#include <chrono> // for milliseconds
#include <fmt/core.h>
#include <ftxui/component/event.hpp> // for Event
#include <ftxui/component/mouse.hpp> // for ftxui
#include <ftxui/dom/elements.hpp> // for text, separator, Element, operator|, vbox, border
#include <memory> // for allocator, shared_ptr
#include <string> // for operator+, to_string
#include <thread> // for sleep_for
#include <ftxui/component/component.hpp> // for CatchEvent, Renderer, operator|=
#include <ftxui/component/loop.hpp> // for Loop
#include <ftxui/component/screen_interactive.hpp> // for ScreenInteractive
#include <vector>
using namespace ftxui;
using namespace std;
ButtonOption Style() {
auto option = ButtonOption::Animated();
option.transform = [](const EntryState& s) {
auto element = text(s.label);
if (s.focused) {
element |= bold;
}
return element | center | borderEmpty | flex;
};
return option;
}
int main() {
auto screen = ScreenInteractive::Fullscreen();
screen.TrackMouse(true);
vector<string> lines;
// Create a component counting the number of frames drawn and event handled.
float scroll_x = 0.1;
float scroll_y = 1.0;
int hp = 100;
auto status = Renderer([&] {
return vbox({
paragraph(fmt::format("HP {}", hp)),
separator(),
hbox({
text("HP"),
gauge(hp / 100.0f),
}),
});
});
auto content = Renderer([&] {
vector<Element> output;
for(const auto line : lines) {
output.push_back(text(line));
}
return vbox(output);
});
auto scrollable_content = Renderer(content,
[&, content] {
return content->Render()
| focusPositionRelative(scroll_x, scroll_y)
| frame | flex;
});
auto component = Renderer(scrollable_content, [&] {
return vbox({
status->Render(),
separator(),
scrollable_content->Render() | vscroll_indicator | yframe | size(HEIGHT, LESS_THAN, 20),
}) |
border;
});
component |= CatchEvent([&](Event) -> bool {
return false;
});
Loop loop(&screen, component);
while (!loop.HasQuitted()) {
loop.RunOnce();
screen.Post(Event::Custom);
std::this_thread::sleep_for(std::chrono::milliseconds(10));
}
return EXIT_SUCCESS;
}

27
scratchpad/jsontest.cpp Normal file
View file

@ -0,0 +1,27 @@
#include <iostream>
#include <fstream>
#include <fmt/core.h>
#include <nlohmann/json.hpp>
using json = nlohmann::json;
using namespace fmt;
using std::string, std::cout;
int main(int argc, char *argv[]) {
if(argc != 2) {
println("USAGE: jsontest [jsonfile]");
return 0;
}
std::ifstream infile(argv[1]);
json data = json::parse(infile);
json::string_t s2 = data["happy"].template get<string>();
for(auto &el : data.items()) {
cout << el.key() << "=" << el.value() << "\n";
}
println("DATA HAPPY {}", s2);
return 0;
}

23
scratchpad/meson.build Normal file
View file

@ -0,0 +1,23 @@
executable('regtest', 'regtest.cpp',
dependencies: [fmt])
executable('audiotest', 'audiotest.cpp',
dependencies: dependencies)
executable('jsontest', 'jsontest.cpp',
dependencies: dependencies)
executable('threadtest', 'threadtest.cpp',
dependencies: dependencies)
executable('fsmtest', 'fsmtest.cpp',
dependencies: dependencies)
executable('badref', 'badref.cpp',
dependencies: dependencies)
executable('corotest', [
'corotest.cpp'
],
dependencies: dependencies,
cpp_args: '-fcoroutines')

27
scratchpad/regtest.cpp Normal file
View file

@ -0,0 +1,27 @@
#include <fmt/core.h>
#include <regex>
#include <string>
using namespace fmt;
using namespace std;
int main(int argc, char *argv[]) {
smatch matches;
if(argc != 3) {
println("USAGE: regtest <regex> <line>");
} else {
regex to_test(argv[1]);
string line(argv[2]);
if(regex_match(line, matches, to_test)) {
println("MATCHED: ");
for(auto &match : matches) {
println("\t{}", match.str());
}
} else {
println("NO MATCH");
}
}
}

37
scratchpad/threadtest.cpp Normal file
View file

@ -0,0 +1,37 @@
#include <chrono>
#include <future>
#include <iostream>
#include <thread>
using namespace std::chrono_literals;
int main()
{
std::future<int> future = std::async(std::launch::async, []()
{
std::this_thread::sleep_for(3s);
return 8;
});
std::cout << "waiting...\n";
std::future_status status;
do
{
status = future.wait_for(100ms);
switch (status)
{
case std::future_status::deferred:
std::cout << "deferred\n";
break;
case std::future_status::timeout:
std::cout << "timeout\n";
break;
case std::future_status::ready:
std::cout << "ready!\n";
break;
}
}
while (status != std::future_status::ready);
std::cout << "result is " << future.get() << '\n';
}

130
scratchpad/uniqptrtest.cpp Normal file
View file

@ -0,0 +1,130 @@
#include <cassert>
#include <cstdio>
#include <fstream>
#include <iostream>
#include <locale>
#include <memory>
#include <stdexcept>
// helper class for runtime polymorphism demo below
struct B
{
virtual ~B() = default;
virtual void bar() { std::cout << "B::bar\n"; }
};
struct D : B
{
D() { std::cout << "D::D\n"; }
~D() { std::cout << "D::~D\n"; }
void bar() override { std::cout << "D::bar\n"; }
};
// a function consuming a unique_ptr can take it by value or by rvalue reference
std::unique_ptr<D> pass_through(std::unique_ptr<D> p)
{
p->bar();
return p;
}
// helper function for the custom deleter demo below
void close_file(std::FILE* fp)
{
std::fclose(fp);
}
// unique_ptr-based linked list demo
struct List
{
struct Node
{
int data;
std::unique_ptr<Node> next;
};
std::unique_ptr<Node> head;
~List()
{
// destroy list nodes sequentially in a loop, the default destructor
// would have invoked its `next`'s destructor recursively, which would
// cause stack overflow for sufficiently large lists.
while (head)
{
auto next = std::move(head->next);
head = std::move(next);
}
}
void push(int data)
{
head = std::unique_ptr<Node>(new Node{data, std::move(head)});
}
};
int main()
{
std::cout << "1) Unique ownership semantics demo\n";
{
// Create a (uniquely owned) resource
std::unique_ptr<D> p = std::make_unique<D>();
// Transfer ownership to `pass_through`,
// which in turn transfers ownership back through the return value
std::unique_ptr<D> q = pass_through(std::move(p));
// p is now in a moved-from 'empty' state, equal to nullptr
assert(!p);
}
std::cout << "\n" "2) Runtime polymorphism demo\n";
{
// Create a derived resource and point to it via base type
std::unique_ptr<B> p = std::make_unique<D>();
// Dynamic dispatch works as expected
p->bar();
}
std::cout << "\n" "3) Custom deleter demo\n";
std::ofstream("demo.txt") << 'x'; // prepare the file to read
{
using unique_file_t = std::unique_ptr<std::FILE, decltype(&close_file)>;
unique_file_t fp(std::fopen("demo.txt", "r"), &close_file);
if (fp)
std::cout << char(std::fgetc(fp.get())) << '\n';
} // `close_file()` called here (if `fp` is not null)
std::cout << "\n" "4) Custom lambda-expression deleter and exception safety demo\n";
try
{
std::unique_ptr<D, void(*)(D*)> p(new D, [](D* ptr)
{
std::cout << "destroying from a custom deleter...\n";
delete ptr;
});
throw std::runtime_error(""); // `p` would leak here if it were a plain pointer
}
catch (const std::exception&)
{
std::cout << "Caught exception\n";
}
std::cout << "\n" "5) Array form of unique_ptr demo\n";
{
std::unique_ptr<D[]> p(new D[3]);
} // `D::~D()` is called 3 times
std::cout << "\n" "6) Linked list demo\n";
{
List wall;
const int enough{1'000'000};
for (int beer = 0; beer != enough; ++beer)
wall.push(beer);
std::cout << enough << " bottles of beer on the wall...\n";
} // destroys all the beers
}