| | import glob |
| | import os |
| | import subprocess |
| | from sys import platform |
| | from typing import Optional, List |
| | from mlagents_envs.logging_util import get_logger, DEBUG |
| | from mlagents_envs.exception import UnityEnvironmentException |
| |
|
| |
|
| | logger = get_logger(__name__) |
| |
|
| |
|
| | def get_platform(): |
| | """ |
| | returns the platform of the operating system : linux, darwin or win32 |
| | """ |
| | return platform |
| |
|
| |
|
| | 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)) |
| | logger.debug(f"The true file name is {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 get_platform() == "linux" or get_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: |
| | if os.path.isfile(env_path): |
| | candidates = [env_path] |
| | if len(candidates) > 0: |
| | launch_string = candidates[0] |
| |
|
| | elif get_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 get_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: |
| | |
| | crash_handlers = set( |
| | glob.glob(os.path.join(cwd, env_path, "UnityCrashHandler*.exe")) |
| | ) |
| | candidates = [ |
| | c |
| | for c in glob.glob(os.path.join(cwd, env_path, "*.exe")) |
| | if c not in crash_handlers |
| | ] |
| | 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: |
| | logger.debug(f"The launch string is {launch_string}") |
| | logger.debug(f"Running with args {args}") |
| | |
| | subprocess_args = [launch_string] + args |
| | |
| | |
| | std_out_option = subprocess.DEVNULL if logger.level > DEBUG else None |
| | try: |
| | return subprocess.Popen( |
| | subprocess_args, |
| | |
| | |
| | |
| | |
| | |
| | start_new_session=True, |
| | stdout=std_out_option, |
| | stderr=std_out_option, |
| | ) |
| | except PermissionError as perm: |
| | |
| | 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 |
| |
|