Cocos2d-x 3.0final 终结者系列教程12-Vectormapvalue

2023-11-08 04:32

本文主要是介绍Cocos2d-x 3.0final 终结者系列教程12-Vectormapvalue,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

昨天中午北京温度为40度,在中午12:16分我来到篮球场,思考了1分钟决定开站

转球:

我和另外3名队友开始半场,

球传到我手的刹那顿时烫的我持球不稳,顿时问道了淡淡的胶皮味道和烤肉味道的混搭。

这时我来了一个腾空跳投,

球---------爆炸了。。。。。。。。

听新闻说昨天在路上都是 “熟人”

一位老大爷不慎被车刮倒了,大爷二话没说立马爬了起来,围观众人议论纷纷:

“大爷人不错”,“大爷素质真高”,“大爷身体可真好”

大爷说:

“快拉 秦皇岛吧,烫腚”。

估计昨天又有不少沿街乞讨人士和流浪狗失去生命(咋没人管管)

------------------------------------------------分割线---------------------------------------------------

在做Cocos2d-x2.0人的人们估计正在使用CCArray,CCDirectionary,CCDouble,CCFloat这些正搞得很爽,但不得不说

它们在V3.0中不用了。

看下3.0中的数据结合类Vector,Map,Value(建议大家自行阅读源码,本文只介绍如何使用,关于引用计数的概念推荐大家看我的视频),

以下案例来自TestCpp:

void TemplateVectorTest::onEnter()

