Exemplo n.º 1
0
def _InvokeOnUpdateWrapperEvent (changedSettings: typing.Set[str]) -> UpdateEventArguments:
	updateEventArguments = UpdateEventArguments(changedSettings)  # type: UpdateEventArguments

	for updateCallback in _onUpdateWrapper:  # type: typing.Callable[[types.ModuleType, Events.EventArguments], None]
		try:
			updateCallback(sys.modules[__name__], updateEventArguments)
		except:
			Debug.Log("Failed to run the 'OnUpdateWrapper' callback '" + Types.GetFullName(updateCallback) + "'.", This.Mod.Namespace, Debug.LogLevels.Exception, group = This.Mod.Namespace, owner = __name__)

	return updateEventArguments
Exemplo n.º 2
0
def GetDoesNotInheritExceptionText(valueName: str,
                                   correctParents: typing.Tuple[typing.Union[
                                       type, str], ...], *additional) -> str:
    if not isinstance(valueName, str):
        raise IncorrectTypeException(valueName, "valueName", (str, ))

    if not isinstance(correctParents, tuple):
        raise IncorrectTypeException(correctParents, "correctParents",
                                     (tuple, ))

    if len(correctParents) == 0:
        raise Exception(
            "This exception must receive at least one correct type")

    for correctParentIndex in range(len(correctParents)):  # type: int
        if isinstance(correctParents[correctParentIndex], type):
            continue

        if isinstance(correctParents[correctParentIndex], str):
            continue

        if correctParents[correctParentIndex] is None:
            continue

        raise IncorrectTypeException(correctParents[correctParentIndex],
                                     "correctParents[%d]" % correctParentIndex,
                                     (type, str, None))

    correctString = "'{}'" + (
        ", '{}'" * (len(correctParents) - 2) if len(correctParents) > 2 else
        "") + (" or '{}'" if len(correctParents) > 1 else "")

    formatList = list()

    formatList.append(valueName)

    for correctParentIndex in range(0, len(correctParents)):
        if isinstance(correctParents[correctParentIndex],
                      type) or correctParents[correctParentIndex] is None:
            formatList.append(
                Types.GetFullName(correctParents[correctParentIndex]))
        elif isinstance(correctParents[correctParentIndex], str):
            formatList.append(correctParents[correctParentIndex])
        else:
            formatList.append("")

    exceptionString = ("Expected '{}' to inherit " + correctString +
                       "").format(*formatList)

    for additionalObject in additional:  # type: typing.Any
        exceptionString += "\n" + str(additionalObject)

    return exceptionString
Exemplo n.º 3
0
 def _TargetException(exception: BaseException) -> None:
     originalCallableFullName = Types.GetFullName(
         information.OriginalCallable)  # type: str
     if originalCallableFullName == Types.GetFullName(log.exception):
         Debug.Log("Failed to call target function '" +
                   Types.GetFullName(information.TargetFunction) +
                   "'. Original callable: '" + originalCallableFullName +
                   "'.",
                   This.Mod.Namespace,
                   Debug.LogLevels.Exception,
                   group=This.Mod.Namespace,
                   owner=__name__,
                   exception=exception,
                   logToGame=False)
         information.OriginalCallable(
             This.Mod.Namespace,
             "Failed to call target function '" +
             Types.GetFullName(information.TargetFunction) +
             "'. Original callable: '" + originalCallableFullName + "'.",
             exc=exception)
     else:
         if originalCallableFullName == Types.GetFullName(
                 log.Logger.exception):
             Debug.Log("Failed to call target function '" +
                       Types.GetFullName(information.TargetFunction) +
                       "'. Original callable: '" +
                       originalCallableFullName + "'.",
                       This.Mod.Namespace,
                       Debug.LogLevels.Exception,
                       group=This.Mod.Namespace,
                       owner=__name__,
                       exception=exception,
                       logToGame=False)
             information.OriginalCallable(
                 log.Logger(This.Mod.Namespace),
                 "Failed to call target function '" +
                 Types.GetFullName(information.TargetFunction) +
                 "'. Original callable: '" + originalCallableFullName +
                 "'.",
                 exc=exception)
         else:
             Debug.Log("Failed to call target function '" +
                       Types.GetFullName(information.TargetFunction) +
                       "'. Original callable: '" +
                       originalCallableFullName + "'.",
                       This.Mod.Namespace,
                       Debug.LogLevels.Exception,
                       group=This.Mod.Namespace,
                       owner=__name__,
                       exception=exception)
