【Unity学习笔记】New Input System 部分源码和测试用例补充

转载请注明出处:🔗https://blog.csdn.net/weixin_44013533/article/details/135630016
作者:CSDN@|Ringleader|

主要参考:

  • Unity官方Input System手册与API
  • 【Unity学习笔记】Unity TestRunner使用
  • 【Unity学习笔记】第十二 · New Input System 及其系统结构 和 源码浅析

注:本文使用的unity版本是2021.3.25f,InputSystem版本为1.5.1

deafault Interaction测试用例

  1. ButtonAndValue

    [Test]
    public void Actions_ButtonActions_RespectButtonPressPoints()
    {
        InputSystem.settings.defaultButtonPressPoint = 0.5f;
        InputSystem.settings.buttonReleaseThreshold = 0.9f; // Release at 90% of press point puts release at 0.45.
    
        // Customize gamepad with specific button press point on right trigger (but not on left).
        InputSystem.RegisterLayoutOverride(@"
            {
                ""name"" : ""GamepadRightTriggerWithPressPoint"",
                ""extend"" : ""Gamepad"",
                ""controls"" : [
                    { ""name"" : ""rightTrigger"", ""parameters"" : ""pressPoint=0.75"" }
                ]
            }
        ");
    
        var gamepad = InputSystem.AddDevice<Gamepad>();
    
        var rightTriggerButton = new InputAction(type: InputActionType.Button, binding: "<Gamepad>/rightTrigger");
        var rightTriggerValue = new InputAction(type: InputActionType.Value, binding: "<Gamepad>/rightTrigger");
        var leftTriggerButton = new InputAction(type: InputActionType.Button, binding: "<Gamepad>/leftTrigger");
        var leftTriggerValue = new InputAction(type: InputActionType.Value, binding: "<Gamepad>/leftTrigger");
    
        rightTriggerButton.Enable();
        rightTriggerValue.Enable();
        leftTriggerButton.Enable();
        leftTriggerValue.Enable();
    
        using (var rightTriggerButtonTrace = new InputActionTrace(rightTriggerButton))
        using (var rightTriggerValueTrace = new InputActionTrace(rightTriggerValue))
        using (var leftTriggerButtonTrace = new InputActionTrace(leftTriggerButton))
        using (var leftTriggerValueTrace = new InputActionTrace(leftTriggerValue))
        {
            Set(gamepad.leftTrigger, 0.25f);
            Set(gamepad.rightTrigger, 0.25f);
    
            // Have crossed neither button threshold. Actions start but don't perform.
            Assert.That(leftTriggerButtonTrace, Started(leftTriggerButton, gamepad.leftTrigger, value: 0.25f));
            Assert.That(rightTriggerButtonTrace, Started(rightTriggerButton, gamepad.rightTrigger, value: 0.25f));
    
            Assert.That(leftTriggerValueTrace,
                Started(leftTriggerValue, gamepad.leftTrigger, value: 0.25f)
                    .AndThen(Performed(leftTriggerValue, gamepad.leftTrigger, value: 0.25f)));
            Assert.That(rightTriggerValueTrace,
                Started(rightTriggerValue, gamepad.rightTrigger, value: 0.25f)
                    .AndThen(Performed(rightTriggerValue, gamepad.rightTrigger, value: 0.25f)));
    
            rightTriggerButtonTrace.Clear();
            rightTriggerValueTrace.Clear();
            leftTriggerButtonTrace.Clear();
            leftTriggerValueTrace.Clear();
    
            Set(gamepad.leftTrigger, 0.6f);
            Set(gamepad.rightTrigger, 0.6f);
    
            // Have grossed global but not right trigger threshold.
            Assert.That(leftTriggerButtonTrace, Performed(leftTriggerButton, gamepad.leftTrigger, value: 0.6f));
            Assert.That(rightTriggerButtonTrace, Is.Empty);
    
            Assert.That(leftTriggerValueTrace, Performed(leftTriggerValue, gamepad.leftTrigger, value: 0.6f));
            Assert.That(rightTriggerValueTrace, Performed(rightTriggerValue, gamepad.rightTrigger, value: 0.6f));
    
            rightTriggerButtonTrace.Clear();
            rightTriggerValueTrace.Clear();
            leftTriggerButtonTrace.Clear();
            leftTriggerValueTrace.Clear();
    
            Set(gamepad.leftTrigger, 0.9f);
            Set(gamepad.rightTrigger, 0.9f);
    
            // No change on left trigger action, right trigger crossed threshold.
            Assert.That(leftTriggerButtonTrace, Is.Empty);
            Assert.That(rightTriggerButtonTrace, Performed(rightTriggerButton, gamepad.rightTrigger, value: 0.9f));
    
            Assert.That(leftTriggerValueTrace, Performed(leftTriggerValue, gamepad.leftTrigger, value: 0.9f));
            Assert.That(rightTriggerValueTrace, Performed(rightTriggerValue, gamepad.rightTrigger, value: 0.9f));
    
            rightTriggerButtonTrace.Clear();
            rightTriggerValueTrace.Clear();
            leftTriggerButtonTrace.Clear();
            leftTriggerValueTrace.Clear();
    
            Set(gamepad.leftTrigger, 0.6f);
            Set(gamepad.rightTrigger, 0.6f);
    
            // No change on left trigger action, right trigger action cancels.
            Assert.That(leftTriggerButtonTrace, Is.Empty);
            Assert.That(rightTriggerButtonTrace, Started(rightTriggerButton, gamepad.rightTrigger, value: 0.6f));
    
            Assert.That(leftTriggerValueTrace, Performed(leftTriggerValue, gamepad.leftTrigger, value: 0.6f));
            Assert.That(rightTriggerValueTrace, Performed(rightTriggerValue, gamepad.rightTrigger, value: 0.6f));
    
            rightTriggerButtonTrace.Clear();
            rightTriggerValueTrace.Clear();
            leftTriggerButtonTrace.Clear();
            leftTriggerValueTrace.Clear();
    
            Set(gamepad.leftTrigger, 0.4f);
            Set(gamepad.rightTrigger, 0.4f);
    
            // Left trigger cancels, right trigger *starts* again (but doesn't perform).
            Assert.That(leftTriggerButtonTrace, Started(leftTriggerButton, gamepad.leftTrigger, value: 0.4f));
            Assert.That(rightTriggerButtonTrace, Is.Empty);
    
            Assert.That(leftTriggerValueTrace, Performed(leftTriggerValue, gamepad.leftTrigger, value: 0.4f));
            Assert.That(rightTriggerValueTrace, Performed(rightTriggerValue, gamepad.rightTrigger, value: 0.4f));
    
            rightTriggerButtonTrace.Clear();
            rightTriggerValueTrace.Clear();
            leftTriggerButtonTrace.Clear();
            leftTriggerValueTrace.Clear();
    
            Set(gamepad.leftTrigger, 0f);
            Set(gamepad.rightTrigger, 0f);
    
            // No change on left and right trigger actions.
            Assert.That(leftTriggerButtonTrace, Canceled(leftTriggerButton, gamepad.leftTrigger, 0f));
            Assert.That(rightTriggerButtonTrace, Canceled(rightTriggerButton, gamepad.rightTrigger, 0f));
    
            Assert.That(leftTriggerValueTrace, Canceled(leftTriggerValue, gamepad.leftTrigger, value: 0f));
            Assert.That(rightTriggerValueTrace, Canceled(rightTriggerValue, gamepad.rightTrigger, value: 0f));
    
            rightTriggerButtonTrace.Clear();
            leftTriggerButtonTrace.Clear();
    
            // Make sure that we start and cancel if we press the buttons just a little and then release.
            Set(gamepad.leftTrigger, 0.25f);
            Set(gamepad.rightTrigger, 0.25f);
    
            Assert.That(leftTriggerButtonTrace, Started(leftTriggerButton, gamepad.leftTrigger, value: 0.25f));
            Assert.That(rightTriggerButtonTrace, Started(rightTriggerButton, gamepad.rightTrigger, value: 0.25f));
    
            rightTriggerButtonTrace.Clear();
            leftTriggerButtonTrace.Clear();
    
            Set(gamepad.leftTrigger, 0f);
            Set(gamepad.rightTrigger, 0f);
    
            Assert.That(leftTriggerButtonTrace, Canceled(leftTriggerButton, gamepad.leftTrigger, value: 0f));
            Assert.That(rightTriggerButtonTrace, Canceled(rightTriggerButton, gamepad.rightTrigger, value: 0f));
        }
    }
    
  2. passthrough

    [Test]
    public void Actions_passthroughActions()
    {
    
        var gamepad = InputSystem.AddDevice<Gamepad>();
    
        var rightTriggerValue = new InputAction(type: InputActionType.PassThrough, binding: "<Gamepad>/rightTrigger");
    
        rightTriggerValue.Enable();
    
        using (var rightTriggerValueTrace = new InputActionTrace(rightTriggerValue))
        {
            Set(gamepad.rightTrigger, 0.25f);
            Assert.That(rightTriggerValueTrace, Performed(rightTriggerValue, gamepad.rightTrigger, value: 0.25f));
            rightTriggerValueTrace.Clear();
    
            Set(gamepad.rightTrigger, 0.6f);
            Assert.That(rightTriggerValueTrace, Performed(rightTriggerValue, gamepad.rightTrigger, value: 0.6f));
            rightTriggerValueTrace.Clear();
            
            Set(gamepad.rightTrigger, 0.9f);
            Assert.That(rightTriggerValueTrace, Performed(rightTriggerValue, gamepad.rightTrigger, value: 0.9f));
            rightTriggerValueTrace.Clear();
            
            Set(gamepad.rightTrigger, 0f);
            Assert.That(rightTriggerValueTrace, Performed(rightTriggerValue, gamepad.rightTrigger, value: 0f));
            rightTriggerValueTrace.Clear();
        }
    }
    

Press Interaction测试用例

using System.Diagnostics.CodeAnalysis;
using NUnit.Framework;
using UnityEngine.InputSystem;
using UnityEngine.InputSystem.Utilities;

namespace Scenes.TestAction
{
    [SuppressMessage("ReSharper", "AccessToStaticMemberViaDerivedType")]
    public class TestAction : InputTestFixture
    {

        [Test]
        [TestCase(InputActionType.Value)]
        [TestCase(InputActionType.Button)]
        [TestCase(InputActionType.PassThrough)]
        public void Actions_PressOnly(InputActionType type)
        {
            var gamepad = InputSystem.AddDevice<Gamepad>();

            InputSystem.settings.defaultButtonPressPoint = 0.5f;
            InputSystem.settings.buttonReleaseThreshold = 0.75f; // Puts release point at 0.375.

            var action = new InputAction(type:type, binding: "<Gamepad>/leftTrigger", interactions: "press(behavior=0)");
            action.Enable();

            using (var trace = new InputActionTrace(action))
            {
                Set(gamepad.leftTrigger, 0.35f);

                Assert.That(trace, Started(action, control: gamepad.leftTrigger, value: 0.35f));

                trace.Clear();

                Set(gamepad.leftTrigger, 0.5f);

                Assert.That(trace, Performed(action, control: gamepad.leftTrigger, value: 0.5f));

                trace.Clear();

                Set(gamepad.leftTrigger, 0.6f);

                Assert.That(trace, Is.Empty);

                Set(gamepad.leftTrigger, 0.4f);

                Assert.That(trace, Is.Empty);

                Set(gamepad.leftTrigger, 0.3f);

                Assert.That(trace, Started(action, control: gamepad.leftTrigger, value: 0.3f));
                
                trace.Clear();
                Set(gamepad.leftTrigger, 0);
                Assert.That(trace, Canceled(action, control: gamepad.leftTrigger, value: 0));
            }
        }
        
        [Test]
        [TestCase(InputActionType.Value)]
        [TestCase(InputActionType.Button)]
        [TestCase(InputActionType.PassThrough)]
        public void Actions_RealeasOnly(InputActionType type)
        {
            var gamepad = InputSystem.AddDevice<Gamepad>();

            InputSystem.settings.defaultButtonPressPoint = 0.5f;
            InputSystem.settings.buttonReleaseThreshold = 0.75f; // Puts release point at 0.375.

            var action = new InputAction(type:type, binding: "<Gamepad>/leftTrigger", interactions: "press(behavior=1)");
            action.Enable();

            using (var trace = new InputActionTrace(action))
            {
                Set(gamepad.leftTrigger, 0.35f);
                Assert.That(trace, Started(action, control: gamepad.leftTrigger, value: 0.35f));
                trace.Clear();

                Set(gamepad.leftTrigger, 0.5f);
                Assert.That(trace, Is.Empty);
                trace.Clear();

                Set(gamepad.leftTrigger, 0.6f);
                Assert.That(trace, Is.Empty);
                trace.Clear();

                Set(gamepad.leftTrigger, 0.4f);
                Assert.That(trace, Is.Empty);
                trace.Clear();

                Set(gamepad.leftTrigger, 0.3f);
                Assert.That(trace,
                    Performed(action, control: gamepad.leftTrigger, value: 0.3f)
                        .AndThen(Canceled(action, control: gamepad.leftTrigger, value: 0)));
                trace.Clear();

                Set(gamepad.leftTrigger, 0.1f);
                Assert.That(trace, Started(action, control: gamepad.leftTrigger, value: 0.1f));
                trace.Clear();

                Set(gamepad.leftTrigger, 0);
                Assert.That(trace, Canceled(action, control: gamepad.leftTrigger, value: 0));
                trace.Clear();
                
                Set(gamepad.leftTrigger, 0.4f);
                Set(gamepad.leftTrigger, 0.3f);//onlyRelease 不超过press-threshold只回落release是不会触发的
                Assert.That(trace, Started(action, control: gamepad.leftTrigger, value: 0.4f));
                trace.Clear();
                
                
            }
        }
        
        [Test]
        [TestCase(InputActionType.Value)]
        [TestCase(InputActionType.Button)]
        [TestCase(InputActionType.PassThrough)]
        public void Actions_PressAndRelease(InputActionType type)
        {
            var gamepad = InputSystem.AddDevice<Gamepad>();

            InputSystem.settings.defaultButtonPressPoint = 0.5f;
            InputSystem.settings.buttonReleaseThreshold = 0.75f; // Puts release point at 0.375.

            var action = new InputAction(type:type, binding: "<Gamepad>/leftTrigger", interactions: "press(behavior=2)");
            action.Enable();

            using (var trace = new InputActionTrace(action))
            {
                Set(gamepad.leftTrigger, 0.35f);
                Assert.That(trace, Started(action, control: gamepad.leftTrigger, value: 0.35f));
                trace.Clear();

                Set(gamepad.leftTrigger, 0.5f);
                Assert.That(trace, Performed(action, control: gamepad.leftTrigger, value: 0.5f));
                trace.Clear();

                Set(gamepad.leftTrigger, 0.6f);
                Assert.That(trace, Is.Empty);
                trace.Clear();
                
                Set(gamepad.leftTrigger, 0.4f);
                Assert.That(trace, Is.Empty);
                trace.Clear();

                Set(gamepad.leftTrigger, 0.3f);
                Assert.That(trace,
                    Performed(action, control: gamepad.leftTrigger, value: 0.3f));
                trace.Clear();
                
                Set(gamepad.leftTrigger, 0);
                Assert.That(trace, Is.Empty);
                trace.Clear();
                
                Set(gamepad.leftTrigger, 0.9f);
                Assert.That(trace, 
                    Started(action, control: gamepad.leftTrigger, value: 0.9f)
                        .AndThen(Performed(action, control: gamepad.leftTrigger, value: 0.9f)));
                trace.Clear();
                
                Set(gamepad.leftTrigger, 0);
                Assert.That(trace, 
                    Performed(action, control: gamepad.leftTrigger, value: 0f)
                        .AndThen(Canceled(action, control: gamepad.leftTrigger, value: 0f)));
                trace.Clear();
                
                Set(gamepad.leftTrigger, 0.4f);
                Set(gamepad.leftTrigger, 0.3f);//press&release 不超过press-threshold只回落release是不会触发的
                Assert.That(trace, Started(action, control: gamepad.leftTrigger, value: 0.4f));
                trace.Clear();
            }
        }
        
    }

}

UnityEvent方式注册回调关键逻辑

  1. PlayerInput.InitializeActions()
    UnityEvent方式注册回调的核心在于PlayerInput组件enable时进行InitializeActions初始化操作
    在这里插入图片描述
  2. PlayerInputEditor
    但对于上面ActionEvent的eventId怎么匹配上actionId,则要看PlayerInputEditor.OnInspectorGUI()OnActionAssetChange()
    在这里插入图片描述
  3. UnityEvent<T0>
    上面action触发后,对应actionEvent调用Invoke,但此时真正的回调方法并没有注册,是在下面的InvokableCall中注册的,最后在InvokableCall.Invoke中执行最终的方法回调,处理输入处理。
    在这里插入图片描述
  4. InvokableCall<T1> 注册回调
    在这里插入图片描述
    从上面看,UnityAction方式远比原生C#事件复杂得多。(而且我也并没完全弄懂)

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/338262.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

【征服redis14】认真理解一致性Hash与Redis的三种集群

前面我们介绍了主从复制的方式和sentinel方式&#xff0c;这里我们看第三种模式-Cluster方式。 目录 1.前两种集群模式的特征与不足 2.Cluster模式 2.1 Cluster模式原理 2.2 数据分片与槽位 2.3 Cluster模式配置和实现 3.一致性Hash 3.1 哈希后取模 3.2 一致性Hash算法…

proteus8.15安装教程

proteus8.15安装教程 1.管理员运行 2.一直NEXT到这一步&#xff0c;需要注意&#xff0c;一定要选这一个 3.选中后出现 4.一直下一步到更新 这边结束后准备激活&#xff1a; 1.安装激活插件&#xff0c;先关闭防火墙 2.下一步 3.最后&#xff0c;将数据库放在根目录下 …

RHEL - 更新升级软件或系统

《OpenShift / RHEL / DevSecOps 汇总目录》 文章目录 小版本软件更新yum update 和 yum upgrade 的区别升级软件和升级系统检查软件包是否可升级指定升级软件使用的发行版本方法1方法2方法3方法4 查看软件升级类型更新升级指定的 RHSA/RHBA/RHEA更新升级指定的 CVE更新升级指定…

【C语言】深度探讨文件操作(一)

文章目录 &#x1f4dd;前言&#x1f320; 为什么使用文件&#xff1f;&#x1f309;什么是文件&#xff1f; &#x1f320;程序文件&#x1f309;数据文件 &#x1f320;文件名&#x1f309;二进制文件和文本文件&#xff1f; &#x1f320;文件的打开和关闭&#x1f309; 流和…

机器人电机综述 — 电机分类、舵机、步进与伺服、物理性质和伺服控制系统

电机综述 图片与部分素材来自知乎大佬不看后悔&#xff01;最全的电机分类&#xff0c;看这一篇就够了&#xff01; - 知乎 (zhihu.com)&#xff0c;本文只是把机器人中常用的电机知识提炼了一下 1 按照结构和工作原理划分 1. 同步电机 ​ 电机的转速与定子磁场的转速相同步…

《WebKit 技术内幕》之八(1):硬件加速机制

《WebKit 技术内幕》之八&#xff08;1&#xff09;&#xff1a;硬件加速机制 1 硬件加速基础 1.1 概念 这里说的硬件加速技术是指使用GPU的硬件能力来帮助渲染网页&#xff0c;因为GPU的作用主要是用来绘制3D图形并且性能特别好&#xff0c;这是它的专长所在&#xff0c;它…

k8s 使用cert-manager证书管理自签

个人建议使用安装更快&#xff0c;比helm快&#xff0c;还要等待安装crd kubectl apply -f https://github.com/cert-manager/cert-manager/releases/download/v1.13.3/cert-manager.yaml#官网 https://cert-manager.io/docs/installation/kubectl/#创建自签的ClusterIssuer c…

数据库设计最佳实践:学院个人信息管理系统中的MySQL优化

✍✍计算机编程指导师 ⭐⭐个人介绍&#xff1a;自己非常喜欢研究技术问题&#xff01;专业做Java、Python、微信小程序、安卓、大数据、爬虫、Golang、大屏等实战项目。 ⛽⛽实战项目&#xff1a;有源码或者技术上的问题欢迎在评论区一起讨论交流&#xff01; ⚡⚡ Java实战 |…

【C++记忆站】类和对象(一)

类和对象(一) 1.面向过程和面向对象初步认识 C语言是面向过程的&#xff0c;关注的是过程&#xff0c;分析出求解问题的步骤&#xff0c;通过函数调用逐步解决问题 C是基于面向对象的&#xff0c;关注的是对象&#xff0c;将一件事情拆分成不同的对象&#xff0c;靠对象之间…

2024年热门项目管理软件推荐:提升项目管理效率的工具集合

项目管理系统软件有哪些&#xff1f;本文将根据项目管理系统软件的功能、选择项目管理系统软件对公司的好处&#xff0c;根据国际上知名软件评测网站G2 Grid的评测结果对8款2024年好用的项目管理软件&#xff1a;Zoho Projects、Smartsheet、monday、Asana、ClickUp、Notion、A…

elasticsearch备份恢复,elasticdump使用

准备环境 1. 将node-v10.23.1-linux-x64.tar.xz上传到服务器/usr/local目录下 2. tar xf node-v10.23.1-linux-x64.tar.xz 3. 将node_modules.tar.gz上传到服务器/usr/local目录 4. tar -zxvf node_modules.tar.gz 5. 设置NODE环境 5.1 vim /etc/profile export NODEJS_…

YOLOv5全网首发:新一代高效可形变卷积DCNv4如何做二次创新?高效结合SPPF

💡💡💡本文独家改进:DCNv4更快收敛、更高速度、更高性能,与YOLOv5 SPPF高效结合 收录 YOLOv5原创自研 https://blog.csdn.net/m0_63774211/category_12511931.html 💡💡💡全网独家首发创新(原创),适合paper !!! 💡💡💡 2024年计算机视觉顶会创…

[python]使用pyqt5搭建yolov8钢筋计数一次性钢材计数系统

【官方框架地址】 github地址&#xff1a;https://github.com/ultralytics/ultralytics 【算法介绍】 Yolov8是一种先进的深度学习模型&#xff0c;用于目标检测和识别。在钢筋计数任务中&#xff0c;Yolov8可以有效地识别和计数图像中的钢筋。下面是对如何使用Yolov8实现钢筋…

Java SE入门及基础(25)

目录 方法带参&#xff08;续第24篇&#xff09; 6.方法参数传递规则 方法传参来自官方的说明 基本数据类型传值案例 基本数据类型传值时传递的是值的拷贝 引用数据类型传值案例 引用数据类型传值时传递的是对象在堆内存上的空间地址 Java SE文章参考:Java SE入门及基础知…

【C++第二课 - 类和对象上 - 入门知识】struct类、class类、访问限定符、this指针

目录 面向过程与面向对象初步认识类的定义struct定义类class定义类 类的访问限定符及封装访问限定符 声明与定义分离this指针类成员的命名问题this 类的实例化类的对象大小的计算成员函数为何不在对象里面类对象大小计算 面向过程与面向对象初步认识 C语言是面向过程的&#x…

线程和进程的区别(从JVM角度出发)

进程与线程的区别 线程具有许多传统进程所具有的特征&#xff0c;故又称为轻型进程(Light—Weight Process)或进程元&#xff1b;而把传统的进程称为重型进程(Heavy—Weight Process)&#xff0c;它相当于只有一个线程的任务。在引入了线程的操作系统中&#xff0c;通常一个进…

Linux 的提示符太长了,帮你精简一下

普通用户修改文件 ~/.bashrc 修改 50 行左右的代码&#xff0c;将两个w改为大写的W 如果是root用户则修改文件/root/.bashrc&#xff0c;同样的方法。

自然语言推断:注意力之注意(Attending)

注意&#xff08;Attending&#xff09; 第一步是将一个文本序列中的词元与另一个序列中的每个词元对齐。假设前提是“我确实需要睡眠”&#xff0c;假设是“我累了”。由于语义上的相似性&#xff0c;我们不妨将假设中的“我”与前提中的“我”对齐&#xff0c;将假设中的“累…

数据结构——循环链表

1.循环单链表 最后一个结点的指针不是NULL,而是指向头结点 单链表和循环单链表的比较&#xff1a; 单链表&#xff1a;从一个结点出发只能找到该结点后续的各个结点&#xff1b;对链表的操作大多都在头部或者尾部&#xff1b;设立 头指针&#xff0c;从头结点找到尾部的时间…

《Windows核心编程》若干知识点应用实战分享

目录 1、进程的虚拟内存分区与小于0x10000的小地址内存区 1.1、进程的虚拟内存分区 1.2、小于0x10000的小地址内存区 2、保存线程上下文的CONTEXT结构体 3、从汇编代码角度去理解多线程运行过程的典型实例 4、调用TerminateThread强制结束线程会导致线程中的资源没有释放…