{

    UnitTestDemo::onEnter();

    Vector<Node*> vec;//定义一个向量,其实是对stl Vector的封装,只是加入了对象的内存计数管理

    CCASSERT(vec.empty(), "");

    CCASSERT(vec.capacity() == 0, "");

    CCASSERT(vec.size() == 0, "");

    CCASSERT(vec.max_size() > 0, "");

    auto node1 = Node::create();

    node1->setTag(1);

    vec.pushBack(node1);//在向量添加一个元素

    CCASSERT(node1->getReferenceCount() == 2, "");

    auto node2 = Node::create();

    node2->setTag(2);

    vec.pushBack(node2);//添加元素 编号会从0开始

    CCASSERT(vec.getIndex(node1) == 0, "");

    CCASSERT(vec.getIndex(node2) == 1, "");


    auto node3 = Node::create();

    node3->setTag(3);

    vec.insert(1, node3); //插入元素

    CCASSERT(vec.at(0)->getTag() == 1, "");

    CCASSERT(vec.at(1)->getTag() == 3, "");

    CCASSERT(vec.at(2)->getTag() == 2, "");


    // Test copy constructor

    Vector<Node*> vec2(vec);  //复制一个向量

    CCASSERT(vec2.size() == vec.size(), "");

    ssize_t size = vec.size();

    for (ssize_t i = 0; i < size; ++i)

    {

        CCASSERT(vec2.at(i) == vec.at(i), "");

        CCASSERT(vec.at(i)->getReferenceCount() == 3, "");

        CCASSERT(vec2.at(i)->getReferenceCount() == 3, "");

    }


    // Test copy assignment operator

    Vector<Node*> vec3;

    vec3 = vec2;

    CCASSERT(vec3.size() == vec2.size(), "");

    size = vec3.size();

    for (ssize_t i = 0; i < size; ++i)

    {

        CCASSERT(vec3.at(i) == vec2.at(i), "");

        CCASSERT(vec3.at(i)->getReferenceCount() == 4, "");

        CCASSERT(vec2.at(i)->getReferenceCount() == 4, "");

        CCASSERT(vec.at(i)->getReferenceCount() == 4, "");

    }


    // Test move constructor (Lambda 表达式,定义一个函数用于创建一个Vector,关于Lambda建议看我的视频)

    auto createVector = [this](){

        Vector<Node*> ret;

        for (int i = 0; i < 20; i++)

        {

            ret.pushBack(Node::create());

        }

        int j = 1000;

        for (auto& child : ret)

        {

            child->setTag(j++);

        }

        return ret;

    };

    Vector<Node*> vec4(createVector());

    for (const auto& child : vec4)

    {

        CC_UNUSED_PARAM(child);

        CCASSERT(child->getReferenceCount() == 2, "");

    }


    // Test init Vector<T> with capacity

    Vector<Node*> vec5(10);

    CCASSERT(vec5.capacity() == 10, "");

    vec5.reserve(20);

    CCASSERT(vec5.capacity() == 20, "");


    CCASSERT(vec5.size() == 0, "");

    CCASSERT(vec5.empty(), "");


    auto toRemovedNode = Node::create();

    vec5.pushBack(toRemovedNode);

    CCASSERT(toRemovedNode->getReferenceCount() == 2, "");


    // Test move assignment operator

    vec5 = createVector();

    CCASSERT(toRemovedNode->getReferenceCount() == 1, "");

    CCASSERT(vec5.size() == 20, "size should be 20");


    for (const auto& child : vec5)    //这也是C++11新特性,好用吧,不像STL用迭代器那么麻烦

    {

        CC_UNUSED_PARAM(child);

        CCASSERT(child->getReferenceCount() == 2, "");

    }


    // Test Vector<T>::find

    CCASSERT(vec.find(node3) == (vec.begin() + 1), "");

    CCASSERT(std::find(std::begin(vec), std::end(vec), node2) == (vec.begin() + 2), "");


    CCASSERT(vec.front()->getTag() == 1, "");

    CCASSERT(vec.back()->getTag() == 2, "");


    CCASSERT(vec.getRandomObject(), "");

    CCASSERT(!vec.contains(Node::create()), "");

    CCASSERT(vec.contains(node1), "");

    CCASSERT(vec.contains(node2), "");

    CCASSERT(vec.contains(node3), "");

    CCASSERT(vec.equals(vec2), "");

    CCASSERT(vec.equals(vec3), "");


    // Insert

    vec5.insert(2, node1);

    CCASSERT(vec5.at(2)->getTag() == 1, "");

    CCASSERT(vec5.size() == 21, "");

    vec5.back()->setTag(100);

    vec5.popBack();

    CCASSERT(vec5.size() == 20, "");

    CCASSERT(vec5.back()->getTag() != 100, "");


    // Erase and clear

    Vector<Node*> vec6 = createVector();

    Vector<Node*> vec7 = vec6;  // Copy for check


    CCASSERT(vec6.size() == 20, "");

    vec6.erase(vec6.begin() + 1);  //

    CCASSERT(vec6.size() == 19, "");

    CCASSERT((*(vec6.begin() + 1))->getTag() == 1002, "");

    vec6.erase(vec6.begin() + 2, vec6.begin() + 10);

    CCASSERT(vec6.size() == 11, "");

    CCASSERT(vec6.at(0)->getTag() == 1000, "");

    CCASSERT(vec6.at(1)->getTag() == 1002, "");

    CCASSERT(vec6.at(2)->getTag() == 1011, "");

    CCASSERT(vec6.at(3)->getTag() == 1012, "");

    vec6.erase(3);

    CCASSERT(vec6.at(3)->getTag() == 1013, "");

    vec6.eraseObject(vec6.at(2));

    CCASSERT(vec6.at(2)->getTag() == 1013, "");

    vec6.clear();

    

    auto objA = Node::create(); // retain count is 1

    auto objB = Node::create();

    auto objC = Node::create();

    {

        Vector<Node*> array1;

        Vector<Node*> array2;

        

        // push back objA 3 times

        array1.pushBack(objA); // retain count is 2

        array1.pushBack(objA); // retain count is 3

        array1.pushBack(objA); // retain count is 4

        

        array2.pushBack(objA); // retain count is 5

        array2.pushBack(objB);

        array2.pushBack(objC);

        

        for (auto obj : array1) {

            array2.eraseObject(obj);

        }

        CCASSERT(objA->getReferenceCount() == 4, "");

    }

    CCASSERT(objA->getReferenceCount() == 1, "");

    {    //这是一个代码块,出了块引用计数会恢复,是一个AutoReleasePool

        Vector<Node*> array1;

        // push back objA 3 times

        array1.pushBack(objA); // retain count is 2

        array1.pushBack(objA); // retain count is 3

        array1.pushBack(objA); // retain count is 4

        CCASSERT(objA->getReferenceCount() == 4, "");

        array1.eraseObject(objA, true); // Remove all occurrences in the Vector.

        CCASSERT(objA->getReferenceCount() == 1, "");

        

        array1.pushBack(objA); // retain count is 2

        array1.pushBack(objA); // retain count is 3

        array1.pushBack(objA); // retain count is 4

        

        array1.eraseObject(objA, false);

        CCASSERT(objA->getReferenceCount() == 3, ""); // Only remove the first occurrence in the Vector.

    }


    // Check the retain count in vec7

    CCASSERT(vec7.size() == 20, "");

    for (const auto& child : vec7)

    {

        CC_UNUSED_PARAM(child);

        CCASSERT(child->getReferenceCount() == 2, "");

    }


    // Sort  排序,结合Lambda

    Vector<Node*> vecForSort = createVector();

    std::sort(vecForSort.begin(), vecForSort.end(), [](Node* a, Node* b){

        return a->getTag() >= b->getTag();

    });


    for (int i = 0; i < 20; ++i)

    {

        CCASSERT(vecForSort.at(i)->getTag() - 1000 == (19 - i), "");

    }


    // Reverse

    vecForSort.reverse();

    for (int i = 0; i < 20; ++i)

    {

        CCASSERT(vecForSort.at(i)->getTag() - 1000 == i, "");

    }


    // Swap

    Vector<Node*> vecForSwap = createVector();

    vecForSwap.swap(2, 4);

    CCASSERT(vecForSwap.at(2)->getTag() == 1004, "");

    CCASSERT(vecForSwap.at(4)->getTag() == 1002, "");

    vecForSwap.swap(vecForSwap.at(2), vecForSwap.at(4));

    CCASSERT(vecForSwap.at(2)->getTag() == 1002, "");

    CCASSERT(vecForSwap.at(4)->getTag() == 1004, "");


    // shrinkToFit

    Vector<Node*> vecForShrink = createVector();

    vecForShrink.reserve(100);

    CCASSERT(vecForShrink.capacity() == 100, "");

    vecForShrink.pushBack(Node::create());

    vecForShrink.shrinkToFit();

    CCASSERT(vecForShrink.capacity() == 21, "");


    // get random object

    // Set the seed by time

    srand((unsigned)time(nullptr));

    Vector<Node*> vecForRandom = createVector();

    log("<--- begin ---->");

    for (int i = 0; i < vecForRandom.size(); ++i)

    {

        log("Vector: random object tag = %d", vecForRandom.getRandomObject()->getTag());

    }

    log("<---- end  ---->");


    // Self assignment

    Vector<Node*> vecSelfAssign = createVector();

    vecSelfAssign = vecSelfAssign;

    CCASSERT(vecSelfAssign.size() == 20, "");


    for (const auto& child : vecSelfAssign)

    {

        CC_UNUSED_PARAM(child);

        CCASSERT(child->getReferenceCount() == 2, "");

    }


    vecSelfAssign = std::move(vecSelfAssign);

    CCASSERT(vecSelfAssign.size() == 20, "");


    for (const auto& child : vecSelfAssign)

    {

        CC_UNUSED_PARAM(child);

        CCASSERT(child->getReferenceCount() == 2, "");

    }


    // const at

    Vector<Node*> vecConstAt = createVector();

    constFunc(vecConstAt);

}


