libuv 在 linux 下面运用相比不难,libuv 在 linux 上边使用比较简单

引言 – 近来心起, libuv linux 搭建

引言 – 一时半刻心起, libuv linux 搭建

  有一天突然想起来想写个动画. 找了弹指间 ui 库太大. 后边想起在此之前弄过的
libuv. 但发现 libuv 相关材料也很少.

  有一天突然想起来想写个动画. 找了一下 ui 库太大. 前面想起在此以前弄过的
libuv. 但发现 libuv 相关材料也很少.

故而就有了那几个内容. 

据此就有了这几个内容. 

  libuv
https://github.com/libuv/libuv

  libuv
https://github.com/libuv/libuv

libuv 在 linux 上边使用相比简单,  一伊始 从 linux hello 跑起来

libuv 在 linux 上边运用比较不难,  一发端 从 linux hello 跑起来

libuv linux 安装

libuv linux 安装

第3假定你和本身同一用的是Ubuntu去做开发. 在云平台下边测试过, Ubuntu
Server 版本比 CentOS 版本少个十几兆.

先是假定你和本人同样用的是Ubuntu去做开发. 在云平台上边测试过, Ubuntu
Server 版本比 CentOS 版本少个十几兆.

有趣味朋友能够详细比较数据, 也能够尝试跑跑 Ubuntu Server .

有趣味朋友能够详细相比较数据, 也得以尝试跑跑 Ubuntu Server .

# libuv 安装
cd
wget https://github.com/libuv/libuv/archive/v1.18.0.tar.gz
tar -zxvf v1.18.0.tar.gz
cd libuv-1.18.0

sh autogen.sh
./configure

make -j4

sudo make install
sudo ldconfig
cd ../
rm -rf libuv-1.18.0 v1.18.0.tar.gz
```
# libuv 安装
cd
wget https://github.com/libuv/libuv/archive/v1.18.0.tar.gz
tar -zxvf v1.18.0.tar.gz
cd libuv-1.18.0

sh autogen.sh
./configure

make -j4

sudo make install
sudo ldconfig
cd ../
rm -rf libuv-1.18.0 v1.18.0.tar.gz
```

推行上边命令操作, 大家的种类中就早已有了 libuv 开发环境.

实施上面命令操作, 我们的体系中就早已有了 libuv 开发环境.

有少数亟需注意的是当大家要运用 libuv时候推荐用静态库.

有有些须求注意的是当我们要使用 libuv时候推荐用静态库.

gcc -l:libuv.a
gcc -l:libuv.a

到这里 linux 安装 libuv 已经完工了. 

到这里 linux 安装 libuv 已经完工了. 

  不妨写个 hello world demo

  不妨写个 hello world demo

#include <uv.h>
#include <assext.h>

//
// 测试 libuv tty 操作控制台
// 输出一段有颜色的文字
//
void uv_tty_test(void) {
    uv_tty_t tty;
    uv_buf_t buf[3];
    unsigned i, len = sizeof buf / sizeof *buf;
    uv_loop_t * loop = uv_default_loop();

    // 目前只对 tty 控制台处理
    if (uv_guess_handle(1) != UV_TTY) {
        fprintf(stderr, "uv_guess_handle(1) != UV_TTY!\n");
        exit(EXIT_FAILURE);
    }

    uv_tty_init(loop, &tty, 1, 0);
    uv_tty_set_mode(&tty, UV_TTY_MODE_NORMAL);

    // 开始发送消息
    buf[0].base = "\033[46;37m";
    buf[1].base = u8"(✿◡‿◡) 喵酱 ((●'-'●)) 比 ♥ 里~ \n";
    buf[2].base = "\033[0m";
    for (i = 0; i < len; ++i)
        buf[i].len = (int)strlen(buf[i].base);
    uv_try_write((uv_stream_t *)&tty, buf, len);

    // 重置终端行为
    uv_tty_reset_mode();
    uv_run(loop, UV_RUN_DEFAULT);
}
#include <uv.h>
#include <assext.h>

