OpenRA开源红色警戒游戏RPG源码MapCache.cs解读

python编程示例系列
python编程示例系列二
python的Web神器Streamlit
如何应聘高薪职位
C#视觉应用开发问题系列
c#串口应用开发问题系列
microPython Python最小内核源码解析
NI-motion运动控制c语言示例代码解析
OpenRA开源红色警戒游戏RPG源码解读
# MapCache 类代码解析

这段代码实现了一个地图缓存系统,用于管理游戏中的地图资源。下面是详细的中文注释和逻辑解析:

using System;
using System.Collections;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Threading;
using System.Threading.Tasks;
using OpenRA.FileSystem;  // 文件系统相关
using OpenRA.Graphics;    // 图形处理相关
using OpenRA.Primitives;  // 基本数据类型
using OpenRA.Support;     // 辅助功能

namespace OpenRA
{
            
    // MapCache类实现了IEnumerable<MapPreview>接口,允许遍历所有地图预览
    // 同时实现IDisposable接口,以便正确释放资源
    public sealed class MapCache : IEnumerable<MapPreview>, IDisposable
    {
            
        // 表示未知地图的静态常量
        public static readonly MapPreview UnknownMap = new(null, null, MapGridType.Rectangular, null);
        
        // 只读属性,返回地图位置信息字典
        public IReadOnlyDictionary<IReadOnlyPackage, MapClassification> MapLocations => mapLocations;
        
        // 存储地图包及其分类的字典
        readonly Dictionary<IReadOnlyPackage, MapClassification> mapLocations = new();
        
        // 控制是否加载预览图像的标志
        public bool LoadPreviewImages = true;

        // 地图预览缓存,以地图UID为键
        readonly Cache<string, MapPreview> previews;
        
        // 模组数据
        readonly ModData modData;
        
        // 用于构建图像表的工具
        readonly SheetBuilder sheetBuilder;
        
        // 用于异步加载预览图的线程
        Thread previewLoaderThread;
        
        // 标记预览加载线程是否已关闭
        bool previewLoaderThreadShutDown = true;
        
        // 线程同步对象
        readonly object syncRoot = new();
        
        // 待生成小地图的队列
        readonly Queue<MapPreview> generateMinimap = new();

        // 字符串池,用于减少内存占用
        public HashSet<string> StringPool {
             get; } = new();

        // 地图目录跟踪器列表
        readonly List<MapDirectoryTracker> mapDirectoryTrackers = new();

        /// <summary>
        /// 最近修改或加载的地图的UID
        /// </summary>
        public string LastModifiedMap {
             get; private set; } = null;
        
        // 存储地图更新信息的字典,键为旧UID,值为新UID
        readonly Dictionary<string, string> mapUpdates = new();

        // 记录上次加载的最近修改地图
        string lastLoadedLastModifiedMap;

        /// <summary>
        /// 如果LastModifiedMap已被选择,则返回null
        /// </summary>
        public string PickLastModifiedMap(MapVisibility visibility)
        {
            
            // 更新地图信息
            UpdateMaps();
            
            // 获取最近修改的地图
            var map = string.IsNullOrEmpty(LastModifiedMap) ? null : this[LastModifiedMap];
            
            // 检查地图是否可用,是否符合可见性要求,以及是否已被加载
            if (map != null && map.Status == MapStatus.Available && 
                map.Visibility.HasFlag(visibility) && 
                lastLoadedLastModifiedMap != LastModifiedMap)
            {
            
                // 更新lastLoadedLastModifiedMap并返回
                lastLoadedLastModifiedMap = LastModifiedMap;
                return lastLoadedLastModifiedMap;
            }

            return null;
        }

        // 构造函数,初始化MapCache
        public MapCache(ModData modData)
        {
            
            this.modData = modData;

            // 懒加载地图网格类型
            var gridType = Exts.Lazy(() => modData.Manifest.Get<MapGrid>().Type);
            
            // 初始化预览缓存,为每个UID创建MapPreview实例
            previews = new Cache<string, MapPreview>(uid => 
                new MapPreview(modData, uid, gridType.Value, this));
                
            // 初始化图像表构建器
            sheetBuilder = new SheetBuilder(SheetType.BGRA);
        }