//---------------------------以下是Map的使用-----------------------------------


void TemplateMapTest::onEnter()

{

    UnitTestDemo::onEnter();

    auto createMap = [this](){

        Map<std::string, Node*> ret;

        for (int i = 0; i < 20; ++i)

        {

            auto node = Node::create();

        

            node->setTag(1000 + i);

            ret.insert(StringUtils::toString(i), node);

        }


        return ret;

    };

    // Default constructor

    Map<std::string, Node*> map1;

    CCASSERT(map1.empty(), "");

    CCASSERT(map1.size() == 0, "");

    CCASSERT(map1.keys().empty(), "");

    CCASSERT(map1.keys(Node::create()).empty(), "");

    // Move constructor

    Map<std::string, Node*> map2 = createMap();

    for (const auto& e : map2)

    {

        CC_UNUSED_PARAM(e);

        CCASSERT(e.second->getReferenceCount() == 2, "");

    }

    // Copy constructor

    Map<std::string, Node*> map3(map2);

    for (const auto& e : map3)

    {

        CC_UNUSED_PARAM(e);

        CCASSERT(e.second->getReferenceCount() == 3, "");

    }

    // Move assignment operator

    Map<std::string, Node*> map4;

    auto unusedNode = Node::create();

    map4.insert("unused",unusedNode);

    map4 = createMap();

    CCASSERT(unusedNode->getReferenceCount() == 1, "");

    for (const auto& e : map4)

    {

        CC_UNUSED_PARAM(e);

        CCASSERT(e.second->getReferenceCount() == 2, "");

    }

    // Copy assignment operator

    Map<std::string, Node*> map5;

    map5 = map4;

    for (const auto& e : map5)

    {

        CC_UNUSED_PARAM(e);

        CCASSERT(e.second->getReferenceCount() == 3, "");

    }

    // Check size

    CCASSERT(map4.size() == map5.size(), "");

    for (const auto& e : map4)

    {

        CC_UNUSED_PARAM(e);

        CCASSERT(e.second == map5.find(e.first)->second, "");

    }

    // bucket_count, bucket_size(n), bucket

    log("--------------");

    log("bucket_count = %d", static_cast<int>(map4.bucketCount()));

    log("size = %d", static_cast<int>(map4.size()));

    for (int i = 0; i < map4.bucketCount(); ++i)

    {

        log("bucket_size(%d) = %d", i, static_cast<int>(map4.bucketSize(i)));

    }

    for (const auto& e : map4)

    {

        log("bucket(\"%s\"), bucket index = %d", e.first.c_str(), static_cast<int>(map4.bucket(e.first)));

    }

    log("----- all keys---------");

    // keys and at

    auto keys = map4.keys();

    for (const auto& key : keys)

    {

        log("key = %s", key.c_str());

    }


    auto node10Key = map4.at("10");

    map4.insert("100", node10Key);

    map4.insert("101", node10Key);

    map4.insert("102", node10Key);


    log("------ keys for object --------");

    auto keysForObject = map4.keys(node10Key);

    for (const auto& key : keysForObject)

    {

        log("key = %s", key.c_str());

    }

    log("--------------");


    // at in const function

    constFunc(map4);


    // find

    auto nodeToFind = map4.find("10");

    CC_UNUSED_PARAM(nodeToFind);

    CCASSERT(nodeToFind->second->getTag() == 1010, "");


    // insert

    Map<std::string, Node*> map6;

    auto node1 = Node::create();

    node1->setTag(101);

    auto node2 = Node::create();

    node2->setTag(102);

    auto node3 = Node::create();

    node3->setTag(103);

    map6.insert("insert01", node1);

    map6.insert("insert02", node2);

    map6.insert("insert03", node3);


    CCASSERT(node1->getReferenceCount() == 2, "");

    CCASSERT(node2->getReferenceCount() == 2, "");

    CCASSERT(node3->getReferenceCount() == 2, "");

    CCASSERT(map6.at("insert01") == node1, "");

    CCASSERT(map6.at("insert02") == node2, "");

    CCASSERT(map6.at("insert03") == node3, "");


    // erase

    Map<std::string, Node*> mapForErase = createMap();

    mapForErase.erase(mapForErase.find("9"));

    CCASSERT(mapForErase.find("9") == mapForErase.end(), "");

    CCASSERT(mapForErase.size() == 19, "");


    mapForErase.erase("7");

    CCASSERT(mapForErase.find("7") == mapForErase.end(), "");

    CCASSERT(mapForErase.size() == 18, "");


    std::vector<std::string> itemsToRemove;

    itemsToRemove.push_back("2");

    itemsToRemove.push_back("3");

    itemsToRemove.push_back("4");

    mapForErase.erase(itemsToRemove);

    CCASSERT(mapForErase.size() == 15, "");


    // clear

    Map<std::string, Node*> mapForClear = createMap();

    auto mapForClearCopy = mapForClear;

    mapForClear.clear();


    for (const auto& e : mapForClearCopy)

    {

        CC_UNUSED_PARAM(e);

        CCASSERT(e.second->getReferenceCount() == 2, "");

    }


    // get random object

    // Set the seed by time

    srand((unsigned)time(nullptr));

    Map<std::string, Node*> mapForRandom = createMap();

    log("<--- begin ---->");

    for (int i = 0; i < mapForRandom.size(); ++i)

    {

        log("Map: random object tag = %d", mapForRandom.getRandomObject()->getTag());

    }

    log("<---- end  ---->");


    // Self assignment

    Map<std::string, Node*> mapForSelfAssign = createMap();

    mapForSelfAssign = mapForSelfAssign;

    CCASSERT(mapForSelfAssign.size() == 20, "");


    for (const auto& e : mapForSelfAssign)

    {

        CC_UNUSED_PARAM(e);

        CCASSERT(e.second->getReferenceCount() == 2, "");

    }


    mapForSelfAssign = std::move(mapForSelfAssign);

    CCASSERT(mapForSelfAssign.size() == 20, "");


    for (const auto& e : mapForSelfAssign)

    {

        CC_UNUSED_PARAM(e);

        CCASSERT(e.second->getReferenceCount() == 2, "");

    }

}