//
// 测试 libuv tty 操作控制台
// 输出一段有颜色的文字
//
void uv_tty_test(void) {
    uv_tty_t tty;
    uv_buf_t buf[3];
    unsigned i, len = sizeof buf / sizeof *buf;
    uv_loop_t * loop = uv_default_loop();

    // 目前只对 tty 控制台处理
    if (uv_guess_handle(1) != UV_TTY) {
        fprintf(stderr, "uv_guess_handle(1) != UV_TTY!\n");
        exit(EXIT_FAILURE);
    }

    uv_tty_init(loop, &tty, 1, 0);
    uv_tty_set_mode(&tty, UV_TTY_MODE_NORMAL);

    // 开始发送消息
    buf[0].base = "\033[46;37m";
    buf[1].base = u8"(✿◡‿◡) 喵酱 ((●'-'●)) 比 ♥ 里~ \n";
    buf[2].base = "\033[0m";
    for (i = 0; i < len; ++i)
        buf[i].len = (int)strlen(buf[i].base);
    uv_try_write((uv_stream_t *)&tty, buf, len);

    // 重置终端行为
    uv_tty_reset_mode();
    uv_run(loop, UV_RUN_DEFAULT);
}

代码运转效果是, 输出一段话, 并且设置背景象.  对于  uv_tty_test
能够明白为 main (本质是 structc 一种单元测试函数约束写法)

代码运营效果是, 输出一段话, 并且设置背景象.  对于  uv_tty_test
可以掌握为 main (本质是 structc 一种单元测试函数约束写法)

到那容作者安利2个小东西, 感兴趣的可以品味一下, 从零早先搭建二个 c 的
struct 小框架. 五脏渐渐全了.

到那容小编安利叁个小东西, 感兴趣的能够尝尝一下, 从零开端搭建2个 c 的
struct 小框架. 五脏慢慢全了.

  structc
https://github.com/wangzhione/structc

  structc
https://github.com/wangzhione/structc

简言之说一下libuv中选择的多少个函数,  第三个是 uv_try_write
尝试马上发送消息数组. 不像 uv_write 写入到音讯队列中.

不难易行说一下libuv中运用的多少个函数,  第多少个是 uv_try_write
尝试立即发送音讯数组. 不像 uv_write 写入到新闻队列中.

int uv_try_write(uv_stream_t* handle, const uv_buf_t bufs[], unsigned int nbufs)

    Same as uv_write(), but won’t queue a write request if it can’t be completed immediately.
    Will return either:
        > 0: number of bytes written (can be less than the supplied buffer size).
        < 0: negative error code (UV_EAGAIN is returned if no data can be sent immediately).
int uv_try_write(uv_stream_t* handle, const uv_buf_t bufs[], unsigned int nbufs)

    Same as uv_write(), but won’t queue a write request if it can’t be completed immediately.
    Will return either:
        > 0: number of bytes written (can be less than the supplied buffer size).
        < 0: negative error code (UV_EAGAIN is returned if no data can be sent immediately).

当前我们是用 tty 输出到显示屏方面, 能够用这些 api . 假设单纯是走 TCP,
不要过度依赖那个 api.

此时此刻我们是用 tty 输出到显示屏方面, 能够用这一个 api . 如若唯有是走 TCP,
不要过度注重这一个 api.

简单易行为了稳定如故别用 uv_try_write.

简单为了稳定依然别用 uv_try_write.

第二个要说的是 uv_run

第一个要说的是 uv_run

int uv_run(uv_loop_t* loop, uv_run_mode mode)

    This function runs the event loop. It will act differently depending on the specified mode:
        UV_RUN_DEFAULT: Runs the event loop until there are no more active and referenced handles or requests. 
              Returns non-zero if uv_stop() was called and there are still active handles or requests.
               Returns zero in all other cases.
        UV_RUN_ONCE: Poll for i/o once. Note that this function blocks if there are no pending callbacks. 
             Returns zero when done (no active handles or requests left), 
             or non-zero if more callbacks are expected 
             (meaning you should run the event loop again sometime in the future).
        UV_RUN_NOWAIT: Poll for i/o once but don’t block if there are no pending callbacks. 
              Returns zero if done (no active handles or requests left), 
              or non-zero if more callbacks are expected 
              (meaning you should run the event loop again sometime in the future).
