0%

Jenkins Pipeline 提供了一套可扩展的工具,用于将“简单到复杂”的交付流程实现为“持续交付即代码”。Jenkins Pipeline 的定义通常被写入到一个文本文件(称为 Jenkinsfile )中,该文件可以被放入项目的源代码控制库中。

Application Window

App.xmal

1


MainWindow.xmal
1

dispatch.invoke

从主 UI 线程派生的后台线程不能更新的内容,比如在Button onClick中创建的线程,为了使后台线程访问Button的内容属性,后台线程必须将工作委托给
Dispatcher 与 UI 线程关联。 这通过使用Invoke 或 BeginInvoke实现。 Invoke 是同步,BeginInvoke 是异步的。

control template

实现一个按钮 倒圆角 背景 字体 MouseOver效果

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
<Button HorizontalAlignment="Center" VerticalAlignment="Center" Height="40" Width="120" 
Foreground="#4D4D4D" Content="Close" FontSize="14" FontWeight="bold" Click="btnOK_Click">
<Button.Template >
<ControlTemplate TargetType="{x:Type Button}" >
<Border x:Name="btnBorder" BorderBrush="{TemplateBinding Control.BorderBrush}" CornerRadius="5,5,5,5">
<Border.Background >#DDF9FE</Border.Background>
<TextBlock x:Name="BtnText" Text="{TemplateBinding ContentControl.Content}"
Foreground="{TemplateBinding Foreground}"
HorizontalAlignment="Center" VerticalAlignment="Center"></TextBlock>
</Border>
<ControlTemplate.Triggers>
<Trigger Property="IsMouseOver" Value="True">
<Setter TargetName="btnBorder" Property="Background" Value="#36B0C9"/>
<Setter TargetName="BtnText" Property="Foreground" Value="#FFF"/>
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Button.Template>
</Button>

ARCore

  • VR(Virtual Reality) 模拟三维场景 使用户感觉身临其境
  • AR(Augmented Reality)将虚拟元素叠加到现实世界
  • MR(Mixed Reality) 前两者的融合和交互
  • XR(Extended Reality) 统称以及应用延申

瓶颈

  • 终端的渲染性能
    包括网页端WebGL的渲染性能,以及移动终端的硬件性能
  • 网络对大型模型场景的传输能力

像素流送

UE像素流送

WebGPU

WebGL是OpenGL ES版本API的封装,已经有十几年的历史,随着图形技术的发展,W3C提出全新的规范,浏览器封装了现代图形API(Dx12、Vulkan、Metal)让浏览器里面直接可以调用这三个现代图形API能力,实现高质量的渲染效果,调用GPU的强大计算能力。

WebGPU is available for now in Chrome Canary behind an experimental flag. You can enable it at chrome://flags/#enable-unsafe-webgpu . The API is constantly changing and currently unsafe.

WebGPU学习系列目录

WebGL也会调用GPU工作 那WebGPU技术又是为了解决什么而出现的呢

现代图形API

WebGL 是基于 2007 年的 OpenGL ES 2.0 规范,而 WebGPU 则是基于 2010 年后出现的现代图形 API

WebGL 像一个巨大的、全局共享的“状态机”。你调用 gl.enable()、gl.blendFunc()、gl.bindTexture() 等函数时,你是在修改这个全局状态。当你调用 gl.drawArrays() 时,GPU 就使用当前所有的“全局状态”来执行绘制。

WebGL Api 充当桥梁 一边是js环境 运行在CPU 另一边是GPU图形计算功能

CPU 的工作部分(准备阶段)

  1. 创建数据: JavaScript 代码会创建 3D 模型的数据,比如顶点位置、颜色、纹理坐标等。这些数据通常存储在 JavaScript 的 ArrayFloat32Array 中。
  2. 组织场景: CPU 负责管理场景图,比如哪个物体在哪个位置,相机看向哪里,灯光如何设置。
  3. 编译着色器: CPU 负责将 GLSL(OpenGL Shading Language)代码(即着色器程序)发送给显卡驱动,由驱动将其编译成 GPU 能直接理解的机器码。
  4. 发送指令和数据: 这是最关键的一步。CPU 通过 WebGL API,将准备好的数据(顶点、纹理图片)和指令(“用这个着色器”、“画这些三角形”、“应用这个纹理”)打包,通过总线发送到 GPU 的显存中。

可以把这个过程比作: CPU 是一个总指挥,它准备好所有的“原材料”(模型数据)和“施工图纸”(着色器),然后通过 WebG L 这个“通信系统”把它们全部送到 GPU 这个“超级工厂”。

