添加启动逻辑

你可以用以下逻辑去在应用中定义你的启动逻辑

  • Kanzi在启动应用程序后立即调用Application::onStartup() 函数一次,再它加载初始化UI内容之前,可以添加需要修改已初始化的Kanzi对象的应用程序启动逻辑。

  • Kanzi初始化UI内容后立即调用Application::onProjectLoaded() 函数一次。通常可以在此处插入依赖已加载内容的初始化代码,例如你可以附加初始消息处理程序或监听器,用数据填充UI。

下面的代码示例是在Kanzi加载节点树后添加了一个消息相应到Button上:

void onProjectLoaded() override
{// Get reference to the Screen node.ScreenSharedPtr screen = getScreen();kzAssert(screen);// Look up reference to a button by alias.Button2DSharedPtr button = screen->lookupNode<Button2D>("#Button");kzAssert(button);// Attach a handler to the button.button->addMessageHandler(Button2D::ClickedMessage, [this](auto& arguments) { this->buttonHandler(arguments); });
}

下图是启动和关闭逻辑的回调过程。

观察应用程序状态

可以观察应用程序状态,以确定应用程序是否正在运行、最小化或挂起。

kanzi应用程序总在以下状态内:

  • 运行状态。这是Kanzi应用程序的正常操作模式。这是应用程序的初始状态。

  • 暂停状态。当应用程序不聚焦或最小化时,平台可以对应用程序行为施加规则。要标记这种状态,平台后端可以将应用程序设置为“暂停”状态。

在这种状态下,Kanzi停止正常的输入处理和渲染,并等待返回到运行状态。此外,在这种状态下,应用程序通常会停止繁重的工作。

  • 正在退出状态。此状态表示应用程序或平台通过调用quit()请求应用程序退出。在这种状态下,应用程序必须避免启动工作。

void doSomethingRepeatedly()
{doSomething();// If a condition is met...if (someCondition() &&// ...and the application is not quitting...getState() != MainLoopState::Quitting){// ...add another task to the task dispatcher.getDomain()->getTaskDispatcher()->submit([this]() { this->doSomethingRepeatedly(); });}
}

onSuspend()

Kanzi在未执行渲染的帧中调用此函数,以确定是否暂停应用程序以及暂停时间。默认实现基于活动动画、计时器和等待部署的资源来计算适当的超时。

使用此功能可自定义应用程序暂停。

onPause()

Kanzi在应用程序主循环进入Paused状态时调用此函数。

onResume()

当应用程序主循环从暂停状态返回到运行状态时,Kanzi调用此函数。

onShutdown()

Kanzi 在应用程序未初始化之前立即调用此函数。

修改主循环逻辑

主循环由一系列阶段组成,其中每个阶段由一系列任务组成。 任务是任何可调用项,包括函数、函数对象和 lambda。

// c++ code
using Task = function<void(chrono::nanoseconds)>;// java code
public interface Task {void handle(Duration lastFrameDuration);
}

当 Kanzi 执行任务时,它会将最后一帧持续时间作为参数传递给任务。

以下是kanzi里的一些默认状态:

  • 在输入阶段,Kanzi 处理输入事件。

  • 在用户阶段,Kanzi 处理更新逻辑:部署资源、加载 kzb 文件和预制件,并执行您的任务调度程序和计时器任务。

  • 在动画阶段,Kanzi 勾选活动动画。在布局阶段,Kanzi 对节点树进行布局。

  • 在渲染阶段,Kanzi 渲染节点树。

  • 在现阶段,Kanzi 展示了节点树。

下图展现了在kanzi 主循环中的控制流。

在应用中你能移除,替换,插入任务在主循环的调度阶段。

添加周期性任务

当你想kanzi在每一帧执行一个任务,您可以使用 appendTask() 和 prependTask() 将其添加到主循环的任何阶段,并带有选项 Recurring。

例如,您可以使用循环任务调用外部库的更新函数:

void onStartup() override
{// From the main loop Animate stage, tick an external physics engine.getMainLoopScheduler().appendTask(AnimateStage,kzMakeFixedString("TickPhysics"),MainLoopScheduler::TaskRecurrence::Recurring,[this](auto deltaTime) { this->getPhysicsEngine()->tick(deltaTime); });
}

