<commit_before># Copyright 2014, <NAME> <<EMAIL>>
#
# This file is part of Azrael (https://github.com/olitheolix/azrael)
#
# Azrael is free software: you can redistribute it and/or modify
# it under the terms of the GNU Affero General Public License as
# published by the Free Software Foundation, either version 3 of the
# License, or (at your option) any later version.
#
# Azrael is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU Affero General Public License for more details.
#
# You should have received a copy of the GNU Affero General Public License
# along with Azrael. If not, see <http://www.gnu.org/licenses/>.

"""
Python agnostic Codecs for data transmission to and from Clerk.

The codecs in this module specify the JSON format between Clerk and the
clients.

The encoders and decoders in this module specify the binary protocol for
sending/receiving messages to/from Clerk.

``ToClerk_*_Decode``: Clerk will use this function to de-serialise the incoming
byte stream into native Python types.

``FromClerk_*_Encode``: Clerk will use this function to serialise its response.

``ToClerk_*_Encode``: the (Python) client uses this function to serialise its
request for Clerk.

``FromClerk_*_Decode``: the (Python) client uses this function to de-serialise
Clerk's response.

The binary protocols are not pickled Python objects but (hopefully) language
agnostic encodings of strings, JSON objects, or C-arrays (via NumPy). This
should make it possible to write clients in other languages.
"""

import IPython
import collections
import numpy as np
import azrael.parts as parts
import azrael.config as config
import azrael.bullet.bullet_data as bullet_data

from azrael.typecheck import typecheck

ipshell = IPython.embed


# ---------------------------------------------------------------------------
# Ping
# ---------------------------------------------------------------------------

@typecheck
def ToClerk_Ping_Encode(dummyarg=None):
    return True, {}


@typecheck
def ToClerk_Ping_Decode(data: dict):
    return True, data


@typecheck
def FromClerk_Ping_Encode(response: str):
    return True, {'response': response}


@typecheck
def FromClerk_Ping_Decode(data: dict):
    return True, data['response']


# ---------------------------------------------------------------------------
# GetID
# ---------------------------------------------------------------------------

@typecheck
def ToClerk_GetID_Encode(dummyarg=None):
    return True, {}


@typecheck
def ToClerk_GetID_Decode(data: dict):
    return True, data


@typecheck
def FromClerk_GetID_Encode(objID: bytes):
    return True, {'objID': objID}


@typecheck
def FromClerk_GetID_Decode(data: dict):
    return True, bytes(data['objID'])


# ---------------------------------------------------------------------------
# GetTemplate
# ---------------------------------------------------------------------------

@typecheck
def ToClerk_GetTemplate_Encode(templateID: bytes):
    return True, {'templateID': list(templateID)}


@typecheck
def ToClerk_GetTemplate_Decode(data: dict):
    if 'templateID' in data:
        return True, (bytes(data['templateID']), )
    else:
        return False, 'Corrupt payload'


@typecheck
def FromClerk_GetTemplate_Encode(cs: np.ndarray, geo: np.ndarray,
                                 boosters: (list, tuple),
                                 factories: (list, tuple)):
    for b in boosters:
        assert isinstance(b, parts.Booster)
    for f in factories:
        assert isinstance(f, parts.Factory)

    d = {'cs': cs, 'geo': geo,
         'boosters': [_.tostring() for _ in boosters],
         'factories': [_.tostring() for _ in factories]}
    return True, d


@typecheck
def FromClerk_GetTemplate_Decode(data: dict):
    # Wrap the Booster- and Factory data into their dedicated named tuples.
    boosters = [parts.fromstring(_) for _ in data['boosters']]
    factories = [parts.fromstring(_) for _ in data['factories']]

    # Return the complete information in a named tuple.
    nt = collections.namedtuple('Template', 'cs geo boosters factories')
    ret = nt(np.array(data['cs'], np.float64),
             np.array(data['geo'], np.float64),
             boosters, factories)
    return True, ret


# ---------------------------------------------------------------------------
# GetTemplateID
# ---------------------------------------------------------------------------


@typecheck
def ToClerk_GetTemplateID_Encode(objID: bytes):
    return True, {'objID': objID}


@typecheck
def ToClerk_GetTemplateID_Decode(data: dict):
    return True, (bytes(data['objID']), )


@typecheck
def FromClerk_GetTemplateID_Encode(templateID: bytes):
    return True, {'templateID': templateID}