GPU 的工作部分(执行阶段)

  1. 接收数据: GPU 接收 CPU 发送过来的所有数据和指令,并把它们放在自己的高速显存里。
  2. 并行执行着色器: 一旦收到“开始渲染”的指令(如 gl.drawArraysgl.drawElements),GPU 就会火力全开。
    • 顶点着色器: GPU 的成百上千个核心同时处理成千上万个顶点,计算它们在屏幕上的最终位置。
    • 光栅化: GPU 硬件自动将处理好的顶点组装成三角形,再把这些三角形转换成屏幕上的像素片段。
    • 片元着色器: GPU 的核心们再次同时工作,为每一个像素片段计算最终的颜色(考虑光照、纹理、阴影等)。
  3. 输出结果: 最终,所有像素的颜色值被写入到帧缓冲区,然后显示在屏幕上。

WebGPU 不再是状态机。你创建一个“命令缓冲区”(GPUCommandBuffer),然后像写日志一样,把所有要执行的命令(绑定管线、绑定资源、绘制)都记录进去。记录完成后,你将整个缓冲区一次性提交给 GPU 执行。

C++ 为什么要先声明头文件

  • 声明而非定义:头文件通常包含的是声明(declarations),而不是定义(definitions)。这意味着它们告诉编译器某个变量、函数或类的存在及其类型(即静态类型),但不包括具体的实现细节。例如,函数的原型会告诉你函数的名字、返回类型和参数列表,但不会包含函数体。
  • 避免类型错误和未识别接口:通过在头文件中声明变量、函数和类的结构,编译器可以在编译阶段进行类型检查,确保代码中使用的变量和函数调用与它们的声明相匹配。这有助于提前发现类型错误,并确保所有接口都被正确识别。如果尝试使用一个没有在任何地方声明过的函数或变量,编译器将无法识别并报错。
  • 模块化设计和代码复用:头文件支持模块化设计,允许开发者将程序分割成多个逻辑部分。每个部分可以通过包含相应的头文件来访问其他部分的接口,而不需要了解其内部实现细节。这种方式不仅提高了代码的可读性和维护性,还促进了代码复用。
  • c解决依赖关系:在大型项目中,不同源文件之间可能存在复杂的依赖关系。通过头文件,可以清晰地指定这些依赖关系,使得编译器能够正确解析跨文件的引用。
  • 提高编译效率:合理组织头文件可以帮助减少不必要的重新编译工作。比如,当修改了一个源文件时,只有直接或间接依赖于该源文件的其他文件需要重新编译,从而节省时间。
    成员函数的调用
    1
    2
    3
    void res = ClassA::functionX()
    ClassA a;
    void res = a.functionX()

vcpkg install libjpeg-turbo:x64-windows

内联函数inline function

编译时函数体会直接复制到 调用处(类似宏定义)是一种空间换时间的效率提升

指针

1
2
3
4
5
int a; 
int* p;

p = &a;
// *p 相当于a的值

禁写间接引用

1
2
3
4
5
6
7
8
9
const int *p = &a;
p=&b; // 指针p指向可以修改
// *p=1 非法 禁止操作*p

// 扩展 如果禁止修改指向 应声明为
// const int const* p = &a 声明时必须初始化

// 扩展 禁写指针即禁止修改指向 常指针
// int* const p = &a 可以操作*p修改a的值

debug

在visual studio中open一个cpp文件,执行 Ctrl+F5 提示“Please Select a Valid Startup Item”
一般要下载一个c语言编译器,并配置到vscode
对于已经安装visual studio的环境,应能配置使用已有编译器

类型安全

类型安全指变量仅能访问权限匹配的内存区域。该概念区分编程语言和程序语境,C++是不具有类型安全的,因为在C++中,没有限制对于内存的解释方式,比如如int型的数据1,同时也可以解读为bool型的数据true,但是可以编程声明加以区分,使程序达成类型安全

协程(存目)

troubleshooting

或出现error LNK2019: unresolved external symbol _Thrd_sleep_for类似错误 与编译器版本有关 应升级visual studio

悬空指针

即指针指向内容已被销毁
某年月日 考虑到返回空结构体难以判断,遂返回nullptr

1
2
3
4
5
6
7
8
9
MyExample::AdjustmentPop(){
if(list.size>0){
auto* struct_ptr = &list.back(); // 返回最后一个元素的地址
list.pop_back(); // 注意:此时 structt_ptr 指向的元素已被移除
return structt_ptr;
}else{
return nullptr;
}
}