int uv_run(uv_loop_t* loop, uv_run_mode mode)

    This function runs the event loop. It will act differently depending on the specified mode:
        UV_RUN_DEFAULT: Runs the event loop until there are no more active and referenced handles or requests. 
              Returns non-zero if uv_stop() was called and there are still active handles or requests.
               Returns zero in all other cases.
        UV_RUN_ONCE: Poll for i/o once. Note that this function blocks if there are no pending callbacks. 
             Returns zero when done (no active handles or requests left), 
             or non-zero if more callbacks are expected 
             (meaning you should run the event loop again sometime in the future).
        UV_RUN_NOWAIT: Poll for i/o once but don’t block if there are no pending callbacks. 
              Returns zero if done (no active handles or requests left), 
              or non-zero if more callbacks are expected 
              (meaning you should run the event loop again sometime in the future).

其中 UV_RUN_DEFAULT 表示 uv_run
会向来不通运营, 只到失去工作要拍卖的时候, 才会有重返值.

其中 UV_RUN_DEFAULT 表示 uv_run
会一向不通运维, 只到没有工作要拍卖的时候, 才会有重回值.

而 UV_RUN_ONCE 代表执行 poll 三回.
类比你写代码只调用三回 select 阻塞, 直到事件激活或许逾期触发.

而 UV_RUN_ONCE 表示执行 poll 二遍.
类比你写代码只调用一回 select 阻塞, 直到事件激活只怕逾期触发.

相似的 UV_RUN_NOWAIT 也是只 poll
轮询1次, 不过没有要拍卖工作是不会阻塞.

相似的 UV_RUN_NOWAIT 也是只 poll
轮询一遍, 可是没有要拍卖工作是不会阻塞.

  到此地, 大约 linux libuv 的 hello world 应该也算起来了.

  到那边, 大概 linux libuv 的 hello world 应该也算起来了.

 

 

前言 – winds 跑起 libuv

前言 – winds 跑起 libuv

   下边开端带大家, 在 winds 编译最新版本 libuv.  同样在 github 上 下载
libuv 最新的发表版本.

   下边开首带大家, 在 winds 编写翻译最新版本 libuv.  同样在 github 上 下载
libuv 最新的公布版本.

    libuv-1.18.0

    libuv-1.18.0

解压操作达成后, 会是底下那样的

解压操作完毕后, 会是上边那样的

图片 1

图片 2

此刻候先参照一下官网的 libuv 首页 README.md 表达.  

那时候先参照一下官网的 libuv 首页 README.md 表达.  

先安装 Python 2.7 . 扯一点.  以来 python 好虎 (二〇一七年10月216日), 
可是依旧不通晓为何 2.7 和 3.x 版本不包容. 

先安装 Python 2.7 . 扯一点.  近日 python 好虎 (二〇一七年一月237日), 
可是照旧不知情为何 2.7 和 3.x 版本不包容. 

就当下而言如故多用 Python 2.7 感觉.  随后安装 gyp google
推出的跨平台编写翻译环境.

就当前而言依旧多用 Python 2.7 感觉.  随后安装 gyp google
推出的跨平台编写翻译环境.

  gyp
– https://github.com/svn2github/gyp

  gyp
– https://github.com/svn2github/gyp

鉴于应用的是 VS2017, 原始版本 gyp 不帮忙, 请参照作者提的那几个提交,
实行修改让其协助 VS2017 版本

是因为选用的是 VS2017, 原始版本 gyp 不援助, 请参照作者提的这么些提交,
举行改动让其协理 VS2017 版本

  gyp-vs2017
version
 
– https://github.com/svn2github/gyp/pull/1/commits/66e69a51f4393bc03cc3bfec53c7c35d974339b6

  gyp-vs2017
version
 
– https://github.com/svn2github/gyp/pull/1/commits/66e69a51f4393bc03cc3bfec53c7c35d974339b6

ok winds 10 + VS2017 + libuv-1.18.0 + python2.7 + gyp + gyp vs2017
version 编写翻译环境搭建达成.

