littlevgl_7.11源碼分析(3)--Apple的學(xué)習(xí)筆記

一,前言

之前是從一個(gè)將obj放置到最前面的API開始的分析,從設(shè)置無(wú)效區(qū)域后發(fā)task調(diào)度信號(hào),到最后執(zhí)行重繪渲染及更新顯示的整個(gè)過(guò)程版姑。但是我記得里面有l(wèi)v_refr_obj_and_children函數(shù)是關(guān)于渲染重繪的,我沒(méi)有展開迟郎,因?yàn)槔锩孢M(jìn)入lv_obj_design后都是style和mask相關(guān)的內(nèi)容剥险,基本上可以理解為這是渲染重繪的像素重組的功能。但是這些內(nèi)容應(yīng)該在初始化的時(shí)候設(shè)置過(guò)宪肖,然后再次應(yīng)用表制。所以我有必要從頭開始分析下。我選擇了創(chuàng)建一個(gè)button開始分析源碼控乾。

二么介,lv_btn_create

關(guān)于對(duì)象大小和位置的初始化
按官網(wǎng)教程創(chuàng)建btn后需要設(shè)置位置,設(shè)置大小蜕衡,設(shè)置回調(diào)函數(shù)等壤短。而我改成了最簡(jiǎn)單的,只創(chuàng)建btn慨仿,調(diào)用btn = lv_btn_create(lv_scr_act(),NULL);想看看是否會(huì)出現(xiàn)圖像久脯。結(jié)果真的有一個(gè)按鈕顯示出來(lái),位置在0,0處镶骗,說(shuō)明初始化的時(shí)候就設(shè)置了默認(rèn)值桶现,而關(guān)于大小的默認(rèn)值不是0,所以才能顯示出來(lái)鼎姊。lv_btn_create->lv_cont_create->lv_obj_create,其中l(wèi)v_obj_create函數(shù)很重要相赁。里面創(chuàng)建了new_obj分配了內(nèi)存相寇,然后就開始使用初始化值對(duì)new_obj進(jìn)行填充了。

        new_obj = _lv_ll_ins_head(&parent->child_ll);
        LV_ASSERT_MEM(new_obj);
        if(new_obj == NULL) return NULL;

        _lv_memset_00(new_obj, sizeof(lv_obj_t));

剛剛說(shuō)的對(duì)象大小就是在此函數(shù)中填充的钮科,寬度和高度都和宏定義LV_OBJ_DEF_WIDTH有關(guān)唤衫,而它又和lv_conf.h中的LV_DPI有關(guān)。此宏定義的含義是每個(gè)inch要占用顯示屏多少的像素值绵脯。

        new_obj->coords.y1    = parent->coords.y1;
        new_obj->coords.y2    = parent->coords.y1 + LV_OBJ_DEF_HEIGHT;
        if(lv_obj_get_base_dir(new_obj) == LV_BIDI_DIR_RTL) {
            new_obj->coords.x2    = parent->coords.x2;
            new_obj->coords.x1    = parent->coords.x2 - LV_OBJ_DEF_WIDTH;
        }
        else {
            new_obj->coords.x1    = parent->coords.x1;
            new_obj->coords.x2    = parent->coords.x1 + LV_OBJ_DEF_WIDTH;
        }

lv_obj.c的代碼里面默認(rèn)給對(duì)象的初始化寬度為100佳励,高度為50。不僅僅是btn蛆挫,其它obj的創(chuàng)建都是這個(gè)值赃承。但是這個(gè)比例是核心代碼中的,不是留給用戶配置的悴侵,當(dāng)然我現(xiàn)在看懂代碼瞧剖,知道含義了,想怎么改都行。哈哈抓于,通過(guò)看源碼破解了奧秘做粤。

#define LV_OBJ_DEF_WIDTH    (LV_DPX(100))
#define LV_OBJ_DEF_HEIGHT   (LV_DPX(50))

