예제 #1
0
        private unsafe void _PostResponseImpl(long pctx, MessageBuff *messageBuff)
        {
            int header_len    = TrinityProtocol.MsgHeader + sizeof(int) + sizeof(int) + sizeof(long);
            int socket_header = header_len + (int)messageBuff->Length - TrinityProtocol.SocketMsgHeader;

            byte * buf   = stackalloc byte[header_len];
            byte **bufs  = stackalloc byte *[2];
            int *  sizes = stackalloc int[2];

            sizes[0] = header_len;
            sizes[1] = (int)messageBuff->Length;
            bufs[0]  = buf;
            bufs[1]  = messageBuff->Buffer;

            PointerHelper sp = PointerHelper.New(buf);

            *sp.ip = socket_header;
            *(TrinityMessageType *)(sp.bp + TrinityProtocol.MsgTypeOffset) = TrinityMessageType.SYNC;
            *(ushort *)(sp.bp + TrinityProtocol.MsgIdOffset) = (ushort)TSL.CommunicationModule.TrinityClientModule.SynReqMessageType.PostResponse;
            sp.bp += TrinityProtocol.MsgHeader;
            *sp.ip++ = m_id;
            *sp.ip++ = m_cookie;
            *sp.lp++ = pctx;
            m_mod.SendMessage(m_client, bufs, sizes, 2);
        }
예제 #2
0
        private unsafe void RedirectMessageWithResponse_impl(SynReqRspArgs args)
        {
            /******************************
            * Protocol: RedirectMessage
            * Request: |4B PartitionId| TrinityMessage |
            * Response: | TrinityResponse |
            *
            * Redirects the message to another instance.
            ******************************/

            PointerHelper sp          = PointerHelper.New(args.Buffer + args.Offset);
            int           partitionId = *sp.ip++;

            TrinityMessage tm = new TrinityMessage(sp.bp, (*sp.ip) + TrinityProtocol.SocketMsgHeader);

            m_memorycloud[partitionId].SendMessage(tm, out var rsp);

            int   rsp_size = TrinityProtocol.MsgHeader + rsp.Size;
            byte *rsp_buf  = (byte *)Memory.malloc((ulong)rsp_size);

            *(int *)rsp_buf = rsp_size - TrinityProtocol.SocketMsgHeader;
            Memory.Copy(rsp.Buffer, rsp.Offset, rsp_buf, TrinityProtocol.MsgHeader, rsp.Size);
            rsp.Dispose();

            args.Response = new TrinityMessage(rsp_buf, rsp_size);
        }
예제 #3
0
        private unsafe void LoadCell_impl(SynReqRspArgs args)
        {
            /******************************
            * Protocol: LoadCell
            * Request: |8B CellId|
            * Response: [ 4B TrinityErrorCode header ] -- if success --> | 4B Size|2B CellType| Payload |
            ******************************/
            var id  = *(long *)(args.Buffer + args.Offset);
            var err = m_memorycloud.LoadCell(id, out var cellBuff, out var cellType);

            if (err == TrinityErrorCode.E_SUCCESS)
            {
                var len  = TrinityProtocol.MsgHeader + sizeof(int) + cellBuff.Length + sizeof(ushort);
                var buf  = (byte *)Memory.malloc((ulong)len);
                var sp   = PointerHelper.New(buf);
                *sp.ip++ = len - TrinityProtocol.SocketMsgHeader;
                *sp.ip++ = (int)err;
                *sp.ip++ = cellBuff.Length;
                *sp.sp++ = (short)cellType;
                fixed(byte *p = cellBuff)
                {
                    Memory.memcpy(sp.bp, p, (ulong)cellBuff.Length);
                }

                args.Response = new TrinityMessage(buf, len);
            }
            else
            {
                var buf  = (byte *)Memory.malloc(TrinityProtocol.MsgHeader);
                var sp   = PointerHelper.New(buf);
                *sp.ip++ = TrinityProtocol.MsgHeader - TrinityProtocol.SocketMsgHeader;
                *sp.ip   = (int)err;
                args.Response = new TrinityMessage(buf, TrinityProtocol.MsgHeader);
            }
        }
예제 #4
0
 public byte[] ToByteArray()
 {
     mRawData[0] = (byte)DataType;
     PointerHelper.CopyTo(DataLength, mRawData, 1);
     PointerHelper.CopyTo(Timestamp, mRawData, 9);
     return(mRawData);
 }