当调用AdjustmentPop并访问指向的结构体内容时,其内容会突变为随机值

Defination

1
2
3
4
5
6
7
8
9
10
11
12
13
14
class Employee:
'员工基类'
empCount = 0

def __init__(self, name, salary):
self.name = name
self.salary = salary
Employee.empCount += 1

def displayCount(self):
print("%d" % Employee.empCount)

def displayEmployee(self):
print ("Name : ", self.name, ", Salary: ", self.salary)

__init__:构造函数

self 代表类的实例,self 在定义类的方法时是必须有的,print(self)可以看到类实例字样及内存地址

Python内置类属性

  • __dict__ : 类的属性字典,由类的数据属性组成
  • __doc__ :类的文档字符串
  • __name__: 类名
  • __module__: 类定义所在的模块(类的全名是’__main__.className’,如果类位于一个导入模块mymod中,那么className.__module__ 等于 mymod)
  • __bases__ : 类的所有父类构成元素(包含了一个由所有父类组成的元组)

单下划线、双下划线、头尾双下划线说明:

  • __foo__: 定义的是特殊方法,一般是系统定义名字 ,类似 __init__() 之类的。

_foo: 以单下划线开头的表示的是 protected 类型的变量,即保护类型只能允许其本身与子类进行访问,不能用于 from module import *

__foo: 双下划线的表示的是私有类型(private)的变量, 只能是允许这个类本身进行访问了。

CSDN Blog: 继承和多态

宽松许可

  • MIT
  • Apache
  • BSD
    鼓励开源和代码共享,允许修改、再发布,尊重原作者权利,在发布或代码引用处声明BSD协议

弱化的著作权

  • LGPL

著作权

  • GPL

使用 jenkins ant 自动化脚本调用build.xml任务

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
<?xml version="1.0" ?>
<project basedir="." default="build_all" name="TestProj">
<description>
TestProj Build File.
</description>
<tstamp>
<format locale="en" pattern="yyMMdd" property="TODAY_CN"/>
</tstamp>

<property name="build_ver" Value="1.0.5.0" />

<target description="Create publish folder" name="create_folder">
<delete dir="${build_ver}" quiet="true"/>
<mkdir dir="${build_ver}\publish"/>
</target>

<target description="Pack TestProj" name="sign_and_copy">
<exec dir="." executable="cmd.exe">
<arg line="/c"/>
<arg line=".\uac_cert\signtool.exe sign /f ".\uac_cert\test.pfx" /p passwordxxx /fd SHA256 /t "http://timestamp.digicert.com" "..\TestProj\bin\Release\TestProj.exe""/>
</exec>

<copy file="..\TestProj\bin\Release\TestProj.exe" overwrite="true" todir="${build_ver}\publish"/>
<copy file="..\TestProj\bin\Release\Microsoft.Identity.Client.dll" overwrite="true" todir="${build_ver}\publish"/>
<copy file="..\TestProj\bin\Release\Newtonsoft.Json.dll" overwrite="true" todir="${build_ver}\publish"/>
<zip destfile="${build_ver}\publish.zip" basedir="${build_ver}\publish" />
<delete dir="${build_ver}\publish" quiet="true"/>
</target>

<!-- Build All -->
<target description="Build solution" name="build_all">
<antcall target="create_folder"/>
<antcall target="pack_pubclient"/>
</target>
</project>


其中使用signtool.exe给构建生成的应用添加数字签名,签名密钥保存在pfx文件中 需使用password访问

issue: capicom.dll没有正确安装或者是没有注册

加密API组件对象模型(Cryptographic API Component Object Model,capicom)微软Windows系统组件,用于以数字方式签署数据代码、验证数字签章、加密解密等,见CryptoAPI

注册capicom

1
Regsvr32 c:/windows/system32/capicom.dll

System.Diagnostics命名空间

提供允许你与系统进程、事件日志和性能计数器进行交互的类。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
using System.Diagnostics
...
class Program
{
static void Main(string[] args){
InitLog()
Trace.WriteLine($"log is here")
}
private static void InitLog(){
string logDirectory = @"D:\log\"
string timestamp = DateTime.UtcNow.ToString("yyyyMMdd_HHmmss", CultureInfo.InvariantCulture);
logDirectory = $"{logDirectory}_{timestamp}.log";
Trace.Listeners.Add(new TextWriterTraceListener(File.CreateText(logDirectory)));
Trace.AutoFlush = true;
}
}