        // 更新所有地图信息
        public void UpdateMaps()
        {
            
            foreach (var tracker in mapDirectoryTrackers)
                tracker.UpdateMaps(this);
        }

        // 加载所有地图
        public void LoadMaps()
        {
            
            // 如果模组不支持地图,则直接返回
            if (!modData.Manifest.Contains<MapGrid>())
                return;

            // 枚举地图目录
            foreach (var kv in modData.Manifest.MapFolders)
            {
            
                var name = kv.Key;
                
                // 解析地图分类,如果未指定则设为Unknown
                var classification = string.IsNullOrEmpty(kv.Value)
                    ? MapClassification.Unknown : Enum<MapClassification>.Parse(kv.Value);

                IReadOnlyPackage package;
                
                // 检查是否为可选地图目录(以~开头)
                var optional = name.StartsWith('~');
                if (optional)
                    name = name[1..]; // 去掉~前缀

                try
                {
            
                    // 解析路径,如果位于支持目录且不存在,则创建该目录
                    var resolved = Platform.ResolvePath(name);
                    if (resolved.StartsWith(Platform.SupportDir, StringComparison.Ordinal) && 
                        !File.Exists(resolved))
                        Directory.CreateDirectory(resolved);

                    // 打开地图包
                    package = modData.ModFiles.OpenPackage(name);
                }
                catch
                {
            
                    // 如果是可选目录,则忽略错误继续处理
                    if (optional)
                        continue;

                    throw; // 否则重新抛出异常
                }

                // 添加到地图位置字典和跟踪器列表
                mapLocations.Add(package, classification);
                mapDirectoryTrackers.Add(new MapDirectoryTracker(package, classification));
            }

            // 性能优化:在循环外加载模组YAML规则,避免重复加载
            var modDataRules = modData.GetRulesYaml();
            var gridType = modData.Manifest.Get<MapGrid>().Type;
            
            // 加载所有地图包中的地图
            foreach (var kv in MapLocations)
            {
            
                foreach (var map in kv.Key.Contents)
                    LoadMapInternal(map, kv.Key, kv.Value, null, gridType, modDataRules);
            }

            // 初始加载时不跟踪最近修改的地图
            LastModifiedMap = null;
        }

        // 加载单个地图的公共方法
        public void LoadMap(string map, IReadOnlyPackage package, 
            MapClassification classification, string oldMap)
        {
            
            LoadMapInternal(map, package, classification, oldMap);
        }

        // 内部地图加载方法
        void LoadMapInternal(string map, IReadOnlyPackage package, 
            MapClassification classification, string oldMap,
            MapGridType? gridType = null, IEnumerable<List<MiniYamlNode>> modDataRules = null)
        {
            
            IReadOnlyPackage mapPackage = null;
            try
            {
            
                // 使用性能计时器跟踪加载时间
                using (new PerfTimer(map))
                {
            
                    // 打开地图包
                    mapPackage = package.OpenPackage(map, modData.ModFiles);
                    if (mapPackage != null)
                    {
            
                        // 计算地图UID
                        var uid = Map.ComputeUID(mapPackage);
                        
                        // 更新地图预览信息
                        previews[uid].UpdateFromMapWithoutOwningPackage(
                            mapPackage, package, classification, gridType, modDataRules);
                            
                        // 释放地图包资源
                        mapPackage.Dispose();

                        // 如果是新地图或地图已更新,则更新最近修改的地图和地图更新字典
                        if (oldMap != uid)
                        {
            
                            LastModifiedMap = uid;
                            if (oldMap != null)
                                mapUpdates[oldMap] = uid;
                        }
                    }
                }
            }
            catch (Exception e)
            {
            
                // 异常处理:释放资源并记录错误
                mapPackage?.Dispose();
                Console.WriteLine($"Failed to load map: {
              map}");
                Console.WriteLine("Details:");
                Console.WriteLine(e);
                Log.Write("debug", $"Failed to load map: {
              map}");
                Log.Write("debug", "Details:");
                Log.Write("debug", e);
            }
        }