樣式初始化
剛剛看了關(guān)鍵的位置及大小有初始化,其實(shí)默認(rèn)的按鈕它是藍(lán)色的圓角框捉撮,而且可以click點(diǎn)擊怕品,但是不能被拖動(dòng)。這些click和draw屬性在lv_obj_create函數(shù)中都能看到其初始化值巾遭。那么接下來(lái)我最關(guān)心的就是樣式的應(yīng)用堵泽,因?yàn)閳D片好看不好看就是要看code中是如何設(shè)置風(fēng)格化的了。它這里的風(fēng)格設(shè)置恢总,用了theme主題迎罗,應(yīng)用不同的主題,則顯示出來(lái)的外形則不同片仿。對(duì)于使用windows桌面采用不同的主題則界面效果不同纹安,lvgl也是延續(xù)了這樣的思路。我慢好奇的砂豌,這個(gè)具體實(shí)現(xiàn)機(jī)制是怎么樣的呢厢岂!

    lv_style_list_init(&new_obj->style_list);
    if(copy == NULL) {
        /* 若無(wú)傳入copy對(duì)象,并且沒(méi)有parent則風(fēng)格化參考LV_THEME_OBJ阳距,否則參考LV_THEME_SCR */
        if(parent != NULL) lv_theme_apply(new_obj, LV_THEME_OBJ);
        else lv_theme_apply(new_obj, LV_THEME_SCR);
    }
    else {
        /* 若有傳入copy對(duì)象塔粒,參考其風(fēng)格進(jìn)行樣式格式化 */
        lv_style_list_copy(&new_obj->style_list, &copy->style_list);
    }

好了,那么就來(lái)分析lv_theme_apply函數(shù)筐摘,簡(jiǎn)單來(lái)很容易理解卒茬,先刪除之前的主題,再使用新的主題咖熟。這就是change的操作方法圃酵。

void lv_theme_apply(lv_obj_t * obj, lv_theme_style_t name)
{
    /* Remove the existing styles from all part of the object. */
    clear_styles(obj, name);

    /*Apply the theme including the base theme(s)*/

    apply_theme(act_theme, obj, name);
}

繼續(xù)先看clear_styles椎扬,這里面好多case語(yǔ)句牧氮,寫的不雅觀,建議改成數(shù)組查表調(diào)用宙帝,數(shù)組的每一行也可以添加宏定義确沸。

