Skip to content
/ DDSL Public

Simplely Dynamic DSL Layout Engine written in C++ , that is base on Antlr and Flex(Yoga) . DDSL implement a script,it's useful if you want implement a script.

Notifications You must be signed in to change notification settings

czqasngit/DDSL

Repository files navigation

Dynamic DSL(DDSL)

Dynamic DSL是一个精简的动态布局模板,基于Antlr实现了一门简单的脚本语言,通过脚本语言的运算可以实现布局描述文件动态化,再结合Flex布局引擎(Yoga)计算出最终的渲染视图树。

最终展示效果:

这是一个简单的渲染效果图,for测试通过自定义脚本实现了元素的重复,无数展示的数据通过动态绑定生成,原始的渲染XML如下:
<?xml version="1.0"?>
<View flexDirection="row" width="300" height="auto"
    maxHeight="1000"
    left="20"
    top="50"
    justify="spaceAround"
    alignItems="stretch"
    paddingTop="10"
    paddingBottom="20"
    paddingLeft="15"
    paddingRight="15"
    backgroundColor="#FFCDB2">
    <View flex="2" height="auto" justify="center" alignItems="center" backgroundColor="#B5838D">
        <View width="{{ 50 / 2 + 10 }}"
            height="{{ 59 + 2.5 *2 -3 }}"
            backgroundColor="#6D6875"
            borderColor="#e63946"
            borderWidth="2"
            shadowColor="#d00000"
            shadowRadius="15"
            shadowOpacity="0.5"
            ></View>
    </View>
    <View flex="2" height="200" backgroundColor="#90B36D" justify="start" alignItems="center">
        <Label text="for测试: {{item[name]}} - {{ item[age] }}" fontSize="20" color="#ffd23f" for="{{ for item in items }}"></Label>
        <Label text="测试标题2测试标题2测试标题2"
            fontSize="20"
            color="#ef233c"
            marginTop="10"
            lineNumber="3"
            backgroundColor="#00ff00"></Label>
    </View>
</View>

渲染流程图:

引擎架构:

模块介绍

Runtime: 实现了脚本的语义分析,模板实现了一个栈帧。已经实现的运算有(一元表达式、二元表达式、三元表达式、链式取值、加减乘除、取余、逻辑运算,for语句、if语句)

Libs : 三方库

Antlr: antlr运行时库(这里需要注意的是: antlr运行时支持挺大,所以在流程中设计了IR XML语言,在模板编辑器中将原始模板通过antlr编译成IR 模板,runtime运行时解析IR不再需要antlr支持)

Script: antlr语法文件支持库,通过g4文件生成的用于解析相关词法与语法的库

Compiler: IR编译与动态模板解析支持

Flex: Yoga库与在此基础上抽象出来的节点与属性配置

iOS: iOS平台的一个Demo实现

使用DDSL的关键代码

目前的代码仅实现了功能,还没有实现模板编辑器,生成IR XML的功能使用测试用例代替

生成IR XML

NSBundle *bundle = [NSBundle bundleForClass:[self class]];
NSString *xmlPath = [bundle pathForResource:@"node" ofType:@"xml"];
auto db = DDIR([xmlPath UTF8String]);
cout << db.ObtainXMLIR() << endl;

iOS端加载IR XML实现布局

vector<shared_ptr<DDSL::SemaASTNodeObject>> images;
images.push_back(make_shared<DDSL::SemaASTNodeObject>("http:///www.jd.com/"));
images.push_back(make_shared<DDSL::SemaASTNodeObject>("http:///www.qq.com/"));
images.push_back(make_shared<DDSL::SemaASTNodeObject>("http:///www.taobao.com/"));
map<string, shared_ptr<DDSL::SemaASTNodeObject>> variable;
variable["images"] = make_shared<DDSL::SemaASTNodeObject>(images);
string json = R"({"item":{"age": 30},"agex": 32, "namex": "johnx", "size": {"width": 20, "height": 30}, "object": {"rect": {"point": {"x": 200, "y": 100, "name": "小x强"}}}, "items":[{"name": "小强", "age": 28},{"name": "小明", "age": 23},{"name": "小红", "age": 18}]})";
NSString *xmlPath = [[NSBundle mainBundle] pathForResource:@"node" ofType:@"xml"];
Node *rootNode = NodeParser::LoadXML(xmlPath.UTF8String, [UIScreen mainScreen].scale, json, variable, __MeasureFunc);
if(rootNode) {
    rootNode->calculateLayoutWithSize([UIScreen mainScreen].bounds.size.width, [UIScreen mainScreen].bounds.size.height);
    [self _addView:rootNode pv:self.view];
    rootNode->destory();
}

一起讨论加微信: yxb305107316

About

Simplely Dynamic DSL Layout Engine written in C++ , that is base on Antlr and Flex(Yoga) . DDSL implement a script,it's useful if you want implement a script.

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published