Exemplo n.º 4
0
    def _InvokeOnLoadEvent(self) -> Events.EventArguments:
        eventArguments = Events.EventArguments()  # type: Events.EventArguments

        for loadCallback in self.OnLoad:  # type: typing.Callable[[Persistent, Events.EventArguments], None]
            try:
                loadCallback(self, eventArguments)
            except:
                Debug.Log("Failed to run the 'OnLoad' callback '" +
                          Types.GetFullName(loadCallback) + "'.",
                          This.Mod.Namespace,
                          Debug.LogLevels.Exception,
                          group=This.Mod.Namespace,
                          owner=__name__)

        return eventArguments
Exemplo n.º 5
0
def PatchDirectly(originalCallable: typing.Callable,
                  targetFunction: typing.Callable,
                  patchType: PatchTypes = PatchTypes.After,
                  permanent: bool = False) -> typing.Callable:
    """
	Combine a function with another function or method, the patched function will be returned upon completion.
	:param originalCallable: The original callable object to be patched.
	:param targetFunction: The function object that will be combined with the original. This can only be a function or a built in function.
	:type targetFunction: typing.Callable
	:param patchType: Controls when the original callable is called. A value of PatchTypes.Custom requires that the target function take an extra argument
					  in the first argument position. The extra argument will be a reference to the original callable.
	:type patchType: PatchTypes
	:param permanent: Whether or not the patch will be disabled if the module the patching function resides in is unloaded.
	:type permanent: bool
	:return: Returns the patched function.
	:rtype: typing.Callable
	"""

    if not isinstance(
            originalCallable, types.BuiltinFunctionType) and not isinstance(
                originalCallable, types.FunctionType) and not isinstance(
                    originalCallable, types.MethodType):
        raise Exception(
            Types.GetFullName(originalCallable) +
            " is not a function, built-in function or a method.")

    if not isinstance(targetFunction, types.FunctionType) and not isinstance(
            targetFunction, types.BuiltinFunctionType):
        raise Exceptions.IncorrectTypeException(
            targetFunction, "targetFunction",
            (types.FunctionType, types.BuiltinFunctionType))

    if not isinstance(patchType, PatchTypes):
        raise Exceptions.IncorrectTypeException(patchType, "patchType",
                                                (PatchTypes, ))

    if not isinstance(permanent, bool):
        raise Exceptions.IncorrectTypeException(permanent, "permanent",
                                                (bool, ))

    information = _Information(originalCallable, targetFunction, patchType,
                               permanent)  # type: _Information
    patchedFunction = _Wrapper(information)
    _storage.append(information)

    return patchedFunction
Exemplo n.º 6
0
def Patch(originalObject: typing.Any,
          originalCallableName: str,
          targetFunction: typing.Callable,
          patchType: PatchTypes = PatchTypes.After,
          permanent: bool = False) -> None:
    """
	Combine a function with another function or method, the original callable located in the original object will then be replaced by the patch automatically.
	:param originalObject: The object the original callable resides in.
	:type originalObject: typing.Any
	:param originalCallableName: The name of the callable to be combined, Can be a reference to a function, built in function, or method.
	:type originalCallableName: str
	:param targetFunction: The function object that will be combined with the original. This can only be a function or a built in function.
	:type targetFunction: typing.Callable
	:param patchType: Controls when the original callable is called. A value of PatchTypes.Custom requires that the target function take an extra argument
					  in the first argument position. The extra argument will be a reference to the original callable.
	:type patchType: PatchTypes
	:param permanent: Whether or not the patch will be disabled if the module the patching function resides in is unloaded.
	:type permanent: bool
	"""

    if originalObject is None:
        raise TypeError("originalObject cannot be none.")

    if not isinstance(originalCallableName, str):
        raise Exceptions.IncorrectTypeException(originalCallableName,
                                                "originalCallableName",
                                                (str, ))

    originalCallable = getattr(originalObject,
                               originalCallableName)  # type: typing.Callable

    if originalCallable is None:
        raise Exception("Cannot find attribute named '" +
                        originalCallableName + "' in '" +
                        Types.GetFullName(originalObject) + "'.")

    patchedFunction = PatchDirectly(originalCallable,
                                    targetFunction,
                                    patchType=patchType,
                                    permanent=permanent)
    setattr(originalObject, originalCallableName, patchedFunction)
