65.9K
CodeProject 正在变化。 阅读更多。
Home

Pebble "代码向导"

emptyStarIconemptyStarIconemptyStarIconemptyStarIconemptyStarIcon

0/5 (0投票)

2015 年 10 月 8 日

CPOL

3分钟阅读

viewsIcon

12542

downloadIcon

17

创建定制的 Pebble 项目

引言

在任何平台上启动新项目都可能是一个费力的过程,特别是如果你最终一遍又一遍地做相同的样板代码。

背景

基于命令行的 Pebble 环境可以创建几种基本项目类型,我通常会先将它们重新格式化成我自己的风格,然后再开始处理项目实际的内容。
我决定看看 Pebble 项目是如何创建的,并惊喜地发现它完全由易于编辑的 Python 代码完成。

正如说明

Pebble 命令提供了四个标准模板

  1. Standard:一个检测按钮按下并将按下的内容打印到屏幕上的应用程序(默认)
  2. Worker:一个在后台运行的应用程序 (--worker)
  3. Simple:一个空项目 (--simple)
  4. Javascript:一个基于 JavaScript 的应用程序 (--javascript)

例如

pebble new-project --simple MyProject

将在名为 *MyProject* 的文件夹中生成一个空项目。

所有这些项目模板都是 Python 字符串,其中嵌入了替换位和片段,用于自定义新项目。 可以使用您喜欢的编辑器轻松编辑它们。

第一个有用的更改

我们将要查看的文件是

<Pebble SDK>/pebble-tool/pebble_tool/commands/sdk/create.py
<Pebble SDK>/pebble-tool/pebble_tool/sdk/templates.py

第一个文件 *create.py*,根据给定的参数构造项目文件夹层次结构。

第二个文件 *templates.py*,包含项目中文档的实际文本。

我们可以进行的第一个有用的更改是找到 DICT_DUMMY_APPINFO 并将默认的 company_name 更改为我们自己的。 这是在项目工作时很容易忘记的事情。

同样在 *templates.py* 中,标准应用程序的源代码,寻找 FILE_DUMMY_MAIN,我们可以根据我们的首选风格调整格式,当我们启动一个新项目时,它已经准备就绪,无需任何麻烦。

注意:在编辑 Python 代码时,缩进至关重要,特定缩进级别的每一行都应使用相同类型的缩进,无论是制表符还是空格,而不是混合使用。

进一步发展

现在基本知识已经被揭示,我们有机会做更多的事情。 当我开始一个新项目时,我真的不想从相同的基本 shell 代码开始,例如,我有一个刚起步的游戏“引擎”,我想从它开始。 或者如果我正在编写一个表盘,我想从一个没有按钮处理和基本滴答处理结构已经到位的表盘 shell 开始。

我们将为表盘创建一个新的项目类型。

在 *create.py* 中扩展可用的项目类型,我可以在文件末尾附近添加一个新选项“--watchface

parser.add_argument("--watchface", action="store_true", help="Generate a watchface.")

并且,在上面,更改生成项目的代码,我扩展了 if/else,这使得以后更容易整洁地扩展

        # Create main .c file
        with open(os.path.join(project_src, "{}.c".format(project_name)), "w") as f:
            if args.simple:
                f.write(FILE_SIMPLE_MAIN)
            elif args.watchface:
                f.write(FILE_DUMMY_WATCHFACE)
            else:
                f.write(FILE_DUMMY_MAIN)

        # Add appinfo.json file
        appinfo_dummy = DICT_DUMMY_APPINFO.copy()
        appinfo_dummy['uuid'] = str(uuid.uuid4())
        appinfo_dummy['project_name'] = project_name
        if args.watchface:
            appinfo_dummy['is_watchface'] = 'true'
        with open(os.path.join(project_root, "appinfo.json"), "w") as f:
            f.write(FILE_DUMMY_APPINFO.substitute(**appinfo_dummy))

最后,对于这个文件,在顶部附近,我们添加了对新模板 string 的引用(这将很快添加到 *templates.py*)

from pebble_tool.sdk.templates import (FILE_SIMPLE_MAIN, FILE_DUMMY_MAIN, FILE_DUMMY_APPINFO,
                                       DICT_DUMMY_APPINFO, FILE_GITIGNORE, FILE_DUMMY_JAVASCRIPT_SRC,
                                       FILE_WSCRIPT, FILE_DUMMY_WORKER, FILE_DUMMY_WATCHFACE)

                f.write(FILE_SIMPLE_MAIN)
            elif args.watchface:
                f.write(FILE_DUMMY_WATCHFACE)
            else:
                f.write(FILE_DUMMY_MAIN)

        # Add appinfo.json file
        appinfo_dummy = DICT_DUMMY_APPINFO.copy()
        appinfo_dummy['uuid'] = str(uuid.uuid4())
        appinfo_dummy['project_name'] = project_name
        if args.watchface:
            appinfo_dummy['is_watchface'] = 'true'
        with open(os.path.join(project_root, "appinfo.json"), "w") as f:
            f.write(FILE_DUMMY_APPINFO.substitute(**appinfo_dummy))

在 *templates.py* 的底部,我们可以为我们的 watchface 添加 shell

FILE_DUMMY_WATCHFACE = """#include <pebble.h>

static Window* window = NULL;
static TextLayer* timeLayer = NULL;

static void tickHandler(struct tm* tickTime, TimeUnits unitsChanged)
{
    static char timeString[20];

    if (clock_is_24h_style())
        strftime(timeString, sizeof(timeString), "%H:%M", tickTime);
    else
        strftime(timeString, sizeof(timeString), "%I:%M", tickTime);

    text_layer_set_text(timeLayer, timeString);
}

static void windowLoad(Window* window)
{
    Layer* windowLayer = window_get_root_layer(window);
    GRect bounds = layer_get_bounds(windowLayer);

    timeLayer = text_layer_create((GRect) { .origin = { 0, 72 }, .size = { bounds.size.w, 20 } });
    text_layer_set_text(timeLayer, "Pebble");
    text_layer_set_text_alignment(timeLayer, GTextAlignmentCenter);
    layer_add_child(windowLayer, text_layer_get_layer(timeLayer));
}

static void windowUnload(Window *window)
{
    text_layer_destroy(timeLayer);
}

static void init(void)
{
    window = window_create();
    window_set_window_handlers(window, (WindowHandlers) {
        .load = windowLoad,
        .unload = windowUnload,
    });
    const bool animated = true;
    window_stack_push(window, animated);

    tick_timer_service_subscribe(MINUTE_UNIT, tickHandler);
}

static void deinit(void)
{
    tick_timer_service_unsubscribe();
    window_destroy(window);
}

int main(void)
{
    init();
        APP_LOG(APP_LOG_LEVEL_DEBUG, "Done initializing, pushed window: %p", window);
        app_event_loop();
    deinit();
}
"""

现在我们可以创建一个新项目了。

pebble new-project --watchface WatchFaceTest

没有胡闹,我们现在有一个 watchface 项目准备好工作。 这是它在 Aplite 模拟器上运行的情况

我们现在可以添加我们想要的任何类型的启动项目,包括添加各种选项以允许添加额外的功能,例如,如果我们想使用闪存存储或加速度计等。

未来 - SDK 更新

Pebble 相当定期地发布新的 SDK,但它们已经遵循这种新的项目方法一段时间了,因此应该没有问题合并您个性化的项目模板。

这是我的 *create.py* 和 *templates.py* 的个性化版本:CustomPebbleTemplate.tar.gz

历史

  • 2015-10-15:添加了屏幕截图和扩展可能性
  • 2015-10-08:初稿
© . All rights reserved.