예제 #5
0
        private unsafe void PollEvents_impl(SynReqRspArgs args)
        {
            /******************************
            * Protocol: PollEvents
            * Request: |4B InstanceId|4B Cookie|
            * Response:[4B E_RESULT Header] - |8B p| TrinityMessage |
            * Response.p != 0 if the response is a "request with response"
            * Response.TrinityMessage length header < 0 if there are no events
            * E_RESULT values:
            *
            *      0 = E_SUCCESS
            *      1 = E_NO_EVENTS
            *      2 = E_INVALID_CLIENT
            *
            * !NOTE Here, response itself is a TrinityMessage and Response.TrinityMessage
            * is the inner payload.
            ******************************/
            PointerHelper  sp         = PointerHelper.New(args.Buffer + args.Offset);
            int            instanceId = *sp.ip++;
            int            cookie     = *sp.ip++;
            byte *         outer_buf;
            int            outer_len;
            long           p  = 0;
            TrinityMessage tm = null;
            TaskCompletionSource <bool> tsrc = null;
            bool invalid_client = false;

            try
            {
                var stg = CheckInstanceCookie(cookie, instanceId);
                stg.Pulse     = DateTime.Now;
                (p, tm, tsrc) = stg.PollEvents_impl();
            }
            catch (ClientInstanceNotFoundException)
            {
                invalid_client = true;
            }

            if (tm == null)
            {
                outer_len         = TrinityProtocol.MsgHeader + sizeof(long) + sizeof(int);
                outer_buf         = (byte *)Memory.malloc((ulong)outer_len);
                *(int *)outer_buf = outer_len - TrinityProtocol.SocketMsgHeader;
                *(long *)(outer_buf + TrinityProtocol.MsgHeader) = 0;
                *(int *)(outer_buf + TrinityProtocol.MsgHeader + sizeof(long)) = -1;
                *(int *)(outer_buf + TrinityProtocol.SocketMsgHeader)          = invalid_client ? 2 : 1;
            }
            else
            {
                outer_len         = TrinityProtocol.MsgHeader + sizeof(long) + tm.Size;
                outer_buf         = (byte *)Memory.malloc((ulong)outer_len);
                *(int *)outer_buf = outer_len - TrinityProtocol.SocketMsgHeader;
                *(long *)(outer_buf + TrinityProtocol.MsgHeader) = p;
                Memory.memcpy(outer_buf + TrinityProtocol.MsgHeader + sizeof(long), tm.Buffer, (ulong)tm.Size);
                tsrc.SetResult(true);
                *(int *)(outer_buf + TrinityProtocol.SocketMsgHeader) = 0;
            }
            args.Response = new TrinityMessage(outer_buf, outer_len);
        }
        protected internal unsafe void SendMessage(IMessagePassingEndpoint endpoint, byte **buffers, int *sizes, int count)
        {
            var e_msg_type = PointerHelper.GetUshort(buffers, sizes, TrinityProtocol.MsgTypeOffset);

            PointerHelper.Add(buffers, sizes, TrinityProtocol.MsgIdOffset, m_MessageIdOffsets[e_msg_type]);

            endpoint.SendMessage(buffers, sizes, count);
        }
예제 #7
0
        public unsafe void SendMessage(byte **message, int *sizes, int count)
        {
            byte   msg_type = PointerHelper.GetByte(message, sizes, TrinityProtocol.MsgTypeOffset);
            ushort msg_id   = PointerHelper.GetUshort(message, sizes, TrinityProtocol.MsgIdOffset);
            int    ms       = ProtocolSemanticRegistry.s_protocolSemantics[msg_type, msg_id];

            m_smmfuncs[ms](message, sizes, count);
        }
예제 #8
0
        protected internal unsafe void SendMessage(IMessagePassingEndpoint endpoint, byte **buffers, int *sizes, int count, out TrinityResponse response)
        {
            byte b_msg_type = PointerHelper.GetByte(buffers, sizes, TrinityProtocol.MsgTypeOffset);

            PointerHelper.Add(buffers, sizes, TrinityProtocol.MsgIdOffset, m_MessageIdOffsets[b_msg_type]);

            endpoint.SendMessage(buffers, sizes, count, out response);
        }