Exemplo n.º 7
0
def InvokeModLoadedEvent(mod: Mods.Mod) -> ModLoadedEventArguments:
    """
	Invokes the mod loaded event. Should be triggered every time a mod is loaded.

	:param mod: A reference the mod in question.
	:type mod: Mods.Mod
	:rtype: None
	"""

    eventArguments = ModLoadedEventArguments(
        mod)  # type: ModLoadedEventArguments

    for modLoadedCallback in ModLoadedEvent:
        try:
            modLoadedCallback(sys.modules[__name__], eventArguments)
        except:
            Debug.Log("Failed to invoke a mod loaded callback at '" +
                      Types.GetFullName(modLoadedCallback) + "'.",
                      This.Mod.Namespace,
                      Debug.LogLevels.Exception,
                      group=This.Mod.Namespace,
                      owner=__name__)

    return eventArguments
Exemplo n.º 8
0
    def Save(self) -> typing.Tuple[bool, str]:
        """
		Encodes the persistent data container to a json string. This method can handle cases in which any persistent data's key or value cannot be encoded.

		:return: The first value indicates if this method completed without incident. The second is the save data.
		:rtype: typing.Tuple[bool, dict]
		"""

        operationSuccess = True  # type: bool

        persistenceInformation = self.PersistenceInformation  # type: str

        saveSuccess, persistentDataContainer = super().Save(
        )  # type: bool, dict

        persistentData = persistentDataContainer[self._valuesKey]  # type: dict
        persistentDataValuesString = ""  # type: str

        for persistentKey, persistentValue in persistentData.items(
        ):  # type: str, typing.Any
            keyInformation = "Key: " + persistentKey  # type: str

            try:
                assert isinstance(persistentKey, str)
                persistentKeyString = json.JSONEncoder(indent="\t").encode(
                    persistentKey)  # type: str
                assert "\n" not in persistentKeyString and "\r" not in persistentKeyString
            except Exception:
                Debug.Log(
                    "Failed to encode a persistence key to a json string.\n" +
                    keyInformation + "\n" + persistenceInformation,
                    self.HostNamespace,
                    Debug.LogLevels.Exception,
                    group=self.HostNamespace,
                    owner=__name__)
                operationSuccess = False
                continue

            valueInformation = "Value Type: " + Types.GetFullName(
                persistentKey) + "\nValue Value: " + persistentKey  # type: str

            try:
                persistentValueString = json.JSONEncoder(indent="\t").encode(
                    persistentValue)  # type: str
            except Exception:
                Debug.Log(
                    "Failed to encode a persistence value to a json string.\n"
                    + keyInformation + "\n" + valueInformation + "\n" +
                    persistenceInformation,
                    self.HostNamespace,
                    Debug.LogLevels.Exception,
                    group=self.HostNamespace,
                    owner=__name__)
                operationSuccess = False
                continue

            persistentValueString = persistentValueString.replace(
                "\n", "\n\t\t")

            if persistentDataValuesString != "":
                persistentDataValuesString += ",\n"

            persistentDataValuesString += "\t\t" + persistentKeyString + ": " + persistentValueString

        persistentDataString = "\t\"" + self._valuesKey + "\": {"  # type: str

        if persistentDataValuesString != "":
            persistentDataString += "\n" + persistentDataValuesString + "\n\t}"
        else:
            persistentDataString += "}"

        lastVersion = persistentDataContainer[
            self._lastVersionKey]  # type: str

        try:
            lastVersionString = "\t\"" + self._lastVersionKey + "\": " + json.JSONEncoder(
                indent="\t").encode(lastVersion)  # type: str
        except Exception as e:
            raise Exception(
                "Failed to encode a persistence last version to a json string."
            ) from e

        persistentDataContainerString = "{\n" + persistentDataString + ",\n" + lastVersionString + "\n}"  # type: str

        if not saveSuccess:
            return False, persistentDataContainerString

        return operationSuccess, persistentDataContainerString
