WhiteBoardApe.js 16.3 KB
// //////////////////////////////////////////////////////////////////////////////
//
//  Copyright (C) 2016-present  All Rights Reserved.
//  Licensed under the Apache License, Version 2.0 (the "License");
//  http://www.apache.org/licenses/LICENSE-2.0
//
//  Github Home: https://github.com/AlexWang1987
//  Author: AlexWang
//  Date: 2016-08-26 17:36:20
//  QQ Email: 1669499355@qq.com
//  Last Modified time: 2016-09-21 14:06:12
//  Description: LiveClass-WhiteBoardApe
//
// //////////////////////////////////////////////////////////////////////////////

import Ape from './Ape';
import ApeConsts from './ApeConsts';
import pdu from 'pdus';
import Loger from 'Loger';
import MessageTypes from 'MessageTypes';
import { Zlib } from 'zlibjs/bin/zlib.min';
import UTF8 from 'utf-8';
import GlobalConfig from 'GlobalConfig';
import EngineUtils from 'EngineUtils';

let loger = Loger.getLoger('WhiteBoardApe');

let itemIdx=0;//table插入新数据的计数id,目前用时间戳
const TYPE_BIGHT=0;//任意线段
const TYPE_LINE=1;//直线
const TYPE_RECT=2;//矩形
const TYPE_CIRCLE=3;//圆形
const TYPE_TEXT=4;//文本

class WhiteBoardApe extends Ape {
    constructor() {
        super(
            ApeConsts.WHITEBOARD_SESSION_ID,
            ApeConsts.WHITEBOARD_SESSION_NAME,
            ApeConsts.WHITEBOARD_SESSION_TAG
        );
        // properties
        this.annoInfos = {};//储存所有的标注数据
        this.insertHistory=[];//添加的白板记录,用于撤回操作
        // 白板延迟
        // this._apeDelayed = true;

        //Ape Models
        this.registerKey(this._session_id, this._session_name, this._session_tag, new ArrayBuffer);
        this.registerObj(pdu.RCPDU_REG_REGISTER_TABLE, ApeConsts.WHITEBOARD_OBJ_TABLE_ID,
            ApeConsts.WHITEBOARD_OBJ_TABLE_NAME, ApeConsts.WHITEBOARD_OBJ_TABLE_TAG, 0, new ArrayBuffer);

        // ape listeners
        this.on(pdu.RCPDU_SESSION_JOIN_RESPONSE, this._joinSessionHandler.bind(this));
        //this.on(pdu.RCPDU_CONFERENCE_SEND_DATA_REQUEST, this.whiteboardMsgComingHandler.bind(this));//这个是会议消息类型,flash里在使用这里不再使用,各个模块的消息由模块自己来处理
    }

    _joinSessionHandler(_data) {
        loger.log("RCPDU_SESSION_JOIN_RESPONSE");
        this.insertHistory=[];
    }

