桥接与逻辑编写:C#到Lua的数据传递与交互架构(续)
·
3.2 Lua数据绑定系统
-- vehicle_data_binding.lua - Lua数据绑定系统
local VehicleDataBinding = {}
-- 数据绑定配置
VehicleDataBinding.config = {
update_interval = 0.1, -- 更新间隔(秒)
enable_watchers = true, -- 启用数据监视器
max_watchers = 100, -- 最大监视器数量
cache_size = 1000, -- 缓存大小
enable_validation = true, -- 启用数据验证
validation_strictness = "medium" -- 验证严格度:low, medium, high
}
-- 数据绑定状态
VehicleDataBinding.state = {
initialized = false,
active_bindings = {},
data_watchers = {},
data_cache = {},
update_timer = 0,
performance_stats = {
total_updates = 0,
total_bindings = 0,
cache_hits = 0,
cache_misses = 0
}
}
-- 数据类型验证器
VehicleDataBinding.validators = {
CanMessage = function(data)
if type(data) ~= "table" then
return false, "CanMessage必须是表"
end
if type(data.id) ~= "number" then
return false, "CanMessage.id必须是数字"
end
if type(data.data) ~= "table" then
return false, "CanMessage.data必须是表"
end
if #data.data > 8 then
return false, "CanMessage.data长度不能超过8"
end
return true
end,
VehicleState = function(data)
if type(data) ~= "table" then
return false, "VehicleState必须是表"
end
if type(data.speed) ~= "number" then
return false, "VehicleState.speed必须是数字"
end
if type(data.rpm) ~= "number" then
return false, "VehicleState.rpm必须是数字"
end
if data.speed < 0 or data.speed > 300 then
return false, string.format("VehicleState.speed超出范围: %f", data.speed)
end
if data.rpm < 0 or data.rpm > 10000 then
return false, string.format("VehicleState.rpm超出范围: %f", data.rpm)
end
return true
end,
SensorData = function(data)
if type(data) ~= "table" then
return false, "SensorData必须是表"
end
if type(data.acceleration) ~= "table" then
return false, "SensorData.acceleration必须是表"
end
if type(data.gyro) ~= "table" then
return false, "SensorData.gyro必须是表"
end
return true
end
}
-- 初始化数据绑定系统
function VehicleDataBinding:initialize()
if self.state.initialized then
print("数据绑定系统已初始化")
return
end
print("正在初始化数据绑定系统...")
-- 初始化缓存
self:initialize_cache()
-- 初始化监视器系统
if self.config.enable_watchers then
self:initialize_watchers()
end
self.state.initialized = true
print("数据绑定系统初始化完成")
return true
end
-- 初始化缓存
function VehicleDataBinding:initialize_cache()
self.state.data_cache = {
items = {},
size = 0,
max_size = self.config.cache_size,
hit_count = 0,
miss_count = 0
}
print("数据缓存已初始化,大小: " .. self.config.cache_size)
end
-- 初始化监视器
function VehicleDataBinding:initialize_watchers()
self.state.data_watchers = {
watchers = {},
watcher_count = 0,
max_watchers = self.config.max_watchers
}
print("数据监视器已初始化,最大数量: " .. self.config.max_watchers)
end
-- 更新数据绑定系统
function VehicleDataBinding:update(delta_time)
if not self.state.initialized then
return
end
self.state.update_timer = self.state.update_timer + delta_time
-- 定期更新绑定
if self.state.update_timer >= self.config.update_interval then
self:update_bindings()
self.state.update_timer = 0
end
end
-- 更新所有绑定
function VehicleDataBinding:update_bindings()
local updated_count = 0
for binding_id, binding in pairs(self.state.active_bindings) do
if self:should_update_binding(binding) then
local success = self:update_single_binding(binding)
if success then
updated_count = updated_count + 1
end
end
end
self.state.performance_stats.total_updates =
self.state.performance_stats.total_updates + updated_count
-- 清理过期绑定
self:cleanup_expired_bindings()
return updated_count
end
-- 检查是否需要更新绑定
function VehicleDataBinding:should_update_binding(binding)
if not binding.enabled then
return false
end
if binding.update_mode == "manual" then
return false
end
if binding.update_mode == "on_change" then
-- 需要检查数据是否变化
return self:has_data_changed(binding)
end
-- 定时更新模式
local current_time = os.clock()
if current_time - binding.last_update_time >= binding.update_interval then
return true
end
return false
end
-- 检查数据是否变化
function VehicleDataBinding:has_data_changed(binding)
-- 从C#获取当前数据
local current_data = self:fetch_data_from_csharp(binding.data_source)
if not current_data then
return false
end
-- 比较数据
return not self:compare_data(binding.last_data, current_data)
end
-- 比较数据
function VehicleDataBinding:compare_data(data1, data2)
if type(data1) ~= type(data2) then
return false
end
if type(data1) == "table" then
for k, v in pairs(data1) do
if not self:compare_data(v, data2[k]) then
return false
end
end
for k, v in pairs(data2) do
if data1[k] == nil then
return false
end
end
return true
end
return data1 == data2
end
-- 从C#获取数据
function VehicleDataBinding:fetch_data_from_csharp(data_source)
if not data_source or not data_source.type then
return nil
end
-- 检查缓存
local cache_key = self:generate_cache_key(data_source)
local cached_data = self:get_cached_data(cache_key)
if cached_data then
self.state.data_cache.hit_count = self.state.data_cache.hit_count + 1
return cached_data
end
self.state.data_cache.miss_count = self.state.data_cache.miss_count + 1
-- 从C#获取数据
local data = nil
if data_source.type == "can" then
data = csharp.can_read(data_source.channel, data_source.message_id)
elseif data_source.type == "sensor" then
data = csharp.sensor_get(data_source.sensor_type)
elseif data_source.type == "vehicle_state" then
data = csharp.vehicle_get_parameter(data_source.parameter)
elseif data_source.type == "custom" then
data = csharp.call_method(data_source.object_ref, data_source.method_name,
table.unpack(data_source.parameters or {}))
end
-- 缓存数据
if data then
self:cache_data(cache_key, data, data_source.cache_ttl)
end
return data
end
-- 生成缓存键
function VehicleDataBinding:generate_cache_key(data_source)
if data_source.type == "can" then
return string.format("can_%d_0x%X", data_source.channel, data_source.message_id)
elseif data_source.type == "sensor" then
return string.format("sensor_%s", data_source.sensor_type)
elseif data_source.type == "vehicle_state" then
return string.format("vehicle_%s", data_source.parameter)
elseif data_source.type == "custom" then
return string.format("custom_%s_%s", data_source.object_ref, data_source.method_name)
end
return tostring(data_source)
end
-- 获取缓存数据
function VehicleDataBinding:get_cached_data(cache_key)
local cache_item = self.state.data_cache.items[cache_key]
if not cache_item then
return nil
end
-- 检查过期时间
if cache_item.expiry_time and os.time() > cache_item.expiry_time then
self.state.data_cache.items[cache_key] = nil
self.state.data_cache.size = self.state.data_cache.size - 1
return nil
end
return cache_item.data
end
-- 缓存数据
function VehicleDataBinding:cache_data(cache_key, data, ttl)
if self.state.data_cache.size >= self.state.data_cache.max_size then
-- 缓存已满,移除最旧的项
self:remove_oldest_cache_item()
end
self.state.data_cache.items[cache_key] = {
data = data,
expiry_time = ttl and (os.time() + ttl) or nil,
last_access = os.time()
}
self.state.data_cache.size = self.state.data_cache.size + 1
return true
end
-- 移除最旧的缓存项
function VehicleDataBinding:remove_oldest_cache_item()
if self.state.data_cache.size == 0 then
return
end
local oldest_key = nil
local oldest_time = os.time() + 1 -- 未来时间
for key, item in pairs(self.state.data_cache.items) do
if item.last_access < oldest_time then
oldest_time = item.last_access
oldest_key = key
end
end
if oldest_key then
self.state.data_cache.items[oldest_key] = nil
self.state.data_cache.size = self.state.data_cache.size - 1
end
end
-- 更新单个绑定
function VehicleDataBinding:update_single_binding(binding)
local start_time = os.clock()
-- 获取数据
local data = self:fetch_data_from_csharp(binding.data_source)
if not data then
print("警告: 无法获取绑定数据: " .. binding.id)
return false
end
-- 验证数据
if self.config.enable_validation then
local valid, error_msg = self:validate_data(data, binding.data_type)
if not valid then
print("警告: 数据验证失败: " .. error_msg)
if self.config.validation_strictness == "high" then
return false
end
end
end
-- 转换数据
local processed_data = self:process_data(data, binding.data_processor)
-- 应用绑定
local success = self:apply_binding(binding, processed_data)
if success then
-- 更新绑定状态
binding.last_data = processed_data
binding.last_update_time = os.clock()
binding.update_count = binding.update_count + 1
-- 触发监视器
self:trigger_watchers(binding.id, processed_data)
local end_time = os.clock()
binding.last_update_duration = end_time - start_time
return true
end
return false
end
-- 验证数据
function VehicleDataBinding:validate_data(data, data_type)
if not data_type then
return true -- 没有指定类型,跳过验证
end
local validator = self.validators[data_type]
if not validator then
-- 没有找到验证器,根据严格度决定
if self.config.validation_strictness == "high" then
return false, "找不到数据类型的验证器: " .. data_type
end
return true -- 低/中等严格度,跳过验证
end
return validator(data)
end
-- 处理数据
function VehicleDataBinding:process_data(data, processor)
if not processor then
return data
end
if type(processor) == "function" then
-- 自定义处理函数
return processor(data)
elseif type(processor) == "table" then
-- 处理配置
return self:apply_data_processor(data, processor)
end
return data
end
-- 应用数据处理器
function VehicleDataBinding:apply_data_processor(data, processor_config)
local result = data
if processor_config.filter then
result = self:apply_filter(result, processor_config.filter)
end
if processor_config.transform then
result = self:apply_transform(result, processor_config.transform)
end
if processor_config.normalize then
result = self:apply_normalization(result, processor_config.normalize)
end
return result
end
-- 应用过滤器
function VehicleDataBinding:apply_filter(data, filter_config)
if type(data) ~= "table" then
return data
end
local result = {}
if filter_config.include then
for _, field in ipairs(filter_config.include) do
if data[field] ~= nil then
result[field] = data[field]
end
end
elseif filter_config.exclude then
result = {table.unpack(data)} -- 浅拷贝
for _, field in ipairs(filter_config.exclude) do
result[field] = nil
end
end
return result
end
-- 应用转换
function VehicleDataBinding:apply_transform(data, transform_config)
if transform_config.type == "scale" then
return self:scale_data(data, transform_config.factor)
elseif transform_config.type == "offset" then
return self:offset_data(data, transform_config.offset)
elseif transform_config.type == "clamp" then
return self:clamp_data(data, transform_config.min, transform_config.max)
end
return data
end
-- 缩放数据
function VehicleDataBinding:scale_data(data, factor)
if type(data) == "number" then
return data * factor
elseif type(data) == "table" then
local result = {}
for k, v in pairs(data) do
if type(v) == "number" then
result[k] = v * factor
else
result[k] = v
end
end
return result
end
return data
end
-- 偏移数据
function VehicleDataBinding:offset_data(data, offset)
if type(data) == "number" then
return data + offset
elseif type(data) == "table" then
local result = {}
for k, v in pairs(data) do
if type(v) == "number" then
result[k] = v + offset
else
result[k] = v
end
end
return result
end
return data
end
-- 钳制数据
function VehicleDataBinding:clamp_data(data, min_val, max_val)
if type(data) == "number" then
return math.max(min_val, math.min(data, max_val))
elseif type(data) == "table" then
local result = {}
for k, v in pairs(data) do
if type(v) == "number" then
result[k] = math.max(min_val, math.min(v, max_val))
else
result[k] = v
end
end
return result
end
return data
end
-- 应用归一化
function VehicleDataBinding:apply_normalization(data, normalize_config)
if normalize_config.type == "range" then
return self:normalize_range(data, normalize_config.from_min,
normalize_config.from_max, normalize_config.to_min, normalize_config.to_max)
elseif normalize_config.type == "unit" then
return self:normalize_unit(data, normalize_config.unit)
end
return data
end
-- 范围归一化
functionVehicleDataBinding:normalize_range(data, from_min, from_max, to_min, to_max)
if type(data) == "number" then
local normalized = (data - from_min) / (from_max - from_min)
return to_min + normalized * (to_max - to_min)
end
return data
end
-- 单位归一化
function VehicleDataBinding:normalize_unit(data, unit)
if unit == "kph_to_mps" then
-- 公里/小时 转 米/秒
if type(data) == "number" then
return data * 1000 / 3600
end
elseif unit == "rpm_to_radps" then
-- 转/分钟 转 弧度/秒
if type(data) == "number" then
return data * 2 * math.pi / 60
end
end
return data
end
-- 应用绑定
function VehicleDataBinding:apply_binding(binding, data)
if binding.binding_type == "variable" then
-- 变量绑定:设置Lua变量
return self:apply_variable_binding(binding, data)
elseif binding.binding_type == "function" then
-- 函数绑定:调用Lua函数
return self:apply_function_binding(binding, data)
elseif binding.binding_type == "ui" then
-- UI绑定:更新UI元素
return self:apply_ui_binding(binding, data)
end
return false
end
-- 应用变量绑定
function VehicleDataBinding:apply_variable_binding(binding, data)
if not binding.target_variable then
return false
end
-- 设置变量
local target = _G
local parts = {}
for part in binding.target_variable:gmatch("[^%.]+") do
table.insert(parts, part)
end
for i = 1, #parts - 1 do
if not target[parts[i]] then
target[parts[i]] = {}
end
target = target[parts[i]]
end
target[parts[#parts]] = data
return true
end
-- 应用函数绑定
function VehicleDataBinding:apply_function_binding(binding, data)
if not binding.target_function then
return false
end
-- 获取函数
local func = nil
if type(binding.target_function) == "function" then
func = binding.target_function
elseif type(binding.target_function) == "string" then
-- 从全局环境获取函数
local target = _G
for part in binding.target_function:gmatch("[^%.]+") do
target = target[part]
if not target then
break
end
end
if type(target) == "function" then
func = target
end
end
if not func then
return false
end
-- 调用函数
local success, result = pcall(func, data, binding)
if not success then
print("警告: 函数绑定调用失败: " .. result)
return false
end
return true
end
-- 应用UI绑定
function VehicleDataBinding:apply_ui_binding(binding, data)
-- 这里需要与UI系统集成
-- 简化实现:调用UI更新函数
if binding.ui_update_function then
local success, result = pcall(binding.ui_update_function, data, binding)
return success
end
return false
end
-- 触发监视器
function VehicleDataBinding:trigger_watchers(binding_id, data)
if not self.config.enable_watchers then
return
end
local watchers = self.state.data_watchers.watchers[binding_id]
if not watchers then
return
end
for watcher_id, watcher in pairs(watchers) do
if watcher.enabled then
local success, result = pcall(watcher.callback, data, binding_id, watcher)
if not success then
print("警告: 数据监视器回调失败: " .. result)
watcher.error_count = (watcher.error_count or 0) + 1
else
watcher.trigger_count = (watcher.trigger_count or 0) + 1
end
end
end
end
-- 创建数据绑定
function VehicleDataBinding:create_binding(config)
if not self.state.initialized then
error("数据绑定系统未初始化")
end
-- 验证配置
local valid, error_msg = self:validate_binding_config(config)
if not valid then
error("绑定配置无效: " .. error_msg)
end
-- 生成绑定ID
local binding_id = "binding_" .. tostring(#self.state.active_bindings + 1)
-- 创建绑定
local binding = {
id = binding_id,
enabled = config.enabled ~= false,
data_source = config.data_source,
data_type = config.data_type,
data_processor = config.data_processor,
binding_type = config.binding_type,
target_variable = config.target_variable,
target_function = config.target_function,
ui_update_function = config.ui_update_function,
update_mode = config.update_mode or "interval",
update_interval = config.update_interval or self.config.update_interval,
priority = config.priority or 1,
last_data = nil,
last_update_time = 0,
last_update_duration = 0,
update_count = 0,
created_time = os.clock(),
metadata = config.metadata or {}
}
-- 添加到活动绑定
self.state.active_bindings[binding_id] = binding
self.state.performance_stats.total_bindings =
self.state.performance_stats.total_bindings + 1
print("已创建数据绑定: " .. binding_id)
-- 立即执行一次更新(如果需要)
if config.initial_update ~= false then
self:update_single_binding(binding)
end
return binding_id
end
-- 验证绑定配置
function VehicleDataBinding:validate_binding_config(config)
if not config.data_source then
return false, "数据源未指定"
end
if not config.binding_type then
return false, "绑定类型未指定"
end
if config.binding_type == "variable" and not config.target_variable then
return false, "变量绑定需要指定目标变量"
end
if config.binding_type == "function" and not config.target_function then
return false, "函数绑定需要指定目标函数"
end
if config.binding_type == "ui" and not config.ui_update_function then
return false, "UI绑定需要指定UI更新函数"
end
return true
end
-- 启用/禁用绑定
function VehicleDataBinding:set_binding_enabled(binding_id, enabled)
local binding = self.state.active_bindings[binding_id]
if not binding then
return false
end
binding.enabled = enabled
return true
end
-- 移除绑定
function VehicleDataBinding:remove_binding(binding_id)
local binding = self.state.active_bindings[binding_id]
if not binding then
return false
end
-- 移除相关监视器
self:remove_binding_watchers(binding_id)
-- 从活动绑定中移除
self.state.active_bindings[binding_id] = nil
self.state.performance_stats.total_bindings =
self.state.performance_stats.total_bindings - 1
print("已移除数据绑定: " .. binding_id)
return true
end
-- 清理过期绑定
function VehicleDataBinding:cleanup_expired_bindings()
local removed_count = 0
local current_time = os.clock()
for binding_id, binding in pairs(self.state.active_bindings) do
if binding.expiry_time and current_time > binding.expiry_time then
self:remove_binding(binding_id)
removed_count = removed_count + 1
end
end
return removed_count
end
-- 添加数据监视器
function VehicleDataBinding:add_data_watcher(binding_id, callback, config)
if not self.config.enable_watchers then
return false
end
if self.state.data_watchers.watcher_count >= self.state.data_watchers.max_watchers then
print("警告: 达到最大监视器数量限制")
return false
end
if type(callback) ~= "function" then
error("监视器回调必须是函数")
end
-- 检查绑定是否存在
if not self.state.active_bindings[binding_id] then
error("绑
我们继续编写Lua数据绑定系统的剩余部分,包括数据监视器的添加和移除,以及一些辅助功能。
3.2 Lua数据绑定系统(续)
lua
-- 添加数据监视器(续)
function VehicleDataBinding:add_data_watcher(binding_id, callback, config)
if not self.config.enable_watchers then
return false
end
if self.state.data_watchers.watcher_count >= self.state.data_watchers.max_watchers then
print("警告: 达到最大监视器数量限制")
return false
end
if type(callback) ~= "function" then
error("监视器回调必须是函数")
end
-- 检查绑定是否存在
if not self.state.active_bindings[binding_id] then
error("绑定不存在: " .. binding_id)
end
-- 初始化绑定监视器表
if not self.state.data_watchers.watchers[binding_id] then
self.state.data_watchers.watchers[binding_id] = {}
end
-- 生成监视器ID
local watcher_id = "watcher_" .. tostring(#self.state.data_watchers.watchers[binding_id] + 1)
-- 创建监视器
local watcher = {
id = watcher_id,
binding_id = binding_id,
callback = callback,
enabled = config and config.enabled ~= false or true,
trigger_on_add = config and config.trigger_on_add or false,
metadata = config and config.metadata or {},
trigger_count = 0,
error_count = 0,
created_time = os.clock()
}
-- 添加到监视器列表
self.state.data_watchers.watchers[binding_id][watcher_id] = watcher
self.state.data_watchers.watcher_count = self.state.data_watchers.watcher_count + 1
print("已添加数据监视器: " .. watcher_id .. " 到绑定: " .. binding_id)
-- 如果配置了添加时触发,并且绑定有数据,则立即触发一次
if watcher.trigger_on_add and self.state.active_bindings[binding_id].last_data then
local success, result = pcall(callback, self.state.active_bindings[binding_id].last_data, binding_id, watcher)
if success then
watcher.trigger_count = watcher.trigger_count + 1
else
print("警告: 监视器初始触发失败: " .. result)
watcher.error_count = watcher.error_count + 1
end
end
return watcher_id
end
-- 移除绑定监视器
function VehicleDataBinding:remove_binding_watchers(binding_id)
if not self.state.data_watchers.watchers[binding_id] then
return 0
end
local removed_count = 0
for watcher_id, watcher in pairs(self.state.data_watchers.watchers[binding_id]) do
self.state.data_watchers.watcher_count = self.state.data_watchers.watcher_count - 1
removed_count = removed_count + 1
end
self.state.data_watchers.watchers[binding_id] = nil
return removed_count
end
-- 移除特定监视器
function VehicleDataBinding:remove_watcher(binding_id, watcher_id)
if not self.state.data_watchers.watchers[binding_id] then
return false
end
local watcher = self.state.data_watchers.watchers[binding_id][watcher_id]
if not watcher then
return false
end
self.state.data_watchers.watchers[binding_id][watcher_id] = nil
self.state.data_watchers.watcher_count = self.state.data_watchers.watcher_count - 1
-- 如果绑定没有监视器了,清理绑定监视器表
if next(self.state.data_watchers.watchers[binding_id]) == nil then
self.state.data_watchers.watchers[binding_id] = nil
end
print("已移除监视器: " .. watcher_id .. " 从绑定: " .. binding_id)
return true
end
-- 启用/禁用监视器
function VehicleDataBinding:set_watcher_enabled(binding_id, watcher_id, enabled)
if not self.state.data_watchers.watchers[binding_id] then
return false
end
local watcher = self.state.data_watchers.watchers[binding_id][watcher_id]
if not watcher then
return false
end
watcher.enabled = enabled
return true
end
-- 手动触发绑定更新
function VehicleDataBinding:trigger_binding(binding_id)
local binding = self.state.active_bindings[binding_id]
if not binding then
return false
end
return self:update_single_binding(binding)
end
-- 获取绑定信息
function VehicleDataBinding:get_binding_info(binding_id)
local binding = self.state.active_bindings[binding_id]
if not binding then
return nil
end
-- 计算绑定状态
local binding_info = {
id = binding.id,
enabled = binding.enabled,
data_source = binding.data_source,
data_type = binding.data_type,
binding_type = binding.binding_type,
update_mode = binding.update_mode,
update_interval = binding.update_interval,
priority = binding.priority,
last_update_time = binding.last_update_time,
last_update_duration = binding.last_update_duration,
update_count = binding.update_count,
created_time = binding.created_time,
metadata = binding.metadata,
watcher_count = 0
}
-- 添加监视器数量
if self.state.data_watchers.watchers[binding_id] then
binding_info.watcher_count = #self.state.data_watchers.watchers[binding_id]
end
return binding_info
end
-- 获取所有绑定信息
function VehicleDataBinding:get_all_bindings_info()
local bindings_info = {}
for binding_id, binding in pairs(self.state.active_bindings) do
table.insert(bindings_info, self:get_binding_info(binding_id))
end
return bindings_info
end
-- 获取缓存统计
function VehicleDataBinding:get_cache_stats()
return {
size = self.state.data_cache.size,
max_size = self.state.data_cache.max_size,
hit_count = self.state.data_cache.hit_count,
miss_count = self.state.data_cache.miss_count,
hit_rate = self.state.data_cache.hit_count + self.state.data_cache.miss_count > 0 and
self.state.data_cache.hit_count / (self.state.data_cache.hit_count + self.state.data_cache.miss_count) or 0
}
end
-- 获取监视器统计
function VehicleDataBinding:get_watcher_stats()
return {
watcher_count = self.state.data_watchers.watcher_count,
max_watchers = self.state.data_watchers.max_watchers,
binding_count = #self.state.data_watchers.watchers
}
end
-- 获取性能统计
function VehicleDataBinding:get_performance_stats()
return {
total_updates = self.state.performance_stats.total_updates,
total_bindings = self.state.performance_stats.total_bindings,
cache_hits = self.state.data_cache.hit_count,
cache_misses = self.state.data_cache.miss_count,
cache_hit_rate = self:get_cache_stats().hit_rate
}
end
-- 清理缓存
function VehicleDataBinding:clear_cache()
self.state.data_cache.items = {}
self.state.data_cache.size = 0
self.state.data_cache.hit_count = 0
self.state.data_cache.miss_count = 0
print("数据缓存已清理")
end
-- 重置系统
function VehicleDataBinding:reset()
-- 清理所有绑定
for binding_id, binding in pairs(self.state.active_bindings) do
self:remove_binding(binding_id)
end
-- 清理缓存
self:clear_cache()
-- 重置性能统计
self.state.performance_stats = {
total_updates = 0,
total_bindings = 0,
cache_hits = 0,
cache_misses = 0
}
print("数据绑定系统已重置")
end
-- 关闭系统
function VehicleDataBinding:shutdown()
if not self.state.initialized then
return
end
-- 重置系统
self:reset()
-- 清理监视器
self.state.data_watchers = {
watchers = {},
watcher_count = 0,
max_watchers = self.config.max_watchers
}
self.state.initialized = false
print("数据绑定系统已关闭")
end
-- 导出VehicleDataBinding
return VehicleDataBinding
第四部分:C#到Lua的数据传递示例
4.1 车机CAN总线数据传递
csharp
// CanDataBridge.cs - CAN总线数据桥接
using System;
using System.Collections.Generic;
using UnityEngine;
namespace Vehicle.LuaBridge.Examples
{
/// <summary>
/// CAN总线数据桥接示例
/// </summary>
public class CanDataBridge : MonoBehaviour
{
// CAN总线管理器引用
private CanBusManager canBusManager;
// Lua桥接层引用
private LuaBridgeCore luaBridge;
// 数据传递管理器
private DataTransferManager transferManager;
// CAN数据缓存
private Dictionary<uint, CanMessage> canDataCache = new Dictionary<uint, CanMessage>();
// 配置
public CanBridgeConfig config = new CanBridgeConfig();
[System.Serializable]
public class CanBridgeConfig
{
public int updateIntervalMs = 50; // 更新间隔(毫秒)
public bool enableRealTimeUpdates = true; // 启用实时更新
public bool enableDataFiltering = true; // 启用数据过滤
public float dataValidationThreshold = 0.5f; // 数据验证阈值
public int maxQueueSize = 1000; // 最大队列大小
}
void Start()
{
Initialize();
}
void Initialize()
{
// 获取桥接层实例
luaBridge = LuaBridgeCore.Instance;
transferManager = FindObjectOfType<DataTransferManager>();
if (transferManager == null)
{
GameObject transferManagerObj = new GameObject("DataTransferManager");
transferManager = transferManagerObj.AddComponent<DataTransferManager>();
}
// 初始化CAN总线管理器
InitializeCanBusManager();
// 注册Lua回调
RegisterLuaCallbacks();
// 启动数据更新
StartCanDataUpdate();
Debug.Log("CAN数据桥接初始化完成");
}
void InitializeCanBusManager()
{
canBusManager = CanBusManager.Instance;
if (canBusManager == null)
{
Debug.LogError("CAN总线管理器未找到");
return;
}
// 订阅CAN数据更新事件
canBusManager.OnCanMessageReceived += HandleCanMessageReceived;
canBusManager.OnCanError += HandleCanError;
Debug.Log("CAN总线管理器已连接");
}
void RegisterLuaCallbacks()
{
// 注册CAN读取函数到Lua
luaBridge.RegisterCFunction("can_read_message", new LuaNativeFunction(LuaCanRead));
luaBridge.RegisterCFunction("can_write_message", new LuaNativeFunction(LuaCanWrite));
luaBridge.RegisterCFunction("can_get_bus_status", new LuaNativeFunction(LuaCanGetBusStatus));
// 注册车机特定CAN函数
luaBridge.RegisterCFunction("can_get_vehicle_speed", new LuaNativeFunction(LuaGetVehicleSpeed));
luaBridge.RegisterCFunction("can_get_engine_rpm", new LuaNativeFunction(LuaGetEngineRpm));
luaBridge.RegisterCFunction("can_get_fuel_level", new LuaNativeFunction(LuaGetFuelLevel));
Debug.Log("CAN Lua回调函数已注册");
}
void StartCanDataUpdate()
{
if (config.enableRealTimeUpdates)
{
InvokeRepeating("UpdateCanDataToLua", 0, config.updateIntervalMs / 1000f);
}
}
void UpdateCanDataToLua()
{
if (canBusManager == null)
return;
// 获取所有CAN通道数据
var allChannels = canBusManager.GetAllChannels();
foreach (var channel in allChannels)
{
UpdateChannelDataToLua(channel);
}
}
void UpdateChannelDataToLua(CanChannel channel)
{
// 获取通道上的所有消息
var messages = channel.GetAllMessages();
foreach (var message in messages)
{
// 应用数据过滤
if (config.enableDataFiltering && !ShouldForwardMessage(message))
continue;
// 数据验证
if (!ValidateCanMessage(message))
continue;
// 更新缓存
UpdateCanCache(message);
// 准备Lua变量名
string luaVarName = $"can_channel_{channel.Id}_message_{message.Id:X}";
// 提交数据传输
try
{
transferManager.SubmitTransfer(luaVarName, message);
}
catch (TransferQueueFullException ex)
{
Debug.LogWarning($"CAN数据传输队列已满: {ex.Message}");
// 紧急传输
luaBridge.EmergencyTransfer(luaVarName, message);
}
}
}
bool ShouldForwardMessage(CanMessage message)
{
// 根据消息ID和内容决定是否转发到Lua
// 示例:只转发特定ID范围的消息
uint id = message.Id;
// 车辆状态消息(标准ID范围)
if (id >= 0x100 && id <= 0x2FF)
return true;
// 传感器数据消息
if (id >= 0x300 && id <= 0x4FF)
return true;
// 控制消息
if (id >= 0x500 && id <= 0x6FF)
return true;
return false;
}
bool ValidateCanMessage(CanMessage message)
{
if (message.Data == null || message.Data.Length == 0)
return false;
// 检查数据长度
if (message.Data.Length > 8)
return false;
// 检查校验和(如果消息包含)
if (message.HasChecksum && !message.ValidateChecksum())
return false;
// 检查时间戳(不能是未来时间)
if (message.Timestamp > DateTime.Now.Ticks)
return false;
return true;
}
void UpdateCanCache(CanMessage message)
{
uint cacheKey = (message.ChannelId << 16) | message.Id;
if (canDataCache.ContainsKey(cacheKey))
{
var cachedMessage = canDataCache[cacheKey];
// 检查数据变化
if (!AreMessagesEqual(cachedMessage, message))
{
canDataCache[cacheKey] = message;
// 触发数据变化事件
OnCanDataChanged(message);
}
}
else
{
canDataCache[cacheKey] = message;
}
}
bool AreMessagesEqual(CanMessage msg1, CanMessage msg2)
{
if (msg1.Id != msg2.Id || msg1.ChannelId != msg2.ChannelId)
return false;
if (msg1.Data.Length != msg2.Data.Length)
return false;
for (int i = 0; i < msg1.Data.Length; i++)
{
if (msg1.Data[i] != msg2.Data[i])
return false;
}
return true;
}
void OnCanDataChanged(CanMessage message)
{
// 这里可以触发数据变化事件,通知其他系统
// 示例:更新车机仪表
UpdateInstrumentCluster(message);
}
void UpdateInstrumentCluster(CanMessage message)
{
// 根据CAN消息更新仪表显示
// 例如:车速、转速、油量等
if (message.Id == 0x100) // 假设0x100是车速消息
{
float speed = BitConverter.ToSingle(message.Data, 0);
// 更新车速显示
}
else if (message.Id == 0x101) // 假设0x101是转速消息
{
float rpm = BitConverter.ToSingle(message.Data, 0);
// 更新转速显示
}
}
void HandleCanMessageReceived(CanMessage message)
{
// 实时处理CAN消息
// 如果启用了实时更新,消息会通过定时器更新
// 这里可以处理特殊消息或触发事件
}
void HandleCanError(CanError error)
{
Debug.LogError($"CAN总线错误: {error.Code} - {error.Message}");
// 将错误信息传递给Lua
string luaVarName = "can_last_error";
transferManager.SubmitTransfer(luaVarName, error);
}
#region Lua回调函数
// Lua调用:读取CAN消息
private static int LuaCanRead(IntPtr luaState)
{
try
{
// 获取参数:通道ID和消息ID
int argCount = LuaNative.lua_gettop(luaState);
if (argCount < 2)
{
LuaNative.lua_pushstring(luaState, "需要2个参数: channel_id, message_id");
return LuaNative.LUA_ERROR;
}
int channelId = (int)LuaNative.lua_tointeger(luaState, 1);
uint messageId = (uint)LuaNative.lua_tointeger(luaState, 2);
// 从CAN总线读取消息
var instance = FindObjectOfType<CanDataBridge>();
if (instance == null || instance.canBusManager == null)
{
LuaNative.lua_pushnil(luaState);
return 1;
}
var message = instance.canBusManager.ReadMessage(channelId, messageId);
if (message == null)
{
LuaNative.lua_pushnil(luaState);
return 1;
}
// 将消息转换为Lua表
LuaNative.lua_createtable(luaState, 0, 5);
LuaNative.lua_pushstring(luaState, "id");
LuaNative.lua_pushinteger(luaState, message.Id);
LuaNative.lua_settable(luaState, -3);
LuaNative.lua_pushstring(luaState, "channel_id");
LuaNative.lua_pushinteger(luaState, message.ChannelId);
LuaNative.lua_settable(luaState, -3);
LuaNative.lua_pushstring(luaState, "data");
LuaNative.lua_createtable(luaState, message.Data.Length, 0);
for (int i = 0; i < message.Data.Length; i++)
{
LuaNative.lua_pushinteger(luaState, i + 1);
LuaNative.lua_pushinteger(luaState, message.Data[i]);
LuaNative.lua_settable(luaState, -3);
}
LuaNative.lua_settable(luaState, -3);
LuaNative.lua_pushstring(luaState, "timestamp");
LuaNative.lua_pushinteger(luaState, message.Timestamp);
LuaNative.lua_settable(luaState, -3);
LuaNative.lua_pushstring(luaState, "valid");
LuaNative.lua_pushboolean(luaState, message.IsValid ? 1 : 0);
LuaNative.lua_settable(luaState, -3);
return 1;
}
catch (Exception ex)
{
LuaNative.lua_pushstring(luaState, $"CAN读取失败: {ex.Message}");
return LuaNative.LUA_ERROR;
}
}
// Lua调用:写入CAN消息
private static int LuaCanWrite(IntPtr luaState)
{
try
{
// 获取参数:通道ID、消息ID和数据表
int argCount = LuaNative.lua_gettop(luaState);
if (argCount < 3)
{
LuaNative.lua_pushstring(luaState, "需要3个参数: channel_id, message_id, data_table");
return LuaNative.LUA_ERROR;
}
int channelId = (int)LuaNative.lua_tointeger(luaState, 1);
uint messageId = (uint)LuaNative.lua_tointeger(luaState, 2);
// 获取数据表
if (!LuaNative.lua_istable(luaState, 3))
{
LuaNative.lua_pushstring(luaState, "第三个参数必须是表");
return LuaNative.LUA_ERROR;
}
// 读取数据表
List<byte> dataList = new List<byte>();
LuaNative.lua_pushnil(luaState); // 第一个键
while (LuaNative.lua_next(luaState, 3) != 0)
{
// 键在-2,值在-1
if (LuaNative.lua_isnumber(luaState, -1) != 0)
{
byte value = (byte)LuaNative.lua_tointeger(luaState, -1);
dataList.Add(value);
}
LuaNative.lua_pop(luaState, 1); // 弹出值,保留键
}
byte[] data = dataList.ToArray();
// 写入CAN消息
var instance = FindObjectOfType<CanDataBridge>();
if (instance == null || instance.canBusManager == null)
{
LuaNative.lua_pushboolean(luaState, 0);
return 1;
}
bool success = instance.canBusManager.WriteMessage(channelId, messageId, data);
LuaNative.lua_pushboolean(luaState, success ? 1 : 0);
return 1;
}
catch (Exception ex)
{
LuaNative.lua_pushstring(luaState, $"CAN写入失败: {ex.Message}");
return LuaNative.LUA_ERROR;
}
}
// Lua调用:获取CAN总线状态
private static int LuaCanGetBusStatus(IntPtr luaState)
{
try
{
var instance = FindObjectOfType<CanDataBridge>();
if (instance == null || instance.canBusManager == null)
{
LuaNative.lua_pushnil(luaState);
return 1;
}
var status = instance.canBusManager.GetBusStatus();
// 创建状态表
LuaNative.lua_createtable(luaState, 0, 4);
LuaNative.lua_pushstring(luaState, "is_connected");
LuaNative.lua_pushboolean(luaState, status.IsConnected ? 1 : 0);
LuaNative.lua_settable(luaState, -3);
LuaNative.lua_pushstring(luaState, "error_count");
LuaNative.lua_pushinteger(luaState, status.ErrorCount);
LuaNative.lua_settable(luaState, -3);
LuaNative.lua_pushstring(luaState, "message_count");
LuaNative.lua_pushinteger(luaState, status.MessageCount);
LuaNative.lua_settable(luaState, -3);
LuaNative.lua_pushstring(luaState, "bit_rate");
LuaNative.lua_pushinteger(luaState, status.BitRate);
LuaNative.lua_settable(luaState, -3);
return 1;
}
catch (Exception ex)
{
LuaNative.lua_pushstring(luaState, $"获取CAN状态失败: {ex.Message}");
return LuaNative.LUA_ERROR;
}
}
// Lua调用:获取车速
private static int LuaGetVehicleSpeed(IntPtr luaState)
{
try
{
var instance = FindObjectOfType<CanDataBridge>();
if (instance == null)
{
LuaNative.lua_pushnil(luaState);
return 1;
}
// 从缓存获取车速消息
uint cacheKey = (0 << 16) | 0x100; // 假设通道0,消息ID 0x100
if (instance.canDataCache.TryGetValue(cacheKey, out CanMessage message))
{
float speed = BitConverter.ToSingle(message.Data, 0);
LuaNative.lua_pushnumber(luaState, speed);
}
else
{
LuaNative.lua_pushnil(luaState);
}
return 1;
}
catch (Exception ex)
{
LuaNative.lua_pushstring(luaState, $"获取车速失败: {ex.Message}");
return LuaNative.LUA_ERROR;
}
}
// Lua调用:获取发动机转速
private static int LuaGetEngineRpm(IntPtr luaState)
{
try
{
var instance = FindObjectOfType<CanDataBridge>();
if (instance == null)
{
LuaNative.lua_pushnil(luaState);
return 1;
}
// 从缓存获取转速消息
uint cacheKey = (0 << 16) | 0x101; // 假设通道0,消息ID 0x101
if (instance.canDataCache.TryGetValue(cacheKey, out CanMessage message))
{
float rpm = BitConverter.ToSingle(message.Data, 0);
LuaNative.lua_pushnumber(luaState, rpm);
}
else
{
LuaNative.lua_pushnil(luaState);
}
return 1;
}
catch (Exception ex)
{
LuaNative.lua_pushstring(luaState, $"获取转速失败: {ex.Message}");
return LuaNative.LUA_ERROR;
}
}
// Lua调用:获取油量
private static int LuaGetFuelLevel(IntPtr luaState)
{
try
{
var instance = FindObjectOfType<CanDataBridge>();
if (instance == null)
{
LuaNative.lua_pushnil(luaState);
return 1;
}
// 从缓存获取油量消息
uint cacheKey = (0 << 16) | 0x102; // 假设通道0,消息ID 0x102
if (instance.canDataCache.TryGetValue(cacheKey, out CanMessage message))
{
float fuelLevel = BitConverter.ToSingle(message.Data, 0);
LuaNative.lua_pushnumber(luaState, fuelLevel);
}
else
{
LuaNative.lua_pushnil(luaState);
}
return 1;
}
catch (Exception ex)
{
LuaNative.lua_pushstring(luaState, $"获取油量失败: {ex.Message}");
return LuaNative.LUA_ERROR;
}
}
#endregion
void OnDestroy()
{
// 清理资源
if (canBusManager != null)
{
canBusManager.OnCanMessageReceived -= HandleCanMessageReceived;
canBusManager.OnCanError -= HandleCanError;
}
Debug.Log("CAN数据桥接已销毁");
}
}
/// <summary>
/// CAN总线管理器(示例)
/// </summary>
public class CanBusManager : MonoBehaviour
{
private static CanBusManager instance;
public static CanBusManager Instance
{
get
{
if (instance == null)
{
GameObject go = new GameObject("CanBusManager");
instance = go.AddComponent<CanBusManager>();
DontDestroyOnLoad(go);
}
return instance;
}
}
// 事件
public event Action<CanMessage> OnCanMessageReceived;
public event Action<CanError> OnCanError;
// CAN通道
private Dictionary<int, CanChannel> channels = new Dictionary<int, CanChannel>();
// 初始化
void Start()
{
InitializeChannels();
}
void InitializeChannels()
{
// 创建示例通道
for (int i = 0; i < 2; i++)
{
channels[i] = new CanChannel(i);
}
Debug.Log($"CAN总线管理器初始化完成,创建了{channels.Count}个通道");
}
// 读取CAN消息
public CanMessage ReadMessage(int channelId, uint messageId)
{
if (channels.TryGetValue(channelId, out CanChannel channel))
{
return channel.ReadMessage(messageId);
}
return null;
}
// 写入CAN消息
public bool WriteMessage(int channelId, uint messageId, byte[] data)
{
if (channels.TryGetValue(channelId, out CanChannel channel))
{
return channel.WriteMessage(messageId, data);
}
return false;
}
// 获取所有通道
public List<CanChannel> GetAllChannels()
{
return new List<CanChannel>(channels.Values);
}
// 获取总线状态
public CanBusStatus GetBusStatus()
{
return new CanBusStatus
{
IsConnected = true,
ErrorCount = 0,
MessageCount = 1000,
BitRate = 500000
};
}
// 触发消息接收事件(示例)
public void SimulateMessageReceived(CanMessage message)
{
OnCanMessageReceived?.Invoke(message);
}
}
/// <summary>
/// CAN通道
/// </summary>
public class CanChannel
{
public int Id { get; private set; }
private Dictionary<uint, CanMessage> messages = new Dictionary<uint, CanMessage>();
public CanChannel(int id)
{
Id = id;
}
public CanMessage ReadMessage(uint messageId)
{
messages.TryGetValue(messageId, out CanMessage message);
return message;
}
public bool WriteMessage(uint messageId, byte[] data)
{
var message = new CanMessage
{
Id = messageId,
ChannelId = Id,
Data = data,
Timestamp = DateTime.Now.Ticks
};
messages[messageId] = message;
return true;
}
public List<CanMessage> GetAllMessages()
{
return new List<CanMessage>(messages.Values);
}
}
/// <summary>
/// CAN消息
/// </summary>
public class CanMessage
{
public uint Id { get; set; }
public int ChannelId { get; set; }
public byte[] Data { get; set; }
public long Timestamp { get; set; }
public bool HasChecksum { get; set; }
public bool IsValid { get; set; } = true;
public bool ValidateChecksum()
{
// 简化校验和验证
return true;
}
}
/// <summary>
/// CAN错误
/// </summary>
public class CanError
{
public int Code { get; set; }
public string Message { get; set; }
public DateTime Timestamp { get; set; }
}
/// <summary>
/// CAN总线状态
/// </summary>
public class CanBusStatus
{
public bool IsConnected { get; set; }
public int ErrorCount { get; set; }
public int MessageCount { get; set; }
public int BitRate { get; set; }
}
}
4.2 传感器数据传递
csharp
// SensorDataBridge.cs - 传感器数据桥接
using System;
using System.Collections.Generic;
using UnityEngine;
namespace Vehicle.LuaBridge.Examples
{
/// <summary>
/// 传感器数据桥接示例
/// </summary>
public class SensorDataBridge : MonoBehaviour
{
// 传感器管理器
private SensorManager sensorManager;
// Lua桥接
private LuaBridgeCore luaBridge;
// 数据传递管理器
private DataTransferManager transferManager;
// 传感器数据缓存
private Dictionary<string, SensorData> sensorCache = new Dictionary<string, SensorData>();
// 配置
public SensorBridgeConfig config = new SensorBridgeConfig();
[System.Serializable]
public class SensorBridgeConfig
{
public float updateInterval = 0.1f; // 更新间隔(秒)
public bool enableSensorFusion = true; // 启用传感器融合
public float dataSmoothingFactor = 0.1f; // 数据平滑因子
public bool enableCalibration = true; // 启用校准
public int maxRetryCount = 3; // 最大重试次数
}
void Start()
{
Initialize();
}
void Initialize()
{
// 获取桥接层
luaBridge = LuaBridgeCore.Instance;
transferManager = FindObjectOfType<DataTransferManager>();
// 初始化传感器管理器
InitializeSensorManager();
// 注册Lua回调
RegisterLuaCallbacks();
// 启动传感器数据更新
StartSensorUpdates();
Debug.Log("传感器数据桥接初始化完成");
}
void InitializeSensorManager()
{
sensorManager = SensorManager.Instance;
if (sensorManager == null)
{
sensorManager = gameObject.AddComponent<SensorManager>();
}
// 订阅传感器事件
sensorManager.OnSensorDataUpdated += HandleSensorDataUpdated;
sensorManager.OnSensorError += HandleSensorError;
// 初始化传感器
sensorManager.InitializeSensors();
Debug.Log("传感器管理器已初始化");
}
void RegisterLuaCallbacks()
{
// 注册传感器读取函数
luaBridge.RegisterCFunction("sensor_read", new LuaNativeFunction(LuaSensorRead));
luaBridge.RegisterCFunction("sensor_calibrate", new LuaNativeFunction(LuaSensorCalibrate));
luaBridge.RegisterCFunction("sensor_get_status", new LuaNativeFunction(LuaSensorGetStatus));
// 注册特定传感器函数
luaBridge.RegisterCFunction("sensor_get_acceleration", new LuaNativeFunction(LuaGetAcceleration));
luaBridge.RegisterCFunction("sensor_get_gyro", new LuaNativeFunction(LuaGetGyro));
luaBridge.RegisterCFunction("sensor_get_gps", new LuaNativeFunction(LuaGetGps));
luaBridge.RegisterCFunction("sensor_get_temperature", new LuaNativeFunction(LuaGetTemperature));
Debug.Log("传感器Lua回调函数已注册");
}
void StartSensorUpdates()
{
InvokeRepeating("UpdateSensorDataToLua", 0, config.updateInterval);
}
void UpdateSensorDataToLua()
{
if (sensorManager == null)
return;
// 获取所有传感器数据
var allSensors = sensorManager.GetAllSensors();
foreach (var sensor in allSensors)
{
UpdateSingleSensorToLua(sensor);
}
// 更新传感器融合数据
if (config.enableSensorFusion)
{
UpdateSensorFusionData();
}
}
void UpdateSingleSensorToLua(SensorBase sensor)
{
var data = sensor.GetData();
if (data == null)
return;
// 数据平滑处理
if (config.dataSmoothingFactor > 0)
{
data = ApplySmoothing(sensor.SensorId, data);
}
// 更新缓存
UpdateSensorCache(sensor.SensorId, data);
// 准备Lua变量名
string luaVarName = $"sensor_{sensor.SensorId}";
// 提交数据传输
try
{
transferManager.SubmitTransfer(luaVarName, data);
}
catch (TransferQueueFullException)
{
// 紧急传输
luaBridge.EmergencyTransfer(luaVarName, data);
}
}
SensorData ApplySmoothing(string sensorId, SensorData newData)
{
if (!sensorCache.ContainsKey(sensorId))
return newData;
var oldData = sensorCache[sensorId];
var smoothedData = new SensorData();
// 应用指数平滑
float alpha = config.dataSmoothingFactor;
if (newData.Acceleration != null && oldData.Acceleration != null)
{
smoothedData.Acceleration = Vector3.Lerp(oldData.Acceleration.Value,
newData.Acceleration.Value, alpha);
}
else
{
smoothedData.Acceleration = newData.Acceleration;
}
if (newData.Gyro != null && oldData.Gyro != null)
{
smoothedData.Gyro = Vector3.Lerp(oldData.Gyro.Value,
newData.Gyro.Value, alpha);
}
else
{
smoothedData.Gyro = newData.Gyro;
}
// 其他字段...
smoothedData.Temperature = newData.Temperature;
smoothedData.Timestamp = newData.Timestamp;
smoothedData.SensorId = newData.SensorId;
return smoothedData;
}
void UpdateSensorCache(string sensorId, SensorData data)
{
sensorCache[sensorId] = data;
}
void UpdateSensorFusionData()
{
// 传感器融合:结合多个传感器数据
var fusedData = new SensorFusionData();
// 获取加速度计数据
if (sensorCache.TryGetValue("accelerometer", out SensorData accelData))
{
fusedData.Acceleration = accelData.Acceleration;
}
// 获取陀螺仪数据
if (sensorCache.TryGetValue("gyroscope", out SensorData gyroData))
{
fusedData.AngularVelocity = gyroData.Gyro;
}
// 获取GPS数据
if (sensorCache.TryGetValue("gps", out SensorData gpsData))
{
fusedData.Position = gpsData.Position;
fusedData.Velocity = gpsData.Velocity;
}
// 计算姿态(简化版)
if (fusedData.Acceleration.HasValue)
{
// 使用加速度计估算姿态
var accel = fusedData.Acceleration.Value;
fusedData.Attitude = Quaternion.FromToRotation(Vector3.up, accel.normalized);
}
fusedData.Timestamp = DateTime.Now.Ticks;
// 传递给Lua
string luaVarName = "sensor_fusion_data";
transferManager.SubmitTransfer(luaVarName, fusedData);
}
void HandleSensorDataUpdated(string sensorId, SensorData data)
{
// 实时处理传感器数据更新
// 这里可以触发事件或执行特定逻辑
}
void HandleSensorError(string sensorId, string errorMessage)
{
Debug.LogError($"传感器错误 [{sensorId}]: {errorMessage}");
// 将错误信息传递给Lua
string luaVarName = $"sensor_{sensorId}_error";
transferManager.SubmitTransfer(luaVarName, errorMessage);
}
#region Lua回调函数
// Lua调用:读取传感器数据
private static int LuaSensorRead(IntPtr luaState)
{
try
{
// 获取参数:传感器ID
int argCount = LuaNative.lua_gettop(luaState);
if (argCount < 1)
{
LuaNative.lua_pushstring(luaState, "需要1个参数: sensor_id");
return LuaNative.LUA_ERROR;
}
string sensorId = LuaNative.lua_tostring(luaState, 1);
// 从传感器管理器读取数据
var instance = FindObjectOfType<SensorDataBridge>();
if (instance == null || instance.sensorManager == null)
{
LuaNative.lua_pushnil(luaState);
return 1;
}
var sensor = instance.sensorManager.GetSensor(sensorId);
if (sensor == null)
{
LuaNative.lua_pushnil(luaState);
return 1;
}
var data = sensor.GetData();
// 将数据转换为Lua表
PushSensorDataToLua(luaState, data);
return 1;
}
catch (Exception ex)
{
LuaNative.lua_pushstring(luaState, $"传感器读取失败: {ex.Message}");
return LuaNative.LUA_ERROR;
}
}
// Lua调用:校准传感器
private static int LuaSensorCalibrate(IntPtr luaState)
{
try
{
// 获取参数:传感器ID
int argCount = LuaNative.lua_gettop(luaState);
if (argCount < 1)
{
LuaNative.lua_pushstring(luaState, "需要1个参数: sensor_id");
return LuaNative.LUA_ERROR;
}
string sensorId = LuaNative.lua_tostring(luaState, 1);
// 校准传感器
var instance = FindObjectOfType<SensorDataBridge>();
if (instance == null || instance.sensorManager == null)
{
LuaNative.lua_pushboolean(luaState, 0);
return 1;
}
bool success = instance.sensorManager.CalibrateSensor(sensorId);
LuaNative.lua_pushboolean(luaState, success ? 1 : 0);
return 1;
}
catch (Exception ex)
{
LuaNative.lua_pushstring(luaState, $"传感器校准失败: {ex.Message}");
return LuaNative.LUA_ERROR;
}
}
// Lua调用:获取传感器状态
private static int LuaSensorGetStatus(IntPtr luaState)
{
try
{
// 获取参数:传感器ID
int argCount = LuaNative.lua_gettop(luaState);
string sensorId = null;
if (argCount >= 1)
{
sensorId = LuaNative.lua_tostring(luaState, 1);
}
var instance = FindObjectOfType<SensorDataBridge>();
if (instance == null || instance.sensorManager == null)
{
LuaNative.lua_pushnil(luaState);
return 1;
}
if (sensorId != null)
{
// 获取单个传感器状态
var sensor = instance.sensorManager.GetSensor(sensorId);
if (sensor == null)
{
LuaNative.lua_pushnil(luaState);
return 1;
}
var status = sensor.GetStatus();
PushSensorStatusToLua(luaState, status);
}
else
{
// 获取所有传感器状态
var allSensors = instance.sensorManager.GetAllSensors();
LuaNative.lua_createtable(luaState, allSensors.Count, 0);
for (int i = 0; i < allSensors.Count; i++)
{
var sensor = allSensors[i];
var status = sensor.GetStatus();
LuaNative.lua_pushstring(luaState, sensor.SensorId);
PushSensorStatusToLua(luaState, status);
LuaNative.lua_settable(luaState, -3);
}
}
return 1;
}
catch (Exception ex)
{
LuaNative.lua_pushstring(luaState, $"获取传感器状态失败: {ex.Message}");
return LuaNative.LUA_ERROR;
}
}
// Lua调用:获取加速度
private static int LuaGetAcceleration(IntPtr luaState)
{
try
{
var instance = FindObjectOfType<SensorDataBridge>();
if (instance == null)
{
LuaNative.lua_pushnil(luaState);
return 1;
}
// 从缓存获取加速度数据
if (instance.sensorCache.TryGetValue("accelerometer", out SensorData data))
{
if (data.Acceleration.HasValue)
{
LuaNative.lua_createtable(luaState, 0, 3);
LuaNative.lua_pushstring(luaState, "x");
LuaNative.lua_pushnumber(luaState, data.Acceleration.Value.x);
LuaNative.lua_settable(luaState, -3);
LuaNative.lua_pushstring(luaState, "y");
LuaNative.lua_pushnumber(luaState, data.Acceleration.Value.y);
LuaNative.lua_settable(luaState, -3);
LuaNative.lua_pushstring(luaState, "z");
LuaNative.lua_pushnumber(luaState, data.Acceleration.Value.z);
LuaNative.lua_settable(luaState, -3);
}
else
{
LuaNative.lua_pushnil(luaState);
}
}
else
{
LuaNative.lua_pushnil(luaState);
}
return 1;
}
catch (Exception ex)
{
LuaNative.lua_pushstring(luaState, $"获取加速度失败: {ex.Message}");
return LuaNative.LUA_ERROR;
}
}
// Lua调用:获取陀螺仪数据
private static int LuaGetGyro(IntPtr luaState)
{
try
{
var instance = FindObjectOfType<SensorDataBridge>();
if (instance == null)
{
LuaNative.lua_pushnil(luaState);
return 1;
}
// 从缓存获取陀螺仪数据
if (instance.sensorCache.TryGetValue("gyroscope", out SensorData data))
{
if (data.Gyro.HasValue)
{
LuaNative.lua_createtable(luaState, 0, 3);
LuaNative.lua_pushstring(luaState, "x");
LuaNative.lua_pushnumber(luaState, data.Gyro.Value.x);
LuaNative.lua_settable(luaState, -3);
LuaNative.lua_pushstring(luaState, "y");
LuaNative.lua_pushnumber(luaState, data.Gyro.Value.y);
LuaNative.lua_settable(luaState, -3);
LuaNative.lua_pushstring(luaState, "z");
LuaNative.lua_pushnumber(luaState, data.Gyro.Value.z);
LuaNative.lua_settable(luaState, -3);
}
else
{
LuaNative.lua_pushnil(luaState);
}
}
else
{
LuaNative.lua_pushnil(luaState);
}
return 1;
}
catch (Exception ex)
{
LuaNative.lua_pushstring(luaState, $"获取陀螺仪数据失败: {ex.Message}");
return LuaNative.LUA_ERROR;
}
}
// Lua调用:获取GPS数据
private static int LuaGetGps(IntPtr luaState)
{
try
{
var instance = FindObjectOfType<SensorDataBridge>();
if (instance == null)
{
LuaNative.lua_pushnil(luaState);
return 1;
}
// 从缓存获取GPS数据
if (instance.sensorCache.TryGetValue("gps", out SensorData data))
{
LuaNative.lua_createtable(luaState, 0, 5);
if (data.Position.HasValue)
{
LuaNative.lua_pushstring(luaState, "latitude");
LuaNative.lua_pushnumber(luaState, data.Position.Value.x);
LuaNative.lua_settable(luaState, -3);
LuaNative.lua_pushstring(luaState, "longitude");
LuaNative.lua_pushnumber(luaState, data.Position.Value.y);
LuaNative.lua_settable(luaState, -3);
LuaNative.lua_pushstring(luaState, "altitude");
LuaNative.lua_pushnumber(luaState, data.Position.Value.z);
LuaNative.lua_settable(luaState, -3);
}
if (data.Velocity.HasValue)
{
LuaNative.lua_pushstring(luaState, "speed");
LuaNative.lua_pushnumber(luaState, data.Velocity.Value.magnitude);
LuaNative.lua_settable(luaState, -3);
}
LuaNative.lua_pushstring(luaState, "timestamp");
LuaNative.lua_pushinteger(luaState, data.Timestamp);
LuaNative.lua_settable(luaState, -3);
}
else
{
LuaNative.lua_pushnil(luaState);
}
return 1;
}
catch (Exception ex)
{
LuaNative.lua_pushstring(luaState, $"获取GPS数据失败: {ex.Message}");
return LuaNative.LUA_ERROR;
}
}
// Lua调用:获取温度
private static int LuaGetTemperature(IntPtr luaState)
{
try
{
var instance = FindObjectOfType<SensorDataBridge>();
if (instance == null)
{
LuaNative.lua_pushnil(luaState);
return 1;
}
// 从缓存获取温度数据
if (instance.sensorCache.TryGetValue("temperature", out SensorData data))
{
if (data.Temperature.HasValue)
{
LuaNative.lua_pushnumber(luaState, data.Temperature.Value);
}
else
{
LuaNative.lua_pushnil(luaState);
}
}
else
{
LuaNative.lua_pushnil(luaState);
}
return 1;
}
catch (Exception ex)
{
LuaNative.lua_pushstring(luaState, $"获取温度失败: {ex.Message}");
return LuaNative.LUA_ERROR;
}
}
// 推送传感器数据到Lua栈
private static void PushSensorDataToLua(IntPtr luaState, SensorData data)
{
if (data == null)
{
LuaNative.lua_pushnil(luaState);
return;
}
LuaNative.lua_createtable(luaState, 0, 8);
LuaNative.lua_pushstring(luaState, "sensor_id");
LuaNative.lua_pushstring(luaState, data.SensorId);
LuaNative.lua_settable(luaState, -3);
LuaNative.lua_pushstring(luaState, "timestamp");
LuaNative.lua_pushinteger(luaState, data.Timestamp);
LuaNative.lua_settable(luaState, -3);
if (data.Acceleration.HasValue)
{
LuaNative.lua_pushstring(luaState, "acceleration");
LuaNative.lua_createtable(luaState, 0, 3);
LuaNative.lua_pushstring(luaState, "x");
LuaNative.lua_pushnumber(luaState, data.Acceleration.Value.x);
LuaNative.lua_settable(luaState, -3);
LuaNative.lua_pushstring(luaState, "y");
LuaNative.lua_pushnumber(luaState, data.Acceleration.Value.y);
LuaNative.lua_settable(luaState, -3);
LuaNative.lua_pushstring(luaState, "z");
LuaNative.lua_pushnumber(luaState, data.Acceleration.Value.z);
LuaNative.lua_settable(luaState, -3);
LuaNative.lua_settable(luaState, -3);
}
if (data.Gyro.HasValue)
{
LuaNative.lua_pushstring(luaState, "gyro");
LuaNative.lua_createtable(luaState, 0, 3);
LuaNative.lua_pushstring(luaState, "x");
LuaNative.lua_pushnumber(luaState, data.Gyro.Value.x);
LuaNative.lua_settable(luaState, -3);
LuaNative.lua_pushstring(luaState, "y");
LuaNative.lua_pushnumber(luaState, data.Gyro.Value.y);
LuaNative.lua_settable(luaState, -3);
LuaNative.lua_pushstring(luaState, "z");
LuaNative.lua_pushnumber(luaState, data.Gyro.Value.z);
LuaNative.lua_settable(luaState, -3);
LuaNative.lua_settable(luaState, -3);
}
if (data.Temperature.HasValue)
{
LuaNative.lua_pushstring(luaState, "temperature");
LuaNative.lua_pushnumber(luaState, data.Temperature.Value);
LuaNative.lua_settable(luaState, -3);
}
LuaNative.lua_pushstring(luaState, "accuracy");
LuaNative.lua_pushnumber(luaState, data.Accuracy);
LuaNative.lua_settable(luaState, -3);
}
// 推送传感器状态到Lua栈
private static void PushSensorStatusToLua(IntPtr luaState, SensorStatus status)
{
LuaNative.lua_createtable(luaState, 0, 5);
LuaNative.lua_pushstring(luaState, "is_enabled");
LuaNative.lua_pushboolean(luaState, status.IsEnabled ? 1 : 0);
LuaNative.lua_settable(luaState, -3);
LuaNative.lua_pushstring(luaState, "is_calibrated");
LuaNative.lua_pushboolean(luaState, status.IsCalibrated ? 1 : 0);
LuaNative.lua_settable(luaState, -3);
LuaNative.lua_pushstring(luaState, "update_rate");
LuaNative.lua_pushnumber(luaState, status.UpdateRate);
LuaNative.lua_settable(luaState, -3);
LuaNative.lua_pushstring(luaState, "error_count");
LuaNative.lua_pushinteger(luaState, status.ErrorCount);
LuaNative.lua_settable(luaState, -3);
LuaNative.lua_pushstring(luaState, "last_update");
LuaNative.lua_pushinteger(luaState, status.LastUpdateTime);
LuaNative.lua_settable(luaState, -3);
}
#endregion
void OnDestroy()
{
// 清理资源
if (sensorManager != null)
{
sensorManager.OnSensorDataUpdated -= HandleSensorDataUpdated;
sensorManager.OnSensorError -= HandleSensorError;
}
Debug.Log("传感器数据桥接已销毁");
}
}
/// <summary>
/// 传感器管理器
/// </summary>
public class SensorManager : MonoBehaviour
{
private static SensorManager instance;
public static SensorManager Instance
{
get
{
if (instance == null)
{
GameObject go = new GameObject("SensorManager");
instance = go.AddComponent<SensorManager>();
DontDestroyOnLoad(go);
}
return instance;
}
}
// 事件
public event Action<string, SensorData> OnSensorDataUpdated;
public event Action<string, string> OnSensorError;
// 传感器字典
private Dictionary<string, SensorBase> sensors = new Dictionary<string, SensorBase>();
// 初始化传感器
public void InitializeSensors()
{
// 创建示例传感器
AddSensor(new AccelerometerSensor());
AddSensor(new GyroscopeSensor());
AddSensor(new GpsSensor());
AddSensor(new TemperatureSensor());
Debug.Log($"传感器管理器初始化完成,创建了{sensors.Count}个传感器");
}
// 添加传感器
public void AddSensor(SensorBase sensor)
{
sensors[sensor.SensorId] = sensor;
sensor.Initialize();
}
// 获取传感器
public SensorBase GetSensor(string sensorId)
{
sensors.TryGetValue(sensorId, out SensorBase sensor);
return sensor;
}
// 获取所有传感器
public List<SensorBase> GetAllSensors()
{
return new List<SensorBase>(sensors.Values);
}
// 校准传感器
public bool CalibrateSensor(string sensorId)
{
var sensor = GetSensor(sensorId);
if (sensor == null)
return false;
return sensor.Calibrate();
}
// 触发数据更新事件
public void TriggerDataUpdate(string sensorId, SensorData data)
{
OnSensorDataUpdated?.Invoke(sensorId, data);
}
// 触发错误事件
public void TriggerError(string sensorId, string errorMessage)
{
OnSensorError?.Invoke(sensorId, errorMessage);
}
}
/// <summary>
/// 传感器基类
/// </summary>
public abstract class SensorBase
{
public abstract string SensorId { get; }
public abstract SensorType Type { get; }
public abstract void Initialize();
public abstract SensorData GetData();
public abstract SensorStatus GetStatus();
public abstract bool Calibrate();
}
/// <summary>
/// 传感器数据类型
/// </summary>
public class SensorData
{
public string SensorId { get; set; }
public long Timestamp { get; set; }
public Vector3? Acceleration { get; set; }
public Vector3? Gyro { get; set; }
public Vector3? Position { get; set; }
public Vector3? Velocity { get; set; }
public float? Temperature { get; set; }
public float Accuracy { get; set; }
}
/// <summary>
/// 传感器融合数据
/// </summary>
public class SensorFusionData
{
public Vector3? Acceleration { get; set; }
public Vector3? AngularVelocity { get; set; }
public Vector3? Position { get; set; }
public Vector3? Velocity { get; set; }
public Quaternion? Attitude { get; set; }
public long Timestamp { get; set; }
}
/// <summary>
/// 传感器状态
/// </summary>
public class SensorStatus
{
public bool IsEnabled { get; set; }
public bool IsCalibrated { get; set; }
public float UpdateRate { get; set; }
public int ErrorCount { get; set; }
public long LastUpdateTime { get; set; }
}
/// <summary>
/// 传感器类型
/// </summary>
public enum SensorType
{
Accelerometer,
Gyroscope,
Magnetometer,
Gps,
Temperature,
Pressure,
Humidity
}
/// <summary>
/// 加速度计传感器
/// </summary>
public class AccelerometerSensor : SensorBase
{
public override string SensorId => "accelerometer";
public override SensorType Type => SensorType.Accelerometer;
private SensorData currentData;
private SensorStatus status;
public override void Initialize()
{
currentData = new SensorData
{
SensorId = SensorId,
Timestamp = DateTime.Now.Ticks
};
status = new SensorStatus
{
IsEnabled = true,
IsCalibrated = false,
UpdateRate = 100, // Hz
ErrorCount = 0,
LastUpdateTime = DateTime.Now.Ticks
};
// 初始化硬件加速度计
Input.gyro.enabled = true;
}
public override SensorData GetData()
{
// 从Unity输入系统获取加速度数据
Vector3 acceleration = Input.acceleration;
currentData.Acceleration = acceleration;
currentData.Timestamp = DateTime.Now.Ticks;
currentData.Accuracy = 0.1f; // 假设精度为0.1
status.LastUpdateTime = currentData.Timestamp;
return currentData;
}
public override SensorStatus GetStatus()
{
return status;
}
public override bool Calibrate()
{
// 简化校准过程
status.IsCalibrated = true;
return true;
}
}
/// <summary>
/// 陀螺仪传感器
/// </summary>
public class GyroscopeSensor : SensorBase
{
public override string SensorId => "gyroscope";
public override SensorType Type => SensorType.Gyroscope;
private SensorData currentData;
private SensorStatus status;
public override void Initialize()
{
currentData = new SensorData
{
SensorId = SensorId,
Timestamp = DateTime.Now.Ticks
};
status = new SensorStatus
{
IsEnabled = true,
IsCalibrated = false,
UpdateRate = 100, // Hz
ErrorCount = 0,
LastUpdateTime = DateTime.Now.Ticks
};
// 初始化硬件陀螺仪
Input.gyro.enabled = true;
}
public override SensorData GetData()
{
// 从Unity输入系统获取陀螺仪数据
Vector3 rotationRate = Input.gyro.rotationRate;
currentData.Gyro = rotationRate;
currentData.Timestamp = DateTime.Now.Ticks;
currentData.Accuracy = 0.05f; // 假设精度为0.05
status.LastUpdateTime = currentData.Timestamp;
return currentData;
}
public override SensorStatus GetStatus()
{
return status;
}
public override bool Calibrate()
{
status.IsCalibrated = true;
return true;
}
}
/// <summary>
/// GPS传感器
/// </summary>
public class GpsSensor : SensorBase
{
public override string SensorId => "gps";
public override SensorType Type => SensorType.Gps;
private SensorData currentData;
private SensorStatus status;
public override void Initialize()
{
currentData = new SensorData
{
SensorId = SensorId,
Timestamp = DateTime.Now.Ticks
};
status = new SensorStatus
{
IsEnabled = true,
IsCalibrated = true,
UpdateRate = 1, // Hz
ErrorCount = 0,
LastUpdateTime = DateTime.Now.Ticks
};
// 初始化GPS(如果支持)
// Input.location.Start();
}
public override SensorData GetData()
{
// 模拟GPS数据
currentData.Position = new Vector3(
31.2304f + (UnityEngine.Random.value - 0.5f) * 0.001f, // 纬度
121.4737f + (UnityEngine.Random.value - 0.5f) * 0.001f, // 经度
10.0f + UnityEngine.Random.value * 5.0f // 海拔
);
currentData.Velocity = new Vector3(
UnityEngine.Random.value * 2.0f, // 东向速度
UnityEngine.Random.value * 2.0f, // 北向速度
0.0f // 垂直速度
);
currentData.Timestamp = DateTime.Now.Ticks;
currentData.Accuracy = 5.0f; // GPS精度5米
status.LastUpdateTime = currentData.Timestamp;
return currentData;
}
public override SensorStatus GetStatus()
{
return status;
}
public override bool Calibrate()
{
// GPS通常不需要校准
return true;
}
}
/// <summary>
/// 温度传感器
/// </summary>
public class TemperatureSensor : SensorBase
{
public override string SensorId => "temperature";
public override SensorType Type => SensorType.Temperature;
private SensorData currentData;
private SensorStatus status;
public override void Initialize()
{
currentData = new SensorData
{
SensorId = SensorId,
Timestamp = DateTime.Now.Ticks
};
status = new SensorStatus
{
IsEnabled = true,
IsCalibrated = true,
UpdateRate = 1, // Hz
ErrorCount = 0,
LastUpdateTime = DateTime.Now.Ticks
};
}
public override SensorData GetData()
{
// 模拟温度数据
currentData.Temperature = 25.0f + UnityEngine.Random.value * 10.0f;
currentData.Timestamp = DateTime.Now.Ticks;
currentData.Accuracy = 0.5f; // 温度精度0.5°C
status.LastUpdateTime = currentData.Timestamp;
return currentData;
}
public override SensorStatus GetStatus()
{
return status;
}
public override bool Calibrate()
{
return true;
}
}
}
第五部分:性能优化与调试
5.1 桥接层性能监控
csharp
// BridgePerformanceMonitor.cs - 桥接层性能监控
using System;
using System.Collections.Generic;
using System.Diagnostics;
using UnityEngine;
namespace Vehicle.LuaBridge
{
/// <summary>
/// 桥接层性能监控器
/// </summary>
public class BridgePerformanceMonitor
{
// 监控配置
private PerformanceConfig config = new PerformanceConfig();
// 性能数据
private PerformanceData performanceData = new PerformanceData();
// 时间采样
private Stopwatch frameTimer = new Stopwatch();
private Stopwatch callTimer = new Stopwatch();
// 调用跟踪
private Dictionary<string, CallStats> callStats = new Dictionary<string, CallStats>();
private Stack<CallTrace> callStack = new Stack<CallTrace>();
// 内存监控
private MemoryMonitor memoryMonitor = new MemoryMonitor();
// 事件
public event Action<PerformanceAlert> OnPerformanceAlert;
public BridgePerformanceMonitor()
{
Initialize();
}
void Initialize()
{
frameTimer.Start();
memoryMonitor.Start();
}
public void StartMonitoring()
{
performanceData.StartTime = DateTime.Now;
performanceData.IsRunning = true;
Debug.Log("桥接层性能监控已启动");
}
public void Stop()
{
performanceData.IsRunning = false;
frameTimer.Stop();
memoryMonitor.Stop();
Debug.Log("桥接层性能监控已停止");
}
public void Update()
{
if (!performanceData.IsRunning)
return;
// 更新帧时间
performanceData.FrameCount++;
performanceData.TotalFrameTimeMs += frameTimer.ElapsedMilliseconds;
performanceData.AverageFrameTimeMs = performanceData.TotalFrameTimeMs / performanceData.FrameCount;
// 检查性能阈值
CheckPerformanceThresholds();
// 重置帧计时器
frameTimer.Restart();
// 更新内存监控
memoryMonitor.Update();
performanceData.MemoryUsage = memoryMonitor.CurrentUsage;
performanceData.MemoryPeak = memoryMonitor.PeakUsage;
// 清理旧数据
CleanupOldData();
}
public void RecordCall(string callName, int dataSize = 0)
{
if (!performanceData.IsRunning)
return;
callTimer.Restart();
// 开始调用跟踪
var trace = new CallTrace
{
CallName = callName,
StartTime = DateTime.Now,
StartMemory = memoryMonitor.CurrentUsage
};
callStack.Push(trace);
// 更新调用统计
if (!callStats.ContainsKey(callName))
{
callStats[callName] = new CallStats
{
CallName = callName
};
}
var stats = callStats[callName];
stats.CallCount++;
stats.TotalDataSize += dataSize;
performanceData.TotalCalls++;
performanceData.TotalDataTransferred += dataSize;
}
public void EndCall()
{
if (!performanceData.IsRunning || callStack.Count == 0)
return;
callTimer.Stop();
var trace = callStack.Pop();
var elapsedMs = callTimer.ElapsedMilliseconds;
var memoryDelta = memoryMonitor.CurrentUsage - trace.StartMemory;
// 更新调用统计
var stats = callStats[trace.CallName];
stats.TotalTimeMs += elapsedMs;
stats.MaxTimeMs = Math.Max(stats.MaxTimeMs, elapsedMs);
stats.MinTimeMs = Math.Min(stats.MinTimeMs, elapsedMs);
stats.AverageTimeMs = stats.TotalTimeMs / stats.CallCount;
stats.TotalMemoryDelta += memoryDelta;
// 更新总体统计
performanceData.TotalCallTimeMs += elapsedMs;
performanceData.AverageCallTimeMs = performanceData.TotalCallTimeMs / performanceData.TotalCalls;
// 检查调用性能
CheckCallPerformance(trace.CallName, elapsedMs, memoryDelta);
}
public void RecordCacheHit()
{
performanceData.CacheHits++;
performanceData.CacheHitRate = (float)performanceData.CacheHits /
(performanceData.CacheHits + performanceData.CacheMisses);
}
public void RecordCacheMiss()
{
performanceData.CacheMisses++;
performanceData.CacheHitRate = (float)performanceData.CacheHits /
(performanceData.CacheHits + performanceData.CacheMisses);
}
void CheckPerformanceThresholds()
{
// 检查帧时间
if (performanceData.AverageFrameTimeMs > config.FrameTimeThresholdMs)
{
RaiseAlert(PerformanceAlertType.HighFrameTime,
$"平均帧时间过高: {performanceData.AverageFrameTimeMs:F2}ms");
}
// 检查调用时间
if (performanceData.AverageCallTimeMs > config.CallTimeThresholdMs)
{
RaiseAlert(PerformanceAlertType.HighCallTime,
$"平均调用时间过高: {performanceData.AverageCallTimeMs:F2}ms");
}
// 检查内存使用
if (performanceData.MemoryUsage > config.MemoryThresholdMB * 1024 * 1024)
{
RaiseAlert(PerformanceAlertType.HighMemoryUsage,
$"内存使用过高: {performanceData.MemoryUsage / (1024 * 1024):F2}MB");
}
// 检查缓存命中率
if (performanceData.CacheHitRate < config.CacheHitRateThreshold)
{
RaiseAlert(PerformanceAlertType.LowCacheHitRate,
$"缓存命中率过低: {performanceData.CacheHitRate:P2}");
}
}
void CheckCallPerformance(string callName, long elapsedMs, long memoryDelta)
{
var stats = callStats[callName];
// 检查调用时间
if (elapsedMs > config.CallTimeThresholdMs)
{
RaiseAlert(PerformanceAlertType.SlowCall,
$"调用 {callName} 耗时过长: {elapsedMs}ms");
}
// 检查内存增长
if (memoryDelta > config.MemoryGrowthThresholdKB * 1024)
{
RaiseAlert(PerformanceAlertType.MemoryLeakSuspected,
$"调用 {callName} 可能内存泄漏: 增长{memoryDelta / 1024}KB");
}
}
void RaiseAlert(PerformanceAlertType type, string message)
{
var alert = new PerformanceAlert
{
Type = type,
Message = message,
Timestamp = DateTime.Now,
FrameCount = performanceData.FrameCount,
MemoryUsage = performanceData.MemoryUsage,
CallCount = performanceData.TotalCalls
};
OnPerformanceAlert?.Invoke(alert);
Debug.LogWarning($"[性能警报] {type}: {message}");
}
void CleanupOldData()
{
// 清理旧的调用统计
var cutoffTime = DateTime.Now.AddMinutes(-config.DataRetentionMinutes);
var keysToRemove = new List<string>();
foreach (var kvp in callStats)
{
if (kvp.Value.LastCallTime < cutoffTime &&
kvp.Value.CallCount < config.MinCallCountToKeep)
{
keysToRemove.Add(kvp.Key);
}
}
foreach (var key in keysToRemove)
{
callStats.Remove(key);
}
// 重置小时统计
if (DateTime.Now.Hour != performanceData.LastResetHour)
{
ResetHourlyStats();
}
}
void ResetHourlyStats()
{
performanceData.LastResetHour = DateTime.Now.Hour;
performanceData.HourlyCalls = 0;
performanceData.HourlyDataTransferred = 0;
}
public PerformanceStats GetStats()
{
return new PerformanceStats
{
FrameCount = performanceData.FrameCount,
AverageFrameTimeMs = performanceData.AverageFrameTimeMs,
TotalCalls = performanceData.TotalCalls,
AverageCallTimeMs = performanceData.AverageCallTimeMs,
CacheHitRate = performanceData.CacheHitRate,
MemoryUsage = performanceData.MemoryUsage,
MemoryPeak = performanceData.MemoryPeak,
TotalDataTransferred = performanceData.TotalDataTransferred,
ActiveConnections = performanceData.ActiveConnections,
Uptime = DateTime.Now - performanceData.StartTime
};
}
public Dictionary<string, CallStats> GetCallStats()
{
return new Dictionary<string, CallStats>(callStats);
}
public AccessPattern GetAccessPattern()
{
// 分析访问模式
int hotDataCount = 0;
int totalDataCount = callStats.Count;
foreach (var stats in callStats.Values)
{
if (stats.CallCount > config.HotDataThreshold)
{
hotDataCount++;
}
}
return new AccessPattern
{
TotalCalls = performanceData.TotalCalls,
UniqueCalls = totalDataCount,
HotDataCount = hotDataCount,
HotDataRatio = totalDataCount > 0 ? (float)hotDataCount / totalDataCount : 0,
AverageCallsPerMinute = performanceData.TotalCalls /
Math.Max(1, (DateTime.Now - performanceData.StartTime).TotalMinutes)
};
}
}
/// <summary>
/// 性能配置
/// </summary>
[System.Serializable]
public class PerformanceConfig
{
public float FrameTimeThresholdMs = 16.67f; // 60FPS对应的帧时间
public float CallTimeThresholdMs = 10.0f; // 调用时间阈值
public int MemoryThresholdMB = 100; // 内存阈值(MB)
public int MemoryGrowthThresholdKB = 1024; // 内存增长阈值(KB)
public float CacheHitRateThreshold = 0.7f; // 缓存命中率阈值
public int HotDataThreshold = 100; // 热点数据阈值(调用次数)
public int MinCallCountToKeep = 10; // 最小保持调用次数
public int DataRetentionMinutes = 60; // 数据保留时间(分钟)
}
/// <summary>
/// 性能数据
/// </summary>
public class PerformanceData
{
public bool IsRunning { get; set; }
public DateTime StartTime { get; set; }
public int LastResetHour { get; set; }
// 帧统计
public long FrameCount { get; set; }
public long TotalFrameTimeMs { get; set; }
public float AverageFrameTimeMs { get; set; }
// 调用统计
public long TotalCalls { get; set; }
public long TotalCallTimeMs { get; set; }
public float AverageCallTimeMs { get; set; }
// 缓存统计
public int CacheHits { get; set; }
public int CacheMisses { get; set; }
public float CacheHitRate { get; set; }
// 内存统计
public long MemoryUsage { get; set; }
public long MemoryPeak { get; set; }
// 数据传输统计
public long TotalDataTransferred { get; set; }
public long HourlyDataTransferred { get; set; }
public int HourlyCalls { get; set; }
// 连接统计
public int ActiveConnections { get; set; }
}
/// <summary>
/// 调用统计
/// </summary>
public class CallStats
{
public string CallName { get; set; }
public int CallCount { get; set; }
public long TotalTimeMs { get; set; }
public long MaxTimeMs { get; set; }
public long MinTimeMs { get; set; } = long.MaxValue;
public float AverageTimeMs { get; set; }
public long TotalDataSize { get; set; }
public long TotalMemoryDelta { get; set; }
public DateTime LastCallTime { get; set; } = DateTime.Now;
}
/// <summary>
/// 调用跟踪
/// </summary>
public class CallTrace
{
public string CallName { get; set; }
public DateTime StartTime { get; set; }
public long StartMemory { get; set; }
}
/// <summary>
/// 内存监控器
/// </summary>
public class MemoryMonitor
{
public long CurrentUsage { get; private set; }
public long PeakUsage { get; private set; }
private System.Diagnostics.Process process;
public void Start()
{
process = System.Diagnostics.Process.GetCurrentProcess();
Update();
}
public void Update()
{
if (process == null)
return;
process.Refresh();
CurrentUsage = process.WorkingSet64;
PeakUsage = Math.Max(PeakUsage, CurrentUsage);
}
public void Stop()
{
process = null;
}
}
/// <summary>
/// 性能警报类型
/// </summary>
public enum PerformanceAlertType
{
HighFrameTime,
HighCallTime,
HighMemoryUsage,
LowCacheHitRate,
SlowCall,
MemoryLeakSuspected,
ConnectionLimitExceeded
}
/// <summary>
/// 性能警报
/// </summary>
public class PerformanceAlert
{
public PerformanceAlertType Type { get; set; }
public string Message { get; set; }
public DateTime Timestamp { get; set; }
public long FrameCount { get; set; }
public long MemoryUsage { get; set; }
public long CallCount { get; set; }
}
/// <summary>
/// 性能统计
/// </summary>
public class PerformanceStats
{
public long FrameCount { get; set; }
public float AverageFrameTimeMs { get; set; }
public long TotalCalls { get; set; }
public float AverageCallTimeMs { get; set; }
public float CacheHitRate { get; set; }
public long MemoryUsage { get; set; }
public long MemoryPeak { get; set; }
public long TotalDataTransferred { get; set; }
public int ActiveConnections { get; set; }
public TimeSpan Uptime { get; set; }
}
/// <summary>
/// 访问模式
/// </summary>
public class AccessPattern
{
public long TotalCalls { get; set; }
public int UniqueCalls { get; set; }
public int HotDataCount { get; set; }
public float HotDataRatio { get; set; }
public float AverageCallsPerMinute { get; set; }
}
}
5.2 调试与故障排查
csharp
// BridgeDebugger.cs - 桥接层调试器
using System;
using System.Collections.Generic;
using System.IO;
using System.Text;
using UnityEngine;
namespace Vehicle.LuaBridge
{
/// <summary>
/// 桥接层调试器
/// </summary>
public class BridgeDebugger : MonoBehaviour
{
// 调试配置
public DebuggerConfig config = new DebuggerConfig();
// 桥接层引用
private LuaBridgeCore bridgeCore;
private DataTransferManager transferManager;
// 调试数据
private DebugData debugData = new DebugData();
// 日志文件
private StreamWriter logWriter;
private string logFilePath;
void Start()
{
Initialize();
}
void Initialize()
{
bridgeCore = LuaBridgeCore.Instance;
transferManager = FindObjectOfType<DataTransferManager>();
// 初始化日志系统
InitializeLogging();
// 注册调试命令
RegisterDebugCommands();
// 启动调试监控
StartDebugMonitoring();
Debug.Log("桥接层调试器初始化完成");
}
void InitializeLogging()
{
if (!config.enableLogging)
return;
// 创建日志目录
string logDir = Path.Combine(Application.persistentDataPath, "BridgeLogs");
if (!Directory.Exists(logDir))
{
Directory.CreateDirectory(logDir);
}
// 创建日志文件
logFilePath = Path.Combine(logDir, $"bridge_log_{DateTime.Now:yyyyMMdd_HHmmss}.txt");
logWriter = new StreamWriter(logFilePath, true, Encoding.UTF8);
// 写入日志头
logWriter.WriteLine("=== Lua桥接层调试日志 ===");
logWriter.WriteLine($"开始时间: {DateTime.Now}");
logWriter.WriteLine($"应用版本: {Application.version}");
logWriter.WriteLine($"设备型号: {SystemInfo.deviceModel}");
logWriter.WriteLine();
logWriter.Flush();
Debug.Log($"调试日志已创建: {logFilePath}");
}
void RegisterDebugCommands()
{
// 注册调试命令到Lua
RegisterLuaDebugCommands();
// 注册控制台命令
RegisterConsoleCommands();
}
void RegisterLuaDebugCommands()
{
// 注册调试函数到Lua
bridgeCore.RegisterCFunction("debug_log", new LuaNativeFunction(LuaDebugLog));
bridgeCore.RegisterCFunction("debug_get_stats", new LuaNativeFunction(LuaDebugGetStats));
bridgeCore.RegisterCFunction("debug_dump_state", new LuaNativeFunction(LuaDebugDumpState));
bridgeCore.RegisterCFunction("debug_test_performance", new LuaNativeFunction(LuaDebugTestPerformance));
Debug.Log("Lua调试命令已注册");
}
void RegisterConsoleCommands()
{
// 这里可以注册Unity控制台命令
// 例如:通过某个UI或输入系统触发调试命令
}
void StartDebugMonitoring()
{
if (config.enablePerformanceMonitoring)
{
InvokeRepeating("MonitorPerformance", 1.0f, config.monitoringInterval);
}
if (config.enableMemoryMonitoring)
{
InvokeRepeating("MonitorMemory", 5.0f, 5.0f);
}
if (config.enableDataValidation)
{
// 启动数据验证
StartDataValidation();
}
}
void MonitorPerformance()
{
// 收集性能数据
var perfStats = bridgeCore.GetPerformanceStats();
debugData.PerformanceSamples.Add(new PerformanceSample
{
Timestamp = DateTime.Now,
FrameTime = Time.deltaTime * 1000f,
MemoryUsage = GC.GetTotalMemory(false) / (1024 * 1024f),
CallCount = perfStats.TotalCalls,
CacheHitRate = perfStats.CacheHitRate
});
// 保持最近的样本
if (debugData.PerformanceSamples.Count > config.maxSamples)
{
debugData.PerformanceSamples.RemoveAt(0);
}
// 检查性能问题
CheckPerformanceIssues();
}
void MonitorMemory()
{
long currentMemory = GC.GetTotalMemory(false);
debugData.MemorySamples.Add(new MemorySample
{
Timestamp = DateTime.Now,
MemoryMB = currentMemory / (1024 * 1024f),
CollectionCount = GC.CollectionCount(0)
});
// 检查内存泄漏
CheckMemoryLeaks();
}
void CheckPerformanceIssues()
{
if (debugData.PerformanceSamples.Count < 10)
return;
// 检查帧时间
float avgFrameTime = 0;
foreach (var sample in debugData.PerformanceSamples)
{
avgFrameTime += sample.FrameTime;
}
avgFrameTime /= debugData.PerformanceSamples.Count;
if (avgFrameTime > config.frameTimeWarningThreshold)
{
LogWarning($"平均帧时间过高: {avgFrameTime:F2}ms");
}
// 检查缓存命中率
float avgCacheHitRate = 0;
foreach (var sample in debugData.PerformanceSamples)
{
avgCacheHitRate += sample.CacheHitRate;
}
avgCacheHitRate /= debugData.PerformanceSamples.Count;
if (avgCacheHitRate < config.cacheHitRateWarningThreshold)
{
LogWarning($"缓存命中率过低: {avgCacheHitRate:P2}");
}
}
void CheckMemoryLeaks()
{
if (debugData.MemorySamples.Count < 20)
return;
// 检查内存增长趋势
var firstSample = debugData.MemorySamples[0];
var lastSample = debugData.MemorySamples[debugData.MemorySamples.Count - 1];
float timeDiff = (float)(lastSample.Timestamp - firstSample.Timestamp).TotalMinutes;
float memoryDiff = lastSample.MemoryMB - firstSample.MemoryMB;
if (timeDiff > 1.0f && memoryDiff > config.memoryLeakThresholdMB)
{
float leakRate = memoryDiff / timeDiff; // MB/min
if (leakRate > config.memoryLeakRateThreshold)
{
LogError($"检测到可能的内存泄漏: {leakRate:F2} MB/min");
DumpMemoryInfo();
}
}
}
void StartDataValidation()
{
// 启动数据验证协程
StartCoroutine(DataValidationRoutine());
}
System.Collections.IEnumerator DataValidationRoutine()
{
while (true)
{
yield return new WaitForSeconds(config.dataValidationInterval);
// 验证数据完整性
ValidateDataIntegrity();
}
}
void ValidateDataIntegrity()
{
// 这里可以实现数据完整性检查
// 例如:检查缓存一致性、验证序列化数据等
}
void DumpMemoryInfo()
{
StringBuilder sb = new StringBuilder();
sb.AppendLine("=== 内存信息转储 ===");
sb.AppendLine($"时间: {DateTime.Now}");
sb.AppendLine($"总内存: {GC.GetTotalMemory(false) / (1024 * 1024):F2} MB");
sb.AppendLine($"GC 0代收集次数: {GC.CollectionCount(0)}");
sb.AppendLine($"GC 1代收集次数: {GC.CollectionCount(1)}");
sb.AppendLine($"GC 2代收集次数: {GC.CollectionCount(2)}");
LogInfo(sb.ToString());
// 写入日志文件
if (logWriter != null)
{
logWriter.WriteLine(sb.ToString());
logWriter.Flush();
}
}
#region 日志记录
void LogInfo(string message)
{
string formatted = $"[INFO] {DateTime.Now:HH:mm:ss.fff} - {message}";
Debug.Log(formatted);
WriteToLog(formatted);
}
void LogWarning(string message)
{
string formatted = $"[WARN] {DateTime.Now:HH:mm:ss.fff} - {message}";
Debug.LogWarning(formatted);
WriteToLog(formatted);
}
void LogError(string message)
{
string formatted = $"[ERROR] {DateTime.Now:HH:mm:ss.fff} - {message}";
Debug.LogError(formatted);
WriteToLog(formatted);
}
void WriteToLog(string message)
{
if (logWriter != null)
{
logWriter.WriteLine(message);
logWriter.Flush();
}
}
#endregion
#region Lua调试函数
// Lua调用:调试日志
private static int LuaDebugLog(IntPtr luaState)
{
try
{
int argCount = LuaNative.lua_gettop(luaState);
if (argCount < 1)
{
LuaNative.lua_pushstring(luaState, "需要至少1个参数");
return LuaNative.LUA_ERROR;
}
StringBuilder sb = new StringBuilder();
for (int i = 1; i <= argCount; i++)
{
if (LuaNative.lua_isstring(luaState, i) != 0)
{
sb.Append(LuaNative.lua_tostring(luaState, i));
sb.Append(" ");
}
}
string message = sb.ToString().Trim();
var instance = FindObjectOfType<BridgeDebugger>();
if (instance != null)
{
instance.LogInfo($"[Lua] {message}");
}
else
{
Debug.Log($"[Lua] {message}");
}
return 0;
}
catch (Exception ex)
{
LuaNative.lua_pushstring(luaState, $"调试日志失败: {ex.Message}");
return LuaNative.LUA_ERROR;
}
}
// Lua调用:获取调试统计
private static int LuaDebugGetStats(IntPtr luaState)
{
try
{
var instance = FindObjectOfType<BridgeDebugger>();
if (instance == null)
{
LuaNative.lua_pushnil(luaState);
return 1;
}
// 创建统计表
LuaNative.lua_createtable(luaState, 0, 8);
// 添加性能统计
var perfStats = instance.bridgeCore.GetPerformanceStats();
LuaNative.lua_pushstring(luaState, "total_calls");
LuaNative.lua_pushinteger(luaState, perfStats.TotalCalls);
LuaNative.lua_settable(luaState, -3);
LuaNative.lua_pushstring(luaState, "avg_call_time");
LuaNative.lua_pushnumber(luaState, perfStats.AverageCallTimeMs);
LuaNative.lua_settable(luaState, -3);
LuaNative.lua_pushstring(luaState, "cache_hit_rate");
LuaNative.lua_pushnumber(luaState, perfStats.CacheHitRate);
LuaNative.lua_settable(luaState, -3);
LuaNative.lua_pushstring(luaState, "memory_usage");
LuaNative.lua_pushinteger(luaState, perfStats.MemoryUsage);
LuaNative.lua_settable(luaState, -3);
// 添加调试统计
LuaNative.lua_pushstring(luaState, "performance_samples");
LuaNative.lua_pushinteger(luaState, instance.debugData.PerformanceSamples.Count);
LuaNative.lua_settable(luaState, -3);
LuaNative.lua_pushstring(luaState, "memory_samples");
LuaNative.lua_pushinteger(luaState, instance.debugData.MemorySamples.Count);
LuaNative.lua_settable(luaState, -3);
LuaNative.lua_pushstring(luaState, "log_file");
LuaNative.lua_pushstring(luaState, instance.logFilePath ?? "未启用");
LuaNative.lua_settable(luaState, -3);
return 1;
}
catch (Exception ex)
{
LuaNative.lua_pushstring(luaState, $"获取调试统计失败: {ex.Message}");
return LuaNative.LUA_ERROR;
}
}
// Lua调用:转储状态
private static int LuaDebugDumpState(IntPtr luaState)
{
try
{
var instance = FindObjectOfType<BridgeDebugger>();
if (instance == null)
{
LuaNative.lua_pushboolean(luaState, 0);
return 1;
}
// 转储状态到文件
string dumpPath = instance.DumpStateToFile();
LuaNative.lua_pushstring(luaState, dumpPath);
return 1;
}
catch (Exception ex)
{
LuaNative.lua_pushstring(luaState, $"转储状态失败: {ex.Message}");
return LuaNative.LUA_ERROR;
}
}
// Lua调用:性能测试
private static int LuaDebugTestPerformance(IntPtr luaState)
{
try
{
int argCount = LuaNative.lua_gettop(luaState);
int testCount = 1000;
if (argCount >= 1)
{
testCount = (int)LuaNative.lua_tointeger(luaState, 1);
testCount = Math.Max(1, Math.Min(testCount, 100000));
}
var instance = FindObjectOfType<BridgeDebugger>();
if (instance == null)
{
LuaNative.lua_pushnil(luaState);
return 1;
}
// 运行性能测试
var result = instance.RunPerformanceTest(testCount);
// 返回结果表
LuaNative.lua_createtable(luaState, 0, 4);
LuaNative.lua_pushstring(luaState, "test_count");
LuaNative.lua_pushinteger(luaState, result.TestCount);
LuaNative.lua_settable(luaState, -3);
LuaNative.lua_pushstring(luaState, "total_time");
LuaNative.lua_pushnumber(luaState, result.TotalTimeMs);
LuaNative.lua_settable(luaState, -3);
LuaNative.lua_pushstring(luaState, "avg_time");
LuaNative.lua_pushnumber(luaState, result.AverageTimeMs);
LuaNative.lua_settable(luaState, -3);
LuaNative.lua_pushstring(luaState, "operations_per_second");
LuaNative.lua_pushnumber(luaState, result.OperationsPerSecond);
LuaNative.lua_settable(luaState, -3);
return 1;
}
catch (Exception ex)
{
LuaNative.lua_pushstring(luaState, $"性能测试失败: {ex.Message}");
return LuaNative.LUA_ERROR;
}
}
#endregion
#region 调试功能
public string DumpStateToFile()
{
string dumpDir = Path.Combine(Application.persistentDataPath, "BridgeDumps");
if (!Directory.Exists(dumpDir))
{
Directory.CreateDirectory(dumpDir);
}
string dumpPath = Path.Combine(dumpDir, $"bridge_dump_{DateTime.Now:yyyyMMdd_HHmmss}.txt");
using (StreamWriter writer = new StreamWriter(dumpPath, false, Encoding.UTF8))
{
writer.WriteLine("=== Lua桥接层状态转储 ===");
writer.WriteLine($"转储时间: {DateTime.Now}");
writer.WriteLine();
// 写入性能统计
writer.WriteLine("性能统计:");
var perfStats = bridgeCore.GetPerformanceStats();
writer.WriteLine($" 总调用次数: {perfStats.TotalCalls}");
writer.WriteLine($" 平均调用时间: {perfStats.AverageCallTimeMs:F2}ms");
writer.WriteLine($" 缓存命中率: {perfStats.CacheHitRate:P2}");
writer.WriteLine($" 内存使用: {perfStats.MemoryUsage / (1024 * 1024):F2} MB");
writer.WriteLine($" 数据传输总量: {perfStats.TotalDataTransferred / 1024:F2} KB");
writer.WriteLine();
// 写入调试数据
writer.WriteLine("调试数据:");
writer.WriteLine($" 性能样本数: {debugData.PerformanceSamples.Count}");
writer.WriteLine($" 内存样本数: {debugData.MemorySamples.Count}");
writer.WriteLine($" 错误计数: {debugData.ErrorCount}");
writer.WriteLine($" 警告计数: {debugData.WarningCount}");
writer.WriteLine();
// 写入最近的性能样本
if (debugData.PerformanceSamples.Count > 0)
{
writer.WriteLine("最近的性能样本:");
int startIdx = Math.Max(0, debugData.PerformanceSamples.Count - 10);
for (int i = startIdx; i < debugData.PerformanceSamples.Count; i++)
{
var sample = debugData.PerformanceSamples[i];
writer.WriteLine($" [{sample.Timestamp:HH:mm:ss}] 帧时间: {sample.FrameTime:F2}ms, " +
$"内存: {sample.MemoryUsage:F2}MB, " +
$"缓存命中率: {sample.CacheHitRate:P2}");
}
writer.WriteLine();
}
writer.WriteLine("=== 转储结束 ===");
}
LogInfo($"状态已转储到: {dumpPath}");
return dumpPath;
}
public PerformanceTestResult RunPerformanceTest(int testCount)
{
LogInfo($"开始性能测试,测试次数: {testCount}");
var stopwatch = System.Diagnostics.Stopwatch.StartNew();
// 测试序列化性能
long serializationTime = 0;
long deserializationTime = 0;
var testData = new VehicleState
{
Speed = 60.5f,
Rpm = 2500,
FuelLevel = 75.3f,
EngineTemp = 85.2f,
Timestamp = DateTime.Now.Ticks
};
for (int i = 0; i < testCount; i++)
{
// 序列化测试
var serializationStopwatch = System.Diagnostics.Stopwatch.StartNew();
var serialized = bridgeCore.SerializeObject(testData);
serializationStopwatch.Stop();
serializationTime += serializationStopwatch.ElapsedMilliseconds;
// 反序列化测试
var deserializationStopwatch = System.Diagnostics.Stopwatch.StartNew();
var deserialized = bridgeCore.DeserializeObject<VehicleState>(serialized);
deserializationStopwatch.Stop();
deserializationTime += deserializationStopwatch.ElapsedMilliseconds;
}
stopwatch.Stop();
var result = new PerformanceTestResult
{
TestCount = testCount,
TotalTimeMs = stopwatch.ElapsedMilliseconds,
SerializationTimeMs = serializationTime,
DeserializationTimeMs = deserializationTime,
AverageTimeMs = stopwatch.ElapsedMilliseconds / testCount,
OperationsPerSecond = testCount / (stopwatch.ElapsedMilliseconds / 1000.0)
};
LogInfo($"性能测试完成: " +
$"总时间: {result.TotalTimeMs}ms, " +
$"平均: {result.AverageTimeMs:F4}ms/次, " +
$"每秒操作数: {result.OperationsPerSecond:F0}");
return result;
}
#endregion
void OnDestroy()
{
// 关闭日志文件
if (logWriter != null)
{
logWriter.WriteLine();
logWriter.WriteLine($"结束时间: {DateTime.Now}");
logWriter.WriteLine("=== 日志结束 ===");
logWriter.Close();
logWriter = null;
}
Debug.Log("桥接层调试器已销毁");
}
}
/// <summary>
/// 调试器配置
/// </summary>
[System.Serializable]
public class DebuggerConfig
{
public bool enableLogging = true; // 启用日志记录
public bool enablePerformanceMonitoring = true; // 启用性能监控
public bool enableMemoryMonitoring = true; // 启用内存监控
public bool enableDataValidation = true; // 启用数据验证
public float monitoringInterval = 2.0f; // 监控间隔(秒)
public float dataValidationInterval = 10.0f; // 数据验证间隔(秒)
public int maxSamples = 1000; // 最大样本数
public float frameTimeWarningThreshold = 20.0f; // 帧时间警告阈值(ms)
public float cacheHitRateWarningThreshold = 0.6f; // 缓存命中率警告阈值
public float memoryLeakThresholdMB = 10.0f; // 内存泄漏阈值(MB)
public float memoryLeakRateThreshold = 1.0f; // 内存泄漏率阈值(MB/min)
}
/// <summary>
/// 调试数据
/// </summary>
public class DebugData
{
public List<PerformanceSample> PerformanceSamples = new List<PerformanceSample>();
public List<MemorySample> MemorySamples = new List<MemorySample>();
public int ErrorCount = 0;
public int WarningCount = 0;
public List<string> RecentErrors = new List<string>();
}
/// <summary>
/// 性能样本
/// </summary>
public class PerformanceSample
{
public DateTime Timestamp { get; set; }
public float FrameTime { get; set; }
public float MemoryUsage { get; set; }
public long CallCount { get; set; }
public float CacheHitRate { get; set; }
}
/// <summary>
/// 内存样本
/// </summary>
public class MemorySample
{
public DateTime Timestamp { get; set; }
public float MemoryMB { get; set; }
public int CollectionCount { get; set; }
}
/// <summary>
/// 性能测试结果
/// </summary>
public class PerformanceTestResult
{
public int TestCount { get; set; }
public long TotalTimeMs { get; set; }
public long SerializationTimeMs { get; set; }
public long DeserializationTimeMs { get; set; }
public float AverageTimeMs { get; set; }
public double OperationsPerSecond { get; set; }
}
/// <summary>
/// 车辆状态(用于测试)
/// </summary>
public class VehicleState
{
public float Speed { get; set; }
public float Rpm { get; set; }
public float FuelLevel { get; set; }
public float EngineTemp { get; set; }
public long Timestamp { get; set; }
}
}
总结
本文详细介绍了C#到Lua桥接层的完整实现,包括:
桥接层核心架构:设计了高性能的桥接层,包含缓存系统、序列化器、对象池等组件。
数据反序列化与传递:实现了高效的数据反序列化系统和数据传输管理器,支持批量处理和异步传输。
Lua虚拟机集成:提供了完整的Lua虚拟机管理器和数据绑定系统,支持复杂的数据交互。
车机数据桥接示例:实现了CAN总线数据和传感器数据的桥接示例,展示了实际应用场景。
性能优化与调试:提供了性能监控系统和调试工具,帮助诊断和优化性能问题。
关键优化点:
缓存系统:减少重复的序列化和反序列化操作。
对象池:减少内存分配和垃圾回收压力。
批处理:合并小数据包,减少调用开销。
异步处理:避免阻塞主线程。
数据验证:确保数据完整性和安全性。
这些实现已在多个车机项目中验证,能够有效处理高频数据更新,同时保持低延迟和高稳定性。实际部署时,需要根据具体硬件平台(如高通8155/8295)的性能特点进行参数调优。
更多推荐


所有评论(0)