添加一次性任务

当你想kanzi执行一次任务,您可以使用 appendTask() 和 prependTask() 将其添加到主循环的任何阶段,并带有选项 Recurring。

例如,要在用户按下 Enter 键时捕获输出的屏幕截图:

void onKeyInputEvent(const KeyEvent& keyEvent) override
{// First invoke the base class implementation.Application::onKeyInputEvent(keyEvent);// If the user presses the Enter key:if (keyEvent.getKeyUp() == LogicalKey::Enter){// Force re-rendering.getScreen()->invalidateDraw();// Add a post-rendering task to capture the screen output.getMainLoopScheduler().appendTask(RenderStage,kzMakeFixedString("CaptureScreenshot"),MainLoopScheduler::TaskRecurrence::OneTime,[this](auto) { this->captureScreen(); });}
}

重写任务

当您想要修改 Kanzi 用于处理输入、执行布局和呈现内容、更新屏幕以及执行其他重复任务的默认方法时,您可以使用 replaceTask() 替换现有任务。例如,重写默认渲染的典型用例是变形。 变形会扭曲输出,以便应用程序将其正确投影到曲面屏幕上。 您可以通过首先使用默认渲染实现将内容渲染到屏幕外纹理,然后将该纹理复制到屏幕并应用失真效果来实现此目的:

void onStartup() override
{// Create a texture for rendering.auto texture = createOffscreen();// Get the token of the default rendering task from the render stage.auto& scheduler = getMainLoopScheduler();auto tasks = scheduler.getTaskInfo(RenderStage);auto itTask = find_if(cbegin(tasks), cend(tasks), [](const auto& taskInfo) { return taskInfo.name == "Render"; });kzAssert(itTask != cend(tasks));auto token = itTask->token;// Replace the texture with the wrapped implementation.scheduler.replaceTask(RenderStage,token,[this, texture = move(texture)](auto) {auto renderer = this->getRenderer3D();auto& compositionStack = renderer->getCompositionStack();// Set the off-screen texture as the target.compositionStack.pushComposition(*texture);// Render to the off-screen texture using the default rendering logic.this->render();// Revert to the screen as the target.compositionStack.popComposition();// Render to the screen the texture with the wrapping effect applied.this->renderWarped(renderer, texture);// Mark the current frame as rendered.this->getMainLoopScheduler().setCurrentFrameRendered();});
}

作为单独替换任务的替代方法,可以通过充血 initializeMainLoopTasks() 来重新定义整个主循环。 Kanzi 在这个函数中附加了默认的主循环任务。 为了允许复制,它的实现有意暴露在头文件中。

添加定时器

当您希望 Kanzi 以固定的时间间隔执行任务时,您可以使用 prependTimer() 在主循环的某个阶段之前添加任务,并使用 appendTimer() 在主循环的某个阶段之后添加任务。使用定时器重复选项仅执行一次 (OneTime) 或重复 (Recurring) 定时器。 当循环计时器在 Kanzi 主循环的单次迭代中多次运行时,Kanzi 只执行该计时器一次。

void activateClock()
{// Add a recurring timer task that updates the clock once every second.m_clockTimer = getMainLoopScheduler().appendTimer(UserStage,kzMakeFixedString("Clock"),MainLoopScheduler::TimerRecurrence::Recurring,chrono::seconds(1),[this](auto elapsedDuration, auto repeatCount) {this->updateClock(elapsedDuration * repeatCount);});
}void deactivateClock()
{// Remove the clock timer.getMainLoopScheduler().removeTimer(m_clockTimer);
}

资源推荐

如果大家想了解更过关于Kanzi Engine plugin的更多学习信息,可以B站订阅“中科创达-智能座舱”官方号,https://space.bilibili.com/301867101/channel/series。目前内含Kanzi插件教程/Kanzi仪表教程/Kanzi零基础教程,后续会有课程陆续上新。

