|
|
|
|
@ -12,10 +12,10 @@ signal open_react_graph(data)
|
|
|
|
|
signal open_react_table(data)
|
|
|
|
|
|
|
|
|
|
# Variables
|
|
|
|
|
var _interface = null
|
|
|
|
|
static var _interface = null
|
|
|
|
|
var _init_data = null
|
|
|
|
|
var _init_check_received = false
|
|
|
|
|
var _pending_signals = []
|
|
|
|
|
static var _pending_signals = []
|
|
|
|
|
var _my_js_callback = JavaScriptBridge.create_callback(receive_init_data)
|
|
|
|
|
var window = null
|
|
|
|
|
|
|
|
|
|
@ -34,49 +34,7 @@ func _ready():
|
|
|
|
|
receive_init_data("test")
|
|
|
|
|
|
|
|
|
|
# Set up message listener and interface
|
|
|
|
|
JavaScriptBridge.eval("""
|
|
|
|
|
// Create the Godot interface
|
|
|
|
|
window.godot_interface = {
|
|
|
|
|
_callbacks: {},
|
|
|
|
|
emit_signal: function(signal_name, data) {
|
|
|
|
|
console.log('Emitting signal:', signal_name, 'with data:', data);
|
|
|
|
|
if (window.godot_interface._callbacks[signal_name]) {
|
|
|
|
|
window.godot_interface._callbacks[signal_name](data);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
// Set up message listener
|
|
|
|
|
window.addEventListener('message', function(event) {
|
|
|
|
|
console.log('Received message:', event.data);
|
|
|
|
|
|
|
|
|
|
// Handle the message
|
|
|
|
|
if (event.data && event.data.type) {
|
|
|
|
|
switch(event.data.type) {
|
|
|
|
|
case 'cityBuilder_init':
|
|
|
|
|
console.log('Received init data:', event.data.data);
|
|
|
|
|
window.godot_interface.emit_signal('init_data_received', event.data.data);
|
|
|
|
|
break;
|
|
|
|
|
case 'cityBuilder_init_check':
|
|
|
|
|
console.log('Received init check');
|
|
|
|
|
window.godot_interface.emit_signal('init_check_received');
|
|
|
|
|
break;
|
|
|
|
|
case 'mission_progress_updated':
|
|
|
|
|
window.godot_interface.emit_signal('mission_progress_updated', event.data.data);
|
|
|
|
|
break;
|
|
|
|
|
case 'mission_completed':
|
|
|
|
|
window.godot_interface.emit_signal('mission_completed', event.data.data);
|
|
|
|
|
break;
|
|
|
|
|
case 'open_react_graph':
|
|
|
|
|
window.godot_interface.emit_signal('open_react_graph', event.data.data);
|
|
|
|
|
break;
|
|
|
|
|
case 'open_react_table':
|
|
|
|
|
window.godot_interface.emit_signal('open_react_table', event.data.data);
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
});
|
|
|
|
|
""")
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
# Set up the interface
|
|
|
|
|
_interface = JavaScript.get_interface()
|
|
|
|
|
@ -175,43 +133,142 @@ static func has_interface() -> bool:
|
|
|
|
|
|
|
|
|
|
static func get_interface():
|
|
|
|
|
return JavaScript.get_interface()
|
|
|
|
|
|
|
|
|
|
# Helper method to convert Godot Dictionary to JSON string
|
|
|
|
|
static func JSON_stringify(data) -> String:
|
|
|
|
|
return JSON.stringify(data)
|
|
|
|
|
|
|
|
|
|
#static func send_signal(signal_name: String, data = null):
|
|
|
|
|
# if JavaScript.has_interface():
|
|
|
|
|
# if _interface and _interface.has_method("emit_signal"):
|
|
|
|
|
# _interface.emit_signal(signal_name, data)
|
|
|
|
|
# else:
|
|
|
|
|
# _pending_signals.append({"signal_name": signal_name, "data": data})
|
|
|
|
|
# else:
|
|
|
|
|
# _pending_signals.append({"signal_name": signal_name, "data": data})
|
|
|
|
|
|
|
|
|
|
#func send_mission_progress(mission_id: String, objective_index: int, current_count: int, target_count: int):
|
|
|
|
|
# send_signal("mission_progress_updated", {
|
|
|
|
|
# "mission_id": mission_id,
|
|
|
|
|
# "objective_index": objective_index,
|
|
|
|
|
# "current_count": current_count,
|
|
|
|
|
# "target_count": target_count
|
|
|
|
|
# })
|
|
|
|
|
#
|
|
|
|
|
#func send_mission_completed(mission_id: String):
|
|
|
|
|
# send_signal("mission_completed", {
|
|
|
|
|
# "mission_id": mission_id
|
|
|
|
|
# })
|
|
|
|
|
|
|
|
|
|
static func send_open_graph(graph_data: Dictionary):
|
|
|
|
|
# Format the message to match what React expects
|
|
|
|
|
var message = {
|
|
|
|
|
"source": "godot-game",
|
|
|
|
|
"type": "open_react_graph",
|
|
|
|
|
"data": graph_data
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
# First, emit the Godot signal for internal listeners
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
# Then, send the message directly to React via postMessage for external listeners
|
|
|
|
|
if OS.has_feature("web"):
|
|
|
|
|
# send_signal("open_react_graph", graph_data)
|
|
|
|
|
var message_json = JSON_stringify(message)
|
|
|
|
|
var script = """
|
|
|
|
|
(function() {
|
|
|
|
|
try {
|
|
|
|
|
if (window.parent) {
|
|
|
|
|
console.log('Sending missionStarted message to parent window');
|
|
|
|
|
window.parent.postMessage({
|
|
|
|
|
type: 'open_react_graph',
|
|
|
|
|
data: %s,
|
|
|
|
|
source: 'godot-game',
|
|
|
|
|
timestamp: Date.now()
|
|
|
|
|
}, '*');
|
|
|
|
|
} else {
|
|
|
|
|
console.log('No parent window found for missionStarted event');
|
|
|
|
|
}
|
|
|
|
|
} catch (e) {
|
|
|
|
|
console.error('Error sending missionStarted via postMessage:', e);
|
|
|
|
|
}
|
|
|
|
|
})();
|
|
|
|
|
""" % message_json
|
|
|
|
|
|
|
|
|
|
if Engine.has_singleton("JavaScriptBridge"):
|
|
|
|
|
var js = Engine.get_singleton("JavaScriptBridge")
|
|
|
|
|
js.eval(script)
|
|
|
|
|
else:
|
|
|
|
|
print("JavaScriptBridge singleton not available")
|
|
|
|
|
else:
|
|
|
|
|
# For non-web platforms, add to pending signals
|
|
|
|
|
_pending_signals.append({"signal_name": "open_react_graph", "data": graph_data})
|
|
|
|
|
|
|
|
|
|
func send_signal(signal_name: String, data = null):
|
|
|
|
|
if JavaScript.has_interface():
|
|
|
|
|
if _interface and _interface.has_method("emit_signal"):
|
|
|
|
|
_interface.emit_signal(signal_name, data)
|
|
|
|
|
static func send_open_table(table_data: Dictionary):
|
|
|
|
|
# Format the message to match what React expects
|
|
|
|
|
var message = {
|
|
|
|
|
"source": "godot-game",
|
|
|
|
|
"type": "open_react_table",
|
|
|
|
|
"data": table_data
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
# First, emit the Godot signal for internal listeners
|
|
|
|
|
# emit_signal("open_react_table", table_data)
|
|
|
|
|
|
|
|
|
|
# Then, send the message directly to React via postMessage for external listeners
|
|
|
|
|
if OS.has_feature("web"):
|
|
|
|
|
var message_json = JSON_stringify(message)
|
|
|
|
|
var script = """
|
|
|
|
|
(function() {
|
|
|
|
|
try {
|
|
|
|
|
if (window.parent) {
|
|
|
|
|
console.log('Sending missionStarted message to parent window');
|
|
|
|
|
window.parent.postMessage({
|
|
|
|
|
type: 'stemCity_missionStarted',
|
|
|
|
|
data: %s,
|
|
|
|
|
source: 'godot-game',
|
|
|
|
|
timestamp: Date.now()
|
|
|
|
|
}, '*');
|
|
|
|
|
} else {
|
|
|
|
|
console.log('No parent window found for missionStarted event');
|
|
|
|
|
}
|
|
|
|
|
} catch (e) {
|
|
|
|
|
console.error('Error sending missionStarted via postMessage:', e);
|
|
|
|
|
}
|
|
|
|
|
})();
|
|
|
|
|
""" % message_json
|
|
|
|
|
|
|
|
|
|
if Engine.has_singleton("JavaScriptBridge"):
|
|
|
|
|
var js = Engine.get_singleton("JavaScriptBridge")
|
|
|
|
|
js.eval(script)
|
|
|
|
|
else:
|
|
|
|
|
_pending_signals.append({"signal_name": signal_name, "data": data})
|
|
|
|
|
print("JavaScriptBridge singleton not available")
|
|
|
|
|
|
|
|
|
|
else:
|
|
|
|
|
_pending_signals.append({"signal_name": signal_name, "data": data})
|
|
|
|
|
|
|
|
|
|
func send_mission_progress(mission_id: String, objective_index: int, current_count: int, target_count: int):
|
|
|
|
|
send_signal("mission_progress_updated", {
|
|
|
|
|
"mission_id": mission_id,
|
|
|
|
|
"objective_index": objective_index,
|
|
|
|
|
"current_count": current_count,
|
|
|
|
|
"target_count": target_count
|
|
|
|
|
})
|
|
|
|
|
|
|
|
|
|
func send_mission_completed(mission_id: String):
|
|
|
|
|
send_signal("mission_completed", {
|
|
|
|
|
"mission_id": mission_id
|
|
|
|
|
})
|
|
|
|
|
|
|
|
|
|
func send_open_graph(graph_data: Dictionary):
|
|
|
|
|
send_signal("open_react_graph", graph_data)
|
|
|
|
|
|
|
|
|
|
func send_open_table(table_data: Dictionary):
|
|
|
|
|
send_signal("open_react_table", table_data)
|
|
|
|
|
|
|
|
|
|
func send_companion_dialog(dialog_type: String, dialog_data: Dictionary):
|
|
|
|
|
send_signal("companion_dialog", {
|
|
|
|
|
"type": dialog_type,
|
|
|
|
|
"data": dialog_data
|
|
|
|
|
})
|
|
|
|
|
|
|
|
|
|
func send_audio_action(action: String, data: Dictionary = {}):
|
|
|
|
|
send_signal("audio_action", {
|
|
|
|
|
"action": action,
|
|
|
|
|
"data": data
|
|
|
|
|
})
|
|
|
|
|
# For non-web platforms, add to pending signals
|
|
|
|
|
_pending_signals.append({"signal_name": "open_react_table", "data": table_data})
|
|
|
|
|
|
|
|
|
|
#func send_companion_dialog(dialog_type: String, dialog_data: Dictionary):
|
|
|
|
|
# send_signal("companion_dialog", {
|
|
|
|
|
# "type": dialog_type,
|
|
|
|
|
# "data": dialog_data
|
|
|
|
|
# })
|
|
|
|
|
#
|
|
|
|
|
#func send_audio_action(action: String, data: Dictionary = {}):
|
|
|
|
|
# send_signal("audio_action", {
|
|
|
|
|
# "action": action,
|
|
|
|
|
# "data": data
|
|
|
|
|
# })
|
|
|
|
|
|
|
|
|
|
# Static wrappers so send_open_ functions can be called on the class directly
|
|
|
|
|
#static func send_open_graph(graph_data: Dictionary) -> void:
|
|
|
|
|
# if instance:
|
|
|
|
|
# instance.send_open_graph(graph_data)
|
|
|
|
|
# else:
|
|
|
|
|
# push_error("JavaScriptBridge not initialized; cannot send_open_graph")
|
|
|
|
|
|
|
|
|
|
#static func send_open_table(table_data: Dictionary) -> void:
|
|
|
|
|
# if instance:
|
|
|
|
|
# instance.send_open_table(table_data)
|
|
|
|
|
# else:
|
|
|
|
|
# push_error("JavaScriptBridge not initialized; cannot send_open_table")
|
|
|
|
|
|