예제 #9
0
        public unsafe void SendMessage(byte **message, int *sizes, int count, out TrinityResponse response)
        {
            var    msg_type = PointerHelper.GetUshort(message, sizes, TrinityProtocol.MsgTypeOffset);
            ushort msg_id   = PointerHelper.GetUshort(message, sizes, TrinityProtocol.MsgIdOffset);
            int    ms       = ProtocolSemanticRegistry.s_protocolSemantics[msg_type, msg_id];

            response = m_smrmfuncs[ms](message, sizes, count);
        }
예제 #10
0
        internal static bool GetCommunicationModuleOffset(this IMessagePassingEndpoint storage, string moduleName, out ushort synReqOffset, out ushort synReqRspOffset, out ushort asynReqOffset, out ushort asynReqRspOffset)
        {
            /******************
            * Comm. protocol:
            *  - REQUEST : [char_cnt, char[] moduleName]
            *  - RESPONSE: [int synReqOffset, int synReqRspOffset, int asynReqOffset, int asynReqRspOffset]
            * An response error code other than E_SUCCESS indicates failure of remote module lookup.
            ******************/

            using (TrinityMessage tm = new TrinityMessage(
                       TrinityMessageType.PRESERVED_SYNC_WITH_RSP,
                       (ushort)RequestType.GetCommunicationModuleOffsets,
                       size: sizeof(int) + sizeof(char) * moduleName.Length))
            {
                PointerHelper sp = PointerHelper.New(tm.Buffer + TrinityMessage.Offset);
                *sp.ip++         = moduleName.Length;

                BitHelper.WriteString(moduleName, sp.bp);
                TrinityResponse response = null;
                bool            ret;
                try
                {
                    storage.SendMessage(tm, out response);
                    ret = (response.ErrorCode == TrinityErrorCode.E_SUCCESS);
                }
                catch (System.IO.IOException)
                {
                    ret = false;
                }

                if (ret)
                {
                    sp.bp = response.Buffer + response.Offset;
                    int synReq_msg     = *sp.ip++;
                    int synReqRsp_msg  = *sp.ip++;
                    int asynReq_msg    = *sp.ip++;
                    int asynReqRsp_msg = *sp.ip++;

                    synReqOffset     = (ushort)synReq_msg;
                    synReqRspOffset  = (ushort)synReqRsp_msg;
                    asynReqOffset    = (ushort)asynReq_msg;
                    asynReqRspOffset = (ushort)asynReqRsp_msg;
                }
                else
                {
                    synReqOffset     = 0;
                    synReqRspOffset  = 0;
                    asynReqOffset    = 0;
                    asynReqRspOffset = 0;
                }


                response?.Dispose();
                return(ret);
            }
        }
예제 #11
0
        private unsafe void _PollImpl(TrinityMessage poll_req)
        {
            m_mod.SendMessage(m_client, poll_req.Buffer, poll_req.Size, out var poll_rsp);
            var sp = PointerHelper.New(poll_rsp.Buffer + poll_rsp.Offset);
            //HexDump.Dump(poll_rsp.ToByteArray());
            //Console.WriteLine($"poll_rsp.Size = {poll_rsp.Size}");
            //Console.WriteLine($"poll_rsp.Offset = {poll_rsp.Offset}");
            var payload_len = poll_rsp.Size - TrinityProtocol.TrinityMsgHeader;

            if (payload_len < sizeof(long) + sizeof(int))
            {
                throw new IOException("Poll response corrupted.");
            }
            var errno = *(sp.ip - 1);

            try
            {
                if (errno == 2)
                {
                    Log.WriteLine(LogLevel.Warning, $"{nameof(TrinityClient)}: server drops our connection. Registering again.");
                    RestartPolling();
                    return;
                }
                if (errno != 0)
                {
                    return;
                }

                var pctx    = *sp.lp++;
                var msg_len = *sp.ip++;
                if (msg_len < 0)
                {
                    return;              // no events
                }
                MessageBuff msg_buff = new MessageBuff {
                    Buffer = sp.bp, Length = (uint)msg_len
                };
                MessageDispatcher(&msg_buff);
                // !Note, void-response messages are not acknowledged.
                // Server would not be aware of client side error in this case.
                // This is by-design and an optimization to reduce void-response
                // message delivery latency. In streaming use cases this will be
                // very useful.
                try { if (pctx != 0)
                      {
                          _PostResponseImpl(pctx, &msg_buff);
                      }
                }
                finally { Memory.free(msg_buff.Buffer); }
            }
            finally
            {
                poll_rsp.Dispose();
            }
        }
