first working file watching with efsw, oome namespace overhaul

This commit is contained in:
Harvey Fong 2025-04-14 22:23:55 -06:00
parent ac206809e8
commit e5c7906d35
6 changed files with 682 additions and 58 deletions

View File

@ -7,11 +7,11 @@
namespace oom {
namespace bella {
// Function declaration
dl::bella_sdk::Node essentialsToScene(dl::bella_sdk::Scene& belScene);
dl::bella_sdk::Node defaultScene2025(dl::bella_sdk::Scene& belScene);
// @param belScene - the scene to create the essentials in
// @return - the world node
dl::bella_sdk::Node essentialsToScene(dl::bella_sdk::Scene& belScene) {
dl::bella_sdk::Node defaultScene2025(dl::bella_sdk::Scene& belScene) {
// Create the basic scene elements in Bella
// Each line creates a different type of node in the scene auto belBeautyPass = belScene.createNode("beautyPass","oomerBeautyPass","oomerBeautyPass");
auto belWorld = belScene.world(); // Get scene world root

View File

@ -1,12 +1,10 @@
#pragma once
// Bella SDK includes - external libraries for 3D rendering
#include "../bella_scene_sdk/src/bella_sdk/bella_scene.h" // For creating and manipulating 3D scenes in Bella
//#include "../bella_scene_sdk/src/dl_core/dl_main.inl" // Core functionality from the Diffuse Logic engine
// Now define the oomer namespace with using declarations for all functions/classes
namespace oom {
namespace bella {
// Unit mesh cube created in Blender, with rounded edges
// Used for emitter voxels because procedural Bella box does not currently support emission
void addMeshCube(dl::bella_sdk::Node& belMeshVoxel) {
belMeshVoxel["name"] = "oomerMeshVoxel";
belMeshVoxel["channels"][0] = "st";

View File

@ -1,18 +1,14 @@
#pragma once
// Bella SDK includes - external libraries for 3D rendering
#include "../bella_scene_sdk/src/bella_sdk/bella_scene.h" // For creating and manipulating 3D scenes in Bella
//#include "../bella_scene_sdk/src/dl_core/dl_main.inl" // Core functionality from the Diffuse Logic engine
// Define the oom namespace
namespace oom {
namespace bella {
// Function declaration
dl::bella_sdk::Node essentialsToScene(dl::bella_sdk::Scene& belScene);
dl::bella_sdk::Node defaultScene2025(dl::bella_sdk::Scene& belScene);
// @param belScene - the scene to create the essentials in
// @return - the world node
dl::bella_sdk::Node essentialsToScene(dl::bella_sdk::Scene& belScene) {
dl::bella_sdk::Node defaultScene2025(dl::bella_sdk::Scene& belScene) {
// Create the basic scene elements in Bella
// Each line creates a different type of node in the scene auto belBeautyPass = belScene.createNode("beautyPass","oomerBeautyPass","oomerBeautyPass");
auto belWorld = belScene.world(); // Get scene world root
@ -30,15 +26,15 @@ namespace oom {
auto belGroundMat = belScene.createNode("quickMaterial","oomerGroundMat","oomerGroundMat");
auto belSun = belScene.createNode("sun","oomerSun","oomerSun");
auto belColorDome = belScene.createNode("colorDome","oomerColorDome","oomerColorDome");
auto belSettings = belScene.settings(); // Get scene settings
// Configure camera
belCam["resolution"] = dl::Vec2 {1920, 1080}; // Set resolution to 1080p
belCam["lens"] = belLens; // Connect camera to lens
belCam["sensor"] = belSensor; // Connect camera to sensor
belCamForm.parentTo(belWorld); // Parent camera transform to world
belCam.parentTo(belCamForm); // Parent camera to camera transform
// Position the camera with a transformation matrix
belCamForm["steps"][0]["xform"] = dl::Mat4 {0.525768608156, -0.850627633385, 0, 0, -0.234464751651, -0.144921468924, -0.961261695938, 0, 0.817675761479, 0.505401223947, -0.275637355817, 0, -88.12259018466, -54.468125200218, 50.706001690932, 1};
// Configure environment (image-based lighting)
@ -50,14 +46,9 @@ namespace oom {
belColorDome["zenith"] = dl::Rgba{1.0f, 1.0f, 1.0f, 1.0f};
belColorDome["horizon"] = dl::Rgba{.85f, 0.76f, 0.294f, 1.0f};
belColorDome["altitude"] = 14.0f;
// Configure ground plane
//belGroundPlane["elevation"] = -.5f;
belGroundPlane["material"] = belGroundMat;
/* Commented out: Sun configuration
belSun["size"] = 20.0f;
belSun["month"] = "july";
belSun["rotation"] = 50.0f;*/
// Configure ground plane
belGroundPlane["material"] = belGroundMat;
// Configure materials
belGroundMat["type"] = "metal";
@ -72,7 +63,6 @@ namespace oom {
belSettings["threads"] = dl::bella_sdk::Input(0); // Auto-detect thread count
belSettings["groundPlane"] = belGroundPlane;
belSettings["iprNavigation"]= "maya"; // Use Maya-like navigation in viewer
//settings["sun"] = sun;
auto belVoxel = belScene.createNode("box","oomerVoxel","oomerVoxel");
auto belLiqVoxel = belScene.createNode("box","oomerLiqVoxel","oomerLiqVoxel");
@ -84,7 +74,7 @@ namespace oom {
belBevel["radius"] = 90.0f;
belBevel["samples"] =dl::UInt(6);
oom::bella::addMeshCube(belMeshVoxel);
oom::bella::addMeshCube(belMeshVoxel); // bring in a blender mesh cube for emitters
// Configure voxel box dimensions
belVoxel["radius"] = 0.33f;
belVoxel["sizeX"] = 0.99f;

551
oom_file.h Normal file
View File

@ -0,0 +1,551 @@
#pragma once
#include <iostream>
#include <fstream>
#include <thread>
#include <vector>
#include <chrono>
#include <filesystem>
#include <string>
#include <atomic>
#include <mutex> // Add this line for std::mutex and std::lock_guard
#include <map> // Add this line for std::map
#include "../efsw/src/efsw/FileSystem.hpp" // For file watching
#include "../efsw/src/efsw/System.hpp" // For file watching
#include "../efsw/include/efsw/efsw.hpp" // For file watching
//==============================================================================
// OOM NAMESPACE - Contains core file watching functionality
//==============================================================================
namespace oom {
namespace file {
//--------------------------------------------------------------------------
// RenderQueue Class
//--------------------------------------------------------------------------
/**
* A thread-safe FIFO queue that tracks render files
*
* This class implements a specialized queue that maintains both:
* 1. FIFO (First-In-First-Out) ordering via a vector
* 2. Fast lookup capability via a map
*
* It's designed to be safely used across multiple threads
*/
class Queue {
public:
// Default constructor - Creates an empty queue
Queue() = default;
// Move constructor - Transfers ownership of resources from another queue
Queue(Queue&& other) noexcept {
// Lock the other queue to prevent concurrent modification during the move
std::lock_guard<std::mutex> lock(other.mutex);
// Transfer ownership of the data structures using std::move
pathVector = std::move(other.pathVector);
pathMap = std::move(other.pathMap);
}
// Move assignment operator - Similar to move constructor but for assignment operations
Queue& operator=(Queue&& other) noexcept {
// Avoid self-assignment (moving to itself)
if (this != &other) {
// Lock both queues to prevent concurrent modification
std::lock_guard<std::mutex> lock1(mutex);
std::lock_guard<std::mutex> lock2(other.mutex);
// Transfer ownership of the data structures
pathVector = std::move(other.pathVector);
pathMap = std::move(other.pathMap);
}
return *this;
}
// Delete copy operations since mutexes can't be copied
Queue(const Queue&) = delete;
Queue& operator=(const Queue&) = delete;
// Add a file to the queue if it's not already there
bool push(const std::filesystem::path& path) {
// Lock the queue during modification to ensure thread safety
std::lock_guard<std::mutex> lock(mutex);
// Check if the path already exists in our map (fast lookup)
if (pathMap.find(path) == pathMap.end()) {
// If not found, add to the vector (maintains order)
pathVector.push_back(path);
// Mark as present in the map for fast future lookups
pathMap[path] = true;
return true;
}
return false;
}
// Get the next file to render (FIFO order) and remove it from the queue
bool pop(std::filesystem::path& outPath) {
// Lock the queue during access to ensure thread safety
std::lock_guard<std::mutex> lock(mutex);
if (!pathVector.empty()) {
// Get the first item (oldest) from the vector
outPath = pathVector.front();
// Remove it from the vector
pathVector.erase(pathVector.begin());
// Remove it from the map as well
pathMap.erase(outPath);
return true;
}
return false;
}
// Remove a specific file by name
bool remove(const std::filesystem::path& path) {
// Lock the queue during modification to ensure thread safety
std::lock_guard<std::mutex> lock(mutex);
if (pathMap.find(path) != pathMap.end()) {
// Remove from vector using erase-remove idiom
pathVector.erase(
std::remove(pathVector.begin(), pathVector.end(), path),
pathVector.end()
);
// Remove from map
pathMap.erase(path);
return true;
}
return false;
}
// Check if a file exists in the queue
bool contains(const std::filesystem::path& path) const {
// Lock the queue during access to ensure thread safety
std::lock_guard<std::mutex> lock(mutex);
// Use the map for fast lookup
return pathMap.find(path) != pathMap.end();
}
// Get the number of files in the queue
size_t size() const {
// Lock the queue during access to ensure thread safety
std::lock_guard<std::mutex> lock(mutex);
return pathVector.size();
}
// Check if the queue is empty
bool empty() const {
// Lock the queue during access to ensure thread safety
std::lock_guard<std::mutex> lock(mutex);
return pathVector.empty();
}
// Clear all files from the queue
void clear() {
// Lock the queue during modification to ensure thread safety
std::lock_guard<std::mutex> lock(mutex);
// Clear both data structures
pathVector.clear();
pathMap.clear();
}
private:
std::vector<std::filesystem::path> pathVector; // Stores paths in order (FIFO queue)
std::map<std::filesystem::path, bool> pathMap; // Maps paths to bool for fast existence checks
mutable std::mutex mutex; // Makes operations thread-safe; mutable allows locking in const methods
};
// Forward declaration needed for UpdateListener
class Watcher;
//--------------------------------------------------------------------------
// UpdateListener Class
//--------------------------------------------------------------------------
/**
* Processes file system events from efsw and filters them
*
* This class receives notifications from the file system watcher (efsw)
* when files are created, modified or deleted, and then filters these
* events based on file extensions and directories.
*/
class UpdateListener : public efsw::FileWatchListener {
public:
// Constructor takes a pointer to its parent Watcher
UpdateListener(Watcher* parent);
// Signals the listener to stop processing events
void stop();
// Converts efsw action codes to human-readable strings
std::string getActionName(efsw::Action action);
// Check if a file extension is in our watch list
bool isWatchedExtension(const std::string& extension);
// Check if a directory should be ignored
bool isIgnoredDirectory(const std::string& directory);
// Main callback that efsw calls when file system events occur
void handleFileAction(efsw::WatchID watchid,
const std::string& dir,
const std::string& filename,
efsw::Action action,
std::string oldFilename = "") override;
private:
std::atomic<bool> should_stop_{false}; // Flag to signal stopping
Watcher* parentWatcher; // Reference to parent Watcher
};
//--------------------------------------------------------------------------
// Watcher Class
//--------------------------------------------------------------------------
/**
* Manages file watching and file queues
*
* This class coordinates the file system watching functionality
* and maintains queues of files to be rendered or deleted.
*/
class Watcher {
public:
// Constructor with configurable extensions and ignored directories
Watcher(const std::vector<std::string>& extensions = {".bsz", ".zip"},
const std::vector<std::string>& ignoreDirs = {"download"});
// Destructor to clean up resources
~Watcher();
// Prevent copying or moving to simplify handling
Watcher(const Watcher&) = delete;
Watcher& operator=(const Watcher&) = delete;
Watcher(Watcher&&) = delete;
Watcher& operator=(Watcher&&) = delete;
// Start watching a directory
bool startWatching(const std::string& directory);
// Stop watching
void stopWatching();
// Get the next file to render
bool getNextFileToRender(std::filesystem::path& outPath);
// Get the next file to delete
bool getNextFileToDelete(std::filesystem::path& outPath);
// Check if there are files to render
bool hasFilesToRender() const;
// Check if there are files to delete
bool hasFilesToDelete() const;
// Add or remove extensions dynamically
void addExtension(const std::string& extension);
void removeExtension(const std::string& extension);
// Add or remove ignored directories
void addIgnoreDirectory(const std::string& directory);
void removeIgnoreDirectory(const std::string& directory);
// Get extensions and ignored directories (for UpdateListener)
const std::vector<std::string>& getWatchExtensions() const { return watchExtensions; }
const std::vector<std::string>& getIgnoreDirectories() const { return ignoreDirectories; }
// Access to queues (for UpdateListener)
void addToRenderQueue(const std::filesystem::path& path);
void addToDeleteQueue(const std::filesystem::path& path);
private:
// File extensions to monitor (without leading dot)
std::vector<std::string> watchExtensions;
// Directory names to ignore
std::vector<std::string> ignoreDirectories;
// Queues for the different file actions
Queue incomingRenderQueue;
Queue incomingDeleteQueue;
// Mutexes for thread safety
mutable std::mutex renderQueueMutex;
mutable std::mutex deleteQueueMutex;
mutable std::mutex extensionsMutex;
mutable std::mutex directoriesMutex;
// File watcher components
std::unique_ptr<efsw::FileWatcher> fileWatcher;
std::unique_ptr<UpdateListener> updateListener;
// Watch state
bool isWatching;
std::atomic<bool> stopRequested;
std::thread watcherThread;
// Path being watched
std::string watchPath;
// Internal function to run the watcher in a separate thread
void watcherThreadFunc();
};
//--------------------------------------------------------------------------
// Global variable within oom namespace
//--------------------------------------------------------------------------
std::atomic<bool> active_render(false);
//==========================================================================
// IMPLEMENTATION SECTION - Method implementations for the above classes
//==========================================================================
//--------------------------------------------------------------------------
// UpdateListener implementation
//--------------------------------------------------------------------------
UpdateListener::UpdateListener(Watcher* parent)
: should_stop_(false), parentWatcher(parent) {}
void UpdateListener::stop() {
should_stop_ = true;
}
std::string UpdateListener::getActionName(efsw::Action action) {
switch (action) {
case efsw::Actions::Add:
return "Add";
case efsw::Actions::Modified:
return "Modified";
case efsw::Actions::Delete:
return "Delete";
case efsw::Actions::Moved:
return "Moved";
default:
return "Bad Action";
}
}
bool UpdateListener::isWatchedExtension(const std::string& extension) {
// Get the extensions list from parent
const auto& extensions = parentWatcher->getWatchExtensions();
// Check if the extension is in our watch list
return std::find(extensions.begin(), extensions.end(), extension) != extensions.end();
}
bool UpdateListener::isIgnoredDirectory(const std::string& directory) {
// Get the ignored directories list from parent
const auto& ignoreDirs = parentWatcher->getIgnoreDirectories();
// Check if the directory is in our ignore list
return std::find(ignoreDirs.begin(), ignoreDirs.end(), directory) != ignoreDirs.end();
}
void UpdateListener::handleFileAction(efsw::WatchID watchid,
const std::string& dir,
const std::string& filename,
efsw::Action action,
std::string oldFilename) {
if (should_stop_) return; // Early exit if we're stopping
std::string actionName = getActionName(action);
std::filesystem::path filePath = dir + filename;
std::filesystem::path parentPath = dir;
// Get the filename extension without the dot
std::string extension = filePath.extension().string();
if (!extension.empty() && extension[0] == '.') {
extension = extension.substr(1);
}
// Get the parent directory name
std::string parentDir = parentPath.filename().string();
// Check if we should ignore this directory
if (isIgnoredDirectory(parentDir)) {
return;
}
// Process based on the action type
if (actionName == "Delete") {
if (isWatchedExtension(extension)) {
parentWatcher->addToDeleteQueue(filePath);
std::cout << "\n==" << "STOP RENDER: " << filePath.string() << "\n==" << std::endl;
}
} else if (actionName == "Add" || actionName == "Modified") {
if (should_stop_) return; // Check again before starting render
if (isWatchedExtension(extension)) {
parentWatcher->addToRenderQueue(filePath);
std::cout << "\n==" << "RENDER QUEUED: " << filePath.string() << "\n==" << std::endl;
}
}
}
//--------------------------------------------------------------------------
// Watcher implementation
//--------------------------------------------------------------------------
Watcher::Watcher(const std::vector<std::string>& extensions,
const std::vector<std::string>& ignoreDirs)
: isWatching(false), stopRequested(false) {
// Process extensions to ensure they don't have leading dots
for (const auto& ext : extensions) {
std::string processedExt = ext;
if (!ext.empty() && ext[0] == '.') {
processedExt = ext.substr(1);
}
watchExtensions.push_back(processedExt);
}
// Store ignored directories
ignoreDirectories = ignoreDirs;
}
Watcher::~Watcher() {
stopWatching();
}
bool Watcher::startWatching(const std::string& directory) {
if (isWatching) {
stopWatching();
}
watchPath = directory;
stopRequested = false;
// Start the watcher thread
watcherThread = std::thread(&Watcher::watcherThreadFunc, this);
isWatching = true;
return true;
}
void Watcher::stopWatching() {
if (!isWatching) return;
stopRequested = true;
if (updateListener) {
updateListener->stop();
}
if (watcherThread.joinable()) {
watcherThread.join();
}
isWatching = false;
}
bool Watcher::getNextFileToRender(std::filesystem::path& outPath) {
std::lock_guard<std::mutex> lock(renderQueueMutex);
return incomingRenderQueue.pop(outPath);
}
bool Watcher::getNextFileToDelete(std::filesystem::path& outPath) {
std::lock_guard<std::mutex> lock(deleteQueueMutex);
return incomingDeleteQueue.pop(outPath);
}
bool Watcher::hasFilesToRender() const {
std::lock_guard<std::mutex> lock(renderQueueMutex);
return !incomingRenderQueue.empty();
}
bool Watcher::hasFilesToDelete() const {
std::lock_guard<std::mutex> lock(deleteQueueMutex);
return !incomingDeleteQueue.empty();
}
void Watcher::addExtension(const std::string& extension) {
std::lock_guard<std::mutex> lock(extensionsMutex);
std::string processedExt = extension;
if (!extension.empty() && extension[0] == '.') {
processedExt = extension.substr(1);
}
// Check if it already exists
if (std::find(watchExtensions.begin(), watchExtensions.end(), processedExt) == watchExtensions.end()) {
watchExtensions.push_back(processedExt);
}
}
void Watcher::removeExtension(const std::string& extension) {
std::lock_guard<std::mutex> lock(extensionsMutex);
std::string processedExt = extension;
if (!extension.empty() && extension[0] == '.') {
processedExt = extension.substr(1);
}
auto it = std::find(watchExtensions.begin(), watchExtensions.end(), processedExt);
if (it != watchExtensions.end()) {
watchExtensions.erase(it);
}
}
void Watcher::addIgnoreDirectory(const std::string& directory) {
std::lock_guard<std::mutex> lock(directoriesMutex);
// Check if it already exists
if (std::find(ignoreDirectories.begin(), ignoreDirectories.end(), directory) == ignoreDirectories.end()) {
ignoreDirectories.push_back(directory);
}
}
void Watcher::removeIgnoreDirectory(const std::string& directory) {
std::lock_guard<std::mutex> lock(directoriesMutex);
auto it = std::find(ignoreDirectories.begin(), ignoreDirectories.end(), directory);
if (it != ignoreDirectories.end()) {
ignoreDirectories.erase(it);
}
}
void Watcher::addToRenderQueue(const std::filesystem::path& path) {
std::lock_guard<std::mutex> lock(renderQueueMutex);
if (!incomingRenderQueue.contains(path)) {
incomingRenderQueue.push(path);
}
}
void Watcher::addToDeleteQueue(const std::filesystem::path& path) {
std::lock_guard<std::mutex> lock(deleteQueueMutex);
if (!incomingDeleteQueue.contains(path)) {
incomingDeleteQueue.push(path);
}
}
void Watcher::watcherThreadFunc() {
// Create a new FileWatcher
fileWatcher = std::make_unique<efsw::FileWatcher>(false);
// Create a new UpdateListener
updateListener = std::make_unique<UpdateListener>(this);
// Configure the watcher
fileWatcher->followSymlinks(false);
fileWatcher->allowOutOfScopeLinks(false);
// Check if the directory exists
if (!watchPath.empty() && std::filesystem::exists(watchPath)) {
// Add the directory to watch
efsw::WatchID watchID = fileWatcher->addWatch(watchPath, updateListener.get(), true);
if (watchID > 0) {
// Start watching
fileWatcher->watch();
std::cout << "Watching directory: " << watchPath << std::endl;
// Run until stopped
while (!stopRequested) {
efsw::System::sleep(500);
}
} else {
std::cout << "Error trying to watch directory: " << watchPath << std::endl;
std::cout << efsw::Errors::Log::getLastErrorLog().c_str() << std::endl;
}
} else {
std::cout << "Error: Directory does not exist: " << watchPath << std::endl;
}
}
} // namespace file
} // namespace oom

View File

@ -86,5 +86,106 @@ https://github.com/libimobiledevice/libplist
This software uses libraries from the libplist project under the LGPL version 2.1.)";
}
inline std::string printDayEnvironmentHDRI019_1K_TONEMAPPED() { return R"(
DayEnvironmentHDRI019_1K-TONEMAPPED.jpg from ambientCG.com,
licensed under the Creative Commons CC0 1.0 Universal License.)";
}
inline std::string printJson() { return R"(
// __ _____ _____ _____
// __| | __| | | | JSON for Modern C++
// | | |__ | | | | | | version 3.11.3
// |_____|_____|_____|_|___| https://github.com/nlohmann/json
//
// SPDX-FileCopyrightText: 2013-2023 Niels Lohmann <https://nlohmann.me>
// SPDX-License-Identifier: MIT)";
}
inline std::string printSTBImage() { return R"(
STB Image
https://github.com/nothings/stb
License: Public Domain)";
}
inline std::string printLibSodium() { return R"(
libsodium
ISC License
Copyright (c) 2013-2025
Frank Denis <j at pureftpd dot org>
Permission to use, copy, modify, and/or distribute this software for any
purpose with or without fee is hereby granted, provided that the above
copyright notice and this permission notice appear in all copies.
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.)";
}
inline std::string printCppZMQ() { return R"(
cppZMQ
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to
deal in the Software without restriction, including without limitation the
rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
sell copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
IN THE SOFTWARE.)";
}
inline std::string printLibZMQ() { return R"(
libzmq
https://github.com/zeromq/libzmq
libzmq is free software; you can redistribute it and/or modify it under the terms of the Mozilla Public License Version 2.0.)";
}
inline std::string printEFSW() { return R"(
efsw
Copyright (c) 2020 Martín Lucas Golini
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
This software is a fork of the "simplefilewatcher" by James Wynn (james@jameswynn.com)
http://code.google.com/p/simplefilewatcher/ also MIT licensed.)";
}
}
}

View File

@ -3,17 +3,8 @@
#include <iostream>
#include <fstream> // For std::ofstream
#include <filesystem> // For std::filesystem
//#include "DayEnvironmentHDRI019_1K-TONEMAPPED.h" // embedded image dome light
#include <cmath> // For std::pow
/*extern const unsigned int DayEnvironmentHDRI019_1K_TONEMAPPED_jpg_len;
extern const unsigned char DayEnvironmentHDRI019_1K_TONEMAPPED_jpg[];
inline float srgbToLinear(float value);
inline std::vector<uint8_t> LZFSEToArray(const std::string& lzfseFullName);
inline std::vector<uint8_t> decompressLZFSE(const std::string& dirName, const std::string& compressedName);
inline void saveHDRI();
*/
namespace oom {
namespace misc {
//Forward declarations
@ -93,13 +84,6 @@ namespace oom {
}
}
inline std::string printDayEnvironmentHDRI019_1K_TONEMAPPEDLicence() {
return R"(
DayEnvironmentHDRI019_1K-TONEMAPPED.jpg from ambientCG.com,
licensed under the Creative Commons CC0 1.0 Universal License.)";
}
const unsigned char DayEnvironmentHDRI019_1K_TONEMAPPED_jpg[] = {
0xff, 0xd8, 0xff, 0xe0, 0x00, 0x10, 0x4a, 0x46, 0x49, 0x46, 0x00, 0x01,
0x01, 0x00, 0x00, 0x48, 0x00, 0x48, 0x00, 0x00, 0xff, 0xe1, 0x00, 0x4c,