        // 枚举指定分类的地图目录包
        public IEnumerable<IReadWritePackage> EnumerateMapDirPackages(
            MapClassification classification = MapClassification.System)
        {
            
            // 如果模组不支持地图,则直接返回
            if (!modData.Manifest.Contains<MapGrid>())
                yield break;

            // 枚举地图目录
            foreach (var kv in modData.Manifest.MapFolders)
            {
            
                // 尝试解析地图分类
                if (!Enum.TryParse(kv.Value, out MapClassification packageClassification))
                    continue;

                // 检查是否符合请求的分类
                if (!classification.HasFlag(packageClassification))
                    continue;

                var name = kv.Key;
                var optional = name.StartsWith('~');
                if (optional)
                    name = name[1..];

                // 避免尝试打开不存在的目录
                var resolved = Platform.ResolvePath(name);
                if (resolved.StartsWith(Platform.SupportDir, StringComparison.Ordinal) && 
                    (!Directory.Exists(resolved) || !File.Exists(resolved)))
                    continue;

                // 打开并返回地图包
                using (var package = (IReadWritePackage)modData.ModFiles.OpenPackage(name))
                    yield return package;
            }
        }

        // 枚举地图目录包及其中的地图名称
        public IEnumerable<(IReadWritePackage Package, string Map)> EnumerateMapDirPackagesAndNames(
            MapClassification classification = MapClassification.System)
        {
            
            var mapDirPackages = EnumerateMapDirPackages(classification);

            foreach (var mapDirPackage in mapDirPackages)
                foreach (var map in mapDirPackage.Contents)
                    yield return (mapDirPackage, map);
        }

        // 枚举地图包,不进行缓存
        public IEnumerable<IReadWritePackage> EnumerateMapPackagesWithoutCaching(
            MapClassification classification = MapClassification.System)
        {
            
            var mapDirPackages = EnumerateMapDirPackages(classification);

            foreach (var mapDirPackage in mapDirPackages)
                foreach (var map in mapDirPackage.Contents)
                    if (mapDirPackage.OpenPackage(map, modData.ModFiles) is IReadWritePackage mapPackage)
                        yield return mapPackage;
        }

        // 查询远程地图详情
        public void QueryRemoteMapDetails(string repositoryUrl, IEnumerable<string> uids,
            Action<MapPreview> mapDetailsReceived = null, Action<MapPreview> mapQueryFailed = null)
        {
            
            // 筛选需要查询的地图UID
            var queryUids = uids.Distinct()
                .Where(uid => uid != null)
                .Select(uid => previews[uid])
                .Where(p => p.Status == MapStatus.Unavailable)
                .Select(p => p.Uid)
                .ToList();

            // 将所有待查询地图状态设为Searching
            foreach (var uid in queryUids)
                previews[uid].UpdateRemoteSearch(MapStatus.Searching, null, null);

            // 异步执行远程查询
            Task.Run(async () =>
            {
            
                var client = HttpClientFactory.Create();
                var stringPool = new HashSet<string>(); // 重用YAML中的公共字符串

                // 每次查询最多50个地图,避免请求大小限制
                for (var i = 0; i < queryUids.Count; i += 50)
                {
            
                    var batchUids = queryUids.Skip(i).Take(50).ToList();
                    var url = repositoryUrl + "hash/" + string.Join(",", batchUids) + "/yaml";
                    try
                    {
            
                        // 发送HTTP请求获取地图信息
                        var httpResponseMessage = await client.GetAsync(url);
                        var result = await httpResponseMessage.Content.ReadAsStreamAsync();

                        // 解析YAML响应
                        var yaml = MiniYaml.FromStream(result, url, stringPool: stringPool);
                        
                        // 更新可下载的地图状态
                        foreach (var kv in yaml)
                            previews[kv.Key].UpdateRemoteSearch(
                                MapStatus.DownloadAvailable, kv.Value, mapDetailsReceived);

                        // 将未标记为可下载的地图设为不可用
                        foreach (var uid in batchUids)
                        {
            
                            var p = previews[uid];
                            if (p.Status != MapStatus.DownloadAvailable)
                                p.UpdateRemoteSearch(MapStatus.Unavailable, null, null);
                        }
                    }
                    catch (Exception e)
                    {
            
                        // 异常处理:记录错误并更新地图状态
                        Log.Write("debug", "Remote map query failed with error:");
                        Log.Write("debug", e);
                        Log.Write("debug", $"URL was: {
              url}");

                        foreach (var uid in batchUids)
                        {
            
                            var p = previews[uid];
                            p.UpdateRemoteSearch(MapStatus.Unavailable, null, null);
                            mapQueryFailed?.Invoke(p);
                        }
                    }
                }
            });
        }