//--------------------------以下是Value的使用,它完成基本数据类型到对象的包装--------


void ValueTest::onEnter()

{

    UnitTestDemo::onEnter();

    

    Value v1;

    CCASSERT(v1.getType() == Value::Type::NONE, "");

    CCASSERT(v1.isNull(), "");

    

    Value v2(100);

    CCASSERT(v2.getType() == Value::Type::INTEGER, "");

    CCASSERT(!v2.isNull(), "");

    

    Value v3(101.4f);

    CCASSERT(v3.getType() == Value::Type::FLOAT, "");

    CCASSERT(!v3.isNull(), "");

    

    Value v4(106.1);

    CCASSERT(v4.getType() == Value::Type::DOUBLE, "");

    CCASSERT(!v4.isNull(), "");

    

    unsigned char byte = 50;

    Value v5(byte);

    CCASSERT(v5.getType() == Value::Type::BYTE, "");

    CCASSERT(!v5.isNull(), "");

    

    Value v6(true);

    CCASSERT(v6.getType() == Value::Type::BOOLEAN, "");

    CCASSERT(!v6.isNull(), "");

    

    Value v7("string");

    CCASSERT(v7.getType() == Value::Type::STRING, "");

    CCASSERT(!v7.isNull(), "");

    

    Value v8(std::string("string2"));

    CCASSERT(v8.getType() == Value::Type::STRING, "");

    CCASSERT(!v8.isNull(), "");


    auto createValueVector = [&](){

        ValueVector ret;

        ret.push_back(v1);

        ret.push_back(v2);

        ret.push_back(v3);

        return ret;

    };

    

    

    Value v9(createValueVector());

    CCASSERT(v9.getType() == Value::Type::VECTOR, "");

    CCASSERT(!v9.isNull(), "");


    auto createValueMap = [&](){

        ValueMap ret;

        ret["aaa"] = v1;

        ret["bbb"] = v2;

        ret["ccc"] = v3;

        return ret;

    };

    

    Value v10(createValueMap());

    CCASSERT(v10.getType() == Value::Type::MAP, "");

    CCASSERT(!v10.isNull(), "");

    

    auto createValueMapIntKey = [&](){

        ValueMapIntKey ret;

        ret[111] = v1;

        ret[222] = v2;

        ret[333] = v3;

        return ret;

    };

    

    Value v11(createValueMapIntKey());

    CCASSERT(v11.getType() == Value::Type::INT_KEY_MAP, "");

    CCASSERT(!v11.isNull(), "");

}

