Ember
Loading...
Searching...
No Matches
BehaviorTreeConfig.cpp
Go to the documentation of this file.
2#include "Utils/Logger.h"
3#include <algorithm>
4#include <wx/file.h>
5#include <wx/fileconf.h>
6#include <wx/filename.h>
7
8namespace EmberCore {
9
11 // Initialize with default values (already set in header)
13}
14
16 LOG_INFO("Config", "Resetting configuration to defaults");
17
18 // Reset sync settings
20
21 // Reset visual settings
23
24 // Reset interaction settings
26
27 // Reset debug settings
29
31 NotifyChange("all", "reset_to_defaults");
32}
33
35 LOG_INFO("Config", "Loading configuration from: " + filename);
36
37 if (!wxFile::Exists(filename)) {
38 LOG_WARNING("Config", "Configuration file does not exist: " + filename);
39 return false;
40 }
41
42 try {
43 wxFileConfig config(filename);
44
45 // Load sync settings
46 config.SetPath("/Sync");
47 syncSettings_.enableHierarchyToScene = config.ReadBool("EnableHierarchyToScene", true);
48 syncSettings_.enableSceneToHierarchy = config.ReadBool("EnableSceneToHierarchy", true);
49 syncSettings_.enableAutoCenter = config.ReadBool("EnableAutoCenter", true);
50 syncSettings_.enableSelectionHighlight = config.ReadBool("EnableSelectionHighlight", true);
51 syncSettings_.enableHoverEffects = config.ReadBool("EnableHoverEffects", true);
52 syncSettings_.centerWithAnimation = config.ReadBool("CenterWithAnimation", false);
53 syncSettings_.centeringSpeed = config.ReadDouble("CenteringSpeed", 1.0);
54 syncSettings_.preventSyncLoops = config.ReadBool("PreventSyncLoops", true);
55
56 // Load visual settings
57 config.SetPath("/Visual");
58 visualSettings_.selectionBorderWidth = config.ReadLong("SelectionBorderWidth", 3);
59 visualSettings_.hoverBorderWidth = config.ReadLong("HoverBorderWidth", 2);
60 visualSettings_.highlightOpacity = config.ReadDouble("HighlightOpacity", 1.0);
61 visualSettings_.enableAnimations = config.ReadBool("EnableAnimations", true);
62 visualSettings_.animationDuration = config.ReadLong("AnimationDuration", 200);
63
64 // Load interaction settings
65 config.SetPath("/Interaction");
66 interactionSettings_.enableDoubleClickExpand = config.ReadBool("EnableDoubleClickExpand", true);
67 interactionSettings_.enableRightClickMenu = config.ReadBool("EnableRightClickMenu", true);
68 interactionSettings_.enableKeyboardNavigation = config.ReadBool("EnableKeyboardNavigation", true);
69 interactionSettings_.enableDragAndDrop = config.ReadBool("EnableDragAndDrop", false);
70 interactionSettings_.requireCtrlForMultiSelect = config.ReadBool("RequireCtrlForMultiSelect", true);
71 interactionSettings_.enableMiddleClickCenter = config.ReadBool("EnableMiddleClickCenter", true);
72 interactionSettings_.doubleClickSpeed = config.ReadLong("DoubleClickSpeed", 500);
73
74 // Load debug settings
75 config.SetPath("/Debug");
76 debugSettings_.enableSyncLogging = config.ReadBool("EnableSyncLogging", false);
77 debugSettings_.enablePerformanceMetrics = config.ReadBool("EnablePerformanceMetrics", false);
78 debugSettings_.enableDebugOverlay = config.ReadBool("EnableDebugOverlay", false);
79 debugSettings_.verboseLogging = config.ReadBool("VerboseLogging", false);
80
82 NotifyChange("all", "loaded_from_file");
83
84 LOG_INFO("Config", "Configuration loaded successfully");
85 return true;
86 } catch (const std::exception &e) {
87 LOG_ERROR("Config", "Error loading configuration: " + std::string(e.what()));
88 return false;
89 }
90}
91
93 LOG_INFO("Config", "Saving configuration to: " + filename);
94
95 try {
96 wxFileName fn(filename);
97 // Ensure directory exists
98 if (!fn.DirExists()) {
99 fn.Mkdir(wxS_DIR_DEFAULT, wxPATH_MKDIR_FULL);
100 }
101
102 wxFileConfig config(filename);
103
104 // Save sync settings
105 config.SetPath("/Sync");
106 config.Write("EnableHierarchyToScene", syncSettings_.enableHierarchyToScene);
107 config.Write("EnableSceneToHierarchy", syncSettings_.enableSceneToHierarchy);
108 config.Write("EnableAutoCenter", syncSettings_.enableAutoCenter);
109 config.Write("EnableSelectionHighlight", syncSettings_.enableSelectionHighlight);
110 config.Write("EnableHoverEffects", syncSettings_.enableHoverEffects);
111 config.Write("CenterWithAnimation", syncSettings_.centerWithAnimation);
112 config.Write("CenteringSpeed", syncSettings_.centeringSpeed);
113 config.Write("PreventSyncLoops", syncSettings_.preventSyncLoops);
114
115 // Save visual settings
116 config.SetPath("/Visual");
117 config.Write("SelectionBorderWidth", visualSettings_.selectionBorderWidth);
118 config.Write("HoverBorderWidth", visualSettings_.hoverBorderWidth);
119 config.Write("HighlightOpacity", visualSettings_.highlightOpacity);
120 config.Write("EnableAnimations", visualSettings_.enableAnimations);
121 config.Write("AnimationDuration", visualSettings_.animationDuration);
122
123 // Save interaction settings
124 config.SetPath("/Interaction");
125 config.Write("EnableDoubleClickExpand", interactionSettings_.enableDoubleClickExpand);
126 config.Write("EnableRightClickMenu", interactionSettings_.enableRightClickMenu);
127 config.Write("EnableKeyboardNavigation", interactionSettings_.enableKeyboardNavigation);
128 config.Write("EnableDragAndDrop", interactionSettings_.enableDragAndDrop);
129 config.Write("RequireCtrlForMultiSelect", interactionSettings_.requireCtrlForMultiSelect);
130 config.Write("EnableMiddleClickCenter", interactionSettings_.enableMiddleClickCenter);
131 config.Write("DoubleClickSpeed", interactionSettings_.doubleClickSpeed);
132
133 // Save debug settings
134 config.SetPath("/Debug");
135 config.Write("EnableSyncLogging", debugSettings_.enableSyncLogging);
136 config.Write("EnablePerformanceMetrics", debugSettings_.enablePerformanceMetrics);
137 config.Write("EnableDebugOverlay", debugSettings_.enableDebugOverlay);
138 config.Write("VerboseLogging", debugSettings_.verboseLogging);
139
140 config.Flush();
141
142 LOG_INFO("Config", "Configuration saved successfully");
143 return true;
144 } catch (const std::exception &e) {
145 LOG_ERROR("Config", "Error saving configuration: " + std::string(e.what()));
146 return false;
147 }
148}
149
151 changeCallbacks_.push_back(callback);
152}
153
155 // Note: This is a simplified implementation. In production, you might want
156 // to store callbacks with IDs for easier removal.
157 LOG_WARNING("Config", "UnregisterChangeCallback not fully implemented");
158}
159
160void BehaviorTreeConfig::SetSyncEnabled(bool hierarchyToScene, bool sceneToHierarchy) {
161 bool changed = false;
162
163 if (syncSettings_.enableHierarchyToScene != hierarchyToScene) {
164 syncSettings_.enableHierarchyToScene = hierarchyToScene;
165 NotifyChange("sync", "hierarchy_to_scene");
166 changed = true;
167 }
168
169 if (syncSettings_.enableSceneToHierarchy != sceneToHierarchy) {
170 syncSettings_.enableSceneToHierarchy = sceneToHierarchy;
171 NotifyChange("sync", "scene_to_hierarchy");
172 changed = true;
173 }
174
175 if (changed) {
176 LOG_INFO("Config", "Sync settings updated - H→S: " + std::to_string(hierarchyToScene) +
177 ", S→H: " + std::to_string(sceneToHierarchy));
178 }
179}
180
181void BehaviorTreeConfig::SetCenteringEnabled(bool enabled, bool animated) {
182 bool changed = false;
183
184 if (syncSettings_.enableAutoCenter != enabled) {
185 syncSettings_.enableAutoCenter = enabled;
186 NotifyChange("sync", "auto_center");
187 changed = true;
188 }
189
190 if (syncSettings_.centerWithAnimation != animated) {
191 syncSettings_.centerWithAnimation = animated;
192 NotifyChange("sync", "center_animation");
193 changed = true;
194 }
195
196 if (changed) {
197 LOG_INFO("Config", "Centering settings updated - Enabled: " + std::to_string(enabled) +
198 ", Animated: " + std::to_string(animated));
199 }
200}
201
203 if (syncSettings_.enableSelectionHighlight != enabled) {
204 syncSettings_.enableSelectionHighlight = enabled;
205 NotifyChange("sync", "selection_highlight");
206 LOG_INFO("Config", "Highlighting enabled: " + std::to_string(enabled));
207 }
208}
209
211 debugSettings_.enableSyncLogging = enabled;
212 debugSettings_.verboseLogging = enabled;
213 NotifyChange("debug", "debug_mode");
214 LOG_INFO("Config", "Debug mode: " + std::to_string(enabled));
215}
216
218
219std::vector<std::string> BehaviorTreeConfig::GetValidationErrors() const {
220 std::vector<std::string> errors;
221
222 // Validate sync settings
223 if (syncSettings_.centeringSpeed < 0.1f || syncSettings_.centeringSpeed > 5.0f) {
224 errors.push_back("Centering speed must be between 0.1 and 5.0");
225 }
226
227 // Validate visual settings
228 if (visualSettings_.selectionBorderWidth < 1 || visualSettings_.selectionBorderWidth > 10) {
229 errors.push_back("Selection border width must be between 1 and 10");
230 }
231 if (visualSettings_.highlightOpacity < 0.0f || visualSettings_.highlightOpacity > 1.0f) {
232 errors.push_back("Highlight opacity must be between 0.0 and 1.0");
233 }
234 if (visualSettings_.animationDuration < 50 || visualSettings_.animationDuration > 2000) {
235 errors.push_back("Animation duration must be between 50 and 2000 ms");
236 }
237
238 // Validate interaction settings
239 if (interactionSettings_.doubleClickSpeed < 100 || interactionSettings_.doubleClickSpeed > 2000) {
240 errors.push_back("Double-click speed must be between 100 and 2000 ms");
241 }
242
243 return errors;
244}
245
246void BehaviorTreeConfig::NotifyChange(const std::string &category, const std::string &setting) {
247 for (const auto &callback : changeCallbacks_) {
248 try {
249 callback(category, setting);
250 } catch (const std::exception &e) {
251 LOG_ERROR("Config", "Error in change callback: " + std::string(e.what()));
252 }
253 }
254}
255
257 // Clamp sync settings
258 syncSettings_.centeringSpeed = std::max(0.1f, std::min(5.0f, syncSettings_.centeringSpeed));
259
260 // Clamp visual settings
261 visualSettings_.selectionBorderWidth = std::max(1, std::min(10, visualSettings_.selectionBorderWidth));
262 visualSettings_.hoverBorderWidth = std::max(1, std::min(10, visualSettings_.hoverBorderWidth));
263 visualSettings_.highlightOpacity = std::max(0.0f, std::min(1.0f, visualSettings_.highlightOpacity));
264 visualSettings_.animationDuration = std::max(50, std::min(2000, visualSettings_.animationDuration));
265
266 // Clamp interaction settings
267 interactionSettings_.doubleClickSpeed = std::max(100, std::min(2000, interactionSettings_.doubleClickSpeed));
268}
269
270// BehaviorTreeConfigManager implementation
275
276bool BehaviorTreeConfigManager::IsSyncEnabled(bool hierarchyToScene) const {
277 return hierarchyToScene ? config_.GetSyncSettings().enableHierarchyToScene
278 : config_.GetSyncSettings().enableSceneToHierarchy;
279}
280
281bool BehaviorTreeConfigManager::IsCenteringEnabled() const { return config_.GetSyncSettings().enableAutoCenter; }
282
284 return config_.GetSyncSettings().enableSelectionHighlight;
285}
286
287} // namespace EmberCore
#define LOG_ERROR(category, message)
Definition Logger.h:116
#define LOG_WARNING(category, message)
Definition Logger.h:115
#define LOG_INFO(category, message)
Definition Logger.h:114
static BehaviorTreeConfigManager & GetInstance()
bool IsSyncEnabled(bool hierarchyToScene) const
void UnregisterChangeCallback(const ConfigChangeCallback &callback)
std::function< void(const std::string &category, const std::string &setting)> ConfigChangeCallback
InteractionSettings interactionSettings_
std::vector< ConfigChangeCallback > changeCallbacks_
bool LoadFromFile(const EmberCore::String &filename)
void NotifyChange(const std::string &category, const std::string &setting)
bool SaveToFile(const EmberCore::String &filename) const
void SetSyncEnabled(bool hierarchyToScene, bool sceneToHierarchy)
std::vector< std::string > GetValidationErrors() const
void SetCenteringEnabled(bool enabled, bool animated=false)
void RegisterChangeCallback(const ConfigChangeCallback &callback)
Main types header for EmberCore.
std::string String
Framework-agnostic string type.
Definition String.h:14
Debugging and development settings.
Interaction behavior configuration settings.
Synchronization configuration settings.
Visual appearance configuration settings.