ok winds 10 + VS2017 + libuv-1.18.0 + python2.7 + gyp + gyp vs2017
version 编写翻译环境搭建达成.

开始走起, 先进入 gyp 目录执行 

起首走起, 先进入 gyp 目录执行 

python .\setup.py install
python .\setup.py install

图片 3

图片 4

成就后, 初始营造 uv.sln 工程. 先进入 libuv-1.18.0 开首目录,
执行上边命令 

姣好后, 早先塑造 uv.sln 工程. 先进入 libuv-1.18.0 开头目录,
执行下边命令 

 .\vcbuild.bat release vs2017 x64 static
 .\vcbuild.bat release vs2017 x64 static

继之能够看见 uv.sln 和 Release\lib\libuv.lib 生成文件. 编写翻译进度中
x64版本警告不少.  你一点一滴能够尝尝消除,

随后能够望见 uv.sln 和 Release\lib\libuv.lib 生成文件. 编写翻译进度中
x64本子警告不少.  你一点一滴能够尝试解决,

关键是 linux 和 winds 对于 POSIX socket writev
批量读写实现的构造用了不相同类型导致的. 

最首借使 linux 和 winds 对于 POSIX socket writev
批量读写完结的构造用了不平等类型导致的. 

温馨改了它有个别源码和测试代码, 消除了整套警告. 详细 libuv 在 VS2017
上面使用无外乎 include + lib 

友善改了它有个别源码和测试代码, 消除了全方位警告. 详细 libuv 在 VS2017
上面运用无外乎 include + lib 

带上 libuv.h 下面的 include 头文件

带上 libuv.h 下面的 include 头文件

 图片 5 

 图片 6 

再增长项目工程中程导弹入上面库 

再增长项目工程中程导弹入上边库 

advapi32.lib
iphlpapi.lib
psapi.lib
shell32.lib
user32.lib
userenv.lib
ws2_32.lib
advapi32.lib
iphlpapi.lib
psapi.lib
shell32.lib
user32.lib
userenv.lib
ws2_32.lib

头文件什么的简约导入上边就足以了 

头文件什么的简易导入下边就能够了 

WIN32_LEAN_AND_MEAN
_CRT_SECURE_NO_WARNINGS
_CRT_NONSTDC_NO_DEPRECATE
_WINSOCK_DEPRECATED_NO_WARNINGS
WIN32_LEAN_AND_MEAN
_CRT_SECURE_NO_WARNINGS
_CRT_NONSTDC_NO_DEPRECATE
_WINSOCK_DEPRECATED_NO_WARNINGS

到那基本上 libuv winds 就马到功成了.  

到那基本上 libuv winds 就旗开马到了.  

那里写了个示范 demo, 有趣味的能够尝试演习一下

此处写了个示范 demo, 有趣味的可以尝试演习一下

#include <uv.h>
#include <assext.h>

// 继承 uv_timer_t 结构
struct gravity {
    uv_timer_t tick;

    uv_tty_t tty;

    int width;
    int height;
    int pos;

    char * msg;
};

// _update - 更新图片内容
static void _update(struct gravity * grav) {
    char data[BUFSIZ];
    uv_buf_t buf;
    buf.base = data;
    //
    // \033[2J      : 清屏
    // \033[H       : 光标移到(0, 0)
    // \033[%dB     : 光标下移 %d 行
    // \033[%dC     : 光标右移 %d 行
    // \033[42;37m  : 底色 41 绿底, 字色 37 白字
    //
    // \033[0m      : 关闭所有属性
    //
    buf.len = sprintf(data, "\033[2J\033[H\033[%dB\033[%dC\033[42;37m%s",
                            grav->pos,
                            (grav->width - (int)strlen(grav->msg)) / 2,
                            grav->msg);
    assert(buf.len < BUFSIZ);
    if (grav->pos == grav->height) {
        // 关闭屏幕额外属性
        const char * resets = "\033[0m";
        strcat(data, resets);
        buf.len += (int)strlen(resets);
    }

    // 写入消息
    uv_try_write((uv_stream_t *)&grav->tty, &buf, 1);

    // 当超过当前屏幕, 退出定时器
    if (++grav->pos > grav->height) {
        // 重置tty
        uv_tty_reset_mode();
        uv_timer_stop(&grav->tick);
    }
}