----------------------------亲,学会了没----------------------------



这篇关于Cocos2d-x 3.0final 终结者系列教程12-Vectormapvalue的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/367883

相关文章

电脑提示d3dx11_43.dll缺失怎么办? DLL文件丢失的多种修复教程

《电脑提示d3dx11_43.dll缺失怎么办?DLL文件丢失的多种修复教程》在使用电脑玩游戏或运行某些图形处理软件时,有时会遇到系统提示“d3dx11_43.dll缺失”的错误,下面我们就来分享超... 在计算机使用过程中,我们可能会遇到一些错误提示,其中之一就是缺失某个dll文件。其中,d3dx11_4

Linux下在线安装启动VNC教程

《Linux下在线安装启动VNC教程》本文指导在CentOS7上在线安装VNC,包含安装、配置密码、启动/停止、清理重启步骤及注意事项,强调需安装VNC桌面以避免黑屏,并解决端口冲突和目录权限问题... 目录描述安装VNC安装 VNC 桌面可能遇到的问题总结描js述linux中的VNC就类似于Window

Go语言编译环境设置教程

《Go语言编译环境设置教程》Go语言支持高并发(goroutine)、自动垃圾回收,编译为跨平台二进制文件,云原生兼容且社区活跃,开发便捷,内置测试与vet工具辅助检测错误,依赖模块化管理,提升开发效... 目录Go语言优势下载 Go  配置编译环境配置 GOPROXYIDE 设置(VS Code)一些基本