        // 异步加载小地图的内部方法
        void LoadAsyncInternal()
        {
            
            Log.Write("debug", "MapCache.LoadAsyncInternal started");

            // 空闲时等待的毫秒数
            const int EmptyDelay = 50;

            // 最后一次小地图生成后保持线程活跃的时间(5秒)
            const int MaxKeepAlive = 5000 / EmptyDelay;
            var keepAlive = MaxKeepAlive;

            while (true)
            {
            
                List<MapPreview> todo;
                lock (syncRoot)
                {
            
                    // 获取需要生成小地图的列表
                    todo = generateMinimap.Where(p => p.GetMinimap() == null).ToList();
                    generateMinimap.Clear();
                    
                    // 更新保活计数器
                    if (keepAlive > 0)
                        keepAlive--;
                        
                    // 如果保活时间结束且没有任务,则退出循环
                    if (keepAlive == 0 && todo.Count == 0)
                    {
            
                        previewLoaderThreadShutDown = true;
                        break;
                    }
                }

                // 如果没有任务,则短暂休眠
                if (todo.Count == 0)
                {
            
                    Thread.Sleep(EmptyDelay);
                    continue;
                }
                else
                    keepAlive = MaxKeepAlive; // 重置保活计数器

                // 将小地图渲染到共享图像表中
                foreach (var p in todo)
                {
            
                    if (p.Preview != null)
                    {
            
                        // 在游戏主线程上执行小地图生成
                        Game.RunAfterTick(() =>
                        {
            
                            try
                            {
            
                                p.SetMinimap(sheetBuilder.Add(p.Preview));
                            }
                            catch (Exception e)
                            {
            
                                Log.Write("debug", "Failed to load minimap with exception:");
                                Log.Write("debug", e);
                            }
                        });
                    }

                    // 短暂休眠以减少UI卡顿
                    Thread.Sleep(Environment.ProcessorCount == 1 ? 25 : 5);
                }
            }

            // 释放缓冲区,将更改写入纹理,允许GC回收缓冲区
            Game.RunAfterTick(sheetBuilder.Current.ReleaseBuffer);
            Log.Write("debug", "MapCache.LoadAsyncInternal ended");
        }

        // 获取更新后的地图UID
        public string GetUpdatedMap(string uid)
        {
            
            if (uid == null)
                return null;

            // 循环查找最新版本的地图
            while (this[uid].Status != MapStatus.Available)
            {
            
                if (mapUpdates.TryGetValue(uid, out var newUid))
                    uid = newUid;
                else
                    return null;
            }

            return uid;
        }

        // 缓存小地图
        public void CacheMinimap(MapPreview preview)
        {
            
            bool launchPreviewLoaderThread;
            lock (syncRoot)
            {
            
                // 将预览添加到生成队列
                generateMinimap.Enqueue(preview);
                
                // 检查是否需要启动加载线程
                launchPreviewLoaderThread = previewLoaderThreadShutDown;
                previewLoaderThreadShutDown = false;
            }

            // 如果需要,启动加载线程
            if (launchPreviewLoaderThread)
                Game.RunAfterTick(() =>
                {
            
                    // 等待现有线程退出
                    previewLoaderThread?.Join();

                    // 创建并启动新线程
                    previewLoaderThread = new Thread(LoadAsyncInternal)
                    {
            
                        Name = "Map Preview Loader",
                        IsBackground = true
                    };
                    previewLoaderThread.Start();
                });
        }

        // 判断地图是否适合作为初始地图
        bool IsSuitableInitialMap(MapPreview map)
        {
            
            // 检查地图状态和可见性
            if (map.Status != MapStatus.Available || !map.Visibility.HasFlag(MapVisibility.Lobby))
                return false;

            // 只选择征服类型的地图,其他类型可能有复杂设置或玩法
            if (!map.Categories.Contains("Conquest"))
                return false;

            // 排除禁用机器人的地图,这可能会使新玩家困惑
            if (map.Players.Players.Any(x => !x.Value.AllowBots))
                return false;

            // 排除大型地图,避免性能问题
            if (map.Bounds.Width > 128 || map.Bounds.Height > 128)
                return false;

            return true;
        }

