Compare commits

..

9 Commits

Author SHA1 Message Date
67aefff940 windows mono_time hotfix 2024-01-09 15:37:02 +01:00
74129cabef fix url open with unsanitized strings 2024-01-09 02:26:50 +01:00
be8ceb861c 1 sec cooldown for reduced fps mode 2024-01-07 22:20:40 +01:00
da0f59a3f5 try fix plugin rendering 2024-01-07 19:37:05 +01:00
000254320e add ubuntu linux to cd 2024-01-07 18:54:18 +01:00
2fac7206d2 pull windows fixes 2024-01-07 18:05:36 +01:00
e8234f2a4a properly seperate tick and render 2024-01-07 16:33:08 +01:00
a0ba0b39d8 add fps reduced mode 2024-01-06 18:23:06 +01:00
845967cf12 more main loop fiddling 2024-01-06 16:45:08 +01:00
11 changed files with 166 additions and 64 deletions

View File

@ -10,6 +10,36 @@ env:
BUILD_TYPE: Release BUILD_TYPE: Release
jobs: jobs:
linux-ubuntu:
timeout-minutes: 10
runs-on: ubuntu-20.04
steps:
- uses: actions/checkout@v3
with:
submodules: recursive
- name: Install Dependencies
run: sudo apt update && sudo apt -y install libsodium-dev
- name: Configure CMake
run: cmake -B ${{github.workspace}}/build -DCMAKE_BUILD_TYPE=${{env.BUILD_TYPE}}
- name: Build
run: cmake --build ${{github.workspace}}/build --config ${{env.BUILD_TYPE}} -j 4
- name: temp test
run: ${{github.workspace}}/build/bin/mono_time_test
- uses: actions/upload-artifact@v3
with:
name: ${{ github.event.repository.name }}-ubuntu20.04-x86_64
# TODO: do propper packing
path: |
${{github.workspace}}/build/bin/
windows: windows:
timeout-minutes: 15 timeout-minutes: 15

View File

