QColor
QColor() QColor(Qt::GlobalColor color) QColor(int r, int g, int b, int a = ...) QColor(QRgb color) QColor(QRgba64 rgba64) QColor(const QString &name) QColor(QStringView name) QColor(const char *name) QColor(QLatin1String name) QColor(const QColor &color) QColor(QColor &&other) int alpha() const qreal alphaF() const int black() const qreal blackF() const int blue() const qreal blueF() const QColor convertTo(QColor::Spec colorSpec) const int cyan() const qreal cyanF() const QColor darker(int factor = 200) const void getCmyk(int *c, int *m, int *y, int *k, int *a = nullptr) void getCmykF(qreal *c, qreal *m, qreal *y, qreal *k, qreal *a = nullptr) void getHsl(int *h, int *s, int *l, int *a = nullptr) const void getHslF(qreal *h, qreal *s, qreal *l, qreal *a = nullptr) const void getHsv(int *h, int *s, int *v, int *a = nullptr) const void getHsvF(qreal *h, qreal *s, qreal *v, qreal *a = nullptr) const void getRgb(int *r, int *g, int *b, int *a = nullptr) const void getRgbF(qreal *r, qreal *g, qreal *b, qreal *a = nullptr) const int green() const qreal greenF() const int hslHue() const qreal hslHueF() const int hslSaturation() const qreal hslSaturationF() const int hsvHue() const qreal hsvHueF() const int hsvSaturation() const qreal hsvSaturationF() const int hue() const qreal hueF() const bool isValid() const QColor lighter(int factor = 150) const int lightness() const qreal lightnessF() const int magenta() const qreal magentaF() const QString name() const QString name(QColor::NameFormat format) const int red() const qreal redF() const QRgb rgb() const QRgba64 rgba64() const QRgb rgba() const int saturation() const qreal saturationF() const void setAlpha(int alpha) void setAlphaF(qreal alpha) void setBlue(int blue) void setBlueF(qreal blue) void setCmyk(int c, int m, int y, int k, int a = 255) void setCmykF(qreal c, qreal m, qreal y, qreal k, qreal a = 1.
package com.luban.nio;import java.io.IOException;import java.net.InetSocketAddress;import java.nio.ByteBuffer;import java.nio.channels.*;import java.text.SimpleDateFormat;import java.util.Date;import java.util.Iterator;import java.util.Set;public class NioServer { private ServerSocketChannel serverSocketChannel; private Selector selector; private long timeOut=2000; public NioServer(){ try { serverSocketChannel=ServerSocketChannel.open(); serverSocketChannel.configureBlocking(false); serverSocketChannel.bind(new InetSocketAddress(9090)); selector=Selector.open(); serverSocketChannel.register(selector, SelectionKey.OP_ACCEPT); } catch (IOException e) { System.exit(1); } } public void start(){ try { while (true){ selector.select(timeOut); Set<SelectionKey> selectionKeys = selector.selectedKeys(); Iterator<SelectionKey> keyIterator = selectionKeys.iterator(); while (keyIterator.hasNext()){ SelectionKey selectionKey = keyIterator.next(); if(selectionKey.isValid()){ if(selectionKey.isAcceptable()){ ServerSocketChannel serverSocketChannel = (ServerSocketChannel) selectionKey.channel(); SocketChannel socketChannel = serverSocketChannel.
1 函数参数的默认值
function log(x, y = 'World') { console.log(x, y); }2 一个容易忽略的地方是,参数默认值不是传值的,而是每次都重新计算默认值表达式的值。也就是说,参数默认值是惰性求值的3 与解构赋值默认值结合使用、4 作用域 一旦设置了参数的默认值,函数进行声明初始化时,参数会形成一个单独的作用域(context)。等到初始化结束,这个作用域就会消失。这种语法行为,在不设置参数默认值时,是不会出现的
使用注意点 箭头函数有几个使用注意点。
(1)箭头函数没有自己的this对象(详见下文)。
(2)不可以当作构造函数,也就是说,不可以对箭头函数使用new命令,否则会抛出一个错误。
(3)不可以使用arguments对象,该对象在函数体内不存在。如果要用,可以用 rest 参数代替。
(4)不可以使用yield命令,因此箭头函数不能用作 Generator 函数。
什么是尾调用? § ⇧ 尾调用(Tail Call)是函数式编程的一个重要概念,本身非常简单,一句话就能说清楚,就是指某个函数的最后一步是调用另一个函数。
笔者所在公司最近需要开发一套监控设备实时运行的系统,场景本身直接使用unity引擎的dots技术栈实现,但在用户界面方面,由于没有一个统一的标准,所以都浅试了一下。
1. unity现在的运行时ui解决方案基本上有这几个: ugui。unity editor内置,设置好的组件可转化为prefab实现重用,其布局基于轴心、锚点设置。 ugui相关链接 个人体验:实际使用过程中,我司设计部门出图基于figma,其样式属性基于css样式,公司内的web前端开发人员可以快速实现,但将这一套布局在实际开发时转化为ugui自带的轴心+锚点发现开发效率不太满意 fgui。拥有自己独立的UI编辑器,在其中搭建完之后打成资源包,搭配对应的unity fgui sdk进行解析使用。 fgui相关链接 个人体验:基于上一个理由,改变自己流程还好说,改变合作部门的流程阻力很大,这款解决方案推崇的设计人员也可参与在我司已经稳定的流程中并不现实,而笔者本身也不太喜欢这种UI开发方式(这里属于是个人喜好问题) uiwidgets。基于flutter,需要提前熟悉flutter相关组件开发用法,使用C#语言代替dart。 uiwidgets相关链接 个人体验:组件的样式可以直接使用css样式,开发效率和运行效率非常高。缺点是在高版本的unity editor中不支持webgl平台,我司要求是pc本地端和webgl平台都能支持。而且2.0及以后版本需要unity的中国团队特殊打包的unity editor。(运行效率是真高,而且特别适合开发移动端app) UIE。基于现在的通用web技术包括html和css相关去编写uxml标签和uss规则,使用C#代替js实现功能逻辑。uie相关链接 个人体验:比较契合我司的流程,奈何完善度不够,uss属性使用上有一些问题,现阶段使用在深度定制时容易发现小问题。 在unity中嵌入浏览器相关组件,直接将web页面投到unity中。 个人体验:在我司可以做到极快的开发效率,经过实际测试,帧数能接近uiwidgets,需要特殊的方式实现页面与unity场景间互相通信,但是对应的unity开发工程师需要学习前端相关技术栈,或者通过部门资源申请调web前端开发工程师参与开发工作(这么爽不尝试一下吗)。 那有没有一种方式既能满足设计部门与开发部门流程不变又能减少unity开发侧流程改变和学习成本呢?那就是本文将要介绍的blazor,使用C#构建web页面,降低unity开发工程师学习成本(其实和flutter一样,blazor已经支持多平台了)。blazor相关链接 2. ui界面与场景的互通方式 大多数情况下,web页面和unity场景需要借助额外的开发(独立于业务外)才能进行互相rpc操作,比如unity手册:与浏览器脚本交互。 此场景下其网络通信架构类似下图: 当然可能有些会将客户端与服务端通信部分合并为上半部分,UI不参与后端直接通信,即图中3不存在。 但是blazor有一个特点,能以非常低开发成本的方式使用SignalR这个网络库,进而方便的实现RPC功能 此时网络通信架构就变成了: 当然,此方式也有对应的缺点,即服务端不可用的情况下场景和UI无法互动。但我司当前实现里服务端不可用的情况下客户端场景内也无法渲染(场景内都依赖服务端存储的配置进行动态生成和动作),所以这个缺点我司不用关注。 3. 接下来我们来使用unity+blazor实现一个最小可用的demo,下面是需求整理与具体实现: 客户端场景和UI要能够存在一一绑定关系且有重连机制,具体实现 点击UI中的相机方向按钮或者场景模型列表,要能控制相机移动,具体实现 点击UI中的场景模型对应设置,要能在场景中获取正确模型并材质变化 在场景中控制相机移动,UI中的相机方向按钮要能联动实现样式变化 在场景中点击对应模型,要能在UI中展示对应模型属性 4. 结尾一些想说的话: 在此,我祝文中提到的和其他可能遗漏的各个UI解决方案都能发展的更好更强,各位看官也都能实现自己想要的目标! 大家要根据自己实际条件来选择,这东西本身没有银弹只有适合自己的,要评估个人与部门技术栈(我司软件部门全员除新入职的unity工程师,其余包括笔者均掌握至少一个angular、vue、react、flutter等前端技术栈和一个.net或Java后端技术栈)、公司各部门流程和对接方式(我司设计部门使用figma进行原型设计与素材交付)、项目的条件和特性(我司项目不是竞技类游戏不需要场景和页面快速互相响应、客户端和服务端都在内网进行部署运行)等因素去灵活选择。
上一篇链接 这篇随笔是当前系列第三篇,详细说明点击UI中的相机方向按钮或者场景模型列表,要能控制相机移动的实现步骤。
1. 需求流程图 2. 具体实现步骤 2.1. 实现第一步:场景访问UI界面 详细实现查看上一篇链接 2.2. 实现第二步:UI界面获取对应数据 定义相机方向按钮数据和场景内模型数据 创建相机方向按钮组件,并在Index组件中应用, 创建模型列表按钮组件,并在Index组件中应用, 2.3. 实现第三步:返回页面 启动客户端,访问页面 2.4. 实现第四步:用户点击相机方向按钮,对应按钮组件样式变化,触发事件 完善相机方向按钮组件相关代码 2.5. 实现第五步:将相机移动事件发送给场景 创建CameraHub并完善相关方法,相机按钮状态切换时发送事件 2.6. 实现第六步:场景相机进行移动 将页面的body调至透明,以露出被遮挡的场景 创建相机相关的HubService并完善连接代码,接收服务端消息并将状态同步到相机脚本中,相机脚本根据布尔量判断方向 运行客户端,测试相机方向按钮的功能 运行视频 2.7. 实现第七步:将模型数据推送给场景 新建一个场景数据相关的Hub,然后利用定时器向所有连接发送场景数据 客户端新建一个HubService,根据收到的信息生成对应模型 2.8. 实现第八步:点击模型按钮,按钮样式变化,触发事件 完善模型按钮逻辑 2.9. 实现第九步:将点击模型按钮事件发送给场景 定义一个新方法,在触发按钮状态改变时调用,将模型名称传给场景 2.10. 实现第十步:场景相机定位到模型附近 HubService中添加对应的事件处理配置,实现相机根据模型位置移动自身位置的方法 运行客户端,测试场景模型按钮对应功能 运行视频 3.
上一篇链接 这篇随笔是当前系列第二篇,详细说明客户端场景和UI要能够存在一一绑定关系且有重连机制需求的实现步骤。
1. 需求流程图 2. 具体实现步骤 2.1. 新建unity项目 点开unity hub,新建一个项目 设置项目版本和模板,当前使用2022.1.0b16版本下的URP示例模板 打开Package Manager,导入Embedded Browser(一个实现了嵌入浏览器的资源包,类似包还有很多)和Best HTTP/2(一个封装了更优雅方便的网络接口资源包) 2.2. 实现第一步:生成客户端Id 创建一个类ClientStateManager,继承MonoBehaviour,在Awake生命周期函数中生成对应的id 新建一个空的gameobject,将ClientStateManager以组件方式添加 2.3. 实现第二步:启动HubConnection后发起连接,将客户端Id发送到Hub 点开rider,新建一个项目,Type选用Blazor Server App 完善客户端相关代码, 完善服务端相关代码并启动客户端进行测试, 2.4. 实现第三步:Hub将对应连接放入组中,组名为客户端Id 完善服务端相关代码, 2.5. 实现第四步:定期Ping服务端 完善客户端相关代码, 完善服务端相关代码, 2.6. 实现第五步:服务端回复Ping 完善服务端代码, 2.7. 实现第六步:场景带上客户端Id进行访问 客户端新建Canvas,并新建一个它的子物体,添加对应组件并完善属性, 完善客户端代码, 将页面组件拉入ClientStateManager的webPage属性中, 2.
1.1 基础环境 3台配置一致的虚拟机: 虚拟机配置:4c 8g 虚拟机操作系统:cents7 硬盘:vda:40G vdb:20G Kubernete 版本:1.20.0 Docker版本:20.10.7 默认k8s 已安装完成,采用kubeadm 容器化安装
1.2 所安装rook/ceph版本: ceph:v15.2.11
rook:1.6.3
1.3 前提 正常运行的多节点k8s集群,两个子节点及以上 rook的版本大于1.3,无法使用目录创建集群,要使用单独的裸盘进行创建,也就是创建一个新的磁盘,挂载到宿主机,不进行格式化,直接使用即可。检查步骤: lsblk -fNAME FSTYPE LABEL UUID MOUNTPOINTvda └─vda1 xfs 6f15c206-f516-4ee8-a4b7-89ad880647db /vdb FSTYPE为空的磁盘为可用磁盘,该磁盘需要清除数据(不能格式化)。 做这个实验需要高配置,每个子节点配置不能低于2核4G,主节点不低于4核8G 2 搭建流程 2.1Rook是什么? Rook本身并不是一个分布式存储系统,而是利用 Kubernetes 平台的强大功能,通过 Kubernetes Operator 为每个存储提供商提供服务。它是一个存储“编排器”,可以使用不同的后端(例如 Ceph、EdgeFS 等)执行繁重的管理存储工作,从而抽象出很多复杂性。 Rook 将分布式存储系统转变为自我管理、自我扩展、自我修复的存储服务。它自动执行存储管理员的任务:部署、引导、配置、供应、扩展、升级、迁移、灾难恢复、监控和资源管理 Rook 编排了多个存储解决方案,每个解决方案都有一个专门的 Kubernetes Operator 来实现自动化管理。目前支持Ceph、Cassandra、NFS。 目前主流使用的后端是Ceph ,Ceph 提供的不仅仅是块存储;它还提供与 S3/Swift 兼容的对象存储和分布式文件系统。Ceph 可以将一个卷的数据分布在多个磁盘上,因此可以让一个卷实际使用比单个磁盘更多的磁盘空间,这很方便。当向集群添加更多磁盘时,它会自动在磁盘之间重新平衡/重新分配数据。 2.2 ceph-rook 与k8s集成方式 Rook 是一个开源的cloud-native storage编排, 提供平台和框架;为各种存储解决方案提供平台、框架和支持,以便与云原生环境本地集成。 Rook 将存储软件转变为自我管理、自我扩展和自我修复的存储服务,它通过自动化部署、引导、配置、置备、扩展、升级、迁移、灾难恢复、监控和资源管理来实现此目的。 Rook 使用底层云本机容器管理、调度和编排平台提供的工具来实现它自身的功能。 Rook 目前支持Ceph、NFS、Minio Object Store和CockroachDB。 Rook使用Kubernetes原语使Ceph存储系统能够在Kubernetes上运行 3 安装部署 3.
开发环境 开启ie兼容 在EDGE浏览器中输入edge://settings/defaultBrowser,修改为允许 添加某页面兼容 使用edge打开该页面 出现ie标识 默认是ie11 使用开发者工具 键盘win+r打开运行 输入%systemroot%\system32\f12\IEChooser.exe 点击对应网站 出现调试框 调整ie版本 技术项 IE9不支持flex,grid 其他请百度搜索:“IE9前端开发指南” 或查阅MDN文档:https://developer.mozilla.org/zh-CN/docs/Web/CSS/display
应当从未来的日子夺取欢乐。
-- В.В.马雅可夫斯基《致谢尔盖·叶赛宁》
ZZN而已 Just ZZN 庚辰年春 Spring 2000
[email protected]
统计/数据分析/机器学习/优化问题/R语言/Python Statistics/Data analysis/Machine learning/Optimization problem/R/Python
名义最喜欢清单 Shape of my heart 约翰·卡尔·弗里德里希·高斯 Johann Carl Friedrich Gauß 豪尔赫·路易斯·博尔赫斯 Jorge Luis Borges 李安/周星驰/罗大佑/绿洲乐队 Ang Lee/Stephen Chow/Tayu Lo/Oasis 金蔷薇/花样年华 Золотая роза/In the Mood for Love 武林外传/飞出个未来/寻妈记 My Own Swordsman/Futurama/HIMYM 鲜牛奶/椰子/蟹黄堡/老爸炒的菜 Fresh milk/Coconut/Krabby Patty/Dad's cooking 小尼/向日葵 Nessie/Sunflower 慢跑/功夫(想要但不会) Jogging/Kung Fu (in my dreams) 梦想/钱/没有压迫和剥削的社会 Dreams/Money/A society without oppression and exploitation
A message containing letters from A-Z can be encoded into numbers using the following mapping:
'A' -> 1 'B' -> 2 ... 'Z' -> 26
To decode an encoded message, all the digits must be grouped then mapped back into letters using the reverse of the mapping above (there may be multiple ways). For example, 11106 can be mapped into:
AAJF with the grouping (1 1 10 6) KJF with the grouping (11 10 6) Note that the grouping (1 11 06) is invalid because 06 cannot be mapped into 'F' since 6is different from 06.