//
// uv_timer_test - 测试 timer 使用
//
void uv_timer_test(void) {
    uv_loop_t * loop = uv_default_loop();
    struct gravity grav = { { 0 } };

    uv_tty_init(loop, &grav.tty, 1, 0);
    uv_tty_set_mode(&grav.tty, UV_TTY_MODE_NORMAL);

    // 获取当前屏幕宽高信息
    if (uv_tty_get_winsize(&grav.tty, &grav.width, &grav.height)) {
        fprintf(stderr, "Could not get TTY information\n");
        uv_tty_reset_mode();
        return;
    }

    fprintf(stderr, "Width %d, height %d\n", grav.width, grav.height);

    // 启动 timer 刷新屏幕信息
    grav.msg = u8"我不甘心 ~";
    uv_timer_init(loop, &grav.tick);
    uv_timer_start(&grav.tick, (uv_timer_cb)_update, 200, 200);

    uv_run(loop, UV_RUN_DEFAULT);
}
#include <uv.h>
#include <assext.h>

// 继承 uv_timer_t 结构
struct gravity {
    uv_timer_t tick;

    uv_tty_t tty;

    int width;
    int height;
    int pos;

    char * msg;
};

// _update - 更新图片内容
static void _update(struct gravity * grav) {
    char data[BUFSIZ];
    uv_buf_t buf;
    buf.base = data;
    //
    // \033[2J      : 清屏
    // \033[H       : 光标移到(0, 0)
    // \033[%dB     : 光标下移 %d 行
    // \033[%dC     : 光标右移 %d 行
    // \033[42;37m  : 底色 41 绿底, 字色 37 白字
    //
    // \033[0m      : 关闭所有属性
    //
    buf.len = sprintf(data, "\033[2J\033[H\033[%dB\033[%dC\033[42;37m%s",
                            grav->pos,
                            (grav->width - (int)strlen(grav->msg)) / 2,
                            grav->msg);
    assert(buf.len < BUFSIZ);
    if (grav->pos == grav->height) {
        // 关闭屏幕额外属性
        const char * resets = "\033[0m";
        strcat(data, resets);
        buf.len += (int)strlen(resets);
    }

    // 写入消息
    uv_try_write((uv_stream_t *)&grav->tty, &buf, 1);

    // 当超过当前屏幕, 退出定时器
    if (++grav->pos > grav->height) {
        // 重置tty
        uv_tty_reset_mode();
        uv_timer_stop(&grav->tick);
    }
}

//
// uv_timer_test - 测试 timer 使用
//
void uv_timer_test(void) {
    uv_loop_t * loop = uv_default_loop();
    struct gravity grav = { { 0 } };

    uv_tty_init(loop, &grav.tty, 1, 0);
    uv_tty_set_mode(&grav.tty, UV_TTY_MODE_NORMAL);

    // 获取当前屏幕宽高信息
    if (uv_tty_get_winsize(&grav.tty, &grav.width, &grav.height)) {
        fprintf(stderr, "Could not get TTY information\n");
        uv_tty_reset_mode();
        return;
    }

    fprintf(stderr, "Width %d, height %d\n", grav.width, grav.height);

    // 启动 timer 刷新屏幕信息
    grav.msg = u8"我不甘心 ~";
    uv_timer_init(loop, &grav.tick);
    uv_timer_start(&grav.tick, (uv_timer_cb)_update, 200, 200);

    uv_run(loop, UV_RUN_DEFAULT);
}

本条显示屏音讯会动 哈哈, : )

以此显示器音讯会动 哈哈, : )

图片 7 

图片 8 

(二傻子 入场 ~ ) 

(二傻子 入场 ~ ) 

 

 

正文 – 稍加演习

正文 – 稍加练习

  通过以上对libuv环境的搭建和省略先入为主的概念性描述,.
此时完全能够利用 libuv tty 简单做个

  通过上述对libuv环境的搭建和省略先入为主的概念性描述,.
此时统统能够接纳 libuv tty 简单做个