Windows环境下解决Matplotlib中文字体显示问题的详细教程

《Windows环境下解决Matplotlib中文字体显示问题的详细教程》本文详细介绍了在Windows下解决Matplotlib中文显示问题的方法,包括安装字体、更新缓存、配置文件设置及编码調整,并... 目录引言问题分析解决方案详解1. 检查系统已安装字体2. 手动添加中文字体(以SimHei为例)步骤

Java JDK1.8 安装和环境配置教程详解

《JavaJDK1.8安装和环境配置教程详解》文章简要介绍了JDK1.8的安装流程,包括官网下载对应系统版本、安装时选择非系统盘路径、配置JAVA_HOME、CLASSPATH和Path环境变量,... 目录1.下载JDK2.安装JDK3.配置环境变量4.检验JDK官网下载地址:Java Downloads

使用Docker构建Python Flask程序的详细教程

《使用Docker构建PythonFlask程序的详细教程》在当今的软件开发领域,容器化技术正变得越来越流行,而Docker无疑是其中的佼佼者,本文我们就来聊聊如何使用Docker构建一个简单的Py... 目录引言一、准备工作二、创建 Flask 应用程序三、创建 dockerfile四、构建 Docker

深度解析Spring AOP @Aspect 原理、实战与最佳实践教程

《深度解析SpringAOP@Aspect原理、实战与最佳实践教程》文章系统讲解了SpringAOP核心概念、实现方式及原理,涵盖横切关注点分离、代理机制(JDK/CGLIB)、切入点类型、性能... 目录1. @ASPect 核心概念1.1 AOP 编程范式1.2 @Aspect 关键特性2. 完整代码实

Java Web实现类似Excel表格锁定功能实战教程

《JavaWeb实现类似Excel表格锁定功能实战教程》本文将详细介绍通过创建特定div元素并利用CSS布局和JavaScript事件监听来实现类似Excel的锁定行和列效果的方法,感兴趣的朋友跟随... 目录1. 模拟Excel表格锁定功能2. 创建3个div元素实现表格锁定2.1 div元素布局设计2.

SpringBoot连接Redis集群教程

《SpringBoot连接Redis集群教程》:本文主要介绍SpringBoot连接Redis集群教程,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教... 目录1. 依赖2. 修改配置文件3. 创建RedisClusterConfig4. 测试总结1. 依赖 <de

Nexus安装和启动的实现教程

《Nexus安装和启动的实现教程》:本文主要介绍Nexus安装和启动的实现教程,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教... 目录一、Nexus下载二、Nexus安装和启动三、关闭Nexus总结一、Nexus下载官方下载链接:DownloadWindows系统根