예제 #12
0
 public PersistedCellEnumerator(byte[] content, long target_lowKey, long target_highKey)
 {
     m_content        = content;
     m_length         = content.Length;
     m_target_lowKey  = target_lowKey;
     m_target_highKey = target_highKey;
     m_handle         = GCHandle.Alloc(content, GCHandleType.Pinned);
     m_bp             = (byte *)m_handle.AddrOfPinnedObject().ToPointer();
     m_sp             = PointerHelper.New(m_bp);
     m_ep             = m_bp + m_length;
 }
예제 #13
0
        private static unsafe Span <TTo> CastRefTypeForSlowSpan <TFrom, TTo>(Span <TFrom> span)
        {
            var helper1 = new PointerHelper <TFrom>(span);
            var helper2 = new PointerHelper <TTo>();
            var p1      = (&helper1.Head) + 1;   // p1 = &helper1.Span;
            var p2      = (&helper2.Head) + 1;   // p2 = &helper2.Span;

            *p2 = *p1;                           // ret._pinnale = span._pinnable
            *(p2 + 1)        = *(p1 + 1);        // ret._byteOffset = span._byteOffset;
            *(int *)(p2 + 2) = *(int *)(p1 + 2); // ret._length = span._length;

            return(helper2.Span);
        }
예제 #14
0
 public void Update()
 {
     if (GameManager.Instance != null)
     {
         if (!PointerHelper.IsPointerOverGameObject())
         {
             if (Input.GetMouseButtonDown(0) ||
                 Input.touchCount == 1 && Input.GetTouch(0).phase == TouchPhase.Began)
             {
                 CloseMenu();
             }
         }
     }
 }
예제 #15
0
        private unsafe TrinityMessage _AllocPollMsg(int myInstanceId, int myCookie)
        {
            int           msglen = sizeof(int) + sizeof(int) + TrinityProtocol.MsgHeader;
            byte *        buf    = (byte *)Memory.malloc((ulong)msglen);
            PointerHelper sp     = PointerHelper.New(buf);

            *sp.ip = msglen - TrinityProtocol.SocketMsgHeader;
            *(TrinityMessageType *)(sp.bp + TrinityProtocol.MsgTypeOffset) = TrinityMessageType.SYNC_WITH_RSP;
            *(ushort *)(sp.bp + TrinityProtocol.MsgIdOffset) = (ushort)TSL.CommunicationModule.TrinityClientModule.SynReqRspMessageType.PollEvents;
            sp.bp += TrinityProtocol.MsgHeader;
            *sp.ip++ = myInstanceId;
            *sp.ip++ = myCookie;
            return(new TrinityMessage(buf, msglen));
        }
예제 #16
0
        private unsafe void PostResponse_impl(SynReqArgs args)
        {
            /******************************
            * Protocol: PostResponse
            * Request: |4B InstanceId|4B Cookie|8B p| TrinityResponse |
            * Response: VOID
            ******************************/
            PointerHelper sp         = PointerHelper.New(args.Buffer + args.Offset);
            int           instanceId = *sp.ip++;
            int           cookie     = *sp.ip++;
            long          p          = *sp.lp++;
            var           stg        = CheckInstanceCookie(cookie, instanceId);

            stg.PostResponse_impl(p, sp.bp, args.Size - sizeof(int) * 2 - sizeof(long));
        }
예제 #17
0
        private unsafe void RedirectMessage_impl(SynReqArgs args)
        {
            /******************************
            * Protocol: RedirectMessage
            * Request: |4B InstanceId| TrinityMessage |
            * Response: VOID
            *
            * Redirects the message to another instance.
            ******************************/

            PointerHelper sp         = PointerHelper.New(args.Buffer + args.Offset);
            int           instanceId = *sp.ip++;

            TrinityMessage tm = new TrinityMessage(sp.bp, *sp.ip + sizeof(int));

            m_memorycloud[instanceId].SendMessage(tm);
        }