跨平台的小动画了.  作者先写个, 推荐大家参考例子抄写1遍, 培养手感.
扯一点互连网技术有三个样子

跨平台的小动画了.  作者先写个, 推荐大家参考例子抄写二遍, 作育手感.
扯一点互连网技术有多少个样子

架构师和技巧专家. 有点像在此之前游戏开发中服务器架设和客户端引擎.
可是C程序员还是强调手感,

架构师和技艺术专科学校家. 有点像此前游戏开发中服务器架设和客户端引擎.
但是C程序员还是强调手感,

弱化架构, 追求极致的统一.  (说白点, 代码更关键, 能说更好.)

弱化架构, 追求极致的统一.  (说白点, 代码更重要, 能说更好.)

#include <uv.h>
#include <chead.h>
#include <assext.h>

struct love {
    uv_timer_t tick;

    uv_tty_t tty;

    int width;
    int height;
    int pos;

    char ** msgs;
    int len;
};

static char * _figure[] = {
    u8"  背影 :- 汪国真\n",
    u8"  \n",
    u8"  背影\n",
    u8"  总是很简单\n",
    u8"  简单\n",
    u8"  是一种风景\n",
    u8"  \n",
    u8"  背影\n",
    u8"  总是很年轻\n",
    u8"  年轻\n",
    u8"  是一种清明\n",
    u8"  \n",
    u8"  背影\n",
    u8"  总是很含蓄\n",
    u8"  含蓄\n",
    u8"  是一种魅力\n",
    u8"  \n",
    u8"  背影\n",
    u8"  总是很孤零\n",
    u8"  孤零\n",
    u8"  更让人记得清\n"
};

// _love_stty : 内部发送消息
static inline void _love_stty(struct love * love, const char * msg) {
    uv_buf_t buf;
    buf.base = (char *)msg;
    buf.len = (int)strlen(buf.base);
    uv_try_write((uv_stream_t *)&love->tty, &buf, 1);
}

// _love_init : 初始化当前 tty 结构
static void _love_init(struct love * love) {
    uv_loop_t * loop = uv_default_loop();
    memset(love, 0, sizeof *love);

    // 初始化 tty 环境
    uv_tty_init(loop, &love->tty, 1, 0);
    uv_tty_set_mode(&love->tty, UV_TTY_MODE_NORMAL);

    // 只对 tty 输出处理
    if (uv_guess_handle(1) != UV_TTY)
        CERR_EXIT("uv_guess_handle(1) != UV_TTY!");

    // 获取当前屏幕宽高信息
    if (uv_tty_get_winsize(&love->tty, &love->width, &love->height)) {
        uv_tty_reset_mode();
        CERR_EXIT("Could not get TTY information");
    }

    // 设置具体内容
    love->msgs = _figure;
    love->len = LEN(_figure);

    // 初始化定时器
    uv_timer_init(loop, &love->tick);
}

// _love_screem : 屏幕绘制内容
static void _love_screem(struct love * love) {
    char buf[BUFSIZ];
    int cnt = love->pos < love->len ? love->pos : love->len;

    // 重置索引位置
    int idx = love->height - love->pos;
    snprintf(buf, LEN(buf), "\033[2J\033[H\033[%dB", idx);
    _love_stty(love, buf);

    // 全部显示
    for (idx = 0; idx < cnt; idx++)
        _love_stty(love, love->msgs[idx]);
}

// _update - 更新刷新事件
static void _love_update(struct love * love) {
    ++love->pos;

    // 开始绘制内容
    _love_screem(love);

    // 运行结束直接返回
    if (love->pos >= love->height) {
        // 重置tty
        uv_tty_reset_mode();
        uv_timer_stop(&love->tick);
    }
}

//
// uv_love_test - 情怀 ~
//
void uv_love_test(void) {
    struct love love;
    _love_init(&love);

    // 开始初始化, 定时器刷新事件
    uv_timer_start(&love.tick, (uv_timer_cb)_love_update, 200, 200);

    // 事件启动起来
    uv_run(uv_default_loop(), UV_RUN_DEFAULT);
}
#include <uv.h>
#include <chead.h>
#include <assext.h>

struct love {
    uv_timer_t tick;