static void clear_styles(lv_obj_t * obj, lv_theme_style_t name)
{
    switch(name) {
        case LV_THEME_NONE:
            break;

        case LV_THEME_SCR:
            lv_obj_clean_style_list(obj, LV_OBJ_PART_MAIN);
            break;
        case LV_THEME_OBJ:
            lv_obj_clean_style_list(obj, LV_OBJ_PART_MAIN);
            break;
#if LV_USE_CONT
        case LV_THEME_CONT:
            lv_obj_clean_style_list(obj, LV_OBJ_PART_MAIN);
            break;
#endif

#if LV_USE_BTN
        case LV_THEME_BTN:
            lv_obj_clean_style_list(obj, LV_BTN_PART_MAIN);
            break;
#endif
捌锭。。罗捎。观谦。。宛逗。

由于我那一句按鈕初始化坎匿,其實(shí)傳入的是參數(shù)是LV_THEME_OBJ,所以會(huì)調(diào)用lv_obj_clean_style_list(obj, LV_OBJ_PART_MAIN);,其實(shí)里面就是獲取obj中style_list的地址,然后調(diào)用_lv_style_list_reset(style_dsc);后面還是動(dòng)畫功能的相關(guān)處理我先不管替蔬。
真正的清除原先的style功能就在下面的代碼中實(shí)現(xiàn)告私。但是我不理解的有2個(gè)成員,1個(gè)是lv_style_list_t中的trans和local承桥,是什么意思驻粟,另外就是清除lv_style_list_t只要清除如下幾個(gè)屬性就可以了嗎?lv_style_list_t中其它成員不需要清除嗎凶异?

void _lv_style_list_reset(lv_style_list_t * list)
{
    LV_ASSERT_STYLE_LIST(list);

    if(list == NULL) return;

    if(list->has_local) {
        lv_style_t * local = lv_style_list_get_local_style(list);
        if(local) {
            lv_style_reset(local);
            lv_mem_free(local);
        }
    }

    if(list->has_trans) {
        lv_style_t * trans = _lv_style_list_get_transition_style(list);
        if(trans) {
            lv_style_reset(trans);
            lv_mem_free(trans);
        }
    }

    if(list->style_cnt > 0) lv_mem_free(list->style_list);
    list->style_list = NULL;
    list->style_cnt = 0;
    list->has_local = 0;
    list->has_trans = 0;
    list->skip_trans = 0;

    /* Intentionally leave `ignore_trans` as it is,
     * because it's independent from the styles in the list*/
}

主題樣式初始化
我先帶著問(wèn)題繼續(xù)看應(yīng)用新的主題蜀撑,說(shuō)不定在應(yīng)用新的主題的時(shí)候,其它值都會(huì)被重新設(shè)置一遍剩彬,那么剛剛的clean中就沒(méi)必要清0了酷麦。

static void apply_theme(lv_theme_t * th, lv_obj_t * obj, lv_theme_style_t name)
{
    if(th->base) {
        apply_theme(th->base, obj, name);
    }

    /*apply_xcb is deprecated, use apply_cb instead*/
    if(th->apply_xcb) {
        th->apply_xcb(obj, name);
    }
    else if(th->apply_cb) {
        th->apply_cb(act_theme, obj, name);
    }
}

th->apply_cb其實(shí)是theme_apply函數(shù),它是在lv_theme_material_init函數(shù)中初始化的回調(diào)函數(shù)喉恋。lv_config.h配置中設(shè)置了#define LV_THEME_DEFAULT_INIT lv_theme_material_initlv_init函數(shù)中對(duì)調(diào)用沃饶。

    lv_theme_t * th = LV_THEME_DEFAULT_INIT(LV_THEME_DEFAULT_COLOR_PRIMARY, LV_THEME_DEFAULT_COLOR_SECONDARY,
                                            LV_THEME_DEFAULT_FLAG,
                                            LV_THEME_DEFAULT_FONT_SMALL, LV_THEME_DEFAULT_FONT_NORMAL, LV_THEME_DEFAULT_FONT_SUBTITLE, LV_THEME_DEFAULT_FONT_TITLE);

theme_styles_t結(jié)構(gòu)體對(duì)象中的成員蠻有意思的,除了前7個(gè)固定的轻黑,其它都可以配置糊肤,根據(jù)顯示需要的元素進(jìn)行配置,不同的元素都有自己特色的風(fēng)格成員氓鄙,例如日歷馆揉, 則有日期等,例如arc就有旋鈕特色成員抖拦。另外一個(gè)關(guān)鍵的就是這些成員的類似定義為lv_style_t升酣,要有一個(gè)類型能滿足所有成員,我猜測(cè)就是void *蟋座,因?yàn)榭梢噪S意綁定對(duì)象類型拗踢,結(jié)果查看了下是uint8 *差不多啦~

typedef struct {
    lv_style_t scr;
    lv_style_t bg;
    lv_style_t bg_click;
    lv_style_t bg_sec;
    lv_style_t btn;
    lv_style_t pad_inner;
    lv_style_t pad_small;

#if LV_USE_ARC
    lv_style_t arc_indic;
    lv_style_t arc_bg;
    lv_style_t arc_knob;
#endif

#if LV_USE_BAR
    lv_style_t bar_bg;
    lv_style_t bar_indic;
#endif

#if LV_USE_CALENDAR
    lv_style_t calendar_date_nums, calendar_header, calendar_daynames;
#endif
。向臀。。诸狭。券膀。。

typedef struct {
    uint8_t * map;
} lv_style_t;

然后看看lv_theme_material_init中除了設(shè)置theme.apply_cb回調(diào)函數(shù)驯遇,也包括basic_init等函數(shù)芹彬,分析下。

    basic_init();
    cont_init();
    btn_init();
    label_init();
    bar_init();
    img_init();
    line_init();
    led_init();
    ......
static void basic_init(void)
{
    lv_style_reset(&styles->scr);
    lv_style_set_bg_opa(&styles->scr, LV_STATE_DEFAULT, LV_OPA_COVER);
    lv_style_set_bg_color(&styles->scr, LV_STATE_DEFAULT, COLOR_SCR);
    lv_style_set_text_color(&styles->scr, LV_STATE_DEFAULT, COLOR_SCR_TEXT);
    lv_style_set_value_color(&styles->scr, LV_STATE_DEFAULT, COLOR_SCR_TEXT);
    lv_style_set_text_sel_color(&styles->scr, LV_STATE_DEFAULT, COLOR_SCR_TEXT);
    lv_style_set_text_sel_bg_color(&styles->scr, LV_STATE_DEFAULT, theme.color_primary);
    lv_style_set_value_font(&styles->scr, LV_STATE_DEFAULT, theme.font_normal);

lv_style_set_bg_opa我一開始沒(méi)有搜索到叉庐。原來(lái)是_LV_OBJ_STYLE_SET_GET_DECLARE(BG_OPA, bg_opa, lv_opa_t, _opa)的宏定義展開的inline函數(shù)舒帮,在h文件中。這里_LV_OBJ_STYLE_SET_GET_DECLARE里面又進(jìn)行了合并同類項(xiàng),抽象化玩郊。說(shuō)白了就是定了3個(gè)格式類似的函數(shù)肢执。
這里我又學(xué)習(xí)到了一招,為了少?gòu)?fù)制黏貼code译红,提高工作效率预茄,則采用此宏定義+不同字符的方法來(lái)定義函數(shù),其實(shí)預(yù)編譯的時(shí)候這些宏定義都會(huì)進(jìn)行函數(shù)展開的侦厚。

#define _OBJ_GET_STYLE(prop_name, func_name, value_type, style_type)                                \
    static inline value_type lv_obj_get_style_##func_name(const lv_obj_t * obj, uint8_t part)       \
    {                                                                                               \
        return _lv_obj_get_style##style_type(obj, part, LV_STYLE_##prop_name);                      \
    }
#endif

#define _OBJ_SET_STYLE_LOCAL(prop_name, func_name, value_type, style_type)                                                      \
    static inline void lv_obj_set_style_local_##func_name(lv_obj_t * obj, uint8_t part, lv_state_t state, value_type value)     \
    {                                                                                                                           \
        _lv_obj_set_style_local##style_type(obj, part, LV_STYLE_##prop_name | (state << LV_STYLE_STATE_POS), value);            \
    }

#define _OBJ_SET_STYLE(prop_name, func_name, value_type, style_type)                                                     \
    static inline void lv_style_set_##func_name(lv_style_t * style, lv_state_t state, value_type value)                  \
    {                                                                                                                    \
        _lv_style_set##style_type(style, LV_STYLE_##prop_name | (state << LV_STYLE_STATE_POS), value);                   \
    }

#define _LV_OBJ_STYLE_SET_GET_DECLARE(prop_name, func_name, value_type, style_type)                                      \
    _OBJ_GET_STYLE(prop_name, func_name, value_type, style_type)                                                         \
    _OBJ_SET_STYLE_LOCAL(prop_name, func_name, value_type, style_type)                                                   \
    _OBJ_SET_STYLE(prop_name, func_name, value_type, style_type)

style->map的初始化
所以lv_style_set_bg_opa函數(shù)最后會(huì)調(diào)用_lv_style_set_opa函數(shù)耻陕。這個(gè)函數(shù)寫的蠻有意思的。它需要為lv_style_t中的uint8* map來(lái)賦值刨沦,并且還能保證能找到不同長(zhǎng)度的style成員诗宣。第一次設(shè)置style的話id為0,通過(guò)最后3個(gè)memcpy可以看出map中要保存3個(gè)成員屬性+透明度+結(jié)束符想诅,抽象理解就是屬性+屬性值+結(jié)束符召庞。而里面的new_prop_size,end_mark_size和總size的計(jì)算很容易理解侧蘸,就是每個(gè)成員的長(zhǎng)度裁眯,這些size就是在3次memcpy中用的。style_resize可以理解為通過(guò)malloc重新*map分配空間讳癌。然后在style->map地址開始裝數(shù)據(jù)穿稳。裝載順序入下圖。

image.png

void _lv_style_set_opa(lv_style_t * style, lv_style_property_t prop, lv_opa_t opa)
{
    int32_t id = get_property_index(style, prop);
    /*The property already exists but not sure it's state is the same*/
    if(id >= 0) {
        lv_style_attr_t attr_found;
        lv_style_attr_t attr_goal;

        attr_found = get_style_prop_attr(style, id);
        attr_goal = (prop >> 8) & 0xFFU;
        /* 若找到屬性晌坤,則重置屬性值 */
        if(LV_STYLE_ATTR_GET_STATE(attr_found) == LV_STYLE_ATTR_GET_STATE(attr_goal)) {
            _lv_memcpy_small(style->map + id + sizeof(lv_style_property_t), &opa, sizeof(lv_opa_t));
            return;
        }
    }

    /*Add new property if not exists yet*/
    uint8_t new_prop_size = sizeof(lv_style_property_t) + sizeof(lv_opa_t);
    lv_style_property_t end_mark = _LV_STYLE_CLOSING_PROP;
    uint8_t end_mark_size = sizeof(end_mark);

    uint16_t size = _lv_style_get_mem_size(style);
    if(size == 0) size += end_mark_size;

    size += new_prop_size;
    if(!style_resize(style, size)) return;

    _lv_memcpy_small(style->map + size - new_prop_size - end_mark_size, &prop, sizeof(lv_style_property_t));
    _lv_memcpy_small(style->map + size - sizeof(lv_opa_t) - end_mark_size, &opa, sizeof(lv_opa_t));
    _lv_memcpy_small(style->map + size - end_mark_size, &end_mark, sizeof(end_mark));
}

現(xiàn)在我算是學(xué)習(xí)到了逢艘,結(jié)構(gòu)不同的打包放入指針,通過(guò)成員的類型長(zhǎng)度也可以找到不同的成員骤菠。這個(gè)感覺(jué)和protobuf原理有些類似它改,反正就是解析數(shù)據(jù)一類的。上面代碼中的if的功能就是若找到屬性商乎,則重置屬性值央拖,直接return退出,否則要走下面的添加屬性及屬性值的步驟鹉戚。
然后看看成員不同格式的組合是如何進(jìn)行解析查找的鲜戒。get_property_index函數(shù),我只保留了結(jié)構(gòu)抹凳。

    uint8_t prop_id;
    while((prop_id = get_style_prop_id(style, i)) != _LV_STYLE_CLOSING_PROP) {
        if(prop_id == id_to_find) {
            id_guess = ......
        }

        i = get_next_prop_index(prop_id, i);
    }
    return id_guess;

get_style_prop_id會(huì)調(diào)用如下關(guān)鍵語(yǔ)句遏餐,這容易理解,獲取第i個(gè)熟悉赢底,然后返回屬性值失都。

    lv_style_property_t prop;
    _lv_memcpy_small(&prop, &style->map[idx], sizeof(lv_style_property_t));
    return prop;

若屬性和當(dāng)前查找的不同柏蘑,則需要獲取下一個(gè)屬性,上面的截圖我已經(jīng)分析過(guò)了1個(gè)字節(jié)屬性+2個(gè)字節(jié)屬性值+結(jié)尾符粹庞。那么我要找下一個(gè)屬性應(yīng)該加幾個(gè)字節(jié)應(yīng)該知道了吧咳焚!lvgl設(shè)計(jì)的更加好,因?yàn)樗?類屬性和值混合存放的信粮,當(dāng)然屬性類別的長(zhǎng)度是固定的黔攒,而屬性值的長(zhǎng)度根據(jù)屬性類別而不同。所以不是我說(shuō)的固定值强缘,而是在get_prop_size函數(shù)中可以看出會(huì)增加不同的size督惰。