        // 选择初始地图
        public string ChooseInitialMap(string initialUid, MersenneTwister random)
        {
            
            UpdateMaps();
            
            // 尝试获取指定的初始地图
            var map = string.IsNullOrEmpty(initialUid) ? null : previews[initialUid];
            
            // 检查初始地图是否可用且符合要求
            if (map == null ||
                map.Status != MapStatus.Available ||
                !map.Visibility.HasFlag(MapVisibility.Lobby) ||
                (map.Class != MapClassification.System && map.Class != MapClassification.User))
            {
            
                // 随机选择一个合适的初始地图,或退回到第一个可用的地图
                var selected = previews.Values.Where(IsSuitableInitialMap).RandomOrDefault(random) ??
                    previews.Values.FirstOrDefault(m =>
                    m.Status == MapStatus.Available &&
                    m.Visibility.HasFlag(MapVisibility.Lobby) &&
                    (m.Class == MapClassification.System || m.Class == MapClassification.User));
                    
                return selected == null ? string.Empty : selected.Uid;
            }

            return initialUid;
        }

        // 索引器,允许通过UID访问地图预览
        public MapPreview this[string key]
        {
            
            get
            {
            
                UpdateMaps();
                return previews[key];
            }
        }

        // 实现IEnumerable<MapPreview>接口的GetEnumerator方法
        public IEnumerator<MapPreview> GetEnumerator()
        {
            
            UpdateMaps();
            return previews.Values.GetEnumerator();
        }

        // 实现IEnumerable接口的GetEnumerator方法
        IEnumerator IEnumerable.GetEnumerator()
        {
            
            return GetEnumerator();
        }

        // 实现IDisposable接口的Dispose方法
        public void Dispose()
        {
            
            // 如果预览加载线程未创建,直接释放资源
            if (previewLoaderThread == null)
            {
            
                sheetBuilder.Dispose();
                return;
            }

            // 释放所有地图预览资源
            foreach (var p in previews.Values)
                p.Dispose();

            // 释放所有地图目录跟踪器资源
            foreach (var t in mapDirectoryTrackers)
                t.Dispose();

            // 需要等待加载线程退出后才能释放SheetBuilder
            // 理想情况下应该在返回前释放资源,但不想阻塞等待加载线程退出
            // 所以将释放操作放入线程池队列,在加载线程退出后执行
            ThreadPool.QueueUserWorkItem(_ =>
            {
            
                previewLoaderThread.Join();
                Game.RunAfterTick(sheetBuilder.Dispose);
            });
        }
    }
}

流程图

下面是MapCache主要流程的Mermaid图表:

特殊语法与技巧解析

只读属性简化语法

public IReadOnlyDictionary<IReadOnlyPackage, MapClassification> MapLocations => mapLocations;

这是C#的表达式体成员语法,简化了只读属性的定义,等同于:

public IReadOnlyDictionary<IReadOnlyPackage, MapClassification> MapLocations {
               get {
               return mapLocations; } }

自动属性初始化器

public HashSet<string> StringPool {
               get; } = new();

这种语法允许在声明属性时同时初始化,并且使用了C#的目标类型推断(new())。

范围运算符

name = name[1..];

这是C#8.0引入的范围运算符,用于获取字符串或数组的子集。这里表示从索引1到末尾的子字符串,相当于旧语法的name.Substring(1)

空合并运算符

var map = string.IsNullOrEmpty(initialUid) ? null : previews[initialUid];

这种三元运算符的使用避免了在initialUid为空时访问previews字典。

空条件运算符

mapPackage?.Dispose();
previewLoaderThread?.Join();

只有当左侧的对象不为null时才执行右侧的方法,避免了空引用异常。

LINQ查询

var queryUids = uids.Distinct()
    .Where(uid => uid != null)
    .Select(uid => previews[uid])
    .Where(p => p.Status == MapStatus.Unavailable)
    .Select(p => p.Uid)
    .ToList();