@ -162,7 +162,7 @@ Mono_Time *mono_time_new(const Memory *mem, mono_time_current_time_cb *current_t
#endif #endif
mono_time->cur_time = 0; mono_time->cur_time = 0;
#ifdef FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION #if defined(FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION) || defined(OS_WIN32)
// Maximum reproducibility. Never return time = 0. // Maximum reproducibility. Never return time = 0.
mono_time->base_time = 1; mono_time->base_time = 1;
#else #else

View File

@ -18,17 +18,19 @@
#include "./media_meta_info_loader.hpp" #include "./media_meta_info_loader.hpp"
#include "./sdl_clipboard_utils.hpp" #include "./sdl_clipboard_utils.hpp"
#include <cctype>
#include <cstdint> #include <cstdint>
#include <ctime>
#include <cstdio>
#include <chrono>
#include <filesystem>
#include <fstream>
#include <iomanip>
#include <sstream>
#include <string> #include <string>
#include <variant> #include <variant>
#include <vector> #include <vector>
#include <chrono>
#include <ctime>
#include <cstdio>
#include <iomanip>
#include <fstream>
#include <sstream>
#include <filesystem>
namespace Components { namespace Components {
@ -43,6 +45,32 @@ static float lerp(float a, float b, float t) {
return a + t * (b - a); return a + t * (b - a);
} }
static std::string file_url_escape(const std::string&& value) {
std::ostringstream escaped;
escaped << std::hex;
escaped.fill('0');
for (const char c : value) {
if (
c == '-' || c == '_' || c == '.' || c == '~' || // normal allowed url chars
std::isalnum(static_cast<unsigned char>(c)) || // more normal
c == '/' // special bc its a file://
) {
escaped << c;
} else {
escaped
<< std::uppercase
<< '%' <<
std::setw(2) << static_cast<int>((static_cast<unsigned char>(c)))
<< std::nouppercase
;
}
}
return escaped.str();
}
ChatGui4::ChatGui4( ChatGui4::ChatGui4(
ConfigModelI& conf, ConfigModelI& conf,
RegistryMessageModel& rmm, RegistryMessageModel& rmm,
@ -51,7 +79,7 @@ ChatGui4::ChatGui4(
) : _conf(conf), _rmm(rmm), _cr(cr), _tal(_cr), _contact_tc(_tal, tu), _msg_tc(_mil, tu), _sip(tu) { ) : _conf(conf), _rmm(rmm), _cr(cr), _tal(_cr), _contact_tc(_tal, tu), _msg_tc(_mil, tu), _sip(tu) {
} }
void ChatGui4::render(void) { void ChatGui4::render(float time_delta) {
if (!_cr.storage<Contact::Components::TagAvatarInvalidate>().empty()) { // handle force-reloads for avatars if (!_cr.storage<Contact::Components::TagAvatarInvalidate>().empty()) { // handle force-reloads for avatars
std::vector<Contact3> to_purge; std::vector<Contact3> to_purge;
_cr.view<Contact::Components::TagAvatarInvalidate>().each([&to_purge](const Contact3 c) { _cr.view<Contact::Components::TagAvatarInvalidate>().each([&to_purge](const Contact3 c) {
@ -66,7 +94,7 @@ void ChatGui4::render(void) {
_msg_tc.update(); _msg_tc.update();
_fss.render(); _fss.render();
_sip.render(); _sip.render(time_delta);
const ImGuiViewport* viewport = ImGui::GetMainViewport(); const ImGuiViewport* viewport = ImGui::GetMainViewport();
ImGui::SetNextWindowPos(viewport->WorkPos); ImGui::SetNextWindowPos(viewport->WorkPos);
@ -618,9 +646,8 @@ void ChatGui4::renderMessageBodyFile(Message3Registry& reg, const Message3 e) {
const auto& local_info = reg.get<Message::Components::Transfer::FileInfoLocal>(e); const auto& local_info = reg.get<Message::Components::Transfer::FileInfoLocal>(e);
if (local_info.file_list.size() > i && ImGui::BeginPopupContextItem("##file_c")) { if (local_info.file_list.size() > i && ImGui::BeginPopupContextItem("##file_c")) {
if (ImGui::MenuItem("open")) { if (ImGui::MenuItem("open")) {
std::string url{"file://" + std::filesystem::canonical(local_info.file_list.at(i)).u8string()}; std::string url{"file://" + file_url_escape(std::filesystem::canonical(local_info.file_list.at(i)).u8string())};
std::cout << "opening file '" << url << "'\n"; std::cout << "opening file '" << url << "'\n";
SDL_OpenURL(url.c_str()); SDL_OpenURL(url.c_str());
} }
ImGui::EndPopup(); ImGui::EndPopup();

View File

@ -46,7 +46,7 @@ class ChatGui4 {
); );
public: public:
void render(void); void render(float time_delta);
public: public:
bool any_unread {false}; bool any_unread {false};

View File

@ -84,8 +84,7 @@ int main(int argc, char** argv) {
last_time_tick = new_time; last_time_tick = new_time;
} }
// can do both in the same loop // do events outside of tick/render, so they can influence reported intervals
if (render) {
SDL_Event event; SDL_Event event;
while (SDL_PollEvent(&event)) { while (SDL_PollEvent(&event)) {
if (event.type == SDL_EVENT_QUIT) { if (event.type == SDL_EVENT_QUIT) {
@ -103,11 +102,8 @@ int main(int argc, char** argv) {
break; break;
} }
//float fps_target = 60.f; // can do both in the same loop
//if (SDL_GetWindowFlags(window.get()) & (SDL_WINDOW_HIDDEN | SDL_WINDOW_MINIMIZED)) { if (render) {
//fps_target = 30.f;
//}
ImGui_ImplSDLRenderer3_NewFrame(); ImGui_ImplSDLRenderer3_NewFrame();
ImGui_ImplSDL3_NewFrame(); ImGui_ImplSDL3_NewFrame();
ImGui::NewFrame(); ImGui::NewFrame();
@ -160,12 +156,23 @@ int main(int argc, char** argv) {
//screen->nextRender() - time_delta_render //screen->nextRender() - time_delta_render
//) //)
//)); //));
SDL_Delay(uint32_t(
std::min<float>( const float min_delay = std::min<float>(
screen->nextTick() - time_delta_tick, screen->nextTick() - time_delta_tick,
screen->nextRender() - time_delta_render screen->nextRender() - time_delta_render
) * 1000.f ) * 1000.f;
));
if (min_delay > 0.f) {
SDL_Delay(uint32_t(min_delay));
}
// better in theory, but consumes more cpu on linux for some reason
//SDL_WaitEventTimeout(nullptr, int32_t(
//std::min<float>(
//screen->nextTick() - time_delta_tick,
//screen->nextRender() - time_delta_render
//) * 1000.f
//));
#endif #endif
} }
#else #else

View File

@ -75,6 +75,8 @@ bool MainScreen::handleEvent(SDL_Event& e) {
if (e.type == SDL_EVENT_DROP_FILE) { if (e.type == SDL_EVENT_DROP_FILE) {
std::cout << "DROP FILE: " << e.drop.file << "\n"; std::cout << "DROP FILE: " << e.drop.file << "\n";
cg.sendFilePath(e.drop.file); cg.sendFilePath(e.drop.file);
_render_interval = 1.f/60.f; // TODO: magic
_time_since_event = 0.f;
return true; // TODO: forward return succ from sendFilePath() return true; // TODO: forward return succ from sendFilePath()
} }
@ -116,19 +118,35 @@ bool MainScreen::handleEvent(SDL_Event& e) {
//std::cout << "TOMAT: window shown " << e.window.timestamp << "\n"; //std::cout << "TOMAT: window shown " << e.window.timestamp << "\n";
} }
} }
_render_interval = 1.f/60.f; // TODO: magic
_time_since_event = 0.f;
return true; // forward? return true; // forward?
} }
if (
_fps_perf_mode <= 1 && (
// those are all the events imgui polls
e.type == SDL_EVENT_MOUSE_MOTION ||
e.type == SDL_EVENT_MOUSE_WHEEL ||
e.type == SDL_EVENT_MOUSE_BUTTON_DOWN ||
e.type == SDL_EVENT_MOUSE_BUTTON_UP ||
e.type == SDL_EVENT_TEXT_INPUT ||
e.type == SDL_EVENT_KEY_DOWN ||
e.type == SDL_EVENT_KEY_UP ||
e.type == SDL_EVENT_WINDOW_MOUSE_ENTER ||
e.type == SDL_EVENT_WINDOW_MOUSE_LEAVE ||
e.type == SDL_EVENT_WINDOW_FOCUS_GAINED ||
e.type == SDL_EVENT_WINDOW_FOCUS_LOST
)
) {
_render_interval = 1.f/60.f; // TODO: magic
_time_since_event = 0.f;
}
return false; return false;
} }
Screen* MainScreen::render(float time_delta, bool& quit) { Screen* MainScreen::render(float time_delta, bool&) {
quit = !tc.iterate();
tcm.iterate(time_delta);
tam.iterate();
// HACK: render the tomato main window first, with proper flags set. // HACK: render the tomato main window first, with proper flags set.
// flags need to be set the first time begin() is called. // flags need to be set the first time begin() is called.
// and plugins are run before the main cg is run. // and plugins are run before the main cg is run.
@ -146,15 +164,12 @@ Screen* MainScreen::render(float time_delta, bool& quit) {
ImGui::End(); ImGui::End();
} }
pm.tick(time_delta); const float pm_interval = pm.render(time_delta); // render
tdch.tick(time_delta);
mts.iterate(); cg.render(time_delta); // render
sw.render(); // render
cg.render(); tuiu.render(); // render
sw.render(); tdch.render(); // render
tuiu.render();
tdch.render();
{ // main window menubar injection { // main window menubar injection
if (ImGui::Begin("tomato")) { if (ImGui::Begin("tomato")) {
@ -162,7 +177,7 @@ Screen* MainScreen::render(float time_delta, bool& quit) {
// ImGui::Separator(); // why do we not need this???? // ImGui::Separator(); // why do we not need this????
if (ImGui::BeginMenu("Performance")) { if (ImGui::BeginMenu("Performance")) {
{ // fps { // fps
const auto targets = "normal\0power save\0"; const auto targets = "normal\0reduced\0powersave\0";
ImGui::SetNextItemWidth(ImGui::GetFontSize()*10); ImGui::SetNextItemWidth(ImGui::GetFontSize()*10);
ImGui::Combo("fps mode", &_fps_perf_mode, targets, 4); ImGui::Combo("fps mode", &_fps_perf_mode, targets, 4);
} }
@ -171,7 +186,7 @@ Screen* MainScreen::render(float time_delta, bool& quit) {
const auto targets = "normal\0powersave\0"; const auto targets = "normal\0powersave\0";
ImGui::SetNextItemWidth(ImGui::GetFontSize()*10); ImGui::SetNextItemWidth(ImGui::GetFontSize()*10);
ImGui::Combo("compute mode", &_compute_perf_mode, targets, 4); ImGui::Combo("compute mode", &_compute_perf_mode, targets, 4);
ImGui::SetItemTooltip("Limiting compute can slow down things filetransfers."); ImGui::SetItemTooltip("Limiting compute can slow down things like filetransfers!");
} }
ImGui::EndMenu(); ImGui::EndMenu();
@ -189,22 +204,44 @@ Screen* MainScreen::render(float time_delta, bool& quit) {
} }
if ( if (
_fps_perf_mode > 1 // TODO: magic
) {
// powersave forces 250ms
_render_interval = 1.f/4.f;
} else if (
_time_since_event > 1.f && ( // 1sec cool down
_fps_perf_mode == 1 || // TODO: magic _fps_perf_mode == 1 || // TODO: magic
_window_hidden _window_hidden
)
) { ) {
_render_interval = 1.f/4.f; _render_interval = std::min<float>(1.f/4.f, pm_interval);
} else { } else {
_render_interval = 1.f/60.f; _render_interval = std::min<float>(1.f/60.f, pm_interval);
} }
_time_since_event += time_delta;
return nullptr; return nullptr;
} }
Screen* MainScreen::tick(float time_delta, bool& quit) { Screen* MainScreen::tick(float time_delta, bool& quit) {
quit = !tc.iterate(); // compute
tcm.iterate(time_delta); // compute
tam.iterate(); // compute
const float pm_interval = pm.tick(time_delta); // compute
tdch.tick(time_delta); // compute
mts.iterate(); // compute
_min_tick_interval = std::max<float>( _min_tick_interval = std::max<float>(
std::min<float>( std::min<float>(
tc.toxIterationInterval()/1000.f, tc.toxIterationInterval()/1000.f,
0.03f // HACK: 30ms upper bound, should be the same as tox but will change pm_interval
//0.03f // HACK: 30ms upper bound, should be the same as tox but will change
), ),
(_compute_perf_mode == 0 ? 0.001f : 0.1f) // in powersave fix the lowerbound to 100ms (_compute_perf_mode == 0 ? 0.001f : 0.1f) // in powersave fix the lowerbound to 100ms
); );

View File

@ -66,6 +66,7 @@ struct MainScreen final : public Screen {
bool _window_hidden {false}; bool _window_hidden {false};
bool _window_hidden_ts {0}; bool _window_hidden_ts {0};
float _time_since_event {0.f};
MainScreen(SDL_Renderer* renderer_, std::string save_path, std::string save_password, std::vector<std::string> plugins); MainScreen(SDL_Renderer* renderer_, std::string save_path, std::string save_password, std::vector<std::string> plugins);
~MainScreen(void); ~MainScreen(void);

View File

@ -158,7 +158,7 @@ void SendImagePopup::sendMemory(
} }
void SendImagePopup::render(void) { void SendImagePopup::render(float time_delta) {
if (_open_popup) { if (_open_popup) {
_open_popup = false; _open_popup = false;
ImGui::OpenPopup("send image##SendImagePopup"); ImGui::OpenPopup("send image##SendImagePopup");
@ -171,7 +171,7 @@ void SendImagePopup::render(void) {
preview_image.doAnimation(getNowMS()); preview_image.doAnimation(getNowMS());
time += 1.f/60.f; // TODO: actual delay time += time_delta;
time = fmod(time, 1.f); // fract() time = fmod(time, 1.f); // fract()
//ImGui::Text("send file....\n......"); //ImGui::Text("send file....\n......");

View File

@ -71,6 +71,6 @@ struct SendImagePopup {
// from file_path // from file_path
// call this each frame // call this each frame
void render(void); void render(float time_delta);
}; };