Пример #1
0
	def _TriggerAnnouncement (self, announcementMethodName: str, preemptive: bool, *announcementArgs, **announcementKwargs) -> None:
		for announcer in Director.GetAllAnnouncers():  # type: typing.Type[Director.Announcer]
			readReportLockIdentifier = None  # type: typing.Optional[str]
			readReportLockReference = None  # type: typing.Any

			if self.LimitErrors:
				readReportLockIdentifier = __name__ + ":" + str(Python.GetLineNumber())  # type: str
				readReportLockReference = announcer

			try:
				if not announcer.Enabled:
					continue

				if not announcer.Host.IsLoaded() and not announcer.Reliable:
					continue

				if preemptive != announcer.Preemptive:
					continue

				announcementMethod = getattr(announcer, announcementMethodName)  # type: typing.Callable
			except Exception:
				from NeonOcean.S4.Main import Debug
				Debug.Log("Failed to read the announcer at '" + Types.GetFullName(announcer) + "' when triggering the announcement '" + announcementMethodName + "'.",
						  announcer.Host.Namespace, Debug.LogLevels.Exception, group = announcer.Host.Namespace, owner = __name__, lockIdentifier = readReportLockIdentifier, lockReference = readReportLockReference)

				return
			else:
				if readReportLockIdentifier is not None:
					from NeonOcean.S4.Main import Debug
					Debug.Unlock(readReportLockIdentifier, readReportLockReference)

			callReportLockIdentifier = None  # type: typing.Optional[str]
			callReportLockReference = None  # type: typing.Any

			if self.LimitErrors:
				callReportLockIdentifier = __name__ + ":" + str(Python.GetLineNumber())  # type: str
				callReportLockReference = announcer

			try:
				if self.AnnouncementCallWrapper is None:
					announcementMethod(*announcementArgs, **announcementKwargs)
				else:
					self.AnnouncementCallWrapper(announcementMethod, *announcementArgs, **announcementKwargs)
			except Exception:
				from NeonOcean.S4.Main import Debug
				Debug.Log("Failed to trigger the announcement '" + announcementMethodName + "' for '" + Types.GetFullName(announcer) + "'.", announcer.Host.Namespace, Debug.LogLevels.Exception, group = announcer.Host.Namespace, owner = __name__, lockIdentifier = callReportLockIdentifier, lockReference = callReportLockReference)
				return
			else:
				if callReportLockIdentifier is not None:
					from NeonOcean.S4.Main import Debug
					Debug.Unlock(callReportLockIdentifier, callReportLockReference)
Пример #2
0
def VerifySystems(
    reproductiveSystems: typing.Optional[typing.Iterable[
        ReproductionShared.ReproductiveSystem]] = None
) -> None:
    """
	Verify that all specified reproductive systems should exist and that their values are valid.
	:param reproductiveSystems: All reproductive systems that need to be verified. If this is None the function will go through all registered reproductive systems.
	:type reproductiveSystems: typing.Iterable[ReproductionShared.ReproductiveSystem] | None
	"""

    if reproductiveSystems is None:
        reproductiveSystems = GetAllSystems(automaticallyUpdate=False)

    for reproductiveSystem in reproductiveSystems:  # type: ReproductionShared.ReproductiveSystem
        reportLockIdentifier = __name__ + ":" + str(
            Python.GetLineNumber())  # type: str
        reportLockReference = reproductiveSystem

        try:
            if not reproductiveSystem.ShouldExist:
                UnregisterReproductiveSystem(reproductiveSystem)
                continue

            reproductiveSystem.Verify()
        except:
            Debug.Log("Failed to verify a reproductive system.\n" +
                      reproductiveSystem.DebugInformation,
                      This.Mod.Namespace,
                      Debug.LogLevels.Exception,
                      group=This.Mod.Namespace,
                      owner=__name__,
                      lockIdentifier=reportLockIdentifier,
                      lockReference=reportLockReference)
        else:
            Debug.Unlock(reportLockIdentifier, reportLockReference)