    uv_tty_t tty;

    int width;
    int height;
    int pos;

    char ** msgs;
    int len;
};

static char * _figure[] = {
    u8"  背影 :- 汪国真\n",
    u8"  \n",
    u8"  背影\n",
    u8"  总是很简单\n",
    u8"  简单\n",
    u8"  是一种风景\n",
    u8"  \n",
    u8"  背影\n",
    u8"  总是很年轻\n",
    u8"  年轻\n",
    u8"  是一种清明\n",
    u8"  \n",
    u8"  背影\n",
    u8"  总是很含蓄\n",
    u8"  含蓄\n",
    u8"  是一种魅力\n",
    u8"  \n",
    u8"  背影\n",
    u8"  总是很孤零\n",
    u8"  孤零\n",
    u8"  更让人记得清\n"
};

// _love_stty : 内部发送消息
static inline void _love_stty(struct love * love, const char * msg) {
    uv_buf_t buf;
    buf.base = (char *)msg;
    buf.len = (int)strlen(buf.base);
    uv_try_write((uv_stream_t *)&love->tty, &buf, 1);
}

// _love_init : 初始化当前 tty 结构
static void _love_init(struct love * love) {
    uv_loop_t * loop = uv_default_loop();
    memset(love, 0, sizeof *love);

    // 初始化 tty 环境
    uv_tty_init(loop, &love->tty, 1, 0);
    uv_tty_set_mode(&love->tty, UV_TTY_MODE_NORMAL);

    // 只对 tty 输出处理
    if (uv_guess_handle(1) != UV_TTY)
        CERR_EXIT("uv_guess_handle(1) != UV_TTY!");

    // 获取当前屏幕宽高信息
    if (uv_tty_get_winsize(&love->tty, &love->width, &love->height)) {
        uv_tty_reset_mode();
        CERR_EXIT("Could not get TTY information");
    }

    // 设置具体内容
    love->msgs = _figure;
    love->len = LEN(_figure);

    // 初始化定时器
    uv_timer_init(loop, &love->tick);
}

// _love_screem : 屏幕绘制内容
static void _love_screem(struct love * love) {
    char buf[BUFSIZ];
    int cnt = love->pos < love->len ? love->pos : love->len;

    // 重置索引位置
    int idx = love->height - love->pos;
    snprintf(buf, LEN(buf), "\033[2J\033[H\033[%dB", idx);
    _love_stty(love, buf);

    // 全部显示
    for (idx = 0; idx < cnt; idx++)
        _love_stty(love, love->msgs[idx]);
}

// _update - 更新刷新事件
static void _love_update(struct love * love) {
    ++love->pos;

    // 开始绘制内容
    _love_screem(love);

    // 运行结束直接返回
    if (love->pos >= love->height) {
        // 重置tty
        uv_tty_reset_mode();
        uv_timer_stop(&love->tick);
    }
}

//
// uv_love_test - 情怀 ~
//
void uv_love_test(void) {
    struct love love;
    _love_init(&love);

    // 开始初始化, 定时器刷新事件
    uv_timer_start(&love.tick, (uv_timer_cb)_love_update, 200, 200);

    // 事件启动起来
    uv_run(uv_default_loop(), UV_RUN_DEFAULT);
}

成效是从上到下输出了汪国真先生诗词背影~ 🙂 

作用是从上到下输出了汪国真先生诗词背影~ 🙂 

  背影
https://pan.baidu.com/s/1kVd5aRX

  背影
https://pan.baidu.com/s/1kVd5aRX

      背景,  总是很不难, 更令人记得清 

      背景,  总是很不难, 更令人记得清 

图片 9

图片 10

 

 

后记 – 好久没扯淡了

后记 – 好久没扯淡了

  极度欢迎沟通, 错误是免不了的, 发现再改吧 ~  O_O

  有标题欢迎调换, 错误是免不了的, 发现再改吧 ~  O_O

  只为你活一天
– http://music.163.com/m/song?id=29999535&userid=16529894

  只为你活一天
– http://music.163.com/m/song?id=29999535&userid=16529894

 

 

 

 

  

  

  

  

相关文章