in gym3/libenv.py [0:0]
def _convert_options(ffi: Any, c_lib: Any, options: Dict) -> Any:
"""
Convert a dictionary to libenv_options
"""
# add variables to here to keep them alive after this function returns
keepalives = []
c_options = ffi.new("struct libenv_options *")
c_option_array = ffi.new("struct libenv_option[%d]" % len(options))
for i, (k, v) in enumerate(options.items()):
name = str(k).encode("utf8")
assert (
len(name) < c_lib.LIBENV_MAX_NAME_LEN - 1
), "length of options key is too long"
if isinstance(v, bytes):
c_data = ffi.new("char[]", v)
dtype = c_lib.LIBENV_DTYPE_UINT8
count = len(v)
elif isinstance(v, str):
c_data = ffi.new("char[]", v.encode("utf8"))
dtype = c_lib.LIBENV_DTYPE_UINT8
count = len(v)
elif isinstance(v, bool):
c_data = ffi.new("uint8_t*", v)
dtype = c_lib.LIBENV_DTYPE_UINT8
count = 1
elif isinstance(v, int):
assert -2 ** 31 < v < 2 ** 31
c_data = ffi.new("int32_t*", v)
dtype = c_lib.LIBENV_DTYPE_INT32
count = 1
elif isinstance(v, float):
c_data = ffi.new("float*", v)
dtype = c_lib.LIBENV_DTYPE_FLOAT32
count = 1
elif isinstance(v, np.ndarray):
c_data = ffi.new("char[]", v.tobytes())
if v.dtype == np.dtype("uint8"):
dtype = c_lib.LIBENV_DTYPE_UINT8
elif v.dtype == np.dtype("int32"):
dtype = c_lib.LIBENV_DTYPE_INT32
elif v.dtype == np.dtype("float32"):
dtype = c_lib.LIBENV_DTYPE_FLOAT32
else:
assert False, f"unsupported type {v.dtype}"
count = v.size
else:
assert False, f"unsupported value {v} for option {k}"
c_option_array[i].name = name
c_option_array[i].dtype = dtype
c_option_array[i].count = count
c_option_array[i].data = c_data
keepalives.append(c_data)
keepalives.append(c_option_array)
c_options.items = c_option_array
c_options.count = len(options)
return c_options, keepalives