8#ifdef MAYAFLUX_PLATFORM_MACOS
9#include <CoreFoundation/CoreFoundation.h>
16 , m_current_mode(OperationMode::Direct)
17 , server_loop_rate(0.1F)
19 LILA_DEBUG(Emitter::SYSTEM,
"Lila instance created");
25 LILA_DEBUG(Emitter::SYSTEM,
"Lila instance destroyed");
30 LILA_INFO(Emitter::SYSTEM,
"Initializing Lila");
31 m_current_mode = mode;
33 if (!initialize_interpreter()) {
34 LILA_ERROR(Emitter::SYSTEM,
"Failed to initialize interpreter");
38 if (mode == OperationMode::Server || mode == OperationMode::Both) {
39 if (!initialize_server(server_port)) {
40 LILA_ERROR(Emitter::SYSTEM,
"Failed to initialize server");
45 LILA_INFO(Emitter::SYSTEM,
"Lila initialized successfully");
51 LILA_DEBUG(Emitter::SYSTEM,
"Initializing interpreter subsystem");
52 return m_interpreter->initialize();
57 if (m_server && m_server->is_running()) {
58 LILA_WARN(Emitter::SYSTEM,
"Stopping existing server before starting new one");
63 std::string(
"Initializing server on port ") + std::to_string(port));
65 m_server = std::make_unique<Server>(port);
67 m_server->set_message_handler([
this](std::string_view message) {
68 return this->handle_server_message(message);
71 return m_server->start();
76 if (message.empty()) {
77 return R
"({"status":"error","message":"Empty message"})";
80 auto result = m_interpreter->eval(std::string(message));
83 if (m_success_callback) {
89 if (m_error_callback) {
90 m_error_callback(result.error);
93 return std::unexpected(escape_json(result.error));
99 LILA_ERROR(Emitter::SYSTEM,
"Cannot eval: interpreter not initialized");
103 auto result = m_interpreter->eval(code);
105 if (result.success && m_success_callback) {
106 m_success_callback();
107 }
else if (!result.success && m_error_callback) {
108 m_error_callback(result.error);
111 return result.success;
116 if (!m_interpreter) {
117 LILA_ERROR(Emitter::SYSTEM,
"Cannot eval file: interpreter not initialized");
121 auto result = m_interpreter->eval_file(filepath);
122 return result.success;
128 std::string(
"Starting server on port ") + std::to_string(port));
130 initialize_server(port);
136 LILA_INFO(Emitter::SYSTEM,
"Stopping server");
144 return m_server && m_server->is_running();
149 return m_interpreter ? m_interpreter->get_symbol_address(name) :
nullptr;
154 return m_interpreter ? m_interpreter->get_defined_symbols() : std::vector<std::string> {};
160 m_interpreter->add_include_path(path);
167 m_interpreter->add_compile_flag(flag);
173 m_success_callback = std::move(callback);
174 LILA_DEBUG(Emitter::SYSTEM,
"Success callback registered");
179 m_error_callback = std::move(callback);
180 LILA_DEBUG(Emitter::SYSTEM,
"Error callback registered");
186 m_server->on_server_started(std::move(callback));
187 LILA_DEBUG(Emitter::SYSTEM,
"Server started callback registered");
194 m_server->on_client_connected(std::move(callback));
195 LILA_DEBUG(Emitter::SYSTEM,
"Client connected callback registered");
202 m_server->on_client_disconnected(std::move(callback));
203 LILA_DEBUG(Emitter::SYSTEM,
"Client disconnected callback registered");
209 return m_interpreter ? m_interpreter->get_last_error() :
"Interpreter not initialized";
214 return m_current_mode;
219 LILA_INFO(Emitter::SYSTEM,
"Entering main event loop");
221#ifdef MAYAFLUX_PLATFORM_MACOS
222 while (!m_shutdown_requested.load(std::memory_order_acquire) && (!external_flag || external_flag->load(std::memory_order_acquire))) {
223 if (!is_server_running()) {
224 LILA_ERROR(Emitter::SYSTEM,
"Server stopped unexpectedly");
227 CFRunLoopRunInMode(kCFRunLoopDefaultMode, server_loop_rate,
false);
230 while (!m_shutdown_requested.load(std::memory_order_acquire) && (!external_flag || external_flag->load(std::memory_order_acquire))) {
231 if (!is_server_running()) {
232 LILA_ERROR(Emitter::SYSTEM,
"Server stopped unexpectedly");
235 std::this_thread::sleep_for(std::chrono::milliseconds(
static_cast<int>(server_loop_rate * 1000)));
239 LILA_INFO(Emitter::SYSTEM,
"Exiting main event loop");
244 m_shutdown_requested.store(
true, std::memory_order_release);
246#ifdef MAYAFLUX_PLATFORM_MACOS
247 CFRunLoopStop(CFRunLoopGetMain());
254 escaped.reserve(str.size());
Embedded Clang interpreter for live code evaluation in MayaFlux.
std::vector< std::string > get_defined_symbols()
Gets a list of all defined symbols.
static std::string escape_json(const std::string &str)
Escapes a string for safe JSON encoding.
bool eval(const std::string &code)
Evaluates a C++ code snippet directly.
void on_error(std::function< void(const std::string &)> callback)
Registers a callback for code evaluation errors.
std::expected< std::string, std::string > handle_server_message(std::string_view message)
void stop_server()
Stops the TCP server and disconnects all clients.
OperationMode get_current_mode() const
Gets the current operation mode.
void * get_symbol_address(const std::string &name)
Gets the address of a symbol defined in the interpreter.
bool initialize_interpreter()
void on_server_client_disconnected(std::function< void(const ClientInfo &)> callback)
Registers a callback for client disconnections (server mode)
bool initialize_server(int port)
bool initialize(OperationMode mode=OperationMode::Direct, int server_port=9090) noexcept
Initializes the live coding environment.
void request_shutdown()
Request shutdown from any thread.
void on_server_client_connected(std::function< void(const ClientInfo &)> callback)
Registers a callback for new client connections (server mode)
void add_compile_flag(const std::string &flag)
Adds a compile flag for code evaluation.
void add_include_path(const std::string &path)
Adds an include path for code evaluation.
~Lila()
Destructor; cleans up interpreter and server resources.
void start_server(int port=9090)
Starts the TCP server for remote live coding.
bool eval_file(const std::string &filepath)
Evaluates a C++ code file directly.
std::string get_last_error() const
Gets the last error message.
bool is_server_running() const
Checks if the server is currently running.
void await_shutdown(const std::atomic< bool > *external_flag)
Blocks until server shutdown (main thread event loop)
Lila()
Constructs a Lila instance.
void on_success(std::function< void()> callback)
Registers a callback for successful code evaluation.
void on_server_started(std::function< void()> callback)
Registers a callback for server start events.
Information about a connected client.