    /////////////发送数据操作//////////////////////////////////////////////////////
    // 添加标注,发送信息
    sendInsetAnnotaion(_param){
        if(_param==null||EngineUtils.isEmptyObject(_param)){
            loger.log('sendInsetAnnotaion失败,参数错误');
            this._emit(MessageTypes.MCU_ERROR,MessageTypes.ERR_APE_INTERFACE_PARAM_WRONG);
            return ;
        }

        itemIdx=EngineUtils.creatTimestamp();
        let whiteBoardModelPdu = this.packPdu(_param,itemIdx);
        if(whiteBoardModelPdu==null){
            loger.log('sendInsetAnnotaion失败,参数错误');
            this._emit(MessageTypes.MCU_ERROR,MessageTypes.ERR_APE_INTERFACE_PARAM_WRONG);
            return ;
        }
        //console.log(whiteBoardModelPdu);

        //储存记录,用于返回上一步操作
        this.insertHistory.push(whiteBoardModelPdu);

        let tableItemPdu = new pdu['RCRegistryTableItemPdu'];
        tableItemPdu.itemIdx=itemIdx;//直接用时间戳作为id
        tableItemPdu.registerObjId=ApeConsts.WHITEBOARD_OBJ_TABLE_ID;
        tableItemPdu.owner = 0;//收到flash的是这个值,不清楚先写固定
        tableItemPdu.itemData =whiteBoardModelPdu.toArrayBuffer();

        //insert
        let tableInsertItemPdu = new pdu['RCRegistryTableInsertItemPdu'];
        //optional RCPduType_E type = 1 [default = RCPDU_REG_TABLE_UPDATE_PDU];
        //repeated RCRegistryTableItemPdu items = 2;
        tableInsertItemPdu.type = pdu.RCPDU_REG_TABLE_INSERT_PDU;//
        tableInsertItemPdu.items.push(tableItemPdu);

        let updateObjPdu = new pdu['RCRegistryUpdateObjPdu'];
        updateObjPdu.objId = ApeConsts.WHITEBOARD_OBJ_TABLE_ID;
        updateObjPdu.subType = tableInsertItemPdu.type;
        updateObjPdu.userData = tableInsertItemPdu.toArrayBuffer();

        //同步
        let adapterItemPdu = new pdu['RCAdapterItemPdu'];
        adapterItemPdu.type = pdu.RCPDU_REG_UPDATE_OBJ;
        adapterItemPdu.itemData = updateObjPdu.toArrayBuffer();

        let adapterPdu = new pdu['RCAdapterPdu'];
        adapterPdu.type = pdu.RCPDU_REG_ADAPTER;
        adapterPdu.item.push(adapterItemPdu);

        console.log("添加白板数据=====itemIdx="+tableItemPdu.itemIdx);
        this.sendUniform(adapterPdu,true);
    }
    //撤销上一步
    sendGotoPrev(){
        loger.log("白板返回上一步");
        if(this.insertHistory==null||this.insertHistory.length<1){
            loger.warn("无法继续上一步操作,已经没有可以撤销的数据");
            return;
        }
        console.log(this.insertHistory);
        this.sendDeleteAnnotaion(this.insertHistory.pop());
    }
    //删除当前页码的所有标注
    sendDeleteCurPageAnnotation(_param){
        for (let key in this.annoInfos){
            let item=this.annoInfos[key];
            if(item&&item.parentId==GlobalConfig.activeDocId&&item.curPageNo==GlobalConfig.activeDocCurPage){
                loger.log("sendDeleteCurPageAnnotation 删除当前页面上的标注",key);
                this.sendDeleteAnnotaion({"itemIdx":key});
            }
        }
    }
    //删除所有标注
    sendDeleteAllAnnotation(_param){
        for (let key in this.annoInfos){
            this.sendDeleteAnnotaion({"itemIdx":key});
        }
    }

    //删除标注,发送信息
    sendDeleteAnnotaion(_param){
        if(_param==null){
            loger.warn("要删除的数据不存在");
            return;
        }
        //{"itemIdx":itemIdx}
        let tableDeleteItemPdu = new pdu['RCRegistryTableDeleteItemPdu'];
        //optional RCPduType_E type = 1 [default = RCPDU_REG_TABLE_DELETE_PDU];
        // repeated uint32 item_idx = 2;
        tableDeleteItemPdu.type = pdu.RCPDU_REG_TABLE_DELETE_PDU;//
        tableDeleteItemPdu.itemIdx=parseInt(_param.itemIdx);//这里需要设置要删除的数据的itemIdx,每条数据的这个id都不一样

        let updateObjPdu = new pdu['RCRegistryUpdateObjPdu'];
        updateObjPdu.objId = ApeConsts.WHITEBOARD_OBJ_TABLE_ID;
        updateObjPdu.subType = tableDeleteItemPdu.type;
        updateObjPdu.userData = tableDeleteItemPdu.toArrayBuffer();

        //同步
        let adapterItemPdu = new pdu['RCAdapterItemPdu'];
        adapterItemPdu.type = pdu.RCPDU_REG_UPDATE_OBJ;
        adapterItemPdu.itemData = updateObjPdu.toArrayBuffer();

        let adapterPdu = new pdu['RCAdapterPdu'];
        adapterPdu.type = pdu.RCPDU_REG_ADAPTER;
        adapterPdu.item.push(adapterItemPdu);

        console.log("白板发送删除数据============="+tableDeleteItemPdu.itemIdx);
        this.sendUniform(adapterPdu,true);
    }