使用LINQ链式方法进行复杂的集合操作,提高代码可读性和简洁性。

锁定同步对象

lock (syncRoot)
{
              
    // 线程安全的操作
}

使用lock关键字确保在多线程环境中安全地访问共享资源。

异步/等待模式

Task.Run(async () =>
{
              
    var httpResponseMessage = await client.GetAsync(url);
    var result = await httpResponseMessage.Content.ReadAsStreamAsync();
    // 处理结果
});

使用async/await进行异步操作,避免阻塞主线程。

懒加载

var gridType = Exts.Lazy(() => modData.Manifest.Get<MapGrid>().Type);

使用懒加载模式延迟计算值,直到实际需要时才执行。

线程池

ThreadPool.QueueUserWorkItem(_ =>
{
              
    previewLoaderThread.Join();
    Game.RunAfterTick(sheetBuilder.Dispose);
});

使用线程池执行后台任务,避免创建过多线程。

元组返回

public IEnumerable<(IReadWritePackage Package, string Map)> EnumerateMapDirPackagesAndNames(...)

使用C#7引入的命名元组作为返回类型,可以同时返回多个相关值。

位标志枚举操作

if (!classification.HasFlag(packageClassification))
    continue;

使用HasFlag方法检查枚举值是否包含特定标志,适用于使用[Flags]特性的枚举类型。

使用using语句自动释放资源

using (new PerfTimer(map))
{
              
    // 操作完成后PerfTimer会自动释放
}

using语句确保即使发生异常,资源也会被正确释放。

委托作为可选参数

public void QueryRemoteMapDetails(string repositoryUrl, IEnumerable<string> uids,
    Action<MapPreview> mapDetailsReceived = null, Action<MapPreview> mapQueryFailed = null)

使用委托作为可选参数,允许调用者提供回调函数处理结果。

条件编译

// 根据处理器数量调整休眠时间
Thread.Sleep(Environment.ProcessorCount == 1 ? 25 : 5);

根据运行环境动态调整行为,提高性能和用户体验。

泛型约束和接口实现

public sealed class MapCache : IEnumerable<MapPreview>, IDisposable

实现多个接口,提供集合遍历和资源释放功能。

字符串插值

Log.Write("debug", $"Failed to load map: {
                map}");

使用$前缀和花括号创建格式化字符串,比传统的string.Format更简洁易读。

空值传播运算符

mapQueryFailed?.Invoke(p);

只有当委托不为null时才调用,避免空引用异常。

通过这些技术,MapCache类实现了高效的地图资源管理,支持异步加载、缓存和远程查询,同时保持了代码的可读性和可维护性。