Пример #3
0
def GetUpdateTicks(
    maximumTick: int,
    reproductiveSystems: typing.Optional[typing.Iterable[
        ReproductionShared.ReproductiveSystem]] = None
) -> typing.Dict[int, typing.List[ReproductionShared.ReproductiveSystem]]:
    """
	Get a dictionary of ticks paired with lists of reproductive systems that should update on them.
	:param maximumTick: Planned updates beyond this tick will be ignored.
	:type maximumTick: int
	:param reproductiveSystems: The reproductive systems to get an update tick for. If this is None the function will go through all registered reproductive systems.
	:type reproductiveSystems: typing.Iterable[ReproductionShared.ReproductiveSystem] | None
	"""

    if reproductiveSystems is None:
        reproductiveSystems = GetAllSystems()

    updateTicks = dict(
    )  # type: typing.Dict[int, typing.List[ReproductionShared.ReproductiveSystem]]

    for reproductiveSystem in reproductiveSystems:  # type: ReproductionShared.ReproductiveSystem
        reportLockIdentifier = __name__ + ":" + str(
            Python.GetLineNumber())  # type: str
        reportLockReference = reproductiveSystem

        try:
            planUpdateArguments = reproductiveSystem.PlanUpdate()

            plannedTick = planUpdateArguments.RequestedTick

            if plannedTick is None or plannedTick >= maximumTick:
                plannedTick = maximumTick

            plannedTickSystems = updateTicks.get(
                plannedTick, None
            )  # type: typing.Optional[typing.List[ReproductionShared.ReproductiveSystem]]

            if plannedTickSystems is None:
                plannedTickSystems = list()
                updateTicks[plannedTick] = plannedTickSystems

            plannedTickSystems.append(reproductiveSystem)
        except:
            Debug.Log("Failed to plan the update of a reproductive system\n." +
                      reproductiveSystem.DebugInformation,
                      This.Mod.Namespace,
                      Debug.LogLevels.Exception,
                      group=This.Mod.Namespace,
                      owner=__name__,
                      lockIdentifier=reportLockIdentifier,
                      lockReference=reportLockReference)
        else:
            Debug.Unlock(reportLockIdentifier, reportLockReference)

    return updateTicks
Пример #4
0
	def _plannedUpdateCallback (alarmHandle: alarms.AlarmHandle) -> None:
		if not This.Mod.IsLoaded():
			return

		reportLockIdentifier = __name__ + ":UpdateCallback"  # type: str

		try:
			Reproduction.UpdateSystems(plannedSystems)  # TODO log the time taken?
		except:
			Debug.Log("Reproduction planned update callback failed.", This.Mod.Namespace, Debug.LogLevels.Exception, group = This.Mod.Namespace, owner = __name__, lockIdentifier = reportLockIdentifier)
		else:
			Debug.Unlock(reportLockIdentifier)

		try:
			_plannedUpdateAlarms.remove(alarmHandle)
		except ValueError:
			pass
Пример #5
0
def _StandardUpdateCallback (alarmHandle: alarms.AlarmHandle) -> None:
	if not This.Mod.IsLoaded():
		return

	reportLockIdentifier = __name__ + ":UpdateCallback"  # type: str

	try:
		Reproduction.UpdateSystems()  # TODO log the time taken?

		updateTicks = Reproduction.GetUpdateTicks(_standardUpdateInterval)  # type: typing.Dict[int, typing.List[ReproductionShared.ReproductiveSystem]]

		for plannedTick, plannedSystems in updateTicks.items():  # type: int, typing.List[ReproductionShared.ReproductiveSystem]
			if plannedTick >= _standardUpdateInterval:
				continue

			alarmTimeSpan = date_and_time.TimeSpan(plannedTick)
			plannedUpdateAlarm = alarms.add_alarm(sys.modules[__name__], alarmTimeSpan, _CreatePlannedUpdateCallback(plannedSystems))

			_plannedUpdateAlarms.append(plannedUpdateAlarm)
	except:
		Debug.Log("Reproduction standard update callback failed.", This.Mod.Namespace, Debug.LogLevels.Exception, group = This.Mod.Namespace, owner = __name__, lockIdentifier = reportLockIdentifier)
	else:
		Debug.Unlock(reportLockIdentifier)