    //更新标注
    sendUpdaterAnnotaion(_param){
        if(_param==null||EngineUtils.isEmptyObject(_param)){
            loger.log('sendUpdaterAnnotaion失败,参数错误');
            this._emit(MessageTypes.MCU_ERROR,MessageTypes.ERR_APE_INTERFACE_PARAM_WRONG);
            return ;
        }
        itemIdx=_param.itemIdx;
        let whiteBoardModelPdu = this.packPdu(_param,itemIdx);
        //console.log(whiteBoardModelPdu);

        if(whiteBoardModelPdu==null){
            loger.log('sendInsetAnnotaion失败,参数错误');
            this._emit(MessageTypes.MCU_ERROR,MessageTypes.ERR_APE_INTERFACE_PARAM_WRONG);
            return ;
        }

        let tableItemPdu = new pdu['RCRegistryTableItemPdu'];
        tableItemPdu.itemIdx=itemIdx;
        tableItemPdu.owner = 0;//收到flash的是这个值,不清楚先写固定
        tableItemPdu.registerObjId=ApeConsts.WHITEBOARD_OBJ_TABLE_ID;
        tableItemPdu.itemData =whiteBoardModelPdu.toArrayBuffer();


        //updater
        let whiteBoardUpdateItem = new pdu['RCRegistryTableUpdateItemPdu'];
        //optional RCPduType_E type = 1 [default = RCPDU_REG_TABLE_UPDATE_PDU];
        //repeated RCRegistryTableItemPdu items = 2;
        whiteBoardUpdateItem.type = pdu.RCPDU_REG_TABLE_UPDATE_PDU;//
        whiteBoardUpdateItem.items.push(tableItemPdu);


        let updateObjPdu = new pdu['RCRegistryUpdateObjPdu'];
        updateObjPdu.objId = ApeConsts.WHITEBOARD_OBJ_TABLE_ID;
        updateObjPdu.subType = whiteBoardUpdateItem.type;
        updateObjPdu.userData = whiteBoardUpdateItem.toArrayBuffer();

        //同步
        let adapterItemPdu = new pdu['RCAdapterItemPdu'];
        adapterItemPdu.type = pdu.RCPDU_REG_UPDATE_OBJ;
        adapterItemPdu.itemData = updateObjPdu.toArrayBuffer();

        let adapterPdu = new pdu['RCAdapterPdu'];
        adapterPdu.type = pdu.RCPDU_REG_ADAPTER;
        adapterPdu.item.push(adapterItemPdu);

        console.log("白板发送更新数据===============22");
        this.sendUniform(adapterPdu,true);
    }

    /////收到消息处理/////////////////////////////////////////////////////////////////////////////////
    /*  whiteboardMsgComingHandler(_data) {
     //flash    RCConferenceSendDataRequestPdu
     //loger.warn('whiteboardMsgComingHandler needs to be handled.');
     //const recordInfo = pdu['RCWhiteboardDataRequestPdu'].decode(pdu);
     //loger.log("whiteboardMsgComingHandler",recordInfo);

     let receiveInfo = pdu['RCConferenceSendDataRequestPdu'].decode(_data);
     loger.log("whiteboardMsgComingHandler",receiveInfo);
     }*/