static inline size_t get_next_prop_index(uint8_t prop_id, size_t idx)
{
    return idx + get_prop_size(prop_id);
}
static inline size_t get_prop_size(uint8_t prop_id)
{
    prop_id &= 0xF;
    size_t size = sizeof(lv_style_property_t);
    if(prop_id < LV_STYLE_ID_COLOR) size += sizeof(lv_style_int_t);
    else if(prop_id < LV_STYLE_ID_OPA) size += sizeof(lv_color_t);
    else if(prop_id < LV_STYLE_ID_PTR) size += sizeof(lv_opa_t);
    else size += sizeof(const void *);
    return size;
}

三,小結(jié)

今天從按鈕的創(chuàng)建開始旅掂,重點(diǎn)分析了主題樣式的初始化赏胚,畢竟做引擎的目的就是減少修改,而換皮技術(shù)就是一個(gè)很靈活的GUI引擎必備的功能商虐,這里分析了利用屬性類+屬性值的混合屬性保存及解析方法觉阅。真的感覺(jué)像是我以前做的tcp報(bào)文數(shù)據(jù)解析類似,這樣的設(shè)計(jì)有意思秘车,但是它為什么要這樣設(shè)計(jì)典勇,而不是每種屬性類和值都做成獨(dú)立的結(jié)構(gòu)體對(duì)象呢?我想了下叮趴,估計(jì)是為了使用的時(shí)候更便利割笙,可擴(kuò)展性更強(qiáng),并且我們?cè)O(shè)計(jì)代碼不就是要抽象嘛眯亦!所以它已經(jīng)做的很抽象了伤溉。唯一我覺(jué)得不好的就是查詢算法不太好。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末妻率,一起剝皮案震驚了整個(gè)濱河市乱顾,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌宫静,老刑警劉巖走净,帶你破解...
    沈念sama閱讀 218,941評(píng)論 6 508
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場(chǎng)離奇詭異孤里,居然都是意外死亡温技,警方通過(guò)查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,397評(píng)論 3 395
  • 文/潘曉璐 我一進(jìn)店門扭粱,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái),“玉大人震檩,你說(shuō)我怎么就攤上這事琢蛤◎讯椋” “怎么了?”我有些...
    開封第一講書人閱讀 165,345評(píng)論 0 356
  • 文/不壞的土叔 我叫張陵博其,是天一觀的道長(zhǎng)套才。 經(jīng)常有香客問(wèn)我,道長(zhǎng)慕淡,這世上最難降的妖魔是什么背伴? 我笑而不...
    開封第一講書人閱讀 58,851評(píng)論 1 295
  • 正文 為了忘掉前任,我火速辦了婚禮峰髓,結(jié)果婚禮上傻寂,老公的妹妹穿的比我還像新娘。我一直安慰自己携兵,他們只是感情好疾掰,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,868評(píng)論 6 392
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著徐紧,像睡著了一般静檬。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上并级,一...
    開封第一講書人閱讀 51,688評(píng)論 1 305
  • 那天拂檩,我揣著相機(jī)與錄音,去河邊找鬼嘲碧。 笑死稻励,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的呀潭。 我是一名探鬼主播钉迷,決...
    沈念sama閱讀 40,414評(píng)論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼钠署!你這毒婦竟也來(lái)了糠聪?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 39,319評(píng)論 0 276
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤谐鼎,失蹤者是張志新(化名)和其女友劉穎舰蟆,沒(méi)想到半個(gè)月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體狸棍,經(jīng)...
    沈念sama閱讀 45,775評(píng)論 1 315
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡身害,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,945評(píng)論 3 336
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了草戈。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片塌鸯。...
    茶點(diǎn)故事閱讀 40,096評(píng)論 1 350
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖唐片,靈堂內(nèi)的尸體忽然破棺而出丙猬,到底是詐尸還是另有隱情涨颜,我是刑警寧澤,帶...
    沈念sama閱讀 35,789評(píng)論 5 346
  • 正文 年R本政府宣布茧球,位于F島的核電站庭瑰,受9級(jí)特大地震影響,放射性物質(zhì)發(fā)生泄漏抢埋。R本人自食惡果不足惜弹灭,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,437評(píng)論 3 331
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望揪垄。 院中可真熱鬧穷吮,春花似錦、人聲如沸福侈。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,993評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)肪凛。三九已至堰汉,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間伟墙,已是汗流浹背翘鸭。 一陣腳步聲響...
    開封第一講書人閱讀 33,107評(píng)論 1 271
  • 我被黑心中介騙來(lái)泰國(guó)打工, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留戳葵,地道東北人就乓。 一個(gè)月前我還...
    沈念sama閱讀 48,308評(píng)論 3 372
  • 正文 我出身青樓,卻偏偏與公主長(zhǎng)得像拱烁,于是被迫代替她去往敵國(guó)和親生蚁。 傳聞我的和親對(duì)象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 45,037評(píng)論 2 355

推薦閱讀更多精彩內(nèi)容