예제 #18
0
        private unsafe void RedirectMessage_impl(SynReqArgs args)
        {
            /******************************
            * Protocol: RedirectMessage
            * Request: |4B PartitionId| TrinityMessage |
            * Response: VOID
            *
            * Redirects the message to another instance.
            ******************************/

            PointerHelper sp          = PointerHelper.New(args.Buffer + args.Offset);
            int           partitionId = *sp.ip++;

            TrinityMessage tm = new TrinityMessage(sp.bp, (*sp.ip) + TrinityProtocol.SocketMsgHeader);

            m_memorycloud[partitionId].SendMessage(tm);
        }
예제 #19
0
        private unsafe void UpdateCell_impl(SynReqRspArgs args)
        {
            /******************************
            * Protocol: UpdateCell
            * Request: |8B CellId|4B Size| Payload |
            * Response: [ 4B TrinityErrorCode header ]
            ******************************/
            var sp   = PointerHelper.New(args.Buffer + args.Offset);
            var id   = *sp.lp++;
            var size = *sp.ip++;

            var err = (int)m_memorycloud.UpdateCell(id, sp.bp, size);
            var buf = (byte *)Memory.malloc(TrinityProtocol.MsgHeader);

            sp = PointerHelper.New(buf);
            *sp.ip++ = TrinityProtocol.MsgHeader - TrinityProtocol.SocketMsgHeader;
            *sp.ip   = err;
            args.Response = new TrinityMessage(buf, TrinityProtocol.MsgHeader);
        }
예제 #20
0
        public unsafe void SendMessage(byte *message, int size, out TrinityResponse response)
        {
            byte * header = stackalloc byte[TrinityProtocol.MsgHeader + sizeof(int)];
            byte **bufs   = stackalloc byte *[2];
            int *  sizes  = stackalloc int[2];

            bufs[0]  = header;
            bufs[1]  = message;
            sizes[0] = TrinityProtocol.MsgHeader + sizeof(int);
            sizes[1] = size;

            PointerHelper sp = PointerHelper.New(header);

            *sp.ip = size + sizeof(int) + TrinityProtocol.TrinityMsgHeader;
            *(sp.bp + TrinityProtocol.MsgTypeOffset)         = (byte)TrinityMessageType.SYNC_WITH_RSP;
            *(ushort *)(sp.bp + TrinityProtocol.MsgIdOffset) = (ushort)TSL.CommunicationModule.TrinityClientModule.SynReqRspMessageType.RedirectMessageWithResponse;
            *(int *)(sp.bp + TrinityProtocol.MsgHeader)      = partitionId;

            m_mod.SendMessage(m_ep, bufs, sizes, 2, out response);
        }
예제 #21
0
        public unsafe TrinityErrorCode LoadCell(long cellId, out byte[] cellBuff, out ushort cellType)
        {
            using (var req = new __CellIdStructWriter(cellId))
            {
                TrinityResponse  rsp     = null;
                TrinityErrorCode errcode = TrinityErrorCode.E_RPC_EXCEPTION;

                cellBuff = null;
                cellType = 0;

                try
                {
                    var sp   = PointerHelper.New(req.buffer);
                    *sp.ip++ = TrinityProtocol.TrinityMsgHeader + sizeof(long);
                    *sp.sp++ = (short)TrinityMessageType.SYNC_WITH_RSP;
                    *sp.sp++ = (short)TSL.CommunicationModule.TrinityClientModule.SynReqRspMessageType.LoadCell;

                    m_mod.SendMessage(m_ep, req.buffer, req.BufferLength, out rsp);

                    sp      = PointerHelper.New(rsp.Buffer);
                    errcode = (TrinityErrorCode)(*sp.ip++);
                    if (errcode == TrinityErrorCode.E_SUCCESS)
                    {
                        var length = *sp.ip++;
                        cellType = (ushort)(*sp.sp++);
                        cellBuff = new byte[length];
                        fixed(byte *p = cellBuff)
                        {
                            Memory.memcpy(p, sp.bp, (ulong)length);
                        }
                    }
                    /* otherwise, fails with returned error code */
                }
                finally
                {
                    rsp?.Dispose();
                }

                return(errcode);
            }
        }