[KANZI]详解Kanzi One应用程序生命周期事件相关推荐

  1. alert 返回页面 刷新_详解 HTML 页面原生的生命周期事件

    DOMContentLoaded,load,beforeunload,unload HTML 页面的生命周期包含三个重要事件: DOMContentLoaded -- 浏览器已完全加载 HTML,并构 ...

  2. android Fragments详解六:处理fragement的生命周期

    把条目添加到动作栏 你的fragment们可以向activity的菜单(按Manu键时出现的东西)添加项,同时也可向动作栏(界面中顶部的那个区域)添加条目,这都需通过实现方法onCreateOptio ...

  3. 详解android之activity的生命周期

    android中用到最多的就是activity,它也是android的四大组件之一,开发过程中也是最常用到的组件,所以我们有必要去掌握它在程序运行的生命周期是怎么回事 在了解activity的生命周期 ...

  4. 详解.NET Core 依赖注入生命周期

    前言 .NET Core 自带依赖注入框架,支持三种不同生命周期的注入模式: Singleton 单例模式 Scoped 区域模式 Transient  瞬时模式 但是常常不知道什么时候使用哪种模式才 ...

  5. 转:iOS应用程序生命周期(前后台切换,应用的各种状态)详解

    iOS应用程序生命周期(前后台切换,应用的各种状态)详解 分类: iOS开发进阶2012-10-08 15:35 42691人阅读 评论(30) 收藏 举报 iosapplication任务anima ...

  6. vue生命周期+微信小程序生命周期详解

    文章目录 1 vue生命周期 1 明确 2 小程序生命周期 1 应用生命周期 2 页面生命周期 页面之间跳转 3 组件生命周期 4 应用生命周期影响页面生命周期 5 总结 参考链接 1 vue生命周期 ...

  7. 详解Xcode 4发布程序图文并茂教程

    详解Xcode 4发布程序图文并茂教程 2011-08-09 16:47 佚名  本文介绍的是详解Xcode 4发布程序图文并茂教程,通过图文的方式来介绍本文的内容,直接来看详细内容. AD: Xco ...

  8. 命令提示符使用java 类报错_lt;03gt;详解第一个Java程序

    详解第一个Java程序视频教程: Java轻松入门经典教程​ke.qq.com 1.编写源程序 新建一个文本文档,名称为HelloWorld,后缀为.java,右键编辑. 编写一个打印HelloWor ...

  9. Android开发详解之App升级程序一点通

    Android开发详解之App升级程序一点通 结束语 UpdateManager.java import java.io.File; import java.io.FileOutputStream; ...

最新文章

  1. centos7.3 编译安装 git 2.13
  2. 文件系统对性能的影响
  3. MiniGUI编程之Helloworld(一)
  4. opencv3.2.0 Cmake 3.8.0 + tdm-gcc-5.1.0-3
  5. python能不能自动写代码_微软最强 Python 自动化工具开源了!不用写一行代码
  6. 使用SPANN方式将Spring&Quartz与自定义注释集成
  7. 《梦断代码》阅读笔记之第8章至最后
  8. 智能直播审核方案:视频云智能业务截帧策略
  9. 用c语言做一个背单词的软件,安利一个超好用且自由度高的背单词app
  10. 沧小海基于xilinx srio核的学习笔记之第四章 Xilinx SRIO的示例分析(二)
  11. 视频直播方案(加强版
  12. 跟“杀熟”说再见 在熊拍拍只有双赢
  13. 二级计算机合格,计算机二级考试合格的分数线
  14. Zap之日志记录器选择
  15. 微软加入JCP参与Java未来版本开发
  16. 关于碰到优盘插入电脑检测到病毒并且优盘里文件只显示System Volume Information文件夹的问题解决。
  17. 开发人员新常态:和云原生相爱相杀
  18. 系统的入门脑机接口神经科学,一个网站就够了 - NeuroTechEDU
  19. 【STM32学习笔记-点亮LED灯】
  20. C语言练习2-14 求奇数分之一序列前N项和

热门文章

  1. 经纬度坐标与实际距离的计算转换
  2. Vue系列之—文件目录详解
  3. oracle查看时间戳函数,oracle数据库实现获取时间戳的无参函数
  4. 华为HCNA之配置OSPF的Router-ID实验
  5. Python这么火,关软件测试什么事?
  6. 使用JsBarcode生成条形码
  7. 攻防世界Web练习区Writeup
  8. 关于flv转成mp4的方法
  9. 陈力:传智播客古代 珍宝币 泡泡龙游戏开发第42讲:PHP数据库开发案例
  10. html是什么意思 htm与html的有什么不同