Compare commits
	
		
			3 Commits
		
	
	
		
			3cf3097
			...
			719400068a
		
	
	| Author | SHA1 | Date | |
|---|---|---|---|
| 719400068a | |||
| aaf8c6adc1 | |||
| dc081ae2aa | 
| @@ -35,6 +35,16 @@ namespace Components { | ||||
| 		float fade {1.f}; | ||||
| 	}; | ||||
|  | ||||
| 	struct ConvertedTimeCache { | ||||
| 		// calling localtime is expensive af | ||||
| 		int tm_year {0}; | ||||
| 		int tm_yday {0}; | ||||
| 		int tm_mon {0}; | ||||
| 		int tm_mday {0}; | ||||
| 		int tm_hour {0}; | ||||
| 		int tm_min {0}; | ||||
| 	}; | ||||
|  | ||||
| } // Components | ||||
|  | ||||
| static constexpr float lerp(float a, float b, float t) { | ||||
| @@ -324,7 +334,8 @@ float ChatGui4::render(float time_delta) { | ||||
| 						//tmp_view.use<Message::Components::Timestamp>(); | ||||
| 						//tmp_view.each([&](const Message3 e, Message::Components::ContactFrom& c_from, Message::Components::ContactTo& c_to, Message::Components::Timestamp ts | ||||
| 						//) { | ||||
| 						uint64_t prev_ts {0}; | ||||
| 						//uint64_t prev_ts {0}; | ||||
| 						Components::ConvertedTimeCache prev_time {}; | ||||
| 						auto tmp_view = msg_reg.view<Message::Components::Timestamp>(); | ||||
| 						for (auto view_it = tmp_view.rbegin(), view_last = tmp_view.rend(); view_it != view_last; view_it++) { | ||||
| 							const Message3 e = *view_it; | ||||
| @@ -342,15 +353,12 @@ float ChatGui4::render(float time_delta) { | ||||
| 							// TODO: why? | ||||
| 							ImGui::TableNextRow(0, TEXT_BASE_HEIGHT); | ||||
|  | ||||
| 							{ // check if date changed | ||||
| 								// TODO: find defined ways of casting to time_t | ||||
| 								std::time_t prev = prev_ts / 1000; | ||||
| 								std::time_t next = ts.ts / 1000; | ||||
| 								std::tm prev_tm = *std::localtime(&prev); | ||||
| 								std::tm next_tm = *std::localtime(&next); | ||||
| 							if (msg_reg.all_of<Components::ConvertedTimeCache>(e)) { // check if date changed | ||||
| 								// TODO: move conversion up? | ||||
| 								const auto& next_time = msg_reg.get<Components::ConvertedTimeCache>(e); | ||||
| 								if ( | ||||
| 									prev_tm.tm_yday != next_tm.tm_yday || | ||||
| 									prev_tm.tm_year != next_tm.tm_year // making sure | ||||
| 									prev_time.tm_yday != next_time.tm_yday || | ||||
| 									prev_time.tm_year != next_time.tm_year // making sure | ||||
| 								) { | ||||
| 									// name | ||||
| 									if (ImGui::TableNextColumn()) { | ||||
| @@ -359,14 +367,14 @@ float ChatGui4::render(float time_delta) { | ||||
| 									// msg | ||||
| 									if (ImGui::TableNextColumn()) { | ||||
| 										ImGui::TextDisabled("DATE CHANGED from %d.%d.%d to %d.%d.%d", | ||||
| 											1900+prev_tm.tm_year, 1+prev_tm.tm_mon, prev_tm.tm_mday, | ||||
| 											1900+next_tm.tm_year, 1+next_tm.tm_mon, next_tm.tm_mday | ||||
| 											1900+prev_time.tm_year, 1+prev_time.tm_mon, prev_time.tm_mday, | ||||
| 											1900+next_time.tm_year, 1+next_time.tm_mon, next_time.tm_mday | ||||
| 										); | ||||
| 									} | ||||
| 									ImGui::TableNextRow(0, TEXT_BASE_HEIGHT); | ||||
| 								} | ||||
|  | ||||
| 								prev_ts = ts.ts; | ||||
| 								prev_time = next_time; | ||||
| 							} | ||||
|  | ||||
|  | ||||
| @@ -519,12 +527,24 @@ float ChatGui4::render(float time_delta) { | ||||
|  | ||||
| 							// ts | ||||
| 							if (ImGui::TableNextColumn()) { | ||||
| 								if (!msg_reg.all_of<Components::ConvertedTimeCache>(e)) { | ||||
| 									auto time = std::chrono::system_clock::to_time_t( | ||||
| 										std::chrono::time_point<std::chrono::system_clock, std::chrono::milliseconds>{std::chrono::milliseconds{ts.ts}} | ||||
| 									); | ||||
| 									auto localtime = std::localtime(&time); | ||||
| 									msg_reg.emplace<Components::ConvertedTimeCache>( | ||||
| 										e, | ||||
| 										localtime->tm_year, | ||||
| 										localtime->tm_yday, | ||||
| 										localtime->tm_mon, | ||||
| 										localtime->tm_mday, | ||||
| 										localtime->tm_hour, | ||||
| 										localtime->tm_min | ||||
| 									); | ||||
| 								} | ||||
| 								const auto& ctc = msg_reg.get<Components::ConvertedTimeCache>(e); | ||||
|  | ||||
| 								ImGui::Text("%.2d:%.2d", localtime->tm_hour, localtime->tm_min); | ||||
| 								ImGui::Text("%.2d:%.2d", ctc.tm_hour, ctc.tm_min); | ||||
| 							} | ||||
|  | ||||
| 							// extra | ||||
|   | ||||
| @@ -1,5 +1,6 @@ | ||||
| #include "./image_loader_webp.hpp" | ||||
|  | ||||
| #include <memory> | ||||
| #include <webp/demux.h> | ||||
| #include <webp/mux.h> | ||||
| #include <webp/encode.h> | ||||
| @@ -21,13 +22,16 @@ ImageLoaderWebP::ImageInfo ImageLoaderWebP::loadInfoFromMemory(const uint8_t* da | ||||
| 	// Tune 'dec_options' as needed. | ||||
| 	dec_options.color_mode = MODE_RGBA; | ||||
|  | ||||
| 	WebPAnimDecoder* dec = WebPAnimDecoderNew(&webp_data, &dec_options); | ||||
| 	if (dec == nullptr) { | ||||
| 	std::unique_ptr<WebPAnimDecoder, decltype(&WebPAnimDecoderDelete)> dec{ | ||||
| 		WebPAnimDecoderNew(&webp_data, &dec_options), | ||||
| 		&WebPAnimDecoderDelete | ||||
| 	}; | ||||
| 	if (!static_cast<bool>(dec)) { | ||||
| 		return res; | ||||
| 	} | ||||
|  | ||||
| 	WebPAnimInfo anim_info; | ||||
| 	WebPAnimDecoderGetInfo(dec, &anim_info); | ||||
| 	WebPAnimDecoderGetInfo(dec.get(), &anim_info); | ||||
| 	res.width = anim_info.canvas_width; | ||||
| 	res.height = anim_info.canvas_height; | ||||
| 	res.file_ext = "webp"; | ||||
| @@ -48,22 +52,25 @@ ImageLoaderWebP::ImageResult ImageLoaderWebP::loadFromMemoryRGBA(const uint8_t* | ||||
| 	// Tune 'dec_options' as needed. | ||||
| 	dec_options.color_mode = MODE_RGBA; | ||||
|  | ||||
| 	WebPAnimDecoder* dec = WebPAnimDecoderNew(&webp_data, &dec_options); | ||||
| 	if (dec == nullptr) { | ||||
| 	std::unique_ptr<WebPAnimDecoder, decltype(&WebPAnimDecoderDelete)> dec{ | ||||
| 		WebPAnimDecoderNew(&webp_data, &dec_options), | ||||
| 		&WebPAnimDecoderDelete | ||||
| 	}; | ||||
| 	if (!static_cast<bool>(dec)) { | ||||
| 		return res; | ||||
| 	} | ||||
|  | ||||
| 	WebPAnimInfo anim_info; | ||||
| 	WebPAnimDecoderGetInfo(dec, &anim_info); | ||||
| 	WebPAnimDecoderGetInfo(dec.get(), &anim_info); | ||||
| 	res.width = anim_info.canvas_width; | ||||
| 	res.height = anim_info.canvas_height; | ||||
| 	res.file_ext = "webp"; | ||||
|  | ||||
| 	int prev_timestamp = 0; | ||||
| 	while (WebPAnimDecoderHasMoreFrames(dec)) { | ||||
| 	while (WebPAnimDecoderHasMoreFrames(dec.get())) { | ||||
| 		uint8_t* buf; | ||||
| 		int timestamp; | ||||
| 		WebPAnimDecoderGetNext(dec, &buf, ×tamp); | ||||
| 		WebPAnimDecoderGetNext(dec.get(), &buf, ×tamp); | ||||
| 		// ... (Render 'buf' based on 'timestamp'). | ||||
| 		// ... (Do NOT free 'buf', as it is owned by 'dec'). | ||||
|  | ||||
| @@ -74,8 +81,6 @@ ImageLoaderWebP::ImageResult ImageLoaderWebP::loadFromMemoryRGBA(const uint8_t* | ||||
| 		new_frame.data.insert(new_frame.data.end(), buf, buf+(res.width*res.height*4)); | ||||
| 	} | ||||
|  | ||||
| 	WebPAnimDecoderDelete(dec); | ||||
|  | ||||
| 	assert(anim_info.frame_count == res.frames.size()); | ||||
|  | ||||
| 	return res; | ||||
|   | ||||
| @@ -376,7 +376,7 @@ Screen* MainScreen::render(float time_delta, bool&) { | ||||
| } | ||||
|  | ||||
| Screen* MainScreen::tick(float time_delta, bool& quit) { | ||||
| 	quit = !tc.iterate(); // compute | ||||
| 	quit = !tc.iterate(time_delta); // compute | ||||
|  | ||||
| 	tcm.iterate(time_delta); // compute | ||||
|  | ||||
|   | ||||
| @@ -83,6 +83,7 @@ bool SendImagePopup::load(void) { | ||||
| 			} | ||||
| 		} | ||||
|  | ||||
| 		assert(preview_image.textures.empty()); | ||||
| 		preview_image.timestamp_last_rendered = Message::getTimeMS(); | ||||
| 		preview_image.current_texture = 0; | ||||
| 		for (const auto& [ms, data] : original_image.frames) { | ||||
| @@ -173,7 +174,7 @@ void SendImagePopup::render(float time_delta) { | ||||
|  | ||||
| 	// TODO: add cancel shortcut (esc) | ||||
| 	if (ImGui::BeginPopupModal("send image##SendImagePopup", nullptr/*, ImGuiWindowFlags_NoDecoration*/)) { | ||||
| 		const auto TEXT_BASE_WIDTH = ImGui::CalcTextSize("A").x; | ||||
| 		//const auto TEXT_BASE_WIDTH = ImGui::CalcTextSize("A").x; | ||||
| 		const auto TEXT_BASE_HEIGHT = ImGui::GetTextLineHeightWithSpacing(); | ||||
|  | ||||
| 		preview_image.doAnimation(Message::getTimeMS()); | ||||
|   | ||||
| @@ -1,5 +1,4 @@ | ||||
| #include "./tox_client.hpp" | ||||
| #include "toxcore/tox.h" | ||||
|  | ||||
| // meh, change this | ||||
| #include <exception> | ||||
| @@ -121,10 +120,13 @@ ToxClient::ToxClient(std::string_view save_path, std::string_view save_password) | ||||
| } | ||||
|  | ||||
| ToxClient::~ToxClient(void) { | ||||
| 	if (_tox_profile_dirty) { | ||||
| 		saveToxProfile(); | ||||
| 	} | ||||
| 	tox_kill(_tox); | ||||
| } | ||||
|  | ||||
| bool ToxClient::iterate(void) { | ||||
| bool ToxClient::iterate(float time_delta) { | ||||
| 	Tox_Err_Events_Iterate err_e_it = TOX_ERR_EVENTS_ITERATE_OK; | ||||
| 	auto* events = tox_events_iterate(_tox, false, &err_e_it); | ||||
| 	if (err_e_it == TOX_ERR_EVENTS_ITERATE_OK && events != nullptr) { | ||||
| @@ -136,7 +138,8 @@ bool ToxClient::iterate(void) { | ||||
|  | ||||
| 	tox_events_free(events); | ||||
|  | ||||
| 	if (_tox_profile_dirty) { | ||||
| 	_save_heat -= time_delta; | ||||
| 	if (_tox_profile_dirty && _save_heat <= 0.f) { | ||||
| 		saveToxProfile(); | ||||
| 	} | ||||
|  | ||||
| @@ -180,5 +183,6 @@ void ToxClient::saveToxProfile(void) { | ||||
| 	} | ||||
|  | ||||
| 	_tox_profile_dirty = false; | ||||
| 	_save_heat = 10.f; | ||||
| } | ||||
|  | ||||
|   | ||||
| @@ -22,6 +22,7 @@ class ToxClient : public ToxDefaultImpl, public ToxEventProviderBase { | ||||
| 		std::string _tox_profile_path; | ||||
| 		std::string _tox_profile_password; | ||||
| 		bool _tox_profile_dirty {true}; // set in callbacks | ||||
| 		float _save_heat {0.f}; | ||||
|  | ||||
| 	public: | ||||
| 		//ToxClient(/*const CommandLine& cl*/); | ||||
| @@ -34,7 +35,7 @@ class ToxClient : public ToxDefaultImpl, public ToxEventProviderBase { | ||||
| 		void setDirty(void) { _tox_profile_dirty = true; } | ||||
|  | ||||
| 		// returns false when we shoul stop the program | ||||
| 		bool iterate(void); | ||||
| 		bool iterate(float time_delta); | ||||
| 		void stop(void); // let it know it should exit | ||||
|  | ||||
| 		void setToxProfilePath(const std::string& new_path) { _tox_profile_path = new_path; } | ||||
|   | ||||
		Reference in New Issue
	
	Block a user