@typecheck
def FromClerk_GetTemplateID_Decode(data: dict):
    return True, bytes(data['templateID'])


# ---------------------------------------------------------------------------
# AddTemplate
# ---------------------------------------------------------------------------


@typecheck
def ToClerk_AddTemplate_Encode(templateID: bytes, cs: np.ndarray, geo:
                               np.ndarray, boosters, factories):
    for b in boosters:
        assert isinstance(b, parts.Booster)
    for f in factories:
        assert isinstance(f, parts.Factory)

    d = {'name': templateID, 'cs': cs.tostring(), 'geo': geo.tostring(),
         'boosters': [_.tostring() for _ in boosters],
         'factories': [_.tostring() for _ in factories]}

    return True, d


@typecheck
def ToClerk_AddTemplate_Decode(data: dict):
    # Wrap the Booster- and Factory data into their dedicated named tuples.
    boosters = [parts.fromstring(_) for _ in data['boosters']]
    factories = [parts.fromstring(_) for _ in data['factories']]

    # Convert template ID to a byte string.
    templateID = bytes(data['name'])

    # Convert collision shape and geometry to NumPy array (via byte string).
    cs = np.fromstring(bytes(data['cs']), np.float64)
    geo = np.fromstring(bytes(data['geo']), np.float64)

    # Return decoded quantities.
    return True, (templateID, cs, geo, boosters, factories)


@typecheck
def FromClerk_AddTemplate_Encode(templateID: bytes):
    return True, {'templateID': templateID}


@typecheck
def FromClerk_AddTemplate_Decode(data: dict):
    return True, bytes(data['templateID'])


# ---------------------------------------------------------------------------
# GetAllObjectIDs
# ---------------------------------------------------------------------------


@typecheck
def ToClerk_GetAllObjectIDs_Encode(dummyarg=None):
    return True, {}


@typecheck
def ToClerk_GetAllObjectIDs_Decode(data: dict):
    return True, data<commit_msg>Converted another NumPy array to plain JSON array.<commit_after># Copyright 2014, <NAME> <<EMAIL>>
#
# This file is part of Azrael (https://github.com/olitheolix/azrael)
#
# Azrael is free software: you can redistribute it and/or modify
# it under the terms of the GNU Affero General Public License as
# published by the Free Software Foundation, either version 3 of the
# License, or (at your option) any later version.
#
# Azrael is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU Affero General Public License for more details.
#
# You should have received a copy of the GNU Affero General Public License
# along with Azrael. If not, see <http://www.gnu.org/licenses/>.

"""
Python agnostic Codecs for data transmission to and from Clerk.

The codecs in this module specify the JSON format between Clerk and the
clients.

The encoders and decoders in this module specify the binary protocol for
sending/receiving messages to/from Clerk.

``ToClerk_*_Decode``: Clerk will use this function to de-serialise the incoming
byte stream into native Python types.

``FromClerk_*_Encode``: Clerk will use this function to serialise its response.

``ToClerk_*_Encode``: the (Python) client uses this function to serialise its
request for Clerk.

``FromClerk_*_Decode``: the (Python) client uses this function to de-serialise
Clerk's response.

The binary protocols are not pickled Python objects but (hopefully) language
agnostic encodings of strings, JSON objects, or C-arrays (via NumPy). This
should make it possible to write clients in other languages.
"""

import IPython
import collections
import numpy as np
import azrael.parts as parts
import azrael.config as config
import azrael.bullet.bullet_data as bullet_data

from azrael.typecheck import typecheck

ipshell = IPython.embed


# ---------------------------------------------------------------------------
# Ping
# ---------------------------------------------------------------------------

@typecheck
def ToClerk_Ping_Encode(dummyarg=None):
    return True, {}


@typecheck
def ToClerk_Ping_Decode(data: dict):
    return True, data


@typecheck
def FromClerk_Ping_Encode(response: str):
    return True, {'response': response}


@typecheck
def FromClerk_Ping_Decode(data: dict):
    return True, data['response']


# ---------------------------------------------------------------------------
# GetID
# ---------------------------------------------------------------------------

@typecheck
def ToClerk_GetID_Encode(dummyarg=None):
    return True, {}


@typecheck
def ToClerk_GetID_Decode(data: dict):
    return True, data


@typecheck
def FromClerk_GetID_Encode(objID: bytes):
    return True, {'objID': objID}


