• G
    guluting

    main.cpp

    #include <QApplication>
    #include <QDebug>
    #include "canvas.h"
    
    int main(int argc, char *argv[])
    {
        QApplication a(argc, argv);
    
        QSurfaceFormat glFormat;
        glFormat.setVersion(3, 3);                           //  设置OpenGL版本
        glFormat.setProfile(QSurfaceFormat::CoreProfile);    // 设置使用核心模式
        QSurfaceFormat::setDefaultFormat(glFormat);
    
        Canvas *c = new Canvas();
        c->show();
    
        return a.exec();
    }
    

    Canvas.h

    #ifndef CANVAS_H
    #define CANVAS_H
    
    #include <QWidget>
    #include <QOpenGLWidget>
    #include <QOpenGLExtraFunctions>
    
    class Canvas : public QOpenGLWidget,protected QOpenGLExtraFunctions
    {
        Q_OBJECT
    public:
        explicit Canvas();
    
    signals:
    
    public slots:
    
    private:
    
    protected:
        virtual void initializeGL();
        virtual void resizeGL(int w, int h);
        virtual void paintGL();
    
    private:
        GLuint shaderProgram;
    };
    
    #endif
    

    Canvas.cpp

    #include "canvas.h"
    #include <QtDebug>
    #include <QtOpenGL>
    
    // 以下为测试代码,不推荐这么写
    // =================================
    GLuint VBO, VAO;
    const char *vertexShaderSource =
            "#version 330 core\n"
            "layout(location = 0) in vec3 aPos;\n"
            "void main(){\n"
            "  gl_Position = vec4(aPos.x, aPos.y, aPos.z, 1.0);\n"
            "}\n\0";
    const char *fragmentShaderSource =
            "#version 330 core\n"
            "out vec4 FragColor;\n"
            "void main(){\n"
            "   FragColor = vec4(1.0f, 0.5f, 0.2f, 1.0f);\n"
            "}\n\0";
    // =================================
    
    Canvas::Canvas()
    {
    
    }
    
    void Canvas::initializeGL()
    {
        //着色器部分
        this->initializeOpenGLFunctions();
        int vertexShader = glCreateShader(GL_VERTEX_SHADER);
        glShaderSource(vertexShader, 1, &vertexShaderSource, NULL);
        glCompileShader(vertexShader);
    
        int success;
        char infoLog[512];
        glGetShaderiv(vertexShader, GL_COMPILE_STATUS, &success);
        if (!success)
        {
            glGetShaderInfoLog(vertexShader, 512, NULL, infoLog);
            qDebug() << "ERROR::SHADER::VERTEX::COMPILATION_FAILED\n" << infoLog << endl;
        }
    
        int fragmentShader = glCreateShader(GL_FRAGMENT_SHADER);
    
        glShaderSource(fragmentShader, 1, &fragmentShaderSource, NULL);
        glCompileShader(fragmentShader);
    
        glGetShaderiv(fragmentShader, GL_COMPILE_STATUS, &success);
        if (!success)
        {
            glGetShaderInfoLog(fragmentShader, 512, NULL, infoLog);
            qDebug() << "ERROR::SHADER::FRAGMENT::COMPILATION_FAILED\n" << infoLog << endl;
        }
        shaderProgram = glCreateProgram();
        glAttachShader(shaderProgram, vertexShader);
        glAttachShader(shaderProgram, fragmentShader);
        glLinkProgram(shaderProgram);
    
        glGetProgramiv(shaderProgram, GL_LINK_STATUS, &success);
        if (!success) {
            glGetProgramInfoLog(shaderProgram, 512, NULL, infoLog);
            qDebug() << "ERROR::SHADER::PROGRAM::LINKING_FAILED\n" << infoLog << endl;
        }
        glDeleteShader(vertexShader);
        glDeleteShader(fragmentShader);
    
        GLfloat vertices[] = {
            -0.5f, -0.5f, 0.0f,
            0.5f, -0.5f, 0.0f,
            0.0f,  0.5f, 0.0f
        };
    
        glGenVertexArrays(1, &VAO);
        glGenBuffers(1, &VBO);
        glBindVertexArray(VAO);
        glBindBuffer(GL_ARRAY_BUFFER, VBO);
    
        glBufferData(GL_ARRAY_BUFFER, sizeof(vertices), vertices, GL_STATIC_DRAW);
        glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 3 * sizeof(GLfloat), (void*)0);
        glEnableVertexAttribArray(0);
    
        glBindBuffer(GL_ARRAY_BUFFER, 0);
        glBindVertexArray(0);
    }
    
    void Canvas::resizeGL(int width, int height)
    {
        glViewport(0, 0, width, height);
    }
    
    void Canvas::paintGL()
    {
        glClearColor(0.2f, 0.3f, 0.3f, 1.0f);
        glClear(GL_COLOR_BUFFER_BIT);
    
        glUseProgram(shaderProgram);
        glBindVertexArray(VAO);
        glDrawArrays(GL_TRIANGLES, 0, 3);
        glUseProgram(0);
    }
    

    posted in GuaiK实验室 read more
  • G
    guluting

    使用PlatformIO开发:

    1、Libraries中搜索LiquidCrystal,然后选择”By Arduino“的安装。
    2、修改platformio.ini文件(在lib_deps中添加库)

    [env:uno]
    platform = atmelavr
    board = uno
    framework = arduino
    lib_deps = 
        LiquidCrystal
    

    将Arduino与LCD的线接起来[ GND,VCC(5v),SDA,SCL ]

    0_1560937221828_WechatIMG146.jpeg

    • PS:上图中LCD背面有个蓝色的旋钮,是用来调整对比度的,如果LCD无法显示文字的话可以尝试调节该旋钮。

    DEMO

    #include <Arduino.h>
    #include <LiquidCrystal_I2C.h>
    
    LiquidCrystal_I2C lcd(0x3F, 2, 1, 0, 4, 5, 6, 7, 3, POSITIVE);
    
    void setup() {
    // 初始化LCD,每行16个字符,共两行
    lcd.begin(16, 2);
     
    // 背光闪烁三次
    for(int i = 0; i < 3; i++) {
    lcd.backlight(); 
    delay(250);
    lcd.noBacklight();
    delay(250);
    }
    lcd.backlight();
     
    lcd.setCursor(0, 0); // 设置游标:第一行第一列
    lcd.print(" Welcome Guaik ");
    delay(1000);
    lcd.setCursor(0, 1); // 设置游标:第二行第一列
    lcd.print("<bbs.guaik.org>");
    delay(3000);
    lcd.clear(); // 清除内容
    }
    void loop() {
    lcd.setCursor(0, 0); 
    lcd.print("Message:");
    lcd.setCursor(0, 1);
    lcd.print("Hello world");
    }
    

    如果无法正常工作的话,请检查I2C的设备地址,也就是LiquidCrystal_I2C lcd(0x3F, 2, 1, 0, 4, 5, 6, 7, 3, POSITIVE);的第一个参数,当前的是0x3F。


    0_1560937679044_2019-06-19 171658.gif

    posted in GuaiK实验室 read more
  • G
    guluting

    Upload错误:dyld: Library not loaded: /usr/local/opt/libftdi/lib/libftdi1.2.dylib

    解决方式:brew reinstall openocd


    设置默认项目路径:

    cd /Users/[UserName]/.platformio
    vi homestate.json
    

    找到:"projectsDir"把后面的路径设置成你的工程目录

    posted in GuaiK实验室 read more
  • G
    guluting

    拷屁一段protobuf的简介:

    Protocol buffers是一个灵活的、高效的、自动化的用于对结构化数据进行序列化的协议,与XML相比,Protocol buffers序列化后的码流更小、速度更快、操作更简单。你只需要将要被序列化的数据结构定义一次(译注:使用.proto文件定义),便可以使用特别生成的源代码(译注:使用protobuf提供的生成工具)轻松的使用不同的数据流完成对这些结构数据的读写操作,即使你使用不同的语言(译注:protobuf的跨语言支持特性)。你甚至可以更新你的数据结构的定义(译注:就是更新.proto文件内容)而不会破坏依赖“老”格式编译出来的程序。

    示例.proto文件(api.proto):

    syntax = "proto3";
    
    package gkeng.comet;
    
    option go_package = "grpc";
    
    import "github.com/gogo/protobuf/gogoproto/gogo.proto";
    
    // protocol
    message Proto {
      int32 ver = 1 [(gogoproto.jsontag) = "ver"];
      int32 op = 2 [(gogoproto.jsontag) = "op"];
      int32 seq = 3 [(gogoproto.jsontag) = "seq"];
      int32 body = 4 [(gogoproto.jsontag) = "body"];
    }
    

    生成指令(.pb.go文件)

    protoc -I=. -I=$GOPATH/src -I=$GOPATH/src/github.com/gogo/protobuf --go_out=plugins=grpc:. ./api.proto

    • 通过-I引入了当前目录、Golang的源码目录和github.com/gogo/protobuf

    • 列表--go_out=plugins=grpc:.:在执行时添加grpc的plugin

    • 列表指定的./api.proto就是我们编写的数据结构文件


    .proto 描述文件的编写说明这里就不写了

    posted in GuaiK实验室 read more
  • G
    guluting

    Reader分析


    数据结构

    type Reader struct {
        rd   io.Reader     // 被读取的io缓存,可以是网络的或文件的
        buf  []byte        // 缓冲区,用于给rd当缓存使用
        r, w int           // 读写游标,用来管理buf字段的
        err  error         // 存储当前Reader的异常值
    }
    

    常量分析

    const defaultBufSize = 4096   // 针对Reader中的buf字段,默认缓冲区大小(byte)
    const minReadBufferSize = 16  // 在初始化Reader结构的时候,能够设置的最小的缓冲区大小
    const maxConsecutiveEmptyReads = 100  // 从rd中读取数据无数据(fill操作)返回时(n==0)时,最多的读取次数
    

    函数分析
    func (b *Reader) fill();

    1、缓存对齐,如果读游标不在缓存的起始位置,则将可读数据对齐到起始位置copy(buf,buf[r:w])
    2、经过对齐后,如果w的游标超出了缓冲区的长度,则抛出一次异常
    3、尝试maxConsecutiveEmptyReads次从rd中读取数据到buf中,直到出现异常或者成功的读到数据到buf中了返回,如果超出了尝试次数则设置err为io.ErrNoProgress


    白色:空闲内存,可写入数据
    绿色:已写入内存,可读取数据
    灰色:已读取内存,可回收(fill函数在填充数据的同时会处理回收)
    0_1558596290334_未命名.png

    图中初始时有10个空闲块,R和W都指向下标0处。
    向内存中写入了5Byte的数据,这时候R在下标0处,W指向了下标5,这时候的可读数据为W-R=5Byte。
    读取了3Byte的数据,这时候R指向下标3,可读数据为W-R = 2,可回收空间为R。
    回收已读数据copy(buf,buf[r:w]),将R到W区间的数据平移至buf下标为0的位置。

    posted in GuaiK实验室 read more
  • G
    guluting

    看了Go语言的书后发现它有切片和map类型,但是没有Set类型,那么这时候如果需要用到Set类型如何实现呢?
    借助map和struct就可以很轻易的实现,利用两个特点:
    1、map的key是不会重复的
    2、struct{}是占用0内存空间的


    // 先定义map类型,key为int32,value为struct{}
    var mySet map[int32]struct{}
    // 使用make为map分配内存并初始化
    mySet = make(map[int32]struct{})
    // 使用mySet
    mySet[0] = struct{}{}
    mySet[100] = struct{}{} 
    

    struct{}{}的定义

     struct{}  {}
    |  ^     | ^
      type     empty element list
    

    posted in GuaiK实验室 read more
  • G
    guluting

    刚入门Golang语言的新手而言,gopath简直是一个奇葩的存在,因为你有两个做法可以去创建一个Go的项目:

    第一种:你随便找个目录建立一个工程,然后需要在环境变量中配置gopath的路径。
    第二种:直接把工程建立在现有的gopath的目录下。
    这几种方式确实有点恶心到我了。


    BUT

    我在看开源项目的时候发现了一个好东西,我分析了项目根目录有一个叫"go.mod"的文件,你那么这是干嘛的呢,通过强大的Google搜索了一下,那么下面就记录一下结果吧,废话很少,很精简,自己测试即可:

    生成go.mod的方式:(假设项目根目录叫:“guaik”)

    cd ./guaik
    go mod init guaik
    

    最后的"guaik"名字可以随便更换,这时候目录下就会出现一个go.mod的文件,那么其实这样就完事了。很简单

    之后如果要引用当前项目的包(在guaik目录中年有一个http的包)可以使用以下方式:

    import (
    "guaik/http"
    )
    

    posted in GuaiK实验室 read more
  • G
    guluting

    1、进入flutter的services目录
    cd flutter/packages/flutter/lib/src/services


    2、修改text_input.dart文件的TextInputConnection类的show方法,将以下代码注释掉
    SystemChannels.textInput.invokeMethod<void>('TextInput.show');

      /// Requests that the text input control become visible.
      void show() {
        assert(attached);
        // SystemChannels.textInput.invokeMethod<void>('TextInput.show');
      }
    

    3、重新编译下工程即可

    posted in GuaiK实验室 read more
  • G
    guluting

    • Close Xcode
    • Open Keychain
    • Remove “Iphone Developer” and “Apple Worldwide Developer Relations Certification Authority”
    • Reopen Xcode
    • Product / Run the project again with debug executable checked (Succeed)
    • Close Xcode
    • Open vscode
    • Debug / Start debugging
    • It built and run on physical device successfully

    posted in GuaiK实验室 read more
  • G
    guluting

    sudo vi /etc/bashrc

    #PS1='\h:\W \u\$ '
    PS1='\W \$ '
    

    posted in GuaiK实验室 read more
  • G
    guluting

        AnimationController _panelAnimationController;
        _panelAnimationController = new AnimationController(
          vsync: this,
          duration: new Duration(milliseconds: 300),
        );
        Animation<double> animation =
            new Tween(begin: 300.0, end: 0.0).animate(_panelAnimationController);
        animation.addStatusListener((status) {
          if (status == AnimationStatus.completed) {
            //动画执行结束时反向执行动画
            _panelAnimationController.reverse();
          } else if (status == AnimationStatus.dismissed) {
            //动画恢复到初始状态时执行动画(正向)
            _panelAnimationController.forward();
          }
        });
        animation.addListener(() {
          print(animation.value);
        });
        _panelAnimationController.forward();
    

    posted in GuaiK实验室 read more
  • G
    guluting

    下载地址:
    http://waon.sourceforge.net/#download


    依赖库安装:(Mac OS)

    brew install fftw
    brew install libsndfile
    

    编译:

    make --makefile=Makefile.waon
    

    posted in GuaiK实验室 read more
  • G
    guluting

    CMake是一个很便捷的跨平台编译工具,只要把目录结构排版好,写一个CMakeLists.txt告诉CMake怎么去生成makefile就ok了。


    基本用法

    # 目录结构
    -/ *(根目录)
    |-CMakeLists.txt
    |-main.cpp
    |-ios.toolchain.cmake *(可选项,用来编译ios项目用,下面会提供下载地址)
    |-build *(用来存放编译后可执行文件的目录)
    |-library *(用来存放编译后生成静态库的目录)
    |-utils *(utils静态库源码目录)
        |-CMakeLists.txt
        |-utils.cpp
        |-mem.cpp
        |-utils.h
        |-mem.cpp
    

    根目录中的CMakeLists.txt

    # 项目名称
    project(ANLib)
    # 设置CMake最小版本
    cmake_minimum_required(VERSION 2.8)
    set(CMAKE_MACOSX_RPATH 0)
    # 代码路径
    aux_source_directory(. test_src)
    #设置编译器
    set(CMAKE_CXX_COMPILER "g++")
    #设置构建类型,及相应的编译选项
    set(CMAKE_BUILD_TYPE "Release")
    set(CMAKE_CXX_FLAGS_DEBUG "$ENV{CXXFLAGS} -O0 -Wall -g -ggdb -m64")
    set(CMAKE_CXX_FLAGS_RELEASE "$ENV{CXXFLAGS} -O3 -Wall -m64")
    
    #设置执行文件输出目录
    set(EXECUTABLE_OUTPUT_PATH ${PROJECT_SOURCE_DIR}/build)
    #设置库输出路径
    set(LIBRARY_OUTPUT_PATH ${PROJECT_SOURCE_DIR}/library)
    
    #设置utils库源码路径
    set(utils_dir ./utils)
    add_subdirectory(${utils_dir})
    include_directories(${utils_dir})
    
    link_directories(${PROJECT_SOURCE_DIR}/library)
    
    # 生成可执行的文件
    add_executable(test ${test_src})
    target_link_libraries(test utils)
    
    

    utils目录中的CMakeLists.txt

    set(LIBRARY_OUTPUT_PATH ${PROJECT_SOURCE_DIR}/library)
    aux_source_directory(. dir_srcs)
    add_library(utils STATIC ${dir_srcs})
    target_link_libraries(utils)
    

    开始使用Cmake

    切换到根目录中,编译项目:

    cmake .
    make
    

    在mac中使用cmake编译ios的静态库:(需要mac os系统)

    clone以下项目,让后将’ios.toolchain.cmake’放到根目录中(以下链接选一个下载)
    https://code.google.com/archive/p/ios-cmake/downloads
    https://github.com/leetal/ios-cmake

    切换到根目录中,编译项目:

    cmake . -DCMAKE_TOOLCHAIN_FILE=./ios.toolchain.cmake -DIOS_PLATFORM=SIMULATOR64
    make
    

    相关选项说明:

    Set -DIOS_PLATFORM to "SIMULATOR" to build for iOS simulator 32 bit (i386) DEPRECATED
    Set -DIOS_PLATFORM to "SIMULATOR64" (example above) to build for iOS simulator 64 bit (x86_64)
    Set -DIOS_PLATFORM to "OS" to build for Device (armv7, armv7s, arm64, arm64e)
    Set -DIOS_PLATFORM to "OS64" to build for Device (arm64, arm64e)
    Set -DIOS_PLATFORM to "TVOS" to build for tvOS (arm64)
    Set -DIOS_PLATFORM to "SIMULATOR_TVOS" to build for tvOS Simulator (x86_64)
    Set -DIOS_PLATFORM to "WATCHOS" to build for watchOS (armv7k, arm64_32)
    Set -DIOS_PLATFORM to "SIMULATOR_WATCHOS" to build for watchOS Simulator (x86_64)
    

    posted in GuaiK实验室 read more
  • G
    guluting

    import 'package:flutter/services.dart';
    
    void main() {
      // 强制竖屏
      SystemChrome.setPreferredOrientations([DeviceOrientation.portraitUp])
          .then((_) {
        runApp(MainApp());
      });
    }
    

    posted in GuaiK实验室 read more
  • G
    guluting

    使用Gitlab内置的Nginx服务

    1、去官网下载最新版的Gitlab软件,根据操作系统选择:(我的是CentOS7,选择rpm x64安装包)
    https://packages.gitlab.com/gitlab/gitlab-ce

    wget https://packages.gitlab.com/gitlab/gitlab-ce/packages/el/7/gitlab-ce-11.7.5-ce.0.el7.x86_64.rpm
    

    2、安装依赖包和相关配置

    sudo yum install -y curl policycoreutils-python openssh-server
    sudo yum install postfix
    sudo systemctl enable postfix
    sudo systemctl start postfix
    sudo systemctl enable sshd
    sudo systemctl start sshd
    sudo firewall-cmd --zone=public --add-port=8080/tcp --permanent  
    sudo firewall-cmd --zone=public --add-port=8081/tcp --permanent  
    sudo firewall-cmd --reload
    

    3、安装Gitlab

    rpm -i gitlab-ce-11.7.5-ce.0.el7.x86_64.rpm
    

    4、配置Gitlab,监听8080端口

    vi /etc/gitlab/gitlab.rb
    #=======================
    # 修改external_url,修改成你服务器的ip地址,如:external_url 'http://192.168.1.xxx'
    # 查找所有8080端口,共3个,全部改成8081
    # 查找nginx['listen_port'],将Nginx监听端口修改成8080
    

    5、重启Gitlab服务器

    sudo gitlab-ctl reconfigure
    sudo gitlab-ctl restart
    

    6、用浏览器访问:
    http://192.168.1.xxx:8080

    可能出现问题的解决方案:

    安装过程中卡死不动,强制终止后运行下面指令

    sudo systemctl restart gitlab-runsvdir
    sudo gitlab-ctl reconfigure
    sudo gitlab-ctl restart
    

    网络错误日志调试

    gitlab-ctl tail
    

    posted in GuaiK机房 read more
  • G
    guluting

    Debug:
    flutter run --debug

    Release:
    flutter run --release --no-track-widget-creation

    posted in GuaiK实验室 read more
  • G
    guluting

    启动容器命令:docker start d21a

    报错

    Error response from daemon: devmapper: Error mounting '/dev/mapper/docker-253:3-537354454-cdb4e31a34f55981f2cabe775700719ecc20bfdc6b85c1b26245b41026daa8fe' on '/var/lib/docker/devicemapper/mnt/cdb4e31a34f55981f2cabe775700719ecc20bfdc6b85c1b26245b41026daa8fe': invalid argument
    

    解决方式:
    /var/lib/docker/containers/d21a*目录中找到config.v2.json,然后vi config.v2.json
    找到MountLabelProcessLabel个键,并把其对应的引号中的内容清空即可

    posted in GuaiK机房 read more
  • G
    guluting

    一、安装及测试

    1、安装

    useradd -s /sbin/nologin -d /opt/minio minio
    mkdir -p /opt/minio/bin
    mkdir /opt/minio/data
    wget https://dl.minio.io/server/minio/release/linux-amd64/minio -O /opt/minio/bin/minio
    chmod +x /opt/minio/bin/minio
    chown -R minio:minio /opt/minio
    

    2、添加配置文件

    vi /opt/minio/minio.conf

    MINIO_VOLUMES=/opt/minio/data
    MINIO_OPTS="--address :9090"
    MINIO_ACCESS_KEY=[YOUR_ACCESS_KEY]
    MINIO_SECRET_KEY=[YOUR_SECRET_KEY]
    

    3、添加系统服务

    vi /etc/systemd/system/minio.service

    [Unit]
    Description=Minio
    Documentation=https://docs.minio.io
    Wants=network-online.target
    After=network-online.target
    AssertFileIsExecutable=/opt/minio/bin/minio
    
    [Service]
    WorkingDirectory=/opt/minio
    
    User=minio
    Group=minio
    
    PermissionsStartOnly=true
    
    EnvironmentFile=-/opt/minio/minio.conf
    ExecStartPre=/bin/bash -c "[ -n \"${MINIO_VOLUMES}\" ] || echo \"Variable MINIO_VOLUMES not set in /opt/minio/minio.conf\""
    
    ExecStart=/opt/minio/bin/minio server $MINIO_OPTS $MINIO_VOLUMES
    
    StandardOutput=journal
    StandardError=inherit
    
    # Specifies the maximum file descriptor number that can be opened by this process
    LimitNOFILE=65536
    
    # Disable timeout logic and wait until process is stopped
    TimeoutStopSec=0
    
    # SIGTERM signal is used to stop Minio
    KillSignal=SIGTERM
    
    SendSIGKILL=no
    
    SuccessExitStatus=0
    
    [Install]
    WantedBy=multi-user.target
    

    4、启动Minio服务

    systemctl enable minio
    systemctl start minio
    systemctl status minio
    

    PS:默认minio的监听端口是:9000,我在配置文件中改成了9090,所以可以通过:
    http://host:9090访问minio后台。

    posted in GuaiK机房 read more
  • G
    guluting

    如果是Key-Vlue类型的数据(dict,map)相关的,你默认它遍历的顺序是随机的就好啦,它们本身就是无序的;有序的话主要还是List。

    posted in GuaiK实验室 read more