    tableInsertHandler(owner, itemIdx,itemData) {
        let whiteBoardModel=this.unPackPdu(owner, itemIdx,itemData);
        loger.log('tableInsertHandler');
        console.log(whiteBoardModel);
        if(whiteBoardModel){
            if(GlobalConfig.activeDocId==whiteBoardModel.parentId&&GlobalConfig.activeDocCurPage==whiteBoardModel.curPageNo){
                loger.log('WHITEBOARD_ANNOTAION_INSERT 显示到界面上',whiteBoardModel);
                //this._emit(MessageTypes.WHITEBOARD_ANNOTAION_INSERT,whiteBoardModel);
                this.insertAandShowAnnotaion(whiteBoardModel);
            }
        }
    }
    tableUpdateHandler(owner, itemIdx, itemData) {
        let whiteBoardModel=this.unPackPdu(owner, itemIdx,itemData);
        loger.log('tableUpdateHandler');
        console.log(whiteBoardModel);
        if(whiteBoardModel&&whiteBoardModel.parentId==GlobalConfig.activeDocId&&whiteBoardModel.curPageNo==GlobalConfig.activeDocCurPage){
            this.updateAandShowAnnotaion();
        }
    }
    tableDeleteHandler(object_id, tableDeleteData){
        // console.log("白板收到数据,tableDeleteHandler  object_id="+object_id);//((18<< 16) + 1)=1179649
        loger.log('tableDeleteHandler',object_id,tableDeleteData);//["tableDeleteHandler",1179649,{"type":231,"itemIdx":[1486301768]}]
        if(tableDeleteData&&tableDeleteData.itemIdx){
            let len=tableDeleteData.itemIdx.length;
            let itemIdxs=tableDeleteData.itemIdx;
            for (let i=0;i<len;i++){
                if(this.annoInfos[itemIdxs[i]]){
                    loger.log("删除白板数据:",itemIdxs[i]);
                    //this._emit(MessageTypes.WHITEBOARD_ANNOTAION_DELETE,{ "itemIdx":itemIdxs[i]});
                    delete this.annoInfos[itemIdxs[i]];
                }
            }
        }
        this.updateAandShowAnnotaion();
    }
    //文档更新,白板也要更新
    docUpdateHandler(_data){
        loger.log("白板收到文档更新的消息docUpdateHandler");
        console.log(_data);

        //如果切换了文档或翻页,清除之前的添加步骤记录
        if(_data.action==ApeConsts.DOC_ACTION_SWITCH_DOC){
            this.insertHistory=[];
        }
        this.updateAandShowAnnotaion();
    }
    //删除白板数据
    docDeleteHandler(_parentId){
        loger.log("白板收到文档删除的消息docDeleteHandler",_parentId);
        for (let key in this.annoInfos){
            let item=this.annoInfos[key];
            if(item&&item.parentId==_parentId){
                loger.log("文档删除,白板数据也删除,itemIdx:"+key,"_parentId:",_parentId);
                this.sendDeleteAnnotaion({"itemIdx":key});
            }
        }
    }
    //增量添加标注
    insertAandShowAnnotaion(_item){
        let annotaionItems=[_item];
        var updateObj={
            "isFresh":false,
            "annotaionItems":annotaionItems
        };
        loger.log("WHITEBOARD_ANNOTATION_UPDATE",annotaionItems.length);
        this._emit(MessageTypes.WHITEBOARD_ANNOTATION_UPDATE,updateObj);
    }
    //整体更新并且显示标注
    updateAandShowAnnotaion(){
        let annotaionItems=[];
        for (let key in this.annoInfos){
            let item=this.annoInfos[key];
            if(item&&item.parentId==GlobalConfig.activeDocId&&item.curPageNo==GlobalConfig.activeDocCurPage){
                annotaionItems.push(item);
                loger.log("显示和文档对应的白板数据docUpdateHandler itemIdx:",item.itemIdx,"doc itemIdx:",GlobalConfig.activeDocId,"curPageNo:",GlobalConfig.activeDocCurPage);
            }else{
                //loger.log("不显示白板数据docUpdateHandler",item);
            }
        }
        var updateObj={
            "isFresh":true,
            "annotaionItems":annotaionItems
        };
        loger.log("WHITEBOARD_ANNOTATION_UPDATE",annotaionItems.length);
        this._emit(MessageTypes.WHITEBOARD_ANNOTATION_UPDATE,updateObj);
    }