@typecheck
def FromClerk_GetID_Decode(data: dict):
    return True, bytes(data['objID'])


# ---------------------------------------------------------------------------
# GetTemplate
# ---------------------------------------------------------------------------

@typecheck
def ToClerk_GetTemplate_Encode(templateID: bytes):
    return True, {'templateID': list(templateID)}


@typecheck
def ToClerk_GetTemplate_Decode(data: dict):
    if 'templateID' in data:
        return True, (bytes(data['templateID']), )
    else:
        return False, 'Corrupt payload'


@typecheck
def FromClerk_GetTemplate_Encode(cs: np.ndarray, geo: np.ndarray,
                                 boosters: (list, tuple),
                                 factories: (list, tuple)):
    for b in boosters:
        assert isinstance(b, parts.Booster)
    for f in factories:
        assert isinstance(f, parts.Factory)

    d = {'cs': cs, 'geo': geo,
         'boosters': [_.tostring() for _ in boosters],
         'factories': [_.tostring() for _ in factories]}
    return True, d


@typecheck
def FromClerk_GetTemplate_Decode(data: dict):
    # Wrap the Booster- and Factory data into their dedicated named tuples.
    boosters = [parts.fromstring(_) for _ in data['boosters']]
    factories = [parts.fromstring(_) for _ in data['factories']]

    # Return the complete information in a named tuple.
    nt = collections.namedtuple('Template', 'cs geo boosters factories')
    ret = nt(np.array(data['cs'], np.float64),
             np.array(data['geo'], np.float64),
             boosters, factories)
    return True, ret


# ---------------------------------------------------------------------------
# GetTemplateID
# ---------------------------------------------------------------------------


@typecheck
def ToClerk_GetTemplateID_Encode(objID: bytes):
    return True, {'objID': objID}


@typecheck
def ToClerk_GetTemplateID_Decode(data: dict):
    return True, (bytes(data['objID']), )


@typecheck
def FromClerk_GetTemplateID_Encode(templateID: bytes):
    return True, {'templateID': templateID}


@typecheck
def FromClerk_GetTemplateID_Decode(data: dict):
    return True, bytes(data['templateID'])


# ---------------------------------------------------------------------------
# AddTemplate
# ---------------------------------------------------------------------------


@typecheck
def ToClerk_AddTemplate_Encode(templateID: bytes, cs: np.ndarray, geo:
                               np.ndarray, boosters, factories):
    for b in boosters:
        assert isinstance(b, parts.Booster)
    for f in factories:
        assert isinstance(f, parts.Factory)

    d = {'name': templateID, 'cs': cs.tolist(), 'geo': geo.tolist(),
         'boosters': [_.tostring() for _ in boosters],
         'factories': [_.tostring() for _ in factories]}

    return True, d


@typecheck
def ToClerk_AddTemplate_Decode(data: dict):
    # Wrap the Booster- and Factory data into their dedicated named tuples.
    boosters = [parts.fromstring(_) for _ in data['boosters']]
    factories = [parts.fromstring(_) for _ in data['factories']]

    # Convert template ID to a byte string.
    templateID = bytes(data['name'])

    # Convert collision shape and geometry to NumPy array (via byte string).
    cs = np.array(data['cs'], np.float64)
    geo = np.array(data['geo'], np.float64)

    # Return decoded quantities.
    return True, (templateID, cs, geo, boosters, factories)


@typecheck
def FromClerk_AddTemplate_Encode(templateID: bytes):
    return True, {'templateID': templateID}


@typecheck
def FromClerk_AddTemplate_Decode(data: dict):
    return True, bytes(data['templateID'])


# ---------------------------------------------------------------------------
# GetAllObjectIDs
# ---------------------------------------------------------------------------


@typecheck
def ToClerk_GetAllObjectIDs_Encode(dummyarg=None):
    return True, {}


@typecheck
def ToClerk_GetAllObjectIDs_Decode(data: dict):
    return True, data
{'fraction_non_alphanumeric': 0.21855473057413805, 'fraction_numerical': 0.001911343086083952, 'mean_word_length': 2.230586559012111, 'pattern_counts': {'":': 0, '<': 11, '<?xml version=': 0, '>': 11, 'https://': 2, 'lorem ipsum': 0, 'www.': 2, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 4, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '3991857', 'n_tokens_mistral': 3726, 'n_tokens_neox': 3577, 'n_words': 1202}