python的装饰器模式
c#视觉应用开发中如何使用Emgu CV在C#中进行图像处理?
Python程序记日志竟如此简单
python的click库如何使用
python的PyODE库如何安装使用以及用途
量化交易系统中+如何应用机器学习进行预测和决策?
车载系统软件工程师如何实现车载系统的AR导航和显示
python的Plotly库如何使用
c#视觉应用开发中如何使用OpenCV库进行计算机视觉处理?
python生成和解决迷宫的库maze
车载系统软件工程师如何处理车载系统的电源管理和优化
Python的opencv库使用ORB算法 进行特征检测
microPython的源码解析之 objstr.c
qt开发的程序 为何一个主窗口关闭了,程序不退出,而是到等到所有窗口关闭了,才退出呢?
python 如何不用循环利用对数欧拉方法实现全向量化
python如何开发解压及压缩软件工具
量化交易系统中+如何生成交易报告和绩效分析?
车载系统软件工程师如何处理车载系统的电池寿命管理
c#视觉应用开发中如何在C#中进行图像锐化?
量化交易策略 做多做空策略
c#视觉应用开发中如何在C#中实现图像去模糊?
量化交易系统如何处理多市场、多资产的交易需求?
量化交易系统中+如何进行系统的日志记录和分析?
AstraZeneca公司如何使用Python来改进药物发现的协作过程
Python如何调用pygame库来启动摄像头捕获图像并显示
Pylint
python如何处理国际化域名
量化交易系统中+如何进行策略的实时监控和调整?
智能农业设备软件工程师如何实现传感器数据的校准和验证
3D人物的动作是如何制作出来的
python web应用开发神器 入门二十
python数学量子计算库toqito
智能农业设备软件工程师如何实现农业设备的能耗优化
microPython的源码解析之 mpz.c
在紧迫的截止日期下使用Python进行市场平台开发
量化交易系统中+如何确保系统的安全性和防止黑客攻击?
车载系统软件工程师如何处理车载系统的系统日志和故障报告
允许从Python中调用C++函数、使用C++类和对象的库PyCXX
microPython的源码解析之 parse.c
C#开发串口通讯软件如何如何避免串口通讯中的资源竞争?
python的Ren’Py 库如何安装使用以及功能和用途
智能农业设备软件工程师如何实现农用无人机的导航和控制
python web应用开发神器 入门七
c#视觉应用开发中如何使用C#和TensorFlow进行深度学习?
C#进行串口应用开发如何实现不同波特率的串口通信
c#视觉应用开发中如何在C#中进行图像去伪影?
morris蠕虫病毒
python如何计算 图的社区发现
量化交易系统中+如何进行代码的优化和重构?
Python端到端的测试的生态系统库pyATS
车载系统软件工程师如何实现车载系统的能量回收控制
c#视觉应用开发中如何在C#中进行图像去重叠?
c#如何开发一个linux远程终端工具,类似putty
一个好的编程接口需要具备哪些要素
利用qt及 c++语言如何计算KDJ技术指标,请给出示例代码
C#进行串口应用开发如何修改Windows下串口参数的默认配置
c#如何使用windows的挂钩技术
车载系统软件工程师如何实现车载系统的安全驾驶提醒和警告
Python的opencv库使用SIFT 进行特征检测
量子计算Quantum Fourier Transform (QFT)算法
车载系统软件工程师如何实现车载系统的车辆健康监测
用Python模拟生物大分子
运动控制卡
C#进行串口应用开发如何检测电脑是否有串口
科学界类似matlab的工具
python web应用开发神器 入门四
microPython的源码解析之 obj.c
车载系统软件工程师如何处理车载系统的系统升级和版本控制
Python 如何用opencv进行人脸年龄检测
python如何开发一个远程桌面的工具
OpenAI ChatGPT 可用的第三方插件可能成为威胁行为者寻求未经授权访问敏感数据的新攻击面
c#视觉应用开发中如何在C#中进行图像去混叠?
开源的仿红色警戒OpenRA经典RPG游戏, 源码解读game.cs
Python如何绘制简单的水面效果
c#视觉应用开发中如何在C#中进行姿态估计?
Python 驱动的 CrossCompute 报告自动化为美国公共电力协会的 eReliability Tracker 节省成本和时间
jupyter深度理解三 之nbformat
Electron框架介绍
Python的faker库,测试工作者的福音
量化交易策略 随机游走
智能农业设备软件工程师如何处理设备的系统性能监控和优化
windows程序在后台运行有几种开发方法
智能农业设备软件工程师如何实现农业设备的车载系统集成
在进行股票统计研究中,有很多因子,如何屏蔽其他因子的影响,只研究一个因子的影响大小呢
量子计算Simon算法
NI-Motion如何设置一个周期性断点,当运动轴到达预设的目标位置时,会在周期性断点位置暂停,然后继续运动直到再次到达目标位置的C语言代码示例
NI-Motion如何在运动控制器上设置高速捕获,并通过RTSI线将其路由出去的C语言示例代码
车载系统软件工程师如何与车辆控制系统(如ABS、ESC)集成
量化交易系统中+如何进行策略间的相关性分析?
C#进行串口应用开发如何优化串口通信的实时性与吞吐量
python如何简单实现重试逻辑
车载系统软件工程师如何实现车载系统的驾驶员监控系统
python 把字符串当数组来操作就对了
microPython的源码解析之 emitinlinethumb.c
Q#量子计算示例代码
c#视觉应用开发中如何在C#中进行运动检测?
opencv多线程视频处理示例
c#视觉应用开发中如何在C#中处理多光谱图像?
人工智能开源库有哪些
python有哪些定时触发的框架

© 版权声明
THE END
如果内容对您有所帮助,就支持一下吧!
点赞0 分享
评论 抢沙发

请登录后发表评论

    暂无评论内容