Пример #6
0
def SimulateSystems(
    ticks: int,
    reproductiveSystems: typing.Optional[typing.Iterable[
        ReproductionShared.ReproductiveSystem]] = None
) -> None:
    """
	Simulate this many ticks in the specified reproductive systems. All out of date reproductive systems will be updated before simulating.
	:param ticks: The number of ticks to simulate.
	:type ticks: int
	:param reproductiveSystems: All reproductive systems that need to be simulated. If this is None the function will go through all registered reproductive systems.
	:type reproductiveSystems: typing.Iterable[ReproductionShared.ReproductiveSystem] | None
	"""

    if not isinstance(ticks, int):
        raise Exceptions.IncorrectTypeException(ticks, "ticks", (int, ))

    if reproductiveSystems is None:
        reproductiveSystems = GetAllSystems()

    for reproductiveSystem in reproductiveSystems:  # type: ReproductionShared.ReproductiveSystem
        reportLockIdentifier = __name__ + ":" + str(
            Python.GetLineNumber())  # type: str
        reportLockReference = reproductiveSystem

        try:
            reproductiveSystem.Simulate(ticks)
        except:
            Debug.Log("Failed to simulate a reproductive system\n." +
                      reproductiveSystem.DebugInformation,
                      This.Mod.Namespace,
                      Debug.LogLevels.Exception,
                      group=This.Mod.Namespace,
                      owner=__name__,
                      lockIdentifier=reportLockIdentifier,
                      lockReference=reportLockReference)
        else:
            Debug.Unlock(reportLockIdentifier, reportLockReference)
Пример #7
0
def UpdateSystems(
    reproductiveSystems: typing.Optional[typing.Iterable[
        ReproductionShared.ReproductiveSystem]] = None
) -> None:
    """
	Update all specified reproductive systems.
	:param reproductiveSystems: All reproductive systems that need to be updated. If this is None the function will go through all registered reproductive systems.
	:type reproductiveSystems: typing.Iterable[ReproductionShared.ReproductiveSystem] | None
	"""

    if reproductiveSystems is None:
        reproductiveSystems = GetAllSystems(automaticallyUpdate=False)

    if len(reproductiveSystems) == 0:
        return

    updateTimedRoll = random.random()  # type: float
    updateTimedProbability = 0.125  # type: float

    maximumSavedUpdateTimes = 200  # type: int

    if len(_fullUpdateTimes) == 0:
        updateTimed = True
    else:
        updateTimed = len(
            _fullUpdateTimes
        ) != maximumSavedUpdateTimes and updateTimedRoll <= updateTimedProbability  # type: bool

    if updateTimed:
        fullUpdateStartTime = time.time()  # type: typing.Optional[float]
        chosenTimedSystem = random.choice(
            reproductiveSystems
        )  # type: typing.Optional[ReproductionShared.ReproductiveSystem]
    else:
        fullUpdateStartTime = None  # type: typing.Optional[float]
        chosenTimedSystem = None  # type: typing.Optional[ReproductionShared.ReproductiveSystem]

    for reproductiveSystem in reproductiveSystems:  # type: ReproductionShared.ReproductiveSystem
        reportLockIdentifier = __name__ + ":" + str(
            Python.GetLineNumber())  # type: str
        reportLockReference = reproductiveSystem

        if updateTimed and reproductiveSystem is chosenTimedSystem:
            individualUpdateStartTime = time.time(
            )  # type: typing.Optional[float]
        else:
            individualUpdateStartTime = None  # type: typing.Optional[float]

        try:
            if reproductiveSystem.ShouldUpdate:
                reproductiveSystem.Update()
        except:
            Debug.Log("Failed to update a reproductive system\n." +
                      reproductiveSystem.DebugInformation,
                      This.Mod.Namespace,
                      Debug.LogLevels.Exception,
                      group=This.Mod.Namespace,
                      owner=__name__,
                      lockIdentifier=reportLockIdentifier,
                      lockReference=reportLockReference)
        else:
            Debug.Unlock(reportLockIdentifier, reportLockReference)

        if individualUpdateStartTime is not None:
            _individualUpdateTimes.append(time.time() -
                                          individualUpdateStartTime)

    if fullUpdateStartTime is not None:
        _fullUpdateTimes.append(time.time() - fullUpdateStartTime)