您最多选择25个主题
主题必须以中文或者字母或数字开头,可以包含连字符 (-),并且长度不得超过35个字符
101 行
4.0 KiB
101 行
4.0 KiB
import glob
|
|
import os
|
|
import subprocess
|
|
from sys import platform
|
|
from typing import Optional, List
|
|
from mlagents_envs.logging_util import get_logger
|
|
from mlagents_envs.exception import UnityEnvironmentException
|
|
|
|
|
|
def validate_environment_path(env_path: str) -> Optional[str]:
|
|
"""
|
|
Strip out executable extensions of the env_path
|
|
:param env_path: The path to the executable
|
|
"""
|
|
env_path = (
|
|
env_path.strip()
|
|
.replace(".app", "")
|
|
.replace(".exe", "")
|
|
.replace(".x86_64", "")
|
|
.replace(".x86", "")
|
|
)
|
|
true_filename = os.path.basename(os.path.normpath(env_path))
|
|
get_logger(__name__).debug("The true file name is {}".format(true_filename))
|
|
|
|
if not (glob.glob(env_path) or glob.glob(env_path + ".*")):
|
|
return None
|
|
|
|
cwd = os.getcwd()
|
|
launch_string = None
|
|
true_filename = os.path.basename(os.path.normpath(env_path))
|
|
if platform == "linux" or platform == "linux2":
|
|
candidates = glob.glob(os.path.join(cwd, env_path) + ".x86_64")
|
|
if len(candidates) == 0:
|
|
candidates = glob.glob(os.path.join(cwd, env_path) + ".x86")
|
|
if len(candidates) == 0:
|
|
candidates = glob.glob(env_path + ".x86_64")
|
|
if len(candidates) == 0:
|
|
candidates = glob.glob(env_path + ".x86")
|
|
if len(candidates) > 0:
|
|
launch_string = candidates[0]
|
|
|
|
elif platform == "darwin":
|
|
candidates = glob.glob(
|
|
os.path.join(cwd, env_path + ".app", "Contents", "MacOS", true_filename)
|
|
)
|
|
if len(candidates) == 0:
|
|
candidates = glob.glob(
|
|
os.path.join(env_path + ".app", "Contents", "MacOS", true_filename)
|
|
)
|
|
if len(candidates) == 0:
|
|
candidates = glob.glob(
|
|
os.path.join(cwd, env_path + ".app", "Contents", "MacOS", "*")
|
|
)
|
|
if len(candidates) == 0:
|
|
candidates = glob.glob(
|
|
os.path.join(env_path + ".app", "Contents", "MacOS", "*")
|
|
)
|
|
if len(candidates) > 0:
|
|
launch_string = candidates[0]
|
|
elif platform == "win32":
|
|
candidates = glob.glob(os.path.join(cwd, env_path + ".exe"))
|
|
if len(candidates) == 0:
|
|
candidates = glob.glob(env_path + ".exe")
|
|
if len(candidates) > 0:
|
|
launch_string = candidates[0]
|
|
return launch_string
|
|
|
|
|
|
def launch_executable(file_name: str, args: List[str]) -> subprocess.Popen:
|
|
"""
|
|
Launches a Unity executable and returns the process handle for it.
|
|
:param file_name: the name of the executable
|
|
:param args: List of string that will be passed as command line arguments
|
|
when launching the executable.
|
|
"""
|
|
launch_string = validate_environment_path(file_name)
|
|
if launch_string is None:
|
|
raise UnityEnvironmentException(
|
|
f"Couldn't launch the {file_name} environment. Provided filename does not match any environments."
|
|
)
|
|
else:
|
|
get_logger(__name__).debug("This is the launch string {}".format(launch_string))
|
|
# Launch Unity environment
|
|
subprocess_args = [launch_string] + args
|
|
try:
|
|
return subprocess.Popen(
|
|
subprocess_args,
|
|
# start_new_session=True means that signals to the parent python process
|
|
# (e.g. SIGINT from keyboard interrupt) will not be sent to the new process on POSIX platforms.
|
|
# This is generally good since we want the environment to have a chance to shutdown,
|
|
# but may be undesirable in come cases; if so, we'll add a command-line toggle.
|
|
# Note that on Windows, the CTRL_C signal will still be sent.
|
|
start_new_session=True,
|
|
)
|
|
except PermissionError as perm:
|
|
# This is likely due to missing read or execute permissions on file.
|
|
raise UnityEnvironmentException(
|
|
f"Error when trying to launch environment - make sure "
|
|
f"permissions are set correctly. For example "
|
|
f'"chmod -R 755 {launch_string}"'
|
|
) from perm
|