跳转至内容
  • A place to talk about whatever you want

    13 主题
    117 帖子
    SPeakS

    @MoYingJi 按理一个大众发行的游戏不可能在windows上的优化比linux上差的, 反而可能系统调度原因 刻意压低过高的fps来节省功耗(纯猜测)...

  • 6 主题
    6 帖子
    sunrisepeakS

    动画代码: https://github.com/d2learn/d2ds/blob/main/videos/array/two_dim_array.py
    动画视频: https://www.bilibili.com/video/BV1bQRvY4EDt

    5bdff4ca-714a-4207-9861-465ed10c1e11-image.png

  • 开源软件 | 开源社区 | 开源理念 | 开源与商业 | 开源可持续发展 等相关话的交流讨论
    注: 这里的"开源"是泛化的共建共享概念, 范围包含 OSI的范围、自由软件、CC等相关内容

    34 主题
    150 帖子
    sunrisepeakS

    https://github.com/d2learn/xlings/pull/79

  • d2learn开源组

    3 主题
    3 帖子
    sunrisepeakS

    在前段时间开源了一个开发者命令行工具xlings, 收到了一些关注和反馈, 并且最近也对其中的一键安装功能做了进步增强。希望不仅可以帮助初学者快速的搭建编程环境, 也能用于项目开发者来管理复杂项目的开发环境依赖和一键搭建配置支持

    下面就从 最小功能实现、递归依赖安装、项目依赖管理循序渐进的介绍一下这个功能的设计和思考

    e39f59bf-5006-4ee1-8d34-8f36104417f2-image.png

    注: 这个软件和功能目前依然处于比较前期的探索和开发中

    一、最小功能实现 - 接口规范 1.1 接口设计视角

    对于安装一个软件或编程环境大概可以划分成3个步骤: 下载 - 安装 - 配置

    95355e31-b6bd-4402-9253-cdf3a9094bae-image.png

    并且为了避免重复安装和显示软件的信息, 用top-down的思想,大概核心的接口设计如下:

    function support() -- ... end function installed() -- ... end function install() -- ... end function config() -- ... end function info() -- ... end

    其中support接口用来标识当前系统是否支持, info接口是用于获取软件的基础信息

    function support() return { windows = true, linux = true, macosx = false } end function info() return { name = "vscode", homepage = "https://code.visualstudio.com", author = "https://github.com/microsoft/vscode/graphs/contributors", licenses = "MIT", github = "https://github.com/microsoft/vscode", docs = "https://code.visualstudio.com/docs", profile = "Visual Studio Code", } end 1.2 接口实现视角

    从对于单一软件或环境接口实现视角来看, 有点类似很多项目中的一键安装/配置脚本

    但区别是xlings的安装实现上是符合一个接口规范的, 这样才能为后面的复用提供可能性。并且使用者可以不用关心实现细节, 通过标准接口就可以使用对应的模块。

    function installed() return try { function() if os.host() == "windows" and (os.getenv("USERNAME") or ""):lower() == "administrator" then return os.isfile("C:\\Program Files\\Microsoft VS Code\\Code.exe") else -- os.exec("code --version") - windows cmd not support? common.xlings_exec("code --version") -- for windows end return true end, catch { function(e) return false end } } end function install() print("[xlings]: Installing vscode...") local url = vscode_url[os.host()] -- only windows administrator local use_winget_sys = (os.getenv("USERNAME") or ""):lower() == "administrator" if not os.isfile(vscode_file) and not use_winget_sys then common.xlings_download(url, vscode_file) end return try { function () if os.host() == "windows" then print("[xlings]: runninng vscode installer, it may take some minutes...") if use_winget_sys then os.exec("winget install vscode --scope machine") else common.xlings_exec(vscode_file .. " /verysilent /suppressmsgboxes /mergetasks=!runcode") end elseif os.host() == "linux" then os.exec("sudo dpkg -i " .. vscode_file) elseif os.host() == "macosx" then -- TODO: install vscode on macosx end return true end, catch { function (e) os.tryrm(vscode_file) return false end } } end 二、递归安装依赖 - 复用&依赖图

    通过上面的接口规范化后, 实现软件依赖的自动递归安装和复用就相对简单了。只需要再增加一个用于描述依赖的接口

    function deps() -- pnpm return { windows = { "npm" }, linux = { "npm" }, macosx = { "npm" } } end

    以pnpm的实现为例, 只需要通过依赖描述添加npm, 而不需要关心npm是否安装。当执行pnpm安装的时候会自动的递归检查依赖并安装。从单个软件的依赖链来看像一个不严谨的树形结构, 如果绘制所有软件和依赖会是一个依赖图, 并且节点是可以复用的 -- 软件安装复用

    294e3f7e-3dd6-42a8-b75b-e87a27688abf-image.png

    三、项目依赖管理 - 快速搭建项目开发环境

    很多人在拿到一个不怎么熟悉的项目的时候, 往往要成功的去构建或运行这个项目要花不少时间去解决这个软件或库的依赖问题。所以xlings有了基础软件的安装功能, 就自然而然的想到当把一个项目从github上clone下来的时候能不能通过一行命令就自动配置好开发这个项目所需要的环境

    在有上面的基础后, 就可以通过一个简单的依赖描述文件来描述一个项目依赖。xlings只需要通过加载这个依赖文件, 然后通过解析出依赖项, 按照递归的方式逐个安装,就可以实现一键配置好一个项目的开发环境。

    config.xlings配置文件示例

    xname = "ProjectName" xdeps = { rust = "", python = "3.12", vs = "2022", nodejs = "", vscode = "", ... -- postprocess cmds xppcmds = { "cmd1", "cmd2", } }

    在配置文件中通过xdeps来描述项目的直接依赖, 并且可以通过其中的xppcmds项来自定义安装项目依赖后的后处理命令

    四、统一的软件版本管理

    目前xlings的下一步是期望能实现基于场景记忆的版本管理。例如当在一个特定的项目文件夹下 会使用不同的软件版本, 只不过这个还在规划中...

    Other xlings论坛 xlings开源仓库
  • 10 主题
    30 帖子
    妈耶厥了

    本系列博客作为我学习的一个笔记,注重于代码实现,本人非数学专业,证明能力非常弱,本文掺杂着大量我自己的理解,如有数学大佬光顾,请尽情指正,谢谢
    本系列默认大家都学会了C/C++基本语法

    集合 书上的定义 集合是指具有某种特定性质的不同对象无序聚集成的一个整体。 集合中的每一个对象称为集合的元素; 通常用大写字母表示集合; 用小写字母表示集合中的元素。

    也就是说把一些东西放到一起叫做集合(个人理解)

    代码实现 #include <string> #include <vector> #include <stdint.h> #include <iostream> // 抽象基类,定义集合元素的基本接口 class elmBase { public: // 将元素转换为字节数组的纯虚函数(序列化基础) virtual std::vector<uint8_t> getUint8Array() const = 0; // 默认比较运算符,通过字节数组逐字节比较 virtual int operator==(const elmBase &other) { std::vector<uint8_t> thisDate = getUint8Array(); std::vector<uint8_t> otherDate = other.getUint8Array(); if (thisDate.size() != otherDate.size()) return 0; for (int i = 0; i < thisDate.size(); i++) { if (thisDate[i] != otherDate[i]) return 0; } return 1; } // 转换为字符串表示的纯虚函数 virtual std::string toString() = 0; // 虚析构函数确保正确释放派生类对象 virtual ~elmBase() { } }; // 特殊元素类型,始终返回比较不成立 class alwaysFalse : public elmBase { public: std::vector<uint8_t> getUint8Array() const override { return std::vector<uint8_t>(); // 返回空数组 } std::string toString() override { return {}; // 返回空字符串 } // 重载运算符始终返回false,用于占位符场景 virtual int operator==(const elmBase &other) override { return 0; } ~alwaysFalse() { } }; // 哈希表节点结构,使用链表法解决冲突 using elmNode = struct elmNode { elmBase *elm; // 元素指针 elmNode *next; // 下一个节点指针 }; // 节点工厂函数,创建新节点并初始化元素 elmNode *elmNodeFactory(elmBase *elm) { elmNode *newNode = new elmNode(); newNode->elm = elm; newNode->next = nullptr; return newNode; } // 自定义集合类,基于哈希表实现 class set { private: uint32_t prime; // 哈希表大小(通常选择质数) elmNode **setMap; // 哈希桶数组 // 初始化哈希表结构 void inline _init_(uint32_t prime) { this->prime = prime; this->setMap = new elmNode *[prime]; // 初始化每个桶为alwaysFalse哨兵节点 for (uint32_t i = 0; i < prime; ++i) { this->setMap[i] = elmNodeFactory(new alwaysFalse()); } } protected: // 查找元素对应的哈希桶 elmNode **__find__(elmBase *elm) { uint32_t hash = rotatingHash(elm->getUint8Array(), this->prime); return &(this->setMap[hash]); // 返回桶的指针 } /** * 通用链表操作函数 * @param link 链表头指针的指针 * @param elm 目标元素 * @param cmp 自定义比较函数,返回true时停止遍历 * @param finally 遍历结束后的处理函数(插入等操作) * @return 找到的节点或操作结果节点 */ elmNode *__link__(elmNode **link, elmBase *elm, bool (*cmp)(elmNode *, elmBase *), elmNode *(*finally)(elmNode **, elmNode *, elmBase *) = nullptr) { elmNode *linkPriv = *link; elmNode *linkCurrent = linkPriv; // 遍历链表查找元素 while (linkCurrent != nullptr) { if (cmp(linkCurrent, elm)) { return linkCurrent; } linkPriv = linkCurrent; linkCurrent = linkCurrent->next; } // 执行最终处理函数(如插入新节点) if (finally != nullptr) { return finally(link, linkPriv, elm); } return nullptr; } public: // 构造函数初始化哈希表 set(uint32_t prime) { _init_(prime); } ~set() { for (uint32_t i = 0; i < this->prime; ++i) { elmNode *link = this->setMap[i]; while (link != nullptr) { elmNode *tmp = link; link = link->next; if (tmp != nullptr) { if (tmp->elm != nullptr) { std::cout << "delete " << tmp->elm->toString() << std::endl; delete tmp->elm; } delete tmp; } } } } // 旋转哈希算法实现 static uint32_t rotatingHash(std::vector<uint8_t> key, uint32_t prime) { uint32_t hash = key.size(); for (uint32_t i = 0; i < key.size(); ++i) hash = (hash << 4) ^ (hash >> 28) ^ (uint32_t)(key[i]); return (hash % prime); } // 添加元素到集合 bool add(elmBase *elm, bool force = false) { elmNode **node = __find__(elm); auto finally = [](elmNode **node, elmNode *linkPriv, elmBase *elm) -> elmNode * { // 插入新节点到链表末尾 if (linkPriv->next == nullptr) { linkPriv->next = elmNodeFactory(elm); } return nullptr; }; // 使用lambda作为比较函数 elmNode *targetNode = this->__link__(node, elm, [](elmNode *node, elmBase *tag) -> bool { return *(node->elm) == *tag; }, finally); return targetNode == nullptr; // 返回是否插入成功 } // 检查元素是否存在 bool get(elmBase *elm) { elmNode **node = __find__(elm); elmNode *targetNode = this->__link__(node, elm, [](elmNode *node, elmBase *tag) -> bool { return *(node->elm) == *tag; }); return targetNode != nullptr; } // 移除集合中的元素 bool remove(elmBase *elm) { elmNode **node = __find__(elm); elmNode *ret = this->__link__(node, elm, [](elmNode *current, elmBase *tag) -> bool { // 查找前驱节点执行删除 if (current->next != nullptr && *(current->next->elm) == *tag) { elmNode *tmp = current->next; current->next = current->next->next; delete tmp->elm; // 释放元素内存 delete tmp; // 释放节点内存 return true; } return false; }); return ret != nullptr; } // 调试用打印函数,显示哈希表结构 void print() { std::cout << "[HashTable Structure]" << std::endl; for (int i = 0; i < this->prime; i++) { std::cout << "Bucket " << i << ": "; elmNode *node = this->setMap[i]; while (node != nullptr) { std::cout << node->elm->toString() << " -> "; node = node->next; } std::cout << "NULL" << std::endl; } } }; // 数值类型元素实现 class number : public elmBase { int data; public: number(int data) : data(data) {} std::vector<uint8_t> getUint8Array() const override { // 将整型转换为字节数组 return std::vector<uint8_t>( reinterpret_cast<const uint8_t *>(&data), reinterpret_cast<const uint8_t *>(&data) + sizeof(data)); } std::string toString() override { return std::to_string(data); } ~number() { } }; // 字符串类型元素实现 class string : public elmBase { std::string data; public: string(std::string data) : data(data) {} std::vector<uint8_t> getUint8Array() const override { // 将字符串内容转换为字节数组 return std::vector<uint8_t>(data.begin(), data.end()); } std::string toString() override { return data; } ~string() { } }; 集合与元素的关系 若A表示一个集合,a是集合A中的元素,记作aA,读作a属于A; 若a不是集合A中的元素,则记作aA,读作a不属于A。

    未完待续

  • 一个技术知识分享、学习、交流的社区

    14 主题
    43 帖子
    sunrisepeakS

    中文版

    Introduction and Background

    A community forum oriented towards [knowledge/technology, projects, open courses, creative ideas, etc. + open-source philosophy].

    Why build such a forum?

    Many platforms are moving towards being comprehensive and entertainment-focused, leading to a massive increase in content volume but a decrease in the density of specific thematic content. There are relatively few forums related to open source in Chinese platforms, with content scattered across various platforms, lacking a common platform for exchange and sharing. Provide a platform for discussing topics related to open-source philosophy | open-source licenses | open-source projects | open-source communities | open-source and business | sustainable development of open-source, etc. Main Sections and Topics

    General Discussion Section

    Posts without a specific topic section are generally posted here.

    04473257-cc22-456b-b3e9-cfeed513a14a-image.png

    Open Courses Section

    Post content and discussions related to various open courses. Developers of courses/tutorial projects can create corresponding discussion sections.

    6ae992b8-d831-4a8d-8bbd-e00b4cb4b067-image.png

    Open Source Section

    Discussions on topics related to open-source software | open-source communities | open-source philosophy | open-source and business | sustainable development of open-source. Developers of open-source projects can create discussion sections for their projects.

    cf3aa71e-2fda-44cf-b016-6cea0876bb51-image.png

    d2learn Open Source

    Explorations of open-source content by the d2learn community/open-source group.

    04970ff0-56fb-4f7b-8f2f-a2ce42747315-image.png

    Forum Feedback & Community Building

    Feedback on forum-related issues and suggestions. Discussions on topics related to the sustainable development of the forum.

    ca1f43d9-162a-4a5d-9e3a-1dc7878f926a-image.png

    Functional Perspective A platform for open-source enthusiasts to exchange and discuss. Developers of open-source projects/open courses and tutorials can create discussion/exchange sections for their projects. A platform for discussing topics related to open-source itself (e.g., sustainable development of open-source projects). Others. Forum Philosophy and Restrictions

    Philosophy and Orientation

    Focus on technology, knowledge, creativity, and open-source fields, avoiding entertainment. Professional content and rational discussions, avoiding deliberately emotional content.

    Forum Code of Conduct

    Encouraged behaviors

    Use inclusive language. Respect different viewpoints and experiences. Gracefully accept constructive criticism.

    Prohibited/Restricted

    Provocative, insulting/derogatory comments, and personal attacks. Registration and Section Creation

    Registration Methods

    GitHub: Directly use GitHub for SSO single sign-on. Email invitation registration: Users who have already registered and completed email verification can invite others to register via the user interface.

    Personal Blogs and Subsection Creation

    Application Template Others https://d2learn.org https://github.com/d2learn Instant communication group (Q): 167535744

    Note: translate by ai-llm - original

  • Got a question? Ask away!

    2 主题
    9 帖子
    sunrisepeakS

    推荐一个开源浏览器插件, 效果不错。后面研究研究看能不能直接集成到论坛上
    image.png

    https://github.com/darkreader/darkreader

公告栏 | Bulletin Board

欢迎加入d2learn社区 - 社区指南
Welcome to the d2learn Community - Community Guide

一个以 [知识、技术、代码、项目、想法、开源] 相关话题为主导的社区
A community focused on topics related to [knowledge, technology, code, projects, ideas, and open source].


在线用户