예제 #22
0
        public unsafe void SendMessage(byte **_bufs, int *_sizes, int count, out TrinityResponse response)
        {
            byte * header    = stackalloc byte[TrinityProtocol.MsgHeader + sizeof(int)];
            ulong  bufs_len  = (ulong)(sizeof(byte *) * (count + 1));
            ulong  sizes_len = (ulong)(sizeof(int) * (count + 1));
            byte **bufs      = (byte **)Memory.malloc(bufs_len);
            int *  sizes     = (int *)Memory.malloc(sizes_len);

            bufs[0]  = header;
            sizes[0] = TrinityProtocol.MsgHeader + sizeof(int);
            Memory.memcpy(bufs + 1, _bufs, bufs_len);
            Memory.memcpy(sizes + 1, _sizes, sizes_len);

            PointerHelper sp = PointerHelper.New(header);

            *sp.ip = sizeof(int) + TrinityProtocol.TrinityMsgHeader + Utils._sum(_sizes, count);
            *(sp.bp + TrinityProtocol.MsgTypeOffset)         = (byte)TrinityMessageType.SYNC_WITH_RSP;
            *(ushort *)(sp.bp + TrinityProtocol.MsgIdOffset) = (ushort)TSL.CommunicationModule.TrinityClientModule.SynReqRspMessageType.RedirectMessageWithResponse;
            *(int *)(sp.bp + TrinityProtocol.MsgHeader)      = partitionId;

            m_mod.SendMessage(m_ep, bufs, sizes, count + 1, out response);
        }
예제 #23
0
        public static InMemoryDataChunk New(IEnumerable <CellInfo> cells, int estimated_size)
        {
            MemoryStream ms = new MemoryStream(estimated_size);

            byte[] buf = new byte[sizeof(long) + sizeof(ushort) + sizeof(int)];
            byte[] buf_cell = new byte[1024];
            long   lowkey = 0, highkey = 0;
            int    size = 0;

            fixed(byte *p = buf)
            {
                foreach (var cell in cells)
                {
                    if (size == 0)
                    {
                        lowkey = cell.CellId;
                    }
                    highkey = cell.CellId;
                    PointerHelper sp = PointerHelper.New(p);
                    *sp.lp++         = cell.CellId;
                    *sp.sp++         = (short)cell.CellType;
                    *sp.ip++         = cell.CellSize;
                    ms.Write(buf, 0, buf.Length);
                    while (buf_cell.Length < cell.CellSize)
                    {
                        buf_cell = new byte[buf_cell.Length * 2];
                    }
                    Memory.Copy(cell.CellPtr, 0, buf_cell, 0, cell.CellSize);
                    ms.Write(buf_cell, 0, cell.CellSize);
                    size += cell.CellSize + buf.Length;
                }
            }

            byte[] payload = ms.GetBuffer();
            Chunk  chunk   = new Chunk(lowkey, highkey);

            return(new InMemoryDataChunk(chunk, payload, lowkey, highkey));
        }
예제 #24
0
        private unsafe TrinityErrorCode _SendCellPayload(long cellId, byte *buff, int size, ushort?cellType, short msgId)
        {
            //header: cellId, size, type
            int           header_len = TrinityProtocol.MsgHeader + sizeof(long) + sizeof(int) + (cellType.HasValue? sizeof(ushort): 0);
            byte *        header     = stackalloc byte[header_len];
            byte **       holder     = stackalloc byte *[2];
            int *         length     = stackalloc int[2];
            PointerHelper sp         = PointerHelper.New(header);

            *sp.ip++ = header_len + size - TrinityProtocol.SocketMsgHeader;
            *sp.sp++ = (short)TrinityMessageType.SYNC_WITH_RSP;
            *sp.sp++ = msgId;
            *sp.lp++ = cellId;
            *sp.ip++ = size;

            if (cellType.HasValue)
            {
                *sp.sp++ = (short)cellType;
            }

            holder[0] = header;
            holder[1] = buff;
            length[0] = header_len;
            length[1] = size;

            TrinityResponse rsp = null;

            try
            {
                m_mod.SendMessage(m_ep, holder, length, 2, out rsp);
                return(*(TrinityErrorCode *)(rsp.Buffer));
            }
            finally
            {
                rsp?.Dispose();
            }
        }