Exemplo n.º 9
0
	def run (self) -> None:
		if self._repeat:
			lastInterval = self.Interval  # type: float
			sleepStartTime = time.time()  # type: float
			targetTime = sleepStartTime + lastInterval  # type: float
			sleepTime = lastInterval  # type: float

			while self.isAlive():
				time.sleep(sleepTime)

				if self.isAlive():
					self._CallCallback()

					sleepEndTime = time.time()  # type: float

					sleepTimeOversleep = sleepEndTime - targetTime  # type: float

					if self.Interval != lastInterval:
						sleepTimeOversleep = max(min(sleepTimeOversleep, self.Interval), -self.Interval)

					sleepTime = self.Interval - sleepTimeOversleep  # type: float

					if sleepTime < 0:
						if not self._reportedMissedTick:
							actualSleepTime = sleepEndTime - sleepStartTime  # type: float

							Debug.Log("A timer slept over an interval. This will be the only warning though there may be more missed ticks. Interval: '" + str(self.Interval) + "' Actual Interval: '" + str(actualSleepTime) + "' Callback: '" + Types.GetFullName(self.Callback) + "'", This.Mod.Namespace, level = Debug.LogLevels.Warning, group = This.Mod.Namespace, owner = __name__)
							self._reportedMissedTick = True

						sleepTime = 0

					lastInterval = self.Interval
					sleepStartTime = time.time()  # type: float
					targetTime += lastInterval
		else:
			if self.isAlive():
				time.sleep(self.Interval)

				if self.isAlive():
					self._CallCallback()
Exemplo n.º 10
0
	def Compare (cls, leftVersion, rightVersion) -> int:
		"""
		Compare two version objects together.
		:return: Less than zero, if the left version is less than the right version. Zero, If the left and right version are equal. Greater than zero, If the
		left version is greater than the right version.
		:rtype: int
		"""

		if not isinstance(leftVersion, Version) or not isinstance(rightVersion, Version):
			raise TypeError("Version compare operations are not supported between instances of '%s' and '%s'" % (Types.GetFullName(leftVersion), Types.GetFullName(rightVersion)))

		if leftVersion.Major != rightVersion.Major:
			if leftVersion.Major < rightVersion.Major:
				return -1
			else:
				return 1

		if leftVersion.Minor != rightVersion.Minor:
			if leftVersion.Minor < rightVersion.Minor:
				return -1
			else:
				return 1

		leftPatch = leftVersion.Patch if leftVersion.Patch >= 0 else 0  # type: int
		rightPatch = rightVersion.Patch if rightVersion.Patch >= 0 else 0  # type: int
		if leftPatch != rightPatch:
			if leftPatch < rightPatch:
				return -1
			else:
				return 1

		if len(leftVersion.PreRelease) != 0 and len(rightVersion.PreRelease) == 0:
			return -1
		elif len(leftVersion.PreRelease) == 0 and len(rightVersion.PreRelease) != 0:
			return 1

		for preReleaseIndex in range(len(leftVersion.PreRelease)):  # type: int
			if len(rightVersion.PreRelease) - 1 < preReleaseIndex:
				break

			leftPreReleaseIdentifier = leftVersion.PreRelease[preReleaseIndex]  # type: typing.Union[str, int]
			rightPreReleaseIdentifier = rightVersion.PreRelease[preReleaseIndex]  # type: typing.Union[str, int]

			if leftPreReleaseIdentifier == rightPreReleaseIdentifier:
				continue

			if isinstance(leftPreReleaseIdentifier, int) and isinstance(rightPreReleaseIdentifier, str):
				return -1
			elif isinstance(leftPreReleaseIdentifier, str) and isinstance(rightPreReleaseIdentifier, int):
				return 1

			assert isinstance(leftPreReleaseIdentifier, int) and isinstance(rightPreReleaseIdentifier, int) or \
				   isinstance(leftPreReleaseIdentifier, str) and isinstance(rightPreReleaseIdentifier, str)

			if leftPreReleaseIdentifier < rightPreReleaseIdentifier:
				return -1
			else:
				return 1

		if len(leftVersion.PreRelease) < len(rightVersion.PreRelease):
			return -1
		elif len(leftVersion.PreRelease) > len(rightVersion.PreRelease):
			return 1

		return 0