diff --git a/Makefile b/Makefile new file mode 100644 index 0000000..7aa4ea1 --- /dev/null +++ b/Makefile @@ -0,0 +1,115 @@ +EXECUTABLE_NAME = joomer-efsw-bsz-monitoring +PLATFORM = $(shell uname) +BUILD_TYPE ?= release# Default to release build if not specified + +# Common paths +LIBEFSW_PATH = ../efsw + +OBJ_DIR = obj/$(PLATFORM)/$(BUILD_TYPE) +BIN_DIR = bin/$(PLATFORM)/$(BUILD_TYPE) +OUTPUT_FILE = $(BIN_DIR)/$(EXECUTABLE_NAME) + +# Platform-specific configuration +ifeq ($(PLATFORM), Darwin) + # macOS configuration + SDK_LIB_EXT = dylib + EFSW_LIB_NAME = libefsw.$(SDK_LIB_EXT) + MACOS_SDK_PATH = /Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX.sdk + + # Compiler settings + CC = clang + CXX = clang++ + + # Architecture flags + ARCH_FLAGS = -arch arm64 -mmacosx-version-min=11.0 -isysroot $(MACOS_SDK_PATH) + + # Linking flags - Use multiple rpath entries to look in executable directory + LINKER_FLAGS = $(ARCH_FLAGS) -framework Cocoa -framework IOKit -fvisibility=hidden -O5 \ + -rpath @executable_path \ + -rpath . + +else + # Linux configuration + SDK_LIB_EXT = so + EFSW_LIB_NAME = libefsw.$(SDK_LIB_EXT) + + # Compiler settings + CC = gcc + CXX = g++ + + # Architecture flags + ARCH_FLAGS = -m64 -D_FILE_OFFSET_BITS=64 + + # Linking flags + LINKER_FLAGS = $(ARCH_FLAGS) -fvisibility=hidden -O3 -Wl,-rpath,'$$ORIGIN' -Wl,-rpath,'$$ORIGIN/lib' -Wl,-rpath,'$$ORIGIN/../../../../bella_engine_sdk/lib' -Wl,-rpath,'$$ORIGIN/../../../../efsw/build' + + # Platform-specific libraries + #PLIST_LIB = -lplist +endif + + +# Common include and library paths +INCLUDE_PATHS = -I$(LIBEFSW_PATH)/include -I$(LIBEFSW_PATH)/src -I../bella_engine_sdk/src +EFSW_LIB_PATH = $(LIBEFSW_PATH)/build +BELLA_LIB_PATH = ../bella_engine_sdk/lib +# Library flags +LIB_PATHS = -L$(EFSW_LIB_PATH) -L$(BELLA_LIB_PATH) +LIBRARIES = -lm -ldl -lefsw -lbella_engine_sdk + +# Build type specific flags +ifeq ($(BUILD_TYPE), debug) + CPP_DEFINES = -D_DEBUG -DDL_USE_SHARED + COMMON_FLAGS = $(ARCH_FLAGS) -fvisibility=hidden -g -O0 $(INCLUDE_PATHS) +else + CPP_DEFINES = -DNDEBUG=1 -DDL_USE_SHARED + COMMON_FLAGS = $(ARCH_FLAGS) -fvisibility=hidden -O3 $(INCLUDE_PATHS) +endif + +# Language-specific flags +C_FLAGS = $(COMMON_FLAGS) -std=c17 +CXX_FLAGS = $(COMMON_FLAGS) -std=c++17 -Wno-deprecated-declarations + +# Objects +OBJECTS = $(EXECUTABLE_NAME).o +OBJECT_FILES = $(patsubst %,$(OBJ_DIR)/%,$(OBJECTS)) + +# Build rules +$(OBJ_DIR)/$(EXECUTABLE_NAME).o: $(EXECUTABLE_NAME).cpp + @mkdir -p $(@D) + $(CXX) -c -o $@ $< $(CXX_FLAGS) $(CPP_DEFINES) + +$(OUTPUT_FILE): $(OBJECT_FILES) + @mkdir -p $(@D) + $(CXX) -o $@ $(OBJECT_FILES) $(LINKER_FLAGS) $(LIB_PATHS) $(LIBRARIES) + @echo "Copying libraries to $(BIN_DIR)..." + @cp $(EFSW_LIB_PATH)/$(EFSW_LIB_NAME) $(BIN_DIR)/$(EFSW_LIB_NAME) + @echo "Build complete: $(OUTPUT_FILE)" + +# Add default target +all: $(OUTPUT_FILE) + +.PHONY: clean cleanall all +clean: + rm -f $(OBJ_DIR)/$(EXECUTABLE_NAME).o + rm -f $(OUTPUT_FILE) + rm -f $(BIN_DIR)/*.dylib + rmdir $(OBJ_DIR) 2>/dev/null || true + rmdir $(BIN_DIR) 2>/dev/null || true + +cleanall: + rm -f obj/*/release/*.o + rm -f obj/*/debug/*.o + rm -f bin/*/release/$(EXECUTABLE_NAME) + rm -f bin/*/debug/$(EXECUTABLE_NAME) + rm -f bin/*/release/$(SDK_LIB_FILE) + rm -f bin/*/debug/$(SDK_LIB_FILE) + rm -f bin/*/release/*.dylib + rm -f bin/*/debug/*.dylib + rmdir obj/*/release 2>/dev/null || true + rmdir obj/*/debug 2>/dev/null || true + rmdir bin/*/release 2>/dev/null || true + rmdir bin/*/debug 2>/dev/null || true + rmdir obj/* 2>/dev/null || true + rmdir bin/* 2>/dev/null || true + rmdir obj 2>/dev/null || true + rmdir bin 2>/dev/null || true diff --git a/joomer-efsw-bsz-monitoring.cpp b/joomer-efsw-bsz-monitoring.cpp index 98441ae..7e4e4c6 100644 --- a/joomer-efsw-bsz-monitoring.cpp +++ b/joomer-efsw-bsz-monitoring.cpp @@ -31,8 +31,9 @@ int height = 600; void flip_image_vertically(unsigned char* data, int width, int height, int channels); -void sigend( int ) { - std::cout << std::endl << "close file monitoring" << std::endl; +void sigend( int sig) { + std::cout << std::endl << ">>> SIGNAL RECEIVED: " << sig << " - close file monitoring" << std::endl; +// std::cout << std::endl << "close file monitoring" << std::endl; STOP = true; } @@ -184,6 +185,10 @@ void do_sync_render(std::string fileToRender) // Get the global settings node instead of the beautyPass node dl::bella_sdk::Node settings = engine.scene().settings(); dl::bella_sdk::Node cam = settings["camera"].asNode(); + + //settings["maxSubdivLevel"] = dl::bella_sdk::Value(40); + //settings["threads"] = dl::bella_sdk::Value(2); // Caps Bella to 2 cores, leaving 2 free for the OS/Proxmox! + auto inputs = settings.inputs(); // This gets all valid attribute names for (const auto& input : inputs) { std::cout << "Valid attribute: " << input.name() << std::endl; @@ -211,14 +216,22 @@ void do_sync_render(std::string fileToRender) bPass["overridePath"] = pathNode; - + //bPass["timeLimit"] = 30.0f; std::cout << ">>> STARTING BELLA ENGINE..." << std::endl; engine.start(); - // 3. Monitor progress + // 3. Monitor progress with a strict 15 second C++ safety valve + int elapsed_ms = 0; while (engine.rendering()) { std::this_thread::sleep_for(std::chrono::milliseconds(500)); std::cout << "rendering..." << std::endl; + + elapsed_ms += 500; + if (elapsed_ms >= 15000) { // 15,000 milliseconds = 15 seconds + std::cout << ">>> SAFETY VALVE TRIGGERED: Hard stopping engine!" << std::endl; + engine.stop(); // Cleanly forces the render context to drop out + break; + } } std::this_thread::sleep_for(std::chrono::milliseconds(1000)); // Give Windows time to finish the file write @@ -251,14 +264,23 @@ void render_thread(dl::bella_sdk::Engine& engine, MyEngineObserver& engineObserv dl::bella_sdk::Node bPass = engine.scene().beautyPass(); bPass["overridePath"] = pathNode; + bPass["timeLimit"] = 30.0f; std::cout << ">>> STARTING BELLA ENGINE..." << std::endl; engine.start(); // 3. Monitor progress + int elapsed_ms = 0; while (engine.rendering()) { std::this_thread::sleep_for(std::chrono::milliseconds(500)); std::cout << "rendering..." << std::endl; + + elapsed_ms += 500; + if (elapsed_ms >= 15000) { // 15,000 milliseconds = 15 seconds + std::cout << ">>> SAFETY VALVE TRIGGERED: Hard stopping engine!" << std::endl; + engine.stop(); // Cleanly forces the render context to drop out + break; + } } std::this_thread::sleep_for(std::chrono::milliseconds(1000)); // Give Windows time to finish the file write @@ -289,7 +311,7 @@ class UpdateListener : public efsw::FileWatchListener { void handleFileAction( efsw::WatchID watchid, const std::string& dir, const std::string& filename, efsw::Action action, - std::string oldFilename = "" ) override { + const std::string& oldFilename = "") override { std::cout << "Watch ID " << watchid << " DIR (" << dir + ") FILE (" + ( oldFilename.empty() ? "" : "from file " + oldFilename + " to " ) + @@ -297,6 +319,10 @@ class UpdateListener : public efsw::FileWatchListener { << getActionName( action ) << std::endl; if (action == efsw::Actions::Add || action == efsw::Actions::Modified) { + // if already rendering a file + if (pendingRender) { + return; + } directory_path = dir; std::string fullPath = dir + filename; int width, height, channels;