    ///////白板数据的封包和解包/////////////////////////////////////////
    packPdu(_param,_itemIdx){
        /* required uint32 type= 1;//白板类型
         required uint32 id= 2;//id 每一次绘制的唯一标识
         required uint32 initiator=3; //绘制来自谁
         optional string pointGroup=4; //坐标点集数组的JSON字符串
         optional string color= 5  [default = "#000000"]; //颜色
         optional uint32 thickness= 6 ;//线条粗细
         optional uint32 radius= 7;//园的半径
         optional uint32 fontSize= 8;//字体大小
         optional uint32 fontName= 9;//字体名称
         optional uint32 text= 10;//文本内容*/

        //验证坐标点集合数组是否合法
        if(_param.pointGroup==null||_param.pointGroup.length<1){
            this._emit(MessageTypes.MCU_ERROR,MessageTypes.ERR_APE_INTERFACE_PARAM_WRONG);
            return null;
        }
        //判断type类型,根据type设置不同的参数
        let whiteBoardModelPdu =new pdu['RCWhiteBoardDataModelPdu'];
        switch (_param.type){
            case TYPE_BIGHT:
                break;
            case TYPE_LINE:
                break;
            case TYPE_RECT:
                break;
            case TYPE_CIRCLE:
                whiteBoardModelPdu.radius=parseInt(_param.radius);
                break;
            case TYPE_TEXT:
                whiteBoardModelPdu.fontSize=parseInt(_param.fontSize);
                whiteBoardModelPdu.fontName=_param.fontName||null;
                whiteBoardModelPdu.text=_param.text||null;
                break;
            default:
                //其它类型不做处理
                return null;
                break;
        }
        //下面4个是必须的参数
        whiteBoardModelPdu.type =_param.type;
        whiteBoardModelPdu.itemIdx =_itemIdx;
        whiteBoardModelPdu.initiator =GlobalConfig.nodeId;

        /* whiteBoardModelPdu.parentId=_param.parentId||0;
         whiteBoardModelPdu.curPage=_param.curPage||1;*/

        whiteBoardModelPdu.parentId=GlobalConfig.activeDocId;//当前激活的文档id
        whiteBoardModelPdu.curPageNo=GlobalConfig.activeDocCurPage;//当前激活的文档页码

        whiteBoardModelPdu.pointGroup =EngineUtils.arrayToJsonString(_param.pointGroup);
        whiteBoardModelPdu.color=_param.color||"#000000";

        return whiteBoardModelPdu;
    }
    unPackPdu(owner, itemIdx,itemData){
        try{
            loger.log("白板收到数据===unPackPdu ");
            let whiteBoardModelPdu= pdu['RCWhiteBoardDataModelPdu'].decode(itemData);
            //console.log(whiteBoardModelPdu);
            //loger.log(whiteBoardModelPdu);
            let _pointGroup= EngineUtils.arrayFromJsonString(whiteBoardModelPdu.pointGroup);
            whiteBoardModelPdu.pointGroup=_pointGroup;
            this.annoInfos[itemIdx] = whiteBoardModelPdu;
            return whiteBoardModelPdu;
        }catch (err){
            console.log("unPackPdu Pdu解析错误,itemIdx="+itemIdx+"  err:"+err.message);
        }
        return null;
    }

}

export default WhiteBoardApe;