예제 #25
0
        internal static void GetCommunicationSchema(this IMessagePassingEndpoint storage, out string name, out string signature)
        {
            /******************
            * Comm. protocol:
            *  - REQUEST : VOID
            *  - RESPONSE: [char_cnt, char[] name, char_cnt, char[] sig]
            ******************/
            using (TrinityMessage tm = new TrinityMessage(
                       TrinityMessageType.PRESERVED_SYNC_WITH_RSP,
                       (ushort)RequestType.GetCommunicationSchema,
                       size: 0))
            {
                TrinityResponse response;
                storage.SendMessage(tm, out response);
                PointerHelper sp = PointerHelper.New(response.Buffer + response.Offset);
                int           name_string_len = *sp.ip++;
                name   = BitHelper.GetString(sp.bp, name_string_len * 2);
                sp.cp += name_string_len;
                int sig_string_len = *sp.ip++;
                signature = BitHelper.GetString(sp.bp, sig_string_len * 2);

                response.Dispose();
            }
        }
    void Update()
    {
        if (InBuildMode && MainCanvas.Instance.IsDraggingIcon && !BuildMenuContainer.Instance.IsOpen)
        {
            if (PointerIsOnAvailablePlot)
            {
                if (GameManager.Instance.CurrentPlatform == Platform.PC)
                {
                    if (Input.GetMouseButtonDown(0))
                    {
                        Logger.Warning("Let's build a {0}", SelectedRoom.Name);
                        BuildingPlot buildingPlot = BuildingPlot.FindBuildingPlot(BuildingPlot.AvailablePlotVectorPosition);
                        BuildRoom(SelectedRoom, buildingPlot);

                        if (BuildMenuContainer.Instance.PanelAnimationPlaying)
                        {
                            ReopenBuildMenu();
                        }
                        else
                        {
                            BuildMenuContainer.Instance.ActivateAnimationFreeze();
                            ActivateBuildMenuMode();
                        }
                    }
                }
            }
            else
            {
                if (GameManager.Instance.CurrentPlatform == Platform.PC)
                {
                    if (Input.GetMouseButtonDown(0))
                    {
                        Logger.Warning("Cannot build here!");
                        GameObject   notificationGO = Instantiate(MainCanvas.Instance.NotificationPrefab, MainCanvas.Instance.transform);
                        Notification notification   = notificationGO.transform.GetComponent <Notification>();
                        notification.Setup(NotificationType.FromPointer, "Cannot build in location");

                        if (BuildMenuContainer.Instance.PanelAnimationPlaying)
                        {
                            ReopenBuildMenu();
                        }
                        else
                        {
                            BuildMenuContainer.Instance.ActivateAnimationFreeze();
                            ActivateBuildMenuMode();
                        }
                    }
                }
            }
        }

        if (Input.touchCount == 1)
        {
            if (Input.touches[0].phase == TouchPhase.Ended)
            {
                if (MainCanvas.Instance.PointerImage.sprite != null && !BuildMenuContainer.Instance.IsOpen)
                {
                    if (PointerIsOnAvailablePlot)
                    {
                        Logger.Warning("Let's build!");
                        BuildingPlot buildingPlot = BuildingPlot.FindBuildingPlot(BuildingPlot.AvailablePlotVectorPosition);
                        BuildRoom(SelectedRoom, buildingPlot);
                    }
                    else
                    {
                        if (MainCanvas.Instance.IsDraggingIcon && !BuildMenuContainer.Instance.IsOpen)
                        {
                            GameObject   notificationGO = Instantiate(MainCanvas.Instance.NotificationPrefab, MainCanvas.Instance.transform);
                            Notification notification   = notificationGO.transform.GetComponent <Notification>();
                            notification.Setup(NotificationType.FromPointer, "Cannot build in location");
                        }
                    }

                    if (BuildMenuContainer.Instance.PanelAnimationPlaying)
                    {
                        ReopenBuildMenu();
                    }
                    else
                    {
                        BuildMenuContainer.Instance.ActivateAnimationFreeze();
                        ActivateBuildMenuMode();
                    }
                }
                else
                {
                    MainCanvas.Instance.UnsetPointerImage();
                }
            }
        }

        if (ConfirmationModal.CurrentConfirmationModal != null)
        {
            if (Input.GetMouseButtonDown(0) || (Input.touchCount == 1 && Input.touches[0].phase == TouchPhase.Began))
            {
                bool isPointerOverGameObject = PointerHelper.IsPointerOverGameObject();
                if (!isPointerOverGameObject)
                {
                    ConfirmationModal.CurrentConfirmationModal.ResetDeleteTrigger();
                    ConfirmationModal.CurrentConfirmationModal.DestroyConfirmationModal();
                }
            }
        }
    }
예제 #27
0
    public void Update()
    {
        if (Console.Instance && Console.Instance.ConsoleState == ConsoleState.Large)
        {
            return;
        }

        if (PointerImage.sprite != null)
        {
            Vector2 mousePosition           = Input.mousePosition;
            bool    isPointerOverGameObject = PointerHelper.IsPointerOverGameObject();
            if (isPointerOverGameObject && BuildMenuContainer.Instance.IsOpen)
            {
                PointerImageGO.transform.position = new Vector2(mousePosition.x, mousePosition.y);
            }
            else
            {
                if (BuildMenuContainer.Instance.IsOpen)
                {
                    Logger.Log(Logger.UI, "Close build menu");
                    BuildMenuContainer.Instance.ActivateAnimationFreeze();

                    BuildMenuContainer.Instance.IsOpen = false;
                    BuildMenuContainer.Instance.RemoveBuildMenuContent(0.5f);
                }
                Vector2 mouseWorldPosition = Camera.main.ScreenToWorldPoint(mousePosition);
                mouseWorldPosition = new Vector2(mouseWorldPosition.x, mouseWorldPosition.y + 7.5f);

                float xx = Mathf.Round((mouseWorldPosition.y) / TileSizeInUnits.y + (mouseWorldPosition.x) / TileSizeInUnits.x);
                float yy = Mathf.Round((mouseWorldPosition.y) / TileSizeInUnits.y - (mouseWorldPosition.x) / TileSizeInUnits.x) - 1;

                // Calculate grid aligned position from current position
                float snappedX = (xx - yy) * 0.5f * TileSizeInUnits.x;
                float snappedY = (xx + yy) * 0.5f * TileSizeInUnits.y;

                if (_currentSnappedX != snappedX || _currentSnappedY != snappedY)
                {
                    _currentSnappedX = snappedX;
                    _currentSnappedY = snappedY;

                    if (BuilderManager.Instance.BuildingPlotLocations.ContainsKey(new Vector2(_currentSnappedX, _currentSnappedY)))
                    {
                        Vector2 availablePlotVectorPosition = BuilderManager.Instance.BuildingPlotLocations[new Vector2(_currentSnappedX, _currentSnappedY)];
                        if (BuildingPlot.AvailablePlotVectorPosition == availablePlotVectorPosition && BuilderManager.PointerIsOnAvailablePlot)
                        {
                            return;
                        }

                        BuildingPlot.AvailablePlotVectorPosition = availablePlotVectorPosition;

                        SetPointerImageOverlayColor(PointerImageOverlayState.Normal);
                        BuilderManager.PointerIsOnAvailablePlot = true;
                        BuildingPlot buildingPlot = BuilderManager.Instance.BuildingPlots[BuildingPlot.AvailablePlotVectorPosition];

                        Sprite roomIcon = GetRoomIcon(buildingPlot.RoomBlueprint.Name, buildingPlot.PlotRotation);
                        SetPointerImage(roomIcon, buildingPlot.PlotRotation);

                        RepositionImage();
                    }
                    else
                    {
                        if (BuilderManager.PointerIsOnAvailablePlot)
                        {
                            BuilderManager.PointerIsOnAvailablePlot = false;
                        }
                        if (_currentPointerImageOverlayState == PointerImageOverlayState.Normal)
                        {
                            SetPointerImageOverlayColor(PointerImageOverlayState.Red);
                        }

                        RepositionImage();
                    }
                }
            }

            if (GameManager.Instance.CurrentPlatform == Platform.PC)
            {
                if (BuildMenuContainer.Instance.PanelAnimationPlaying)
                {
                    return;
                }

                if (Input.GetMouseButtonDown(1))
                {
                    UnsetPointerImage();

                    if (!BuildMenuContainer.Instance.IsOpen)
                    {
                        BuildMenuContainer.Instance.ActivateAnimationFreeze();
                        BuilderManager.Instance.ActivateBuildMenuMode();
                    }
                }
            }
        }
    }