예제 #1
0
class FrameProfiler:
    notify = directNotify.newCategory('FrameProfiler')

    # because of precision requirements, all times related to the profile/log
    # schedule are stored as integers
    Minute = 60
    Hour = 60 * Minute
    Day = 24 * Hour

    def __init__(self):
        Hour = FrameProfiler.Hour
        # how long to wait between frame profiles
        frequent_profiles = ConfigVariableBool('frequent-frame-profiles',
                                               False)
        self._period = 2 * FrameProfiler.Minute
        if frequent_profiles:
            self._period = 1 * FrameProfiler.Minute
        # used to prevent profile from being taken exactly every 'period' seconds
        self._jitterMagnitude = self._period * .75
        # when to log output
        # each entry must be an integer multiple of all previous entries
        # as well as an integer multiple of the period
        self._logSchedule = [
            1 * FrameProfiler.Hour,
            4 * FrameProfiler.Hour,
            12 * FrameProfiler.Hour,
            1 * FrameProfiler.Day,
        ]  # day schedule proceeds as 1, 2, 4, 8 days, etc.
        if frequent_profiles:
            self._logSchedule = [
                1 * FrameProfiler.Minute,
                4 * FrameProfiler.Minute,
                12 * FrameProfiler.Minute,
                24 * FrameProfiler.Minute,
            ]
        for t in self._logSchedule:
            #assert isInteger(t)
            # make sure the period is evenly divisible into each element of the log schedule
            assert (t % self._period) == 0
        # make sure each element of the schedule is evenly divisible into each subsequent element
        for i in range(len(self._logSchedule)):
            e = self._logSchedule[i]
            for j in range(i, len(self._logSchedule)):
                assert (self._logSchedule[j] % e) == 0
        #assert isInteger(self._period)
        self._enableFC = FunctionCall(self._setEnabled,
                                      taskMgr.getProfileFramesSV())
        self._enableFC.pushCurrentState()

    def destroy(self):
        self._enableFC.set(False)
        self._enableFC.destroy()

    def _setEnabled(self, enabled):
        if enabled:
            self.notify.info('frame profiler started')
            self._startTime = globalClock.getFrameTime()
            self._profileCounter = 0
            self._jitter = None
            self._period2aggregateProfile = {}
            self._id2session = {}
            self._id2task = {}
            # don't profile process startup
            self._task = taskMgr.doMethodLater(
                self._period, self._scheduleNextProfileDoLater,
                'FrameProfilerStart-%s' % serialNum())
        else:
            self._task.remove()
            del self._task
            for session in self._period2aggregateProfile.values():
                session.release()
            del self._period2aggregateProfile
            for task in self._id2task.values():
                task.remove()
            del self._id2task
            for session in self._id2session.values():
                session.release()
            del self._id2session
            self.notify.info('frame profiler stopped')

    def _scheduleNextProfileDoLater(self, task):
        self._scheduleNextProfile()
        return Task.done

    def _scheduleNextProfile(self):
        self._profileCounter += 1
        self._timeElapsed = self._profileCounter * self._period
        #assert isInteger(self._timeElapsed)
        time = self._startTime + self._timeElapsed

        # vary the actual delay between profiles by a random amount to prevent interaction
        # with periodic events
        jitter = self._jitter
        if jitter is None:
            jitter = normalDistrib(-self._jitterMagnitude,
                                   self._jitterMagnitude)
            time += jitter
        else:
            time -= jitter
            jitter = None
        self._jitter = jitter

        sessionId = serialNum()
        session = taskMgr.getProfileSession('FrameProfile-%s' % sessionId)
        self._id2session[sessionId] = session
        taskMgr.profileFrames(num=1,
                              session=session,
                              callback=Functor(self._analyzeResults,
                                               sessionId))

        # schedule the next profile
        delay = max(time - globalClock.getFrameTime(), 0.)
        self._task = taskMgr.doMethodLater(delay,
                                           self._scheduleNextProfileDoLater,
                                           'FrameProfiler-%s' % serialNum())

    def _analyzeResults(self, sessionId):
        # do the analysis in a task 1) to separate the processing from the profiled frame,
        # and 2) to get the processing to show up in a named task instead of in the taskMgr
        self._id2task[sessionId] = taskMgr.add(
            Functor(self._doAnalysis, sessionId),
            'FrameProfilerAnalysis-%s' % sessionId)

    def _doAnalysis(self, sessionId, task):
        if hasattr(task, '_generator'):
            gen = task._generator
        else:
            gen = self._doAnalysisGen(sessionId)
            task._generator = gen
        result = next(gen)
        if result == Task.done:
            del task._generator
        return result

    def _doAnalysisGen(self, sessionId):
        # generator to limit max number of profile loggings per frame
        p2ap = self._period2aggregateProfile

        self._id2task.pop(sessionId)
        session = self._id2session.pop(sessionId)

        if session.profileSucceeded():
            # always add this profile to the first aggregated profile
            period = self._logSchedule[0]
            if period not in self._period2aggregateProfile:
                p2ap[period] = session.getReference()
            else:
                p2ap[period].aggregate(session)
        else:
            self.notify.warning('frame profile did not succeed')

        session.release()
        session = None

        counter = 0

        # log profiles when it's time, and aggregate them upwards into the
        # next-longer profile
        for pi in range(len(self._logSchedule)):
            period = self._logSchedule[pi]
            if (self._timeElapsed % period) == 0:
                if period in p2ap:
                    # delay until the next frame if we've already processed N profiles this frame
                    if counter >= 3:
                        counter = 0
                        yield Task.cont
                    self.notify.info(
                        'aggregate profile of sampled frames over last %s\n%s'
                        % (formatTimeExact(period), p2ap[period].getResults()))
                    counter += 1
                    # aggregate this profile into the next larger profile
                    nextIndex = pi + 1
                    if nextIndex >= len(self._logSchedule):
                        # if we're adding a new period to the end of the log period table,
                        # set it to double the duration of the current longest period
                        nextPeriod = period * 2
                        self._logSchedule.append(nextPeriod)
                    else:
                        nextPeriod = self._logSchedule[nextIndex]
                    if nextPeriod not in p2ap:
                        p2ap[nextPeriod] = p2ap[period].getReference()
                    else:
                        p2ap[nextPeriod].aggregate(p2ap[period])
                    # this profile is now represented in the next larger profile
                    # throw it out
                    p2ap[period].release()
                    del p2ap[period]
            else:
                # current time is not divisible evenly into selected period, and all higher
                # periods are multiples of this one
                break

        yield Task.done
class TaskProfiler:
    # this does intermittent profiling of tasks running on the system
    # if a task has a spike in execution time, the profile of the spike is logged
    notify = directNotify.newCategory("TaskProfiler")

    def __init__(self):
        self._enableFC = FunctionCall(self._setEnabled, taskMgr.getProfileTasksSV())
        self._enableFC.pushCurrentState()
        # table of task name pattern to TaskTracker
        self._namePrefix2tracker = {}
        self._task = None

    def destroy(self):
        if taskMgr.getProfileTasks():
            self._setEnabled(False)
        self._enableFC.destroy()
        for tracker in self._namePrefix2tracker.itervalues():
            tracker.destroy()
        del self._namePrefix2tracker
        del self._task

    @staticmethod
    def GetDefaultSpikeThreshold():
        return config.GetFloat('profile-task-spike-threshold', 5.)

    @staticmethod
    def SetSpikeThreshold(spikeThreshold):
        TaskTracker.SpikeThreshold = spikeThreshold
    @staticmethod
    def GetSpikeThreshold():
        return TaskTracker.SpikeThreshold

    def logProfiles(self, name=None):
        if name:
            name = name.lower()
        for namePrefix, tracker in self._namePrefix2tracker.iteritems():
            if (name and (name not in namePrefix.lower())):
                continue
            tracker.log()

    def flush(self, name):
        if name:
            name = name.lower()
        # flush stored task profiles
        for namePrefix, tracker in self._namePrefix2tracker.iteritems():
            if (name and (name not in namePrefix.lower())):
                continue
            tracker.flush()

    def _setEnabled(self, enabled):
        if enabled:
            self.notify.info('task profiler started')
            self._taskName = 'profile-tasks-%s' % id(self)
            taskMgr.add(self._doProfileTasks, self._taskName, priority=-200)
        else:
            taskMgr.remove(self._taskName)
            del self._taskName
            self.notify.info('task profiler stopped')

    def _doProfileTasks(self, task=None):
        # gather data from the previous frame
        # set up for the next frame
        if (self._task is not None) and taskMgr._hasProfiledDesignatedTask():
            session = taskMgr._getLastTaskProfileSession()
            # if we couldn't profile, throw this result out
            if session.profileSucceeded():
                namePrefix = self._task.getNamePrefix()
                if namePrefix not in self._namePrefix2tracker:
                    self._namePrefix2tracker[namePrefix] = TaskTracker(namePrefix)
                tracker = self._namePrefix2tracker[namePrefix]
                tracker.addProfileSession(session)

        # set up the next task
        self._task = taskMgr._getRandomTask()
        taskMgr._setProfileTask(self._task)

        return task.cont
예제 #3
0
class SiegeManager(DistributedObject, SiegeManagerBase):
    TeamJoinableChangedEvent = 'PVPTeamJoinableChanged'
    
    def __init__(self, cr):
        DistributedObject.__init__(self, cr)
        SiegeManagerBase.__init__(self)

    
    def generate(self):
        self._announcerInterest = None
        self._siegeTeam = 0
        self._siegeTeamUpdater = FunctionCall(self._setSiegeTeam, localAvatar._siegeTeamSV)
        self._siegeTeamUpdater.pushCurrentState()
        DistributedObject.generate(self)
        self._pvpTeamJoinable = { }
        base.cr.distributedDistrict.siegeManager = self

    
    def delete(self):
        self._siegeTeamUpdater.destroy()
        del self._siegeTeamUpdater
        self._removeAnnouncerInterest()
        del self._pvpTeamJoinable
        del base.cr.distributedDistrict.siegeManager
        DistributedObject.delete(self)

    
    def setPvpEnabled(self, enabled):
        self._pvpEnabled = enabled

    
    def getPvpEnabled(self):
        return self._pvpEnabled

    
    def setTeamsJoinable(self, teamJoinableItems):
        for (teamId, joinable) in teamJoinableItems:
            self._pvpTeamJoinable[teamId] = joinable
        
        messenger.send(SiegeManager.TeamJoinableChangedEvent)

    
    def teamIsJoinable(self, teamId):
        if not config.GetBool('want-pvp-team-balance', 1):
            return True
        
        return self._pvpTeamJoinable.get(teamId, True)

    
    def sendTalk(self, message):
        print 'Seige Manager Sending Message %s' % message
        self.sendUpdate('setTalkGroup', [
            0,
            0,
            '',
            message,
            [],
            0])

    
    def sendWLChat(self, message):
        self.sendUpdate('sendWLChat', [
            message,
            0,
            0])

    
    def sendSC(self, msgIndex):
        self.sendUpdate('sendSC', [
            msgIndex])

    
    def setTalkGroup(self, fromAv, fromAC, avatarName, chat, mods, flags):
        print 'Seige Manager- SetTalkGroup %s' % chat
        teamName = self.getPVPChatTeamName(localAvatar.getSiegeTeam())
        (message, scrubbed) = localAvatar.scrubTalk(chat, mods)
        base.talkAssistant.receiveShipPVPMessage(fromAv, fromAC, avatarName, teamName, message, scrubbed)

    
    def recvChat(self, avatarId, message, chatFlags, DISLid, name):
        teamName = self.getPVPChatTeamName(localAvatar.getSiegeTeam())
        if not self.cr.avatarFriendsManager.checkIgnored(avatarId):
            displayMess = '%s %s %s' % (name, self.getPVPChatTeamName(localAvatar.getSiegeTeam()), message)
            base.talkAssistant.receiveShipPVPMessage(avatarId, DISLid, name, teamName, message)
        

    
    def recvWLChat(self, avatarId, message, chatFlags, DISLid, name):
        teamName = self.getPVPChatTeamName(localAvatar.getSiegeTeam())
        if not self.cr.avatarFriendsManager.checkIgnored(avatarId):
            displayMess = '%s %s %s' % (name, self.getPVPChatTeamName(localAvatar.getSiegeTeam()), message)
            base.talkAssistant.receiveShipPVPMessage(avatarId, DISLid, name, teamName, message)
        

    
    def recvSpeedChat(self, avatarId, msgIndex, name):
        print 'siege manager recvSpeedChat'
        if not self.cr.avatarFriendsManager.checkIgnored(avatarId):
            displayMess = '%s %s %s' % (name, self.getPVPChatTeamName(localAvatar.getSiegeTeam()), SCDecoders.decodeSCStaticTextMsg(msgIndex))
            message = SCDecoders.decodeSCStaticTextMsg(msgIndex)
            teamName = self.getPVPChatTeamName(localAvatar.getSiegeTeam())
            base.talkAssistant.receiveShipPVPMessage(avatarId, 0, name, teamName, message)
        

    
    def sendSCQuest(self, questInt, msgType, taskNum):
        self.sendUpdate('sendSCQuest', [
            questInt,
            msgType,
            taskNum])

    
    def recvSCQuest(self, avName, senderId, questInt, msgType, taskNum):
        senderName = avName
        message = base.talkAssistant.SCDecoder.decodeSCQuestMsgInt(questInt, msgType, taskNum)
        if not self.cr.avatarFriendsManager.checkIgnored(senderId):
            teamName = self.getPVPChatTeamName(localAvatar.getSiegeTeam())
            displayMess = '%s %s %s' % (avName, teamName, message)
            base.talkAssistant.receiveShipPVPMessage(senderId, 0, avName, teamName, message)
        

    
    def getPVPChatTeamName(self, teamId):
        if teamId == 2:
            return PLocalizer.PVPSpanish
        elif teamId == 1:
            return PLocalizer.PVPFrench
        else:
            return PLocalizer.PVPPrefix

    
    def _addAnnouncerInterest(self):
        if not self._announcerInterest:
            self._announcerInterest = self.cr.addTaggedInterest(self.doId, self.ANNOUNCER_ZONE, self.cr.ITAG_GAME, 'siegeAnnouncer')
        

    
    def _removeAnnouncerInterest(self):
        if self._announcerInterest:
            self.cr.removeTaggedInterest(self._announcerInterest)
            self._announcerInterest = None
        

    
    def _setSiegeTeam(self, siegeTeam):
        if siegeTeam and not (self._siegeTeam):
            self._addAnnouncerInterest()
        elif not siegeTeam and self._siegeTeam:
            self._removeAnnouncerInterest()
        
        self._siegeTeam = siegeTeam
예제 #4
0
class SiegeManager(DistributedObject, SiegeManagerBase):
    TeamJoinableChangedEvent = 'PVPTeamJoinableChanged'

    def __init__(self, cr):
        DistributedObject.__init__(self, cr)
        SiegeManagerBase.__init__(self)

    def generate(self):
        self._announcerInterest = None
        self._siegeTeam = 0
        self._siegeTeamUpdater = FunctionCall(self._setSiegeTeam,
                                              localAvatar._siegeTeamSV)
        self._siegeTeamUpdater.pushCurrentState()
        DistributedObject.generate(self)
        self._pvpTeamJoinable = {}
        base.cr.distributedDistrict.siegeManager = self

    def delete(self):
        self._siegeTeamUpdater.destroy()
        del self._siegeTeamUpdater
        self._removeAnnouncerInterest()
        del self._pvpTeamJoinable
        del base.cr.distributedDistrict.siegeManager
        DistributedObject.delete(self)

    def setPvpEnabled(self, enabled):
        self._pvpEnabled = enabled

    def getPvpEnabled(self):
        return self._pvpEnabled

    def setTeamsJoinable(self, teamJoinableItems):
        for (teamId, joinable) in teamJoinableItems:
            self._pvpTeamJoinable[teamId] = joinable

        messenger.send(SiegeManager.TeamJoinableChangedEvent)

    def teamIsJoinable(self, teamId):
        if not config.GetBool('want-pvp-team-balance', 1):
            return True

        return self._pvpTeamJoinable.get(teamId, True)

    def sendTalk(self, message):
        print 'Seige Manager Sending Message %s' % message
        self.sendUpdate('setTalkGroup', [0, 0, '', message, [], 0])

    def sendWLChat(self, message):
        self.sendUpdate('sendWLChat', [message, 0, 0])

    def sendSC(self, msgIndex):
        self.sendUpdate('sendSC', [msgIndex])

    def setTalkGroup(self, fromAv, fromAC, avatarName, chat, mods, flags):
        print 'Seige Manager- SetTalkGroup %s' % chat
        teamName = self.getPVPChatTeamName(localAvatar.getSiegeTeam())
        (message, scrubbed) = localAvatar.scrubTalk(chat, mods)
        base.talkAssistant.receiveShipPVPMessage(fromAv, fromAC, avatarName,
                                                 teamName, message, scrubbed)

    def recvChat(self, avatarId, message, chatFlags, DISLid, name):
        teamName = self.getPVPChatTeamName(localAvatar.getSiegeTeam())
        if not self.cr.avatarFriendsManager.checkIgnored(avatarId):
            displayMess = '%s %s %s' % (
                name, self.getPVPChatTeamName(
                    localAvatar.getSiegeTeam()), message)
            base.talkAssistant.receiveShipPVPMessage(avatarId, DISLid, name,
                                                     teamName, message)

    def recvWLChat(self, avatarId, message, chatFlags, DISLid, name):
        teamName = self.getPVPChatTeamName(localAvatar.getSiegeTeam())
        if not self.cr.avatarFriendsManager.checkIgnored(avatarId):
            displayMess = '%s %s %s' % (
                name, self.getPVPChatTeamName(
                    localAvatar.getSiegeTeam()), message)
            base.talkAssistant.receiveShipPVPMessage(avatarId, DISLid, name,
                                                     teamName, message)

    def recvSpeedChat(self, avatarId, msgIndex, name):
        print 'siege manager recvSpeedChat'
        if not self.cr.avatarFriendsManager.checkIgnored(avatarId):
            displayMess = '%s %s %s' % (
                name, self.getPVPChatTeamName(localAvatar.getSiegeTeam()),
                SCDecoders.decodeSCStaticTextMsg(msgIndex))
            message = SCDecoders.decodeSCStaticTextMsg(msgIndex)
            teamName = self.getPVPChatTeamName(localAvatar.getSiegeTeam())
            base.talkAssistant.receiveShipPVPMessage(avatarId, 0, name,
                                                     teamName, message)

    def sendSCQuest(self, questInt, msgType, taskNum):
        self.sendUpdate('sendSCQuest', [questInt, msgType, taskNum])

    def recvSCQuest(self, avName, senderId, questInt, msgType, taskNum):
        senderName = avName
        message = base.talkAssistant.SCDecoder.decodeSCQuestMsgInt(
            questInt, msgType, taskNum)
        if not self.cr.avatarFriendsManager.checkIgnored(senderId):
            teamName = self.getPVPChatTeamName(localAvatar.getSiegeTeam())
            displayMess = '%s %s %s' % (avName, teamName, message)
            base.talkAssistant.receiveShipPVPMessage(senderId, 0, avName,
                                                     teamName, message)

    def getPVPChatTeamName(self, teamId):
        if teamId == 2:
            return PLocalizer.PVPSpanish
        elif teamId == 1:
            return PLocalizer.PVPFrench
        else:
            return PLocalizer.PVPPrefix

    def _addAnnouncerInterest(self):
        if not self._announcerInterest:
            self._announcerInterest = self.cr.addTaggedInterest(
                self.doId, self.ANNOUNCER_ZONE, self.cr.ITAG_GAME,
                'siegeAnnouncer')

    def _removeAnnouncerInterest(self):
        if self._announcerInterest:
            self.cr.removeTaggedInterest(self._announcerInterest)
            self._announcerInterest = None

    def _setSiegeTeam(self, siegeTeam):
        if siegeTeam and not (self._siegeTeam):
            self._addAnnouncerInterest()
        elif not siegeTeam and self._siegeTeam:
            self._removeAnnouncerInterest()

        self._siegeTeam = siegeTeam
예제 #5
0
class FrameProfiler:
    notify = directNotify.newCategory('FrameProfiler')
    Minute = 60
    Hour = 60 * Minute
    Day = 24 * Hour
    
    def __init__(self):
        Hour = FrameProfiler.Hour
        self._period = 2 * FrameProfiler.Minute
        if config.GetBool('frequent-frame-profiles', 0):
            self._period = 1 * FrameProfiler.Minute
        
        self._jitterMagnitude = self._period * 0.75
        self._logSchedule = [
            1 * FrameProfiler.Hour,
            4 * FrameProfiler.Hour,
            12 * FrameProfiler.Hour,
            1 * FrameProfiler.Day]
        if config.GetBool('frequent-frame-profiles', 0):
            self._logSchedule = [
                1 * FrameProfiler.Minute,
                4 * FrameProfiler.Minute,
                12 * FrameProfiler.Minute,
                24 * FrameProfiler.Minute]
        
        for t in self._logSchedule:
            pass
        
        for i in xrange(len(self._logSchedule)):
            e = self._logSchedule[i]
            for j in xrange(i, len(self._logSchedule)):
                pass
            
        
        self._enableFC = FunctionCall(self._setEnabled, taskMgr.getProfileFramesSV())
        self._enableFC.pushCurrentState()

    
    def destroy(self):
        self._enableFC.set(False)
        self._enableFC.destroy()

    
    def _setEnabled(self, enabled):
        if enabled:
            self.notify.info('frame profiler started')
            self._startTime = globalClock.getFrameTime()
            self._profileCounter = 0
            self._jitter = None
            self._period2aggregateProfile = { }
            self._id2session = { }
            self._id2task = { }
            self._task = taskMgr.doMethodLater(self._period, self._scheduleNextProfileDoLater, 'FrameProfilerStart-%s' % serialNum())
        else:
            self._task.remove()
            del self._task
            for session in self._period2aggregateProfile.itervalues:
                session.release()
            
            del self._period2aggregateProfile
            for task in self._id2task.itervalues():
                task.remove()
            
            del self._id2task
            for session in self._id2session.itervalues():
                session.release()
            
            del self._id2session
            self.notify.info('frame profiler stopped')

    
    def _scheduleNextProfileDoLater(self, task):
        self._scheduleNextProfile()
        return task.done

    
    def _scheduleNextProfile(self):
        self._profileCounter += 1
        self._timeElapsed = self._profileCounter * self._period
        time = self._startTime + self._timeElapsed
        jitter = self._jitter
        if jitter is None:
            jitter = normalDistrib(-(self._jitterMagnitude), self._jitterMagnitude)
            time += jitter
        else:
            time -= jitter
            jitter = None
        self._jitter = jitter
        sessionId = serialNum()
        session = taskMgr.getProfileSession('FrameProfile-%s' % sessionId)
        self._id2session[sessionId] = session
        taskMgr.profileFrames(num = 1, session = session, callback = Functor(self._analyzeResults, sessionId))
        delay = max(time - globalClock.getFrameTime(), 0.0)
        self._task = taskMgr.doMethodLater(delay, self._scheduleNextProfileDoLater, 'FrameProfiler-%s' % serialNum())

    
    def _analyzeResults(self, sessionId):
        self._id2task[sessionId] = taskMgr.add(Functor(self._doAnalysis, sessionId), 'FrameProfilerAnalysis-%s' % sessionId)

    
    def _doAnalysis(self, sessionId, task):
        if hasattr(task, '_generator'):
            gen = task._generator
        else:
            gen = self._doAnalysisGen(sessionId)
            task._generator = gen
        result = gen.next()
        if result == Task.done:
            del task._generator
        
        return result

    
    def _doAnalysisGen(self, sessionId):
        p2ap = self._period2aggregateProfile
        self._id2task.pop(sessionId)
        session = self._id2session.pop(sessionId)
        if session.profileSucceeded():
            period = self._logSchedule[0]
            if period not in self._period2aggregateProfile:
                p2ap[period] = session.getReference()
            else:
                p2ap[period].aggregate(session)
        else:
            self.notify.warning('frame profile did not succeed')
        session.release()
        session = None
        counter = 0
        for pi in xrange(len(self._logSchedule)):
            period = self._logSchedule[pi]
            if self._timeElapsed % period == 0:
                if period in p2ap:
                    if counter >= 3:
                        counter = 0
                        yield Task.cont
                    
                    self.notify.info('aggregate profile of sampled frames over last %s\n%s' % (formatTimeExact(period), p2ap[period].getResults()))
                    counter += 1
                    nextIndex = pi + 1
                    if nextIndex >= len(self._logSchedule):
                        nextPeriod = period * 2
                        self._logSchedule.append(nextPeriod)
                    else:
                        nextPeriod = self._logSchedule[nextIndex]
                    if nextPeriod not in p2ap:
                        p2ap[nextPeriod] = p2ap[period].getReference()
                    else:
                        p2ap[nextPeriod].aggregate(p2ap[period])
                    p2ap[period].release()
                    del p2ap[period]
                
            period in p2ap
            break
        
        yield Task.done
예제 #6
0
class SCTerminal(SCElement):

    def __init__(self, linkedEmote = None):
        SCElement.__init__(self)
        self.setLinkedEmote(linkedEmote)
        scGui = loader.loadModel(SCMenu.GuiModelName)
        self.emotionIcon = scGui.find('**/emotionIcon')
        self.setDisabled(False)
        self.__numCharges = -1
        self._handleWhisperModeSV = StateVar(False)
        self._handleWhisperModeFC = None
        return

    def destroy(self):
        self._handleWhisperModeSV.set(False)
        if self._handleWhisperModeFC:
            self._handleWhisperModeFC.destroy()
        self._handleWhisperModeSV.destroy()
        SCElement.destroy(self)

    def privSetSettingsRef(self, settingsRef):
        SCElement.privSetSettingsRef(self, settingsRef)
        if self._handleWhisperModeFC is None:
            self._handleWhisperModeFC = FunctionCall(self._handleWhisperModeSVChanged, self._handleWhisperModeSV)
            self._handleWhisperModeFC.pushCurrentState()
        self._handleWhisperModeSV.set(self.settingsRef is not None and not self.isWhisperable())
        return

    def _handleWhisperModeSVChanged(self, handleWhisperMode):
        if handleWhisperMode:
            self._wmcListener = DirectObject()
            self._wmcListener.accept(self.getEventName(SCWhisperModeChangeEvent), self._handleWhisperModeChange)
        elif hasattr(self, '_wmcListener'):
            self._wmcListener.ignoreAll()
            del self._wmcListener
            self.invalidate()

    def _handleWhisperModeChange(self, whisperMode):
        self.invalidate()

    def handleSelect(self):
        messenger.send(self.getEventName(SCTerminalSelectedEvent))
        if self.hasLinkedEmote() and self.linkedEmoteEnabled():
            messenger.send(self.getEventName(SCTerminalLinkedEmoteEvent), [self.linkedEmote])

    def isWhisperable(self):
        return True

    def getLinkedEmote(self):
        return self.linkedEmote

    def setLinkedEmote(self, linkedEmote):
        self.linkedEmote = linkedEmote
        self.invalidate()

    def hasLinkedEmote(self):
        return self.linkedEmote is not None

    def linkedEmoteEnabled(self):
        if Emote.globalEmote:
            return Emote.globalEmote.isEnabled(self.linkedEmote)

    def getCharges(self):
        return self.__numCharges

    def setCharges(self, nCharges):
        self.__numCharges = nCharges
        if nCharges is 0:
            self.setDisabled(True)

    def isDisabled(self):
        return self.__disabled or self.isWhispering() and not self.isWhisperable()

    def setDisabled(self, bDisabled):
        self.__disabled = bDisabled

    def onMouseClick(self, event):
        if not self.isDisabled():
            SCElement.onMouseClick(self, event)
            self.handleSelect()

    def getMinDimensions(self):
        width, height = SCElement.getMinDimensions(self)
        if self.hasLinkedEmote():
            width += 1.3
        return (width, height)

    def finalize(self, dbArgs = {}):
        if not self.isDirty():
            return
        args = {}
        if self.hasLinkedEmote():
            self.lastEmoteIconColor = self.getEmoteIconColor()
            self.emotionIcon.setColorScale(*self.lastEmoteIconColor)
            args.update({'image': self.emotionIcon,
             'image_pos': (self.width - 0.6, 0, -self.height * 0.5)})
        if self.isDisabled():
            args.update({'rolloverColor': (0, 0, 0, 0),
             'pressedColor': (0, 0, 0, 0),
             'rolloverSound': None,
             'clickSound': None,
             'text_fg': self.getColorScheme().getTextDisabledColor() + (1,)})
        args.update(dbArgs)
        SCElement.finalize(self, dbArgs=args)
        return

    def getEmoteIconColor(self):
        if self.linkedEmoteEnabled() and not self.isWhispering():
            r, g, b = self.getColorScheme().getEmoteIconColor()
        else:
            r, g, b = self.getColorScheme().getEmoteIconDisabledColor()
        return (r,
         g,
         b,
         1)

    def updateEmoteIcon(self):
        if hasattr(self, 'button'):
            self.lastEmoteIconColor = self.getEmoteIconColor()
            for i in xrange(self.button['numStates']):
                self.button['image%s_image' % i].setColorScale(*self.lastEmoteIconColor)

        else:
            self.invalidate()

    def enterVisible(self):
        SCElement.enterVisible(self)
        if hasattr(self, 'lastEmoteIconColor'):
            if self.getEmoteIconColor() != self.lastEmoteIconColor:
                self.invalidate()

        def handleWhisperModeChange(whisperMode, self = self):
            if self.hasLinkedEmote():
                if self.isVisible() and not self.isWhispering():
                    self.updateEmoteIcon()

        self.accept(self.getEventName(SCWhisperModeChangeEvent), handleWhisperModeChange)

        def handleEmoteEnableStateChange(self = self):
            if self.hasLinkedEmote():
                if self.isVisible() and not self.isWhispering():
                    self.updateEmoteIcon()

        if self.hasLinkedEmote():
            if Emote.globalEmote:
                self.accept(Emote.globalEmote.EmoteEnableStateChanged, handleEmoteEnableStateChange)

    def exitVisible(self):
        SCElement.exitVisible(self)
        self.ignore(self.getEventName(SCWhisperModeChangeEvent))
        if Emote.globalEmote:
            self.ignore(Emote.globalEmote.EmoteEnableStateChanged)

    def getDisplayText(self):
        if self.getCharges() is not -1:
            return self.text + ' (%s)' % self.getCharges()
        else:
            return self.text
class SCTerminal(SCElement):

    def __init__(self, linkedEmote = None):
        SCElement.__init__(self)
        self.setLinkedEmote(linkedEmote)
        scGui = loader.loadModel(SCMenu.GuiModelName)
        self.emotionIcon = scGui.find('**/emotionIcon')
        self.setDisabled(False)
        self.__numCharges = -1
        self._handleWhisperModeSV = StateVar(False)
        self._handleWhisperModeFC = None
        return

    def destroy(self):
        self._handleWhisperModeSV.set(False)
        if self._handleWhisperModeFC:
            self._handleWhisperModeFC.destroy()
        self._handleWhisperModeSV.destroy()
        SCElement.destroy(self)

    def privSetSettingsRef(self, settingsRef):
        SCElement.privSetSettingsRef(self, settingsRef)
        if self._handleWhisperModeFC is None:
            self._handleWhisperModeFC = FunctionCall(self._handleWhisperModeSVChanged, self._handleWhisperModeSV)
            self._handleWhisperModeFC.pushCurrentState()
        self._handleWhisperModeSV.set(self.settingsRef is not None and not self.isWhisperable())
        return

    def _handleWhisperModeSVChanged(self, handleWhisperMode):
        if handleWhisperMode:
            self._wmcListener = DirectObject()
            self._wmcListener.accept(self.getEventName(SCWhisperModeChangeEvent), self._handleWhisperModeChange)
        elif hasattr(self, '_wmcListener'):
            self._wmcListener.ignoreAll()
            del self._wmcListener
            self.invalidate()

    def _handleWhisperModeChange(self, whisperMode):
        self.invalidate()

    def handleSelect(self):
        messenger.send(self.getEventName(SCTerminalSelectedEvent))
        if self.hasLinkedEmote() and self.linkedEmoteEnabled():
            messenger.send(self.getEventName(SCTerminalLinkedEmoteEvent), [self.linkedEmote])

    def isWhisperable(self):
        return True

    def getLinkedEmote(self):
        return self.linkedEmote

    def setLinkedEmote(self, linkedEmote):
        self.linkedEmote = linkedEmote
        self.invalidate()

    def hasLinkedEmote(self):
        return self.linkedEmote is not None

    def linkedEmoteEnabled(self):
        if Emote.globalEmote:
            return Emote.globalEmote.isEnabled(self.linkedEmote)

    def getCharges(self):
        return self.__numCharges

    def setCharges(self, nCharges):
        self.__numCharges = nCharges
        if nCharges is 0:
            self.setDisabled(True)

    def isDisabled(self):
        return self.__disabled or self.isWhispering() and not self.isWhisperable()

    def setDisabled(self, bDisabled):
        self.__disabled = bDisabled

    def onMouseClick(self, event):
        if not self.isDisabled():
            SCElement.onMouseClick(self, event)
            self.handleSelect()

    def getMinDimensions(self):
        width, height = SCElement.getMinDimensions(self)
        if self.hasLinkedEmote():
            width += 1.3
        return (width, height)

    def finalize(self, dbArgs = {}):
        if not self.isDirty():
            return
        args = {}
        if self.hasLinkedEmote():
            self.lastEmoteIconColor = self.getEmoteIconColor()
            self.emotionIcon.setColorScale(*self.lastEmoteIconColor)
            args.update({'image': self.emotionIcon,
             'image_pos': (self.width - 0.6, 0, -self.height * 0.5)})
        if self.isDisabled():
            args.update({'rolloverColor': (0, 0, 0, 0),
             'pressedColor': (0, 0, 0, 0),
             'rolloverSound': None,
             'clickSound': None,
             'text_fg': self.getColorScheme().getTextDisabledColor() + (1,)})
        args.update(dbArgs)
        SCElement.finalize(self, dbArgs=args)
        return

    def getEmoteIconColor(self):
        if self.linkedEmoteEnabled() and not self.isWhispering():
            r, g, b = self.getColorScheme().getEmoteIconColor()
        else:
            r, g, b = self.getColorScheme().getEmoteIconDisabledColor()
        return (r,
         g,
         b,
         1)

    def updateEmoteIcon(self):
        if hasattr(self, 'button'):
            self.lastEmoteIconColor = self.getEmoteIconColor()
            for i in range(self.button['numStates']):
                self.button['image%s_image' % i].setColorScale(*self.lastEmoteIconColor)

        else:
            self.invalidate()

    def enterVisible(self):
        SCElement.enterVisible(self)
        if hasattr(self, 'lastEmoteIconColor'):
            if self.getEmoteIconColor() != self.lastEmoteIconColor:
                self.invalidate()

        def handleWhisperModeChange(whisperMode, self = self):
            if self.hasLinkedEmote():
                if self.isVisible() and not self.isWhispering():
                    self.updateEmoteIcon()

        self.accept(self.getEventName(SCWhisperModeChangeEvent), handleWhisperModeChange)

        def handleEmoteEnableStateChange(self = self):
            if self.hasLinkedEmote():
                if self.isVisible() and not self.isWhispering():
                    self.updateEmoteIcon()

        if self.hasLinkedEmote():
            if Emote.globalEmote:
                self.accept(Emote.globalEmote.EmoteEnableStateChanged, handleEmoteEnableStateChange)

    def exitVisible(self):
        SCElement.exitVisible(self)
        self.ignore(self.getEventName(SCWhisperModeChangeEvent))
        if Emote.globalEmote:
            self.ignore(Emote.globalEmote.EmoteEnableStateChanged)

    def getDisplayText(self):
        if self.getCharges() is not -1:
            return self.text + ' (%s)' % self.getCharges()
        else:
            return self.text
class FrameProfiler:
    notify = directNotify.newCategory('FrameProfiler')

    # because of precision requirements, all times related to the profile/log
    # schedule are stored as integers
    Minute = 60
    Hour = 60 * Minute
    Day = 24 * Hour

    def __init__(self):
        Hour = FrameProfiler.Hour
        # how long to wait between frame profiles
        self._period = 2 * FrameProfiler.Minute
        if config.GetBool('frequent-frame-profiles', 0):
            self._period = 1 * FrameProfiler.Minute
        # used to prevent profile from being taken exactly every 'period' seconds
        self._jitterMagnitude = self._period * .75
        # when to log output
        # each entry must be an integer multiple of all previous entries
        # as well as an integer multiple of the period
        self._logSchedule = [ 1 * FrameProfiler.Hour,
                              4 * FrameProfiler.Hour,
                             12 * FrameProfiler.Hour,
                              1 * FrameProfiler.Day,
                              ] # day schedule proceeds as 1, 2, 4, 8 days, etc.
        if config.GetBool('frequent-frame-profiles', 0):
            self._logSchedule = [ 1  * FrameProfiler.Minute,
                                  4  * FrameProfiler.Minute,
                                  12 * FrameProfiler.Minute,
                                  24 * FrameProfiler.Minute,
                                  ]
        for t in self._logSchedule:
            assert isInteger(t)
            # make sure the period is evenly divisible into each element of the log schedule
            assert (t % self._period) == 0
        # make sure each element of the schedule is evenly divisible into each subsequent element
        for i in xrange(len(self._logSchedule)):
            e = self._logSchedule[i]
            for j in xrange(i, len(self._logSchedule)):
                assert (self._logSchedule[j] % e) == 0
        assert isInteger(self._period)
        self._enableFC = FunctionCall(self._setEnabled, taskMgr.getProfileFramesSV())
        self._enableFC.pushCurrentState()

    def destroy(self):
        self._enableFC.set(False)
        self._enableFC.destroy()
        
    def _setEnabled(self, enabled):
        if enabled:
            self.notify.info('frame profiler started')
            self._startTime = globalClock.getFrameTime()
            self._profileCounter = 0
            self._jitter = None
            self._period2aggregateProfile = {}
            self._id2session = {}
            self._id2task = {}
            # don't profile process startup
            self._task = taskMgr.doMethodLater(self._period, self._scheduleNextProfileDoLater,
                                               'FrameProfilerStart-%s' % serialNum())
        else:
            self._task.remove()
            del self._task
            for session in self._period2aggregateProfile.itervalues:
                session.release()
            del self._period2aggregateProfile
            for task in self._id2task.itervalues():
                task.remove()
            del self._id2task
            for session in self._id2session.itervalues():
                session.release()
            del self._id2session
            self.notify.info('frame profiler stopped')

    def _scheduleNextProfileDoLater(self, task):
        self._scheduleNextProfile()
        return task.done

    def _scheduleNextProfile(self):
        self._profileCounter += 1
        self._timeElapsed = self._profileCounter * self._period
        assert isInteger(self._timeElapsed)
        time = self._startTime + self._timeElapsed

        # vary the actual delay between profiles by a random amount to prevent interaction
        # with periodic events
        jitter = self._jitter
        if jitter is None:
            jitter = normalDistrib(-self._jitterMagnitude, self._jitterMagnitude)
            time += jitter
        else:
            time -= jitter
            jitter = None
        self._jitter = jitter
            
        sessionId = serialNum()
        session = taskMgr.getProfileSession('FrameProfile-%s' % sessionId)
        self._id2session[sessionId] = session
        taskMgr.profileFrames(num=1, session=session, callback=Functor(
            self._analyzeResults, sessionId))

        # schedule the next profile
        delay = max(time - globalClock.getFrameTime(), 0.)
        self._task = taskMgr.doMethodLater(delay, self._scheduleNextProfileDoLater,
                                           'FrameProfiler-%s' % serialNum())

    def _analyzeResults(self, sessionId):
        # do the analysis in a task 1) to separate the processing from the profiled frame,
        # and 2) to get the processing to show up in a named task instead of in the taskMgr
        self._id2task[sessionId] = taskMgr.add(
            Functor(self._doAnalysis, sessionId), 'FrameProfilerAnalysis-%s' % sessionId)

    def _doAnalysis(self, sessionId, task):
        if hasattr(task, '_generator'):
            gen = task._generator
        else:
            gen = self._doAnalysisGen(sessionId)
            task._generator = gen
        result = gen.next()
        if result == Task.done:
            del task._generator
        return result

    def _doAnalysisGen(self, sessionId):
        # generator to limit max number of profile loggings per frame
        p2ap = self._period2aggregateProfile

        self._id2task.pop(sessionId)
        session = self._id2session.pop(sessionId)

        if session.profileSucceeded():
            # always add this profile to the first aggregated profile
            period = self._logSchedule[0]
            if period not in self._period2aggregateProfile:
                p2ap[period] = session.getReference()
            else:
                p2ap[period].aggregate(session)
        else:
            self.notify.warning('frame profile did not succeed')

        session.release()
        session = None

        counter = 0

        # log profiles when it's time, and aggregate them upwards into the
        # next-longer profile
        for pi in xrange(len(self._logSchedule)):
            period = self._logSchedule[pi]
            if (self._timeElapsed % period) == 0:
                if period in p2ap:
                    # delay until the next frame if we've already processed N profiles this frame
                    if counter >= 3:
                        counter = 0
                        yield Task.cont
                    self.notify.info('aggregate profile of sampled frames over last %s\n%s' %
                                     (formatTimeExact(period), p2ap[period].getResults()))
                    counter += 1
                    # aggregate this profile into the next larger profile
                    nextIndex = pi + 1
                    if nextIndex >= len(self._logSchedule):
                        # if we're adding a new period to the end of the log period table,
                        # set it to double the duration of the current longest period
                        nextPeriod = period * 2
                        self._logSchedule.append(nextPeriod)
                    else:
                        nextPeriod = self._logSchedule[nextIndex]
                    if nextPeriod not in p2ap:
                        p2ap[nextPeriod] = p2ap[period].getReference()
                    else:
                        p2ap[nextPeriod].aggregate(p2ap[period])
                    # this profile is now represented in the next larger profile
                    # throw it out
                    p2ap[period].release()
                    del p2ap[period]
            else:
                # current time is not divisible evenly into selected period, and all higher
                # periods are multiples of this one
                break

        yield Task.done
예제 #9
0
class TaskProfiler:
    notify = directNotify.newCategory('TaskProfiler')

    def __init__(self):
        self._enableFC = FunctionCall(self._setEnabled,
                                      taskMgr.getProfileTasksSV())
        self._enableFC.pushCurrentState()
        self._namePrefix2tracker = {}
        self._task = None
        return

    def destroy(self):
        if taskMgr.getProfileTasks():
            self._setEnabled(False)
        self._enableFC.destroy()
        for tracker in self._namePrefix2tracker.itervalues():
            tracker.destroy()

        del self._namePrefix2tracker
        del self._task

    @staticmethod
    def GetDefaultSpikeThreshold():
        return config.GetFloat('profile-task-spike-threshold', 5.0)

    @staticmethod
    def SetSpikeThreshold(spikeThreshold):
        TaskTracker.SpikeThreshold = spikeThreshold

    @staticmethod
    def GetSpikeThreshold():
        return TaskTracker.SpikeThreshold

    def logProfiles(self, name=None):
        if name:
            name = name.lower()
        for namePrefix, tracker in self._namePrefix2tracker.iteritems():
            if name and name not in namePrefix.lower():
                continue
            tracker.log()

    def flush(self, name):
        if name:
            name = name.lower()
        for namePrefix, tracker in self._namePrefix2tracker.iteritems():
            if name and name not in namePrefix.lower():
                continue
            tracker.flush()

    def _setEnabled(self, enabled):
        if enabled:
            self.notify.info('task profiler started')
            self._taskName = 'profile-tasks-%s' % id(self)
            taskMgr.add(self._doProfileTasks, self._taskName, priority=-200)
        else:
            taskMgr.remove(self._taskName)
            del self._taskName
            self.notify.info('task profiler stopped')

    def _doProfileTasks(self, task=None):
        if self._task is not None and taskMgr._hasProfiledDesignatedTask():
            session = taskMgr._getLastTaskProfileSession()
            if session.profileSucceeded():
                namePrefix = self._task.getNamePrefix()
                if namePrefix not in self._namePrefix2tracker:
                    self._namePrefix2tracker[namePrefix] = TaskTracker(
                        namePrefix)
                tracker = self._namePrefix2tracker[namePrefix]
                tracker.addProfileSession(session)
        self._task = taskMgr._getRandomTask()
        taskMgr._setProfileTask(self._task)
        return task.cont
예제 #10
0
class TaskProfiler:
    # this does intermittent profiling of tasks running on the system
    # if a task has a spike in execution time, the profile of the spike is logged
    notify = directNotify.newCategory("TaskProfiler")

    def __init__(self):
        self._enableFC = FunctionCall(self._setEnabled, taskMgr.getProfileTasksSV())
        self._enableFC.pushCurrentState()
        # table of task name pattern to TaskTracker
        self._namePrefix2tracker = {}
        self._task = None

    def destroy(self):
        if taskMgr.getProfileTasks():
            self._setEnabled(False)
        self._enableFC.destroy()
        for tracker in self._namePrefix2tracker.itervalues():
            tracker.destroy()
        del self._namePrefix2tracker
        del self._task
        
    @staticmethod
    def GetDefaultSpikeThreshold():
        return config.GetFloat('profile-task-spike-threshold', 5.)

    @staticmethod
    def SetSpikeThreshold(spikeThreshold):
        TaskTracker.SpikeThreshold = spikeThreshold
    @staticmethod
    def GetSpikeThreshold():
        return TaskTracker.SpikeThreshold

    def logProfiles(self, name=None):
        if name:
            name = name.lower()
        for namePrefix, tracker in self._namePrefix2tracker.iteritems():
            if (name and (name not in namePrefix.lower())):
                continue
            tracker.log()

    def flush(self, name):
        if name:
            name = name.lower()
        # flush stored task profiles
        for namePrefix, tracker in self._namePrefix2tracker.iteritems():
            if (name and (name not in namePrefix.lower())):
                continue
            tracker.flush()

    def _setEnabled(self, enabled):
        if enabled:
            self.notify.info('task profiler started')
            self._taskName = 'profile-tasks-%s' % id(self)
            taskMgr.add(self._doProfileTasks, self._taskName, priority=-200)
        else:
            taskMgr.remove(self._taskName)
            del self._taskName
            self.notify.info('task profiler stopped')
        
    def _doProfileTasks(self, task=None):
        # gather data from the previous frame
        # set up for the next frame
        if (self._task is not None) and taskMgr._hasProfiledDesignatedTask():
            session = taskMgr._getLastTaskProfileSession()
            # if we couldn't profile, throw this result out
            if session.profileSucceeded():
                namePrefix = self._task.getNamePrefix()
                if namePrefix not in self._namePrefix2tracker:
                    self._namePrefix2tracker[namePrefix] = TaskTracker(namePrefix)
                tracker = self._namePrefix2tracker[namePrefix]
                tracker.addProfileSession(session)

        # set up the next task
        self._task = taskMgr._getRandomTask()
        taskMgr._setProfileTask(self._task)

        return task.cont
예제 #11
0
    1.0,
    1.0])
RepairKitHp = StateVarSetting('pvp.shipHeal.repairKit.HP', WeaponGlobals.getAttackHullHP(InventoryType.ShipRepairKit))
RepairKitSp = StateVarSetting('pvp.shipHeal.repairKit.SP', WeaponGlobals.getAttackSailHP(InventoryType.ShipRepairKit))
SinkHpBonusPercent = StateVarSetting('pvp.sinkBonus.hp.percent', 0.80000000000000004)
SinkStreakPeriod = StateVarSetting('pvp.announcements.sinkStreakPeriod', 5)

def updateRepairKitHp(hp):
    WeaponGlobals.__skillInfo[InventoryType.ShipRepairKit][WeaponGlobals.HULL_HP_INDEX] = hp


def updateRepairKitSp(sp):
    WeaponGlobals.__skillInfo[InventoryType.ShipRepairKit][WeaponGlobals.SAIL_HP_INDEX] = sp

UpdateRepairKitHp = FunctionCall(updateRepairKitHp, RepairKitHp)
UpdateRepairKitHp.pushCurrentState()
UpdateRepairKitSp = FunctionCall(updateRepairKitSp, RepairKitSp)
UpdateRepairKitSp.pushCurrentState()
RepairSpotLocatorNames = [
    'repair_spot_0',
    'repair_spot_1',
    'repair_spot_2',
    'repair_spot_3']
repairSpotNamePrefix = 'pvp.shipHeal.repairSpots.spots.'
ShipClass2repairLocators = {
    ShipGlobals.INTERCEPTORL1: StateVarSetting(repairSpotNamePrefix + 'interceptorL1', [
        0,
        1,
        2,
        3]),
    ShipGlobals.INTERCEPTORL2: StateVarSetting(repairSpotNamePrefix + 'interceptorL2', [
    1.0,
    1.0])
RepairKitHp = StateVarSetting('pvp.shipHeal.repairKit.HP', WeaponGlobals.getAttackHullHP(InventoryType.ShipRepairKit))
RepairKitSp = StateVarSetting('pvp.shipHeal.repairKit.SP', WeaponGlobals.getAttackSailHP(InventoryType.ShipRepairKit))
SinkHpBonusPercent = StateVarSetting('pvp.sinkBonus.hp.percent', 0.80000000000000004)
SinkStreakPeriod = StateVarSetting('pvp.announcements.sinkStreakPeriod', 5)

def updateRepairKitHp(hp):
    WeaponGlobals.__skillInfo[InventoryType.ShipRepairKit][WeaponGlobals.HULL_HP_INDEX] = hp


def updateRepairKitSp(sp):
    WeaponGlobals.__skillInfo[InventoryType.ShipRepairKit][WeaponGlobals.SAIL_HP_INDEX] = sp

UpdateRepairKitHp = FunctionCall(updateRepairKitHp, RepairKitHp)
UpdateRepairKitHp.pushCurrentState()
UpdateRepairKitSp = FunctionCall(updateRepairKitSp, RepairKitSp)
UpdateRepairKitSp.pushCurrentState()
RepairSpotLocatorNames = [
    'repair_spot_0',
    'repair_spot_1',
    'repair_spot_2',
    'repair_spot_3']
repairSpotNamePrefix = 'pvp.shipHeal.repairSpots.spots.'
ShipClass2repairLocators = {
    ShipGlobals.INTERCEPTORL1: StateVarSetting(repairSpotNamePrefix + 'interceptorL1', [
        0,
        1,
        2,
        3]),
    ShipGlobals.INTERCEPTORL2: StateVarSetting(repairSpotNamePrefix + 'interceptorL2', [
예제 #13
0
class SCTerminal(SCElement):
    """ SCTerminal is the base class for all 'terminal' speedchat
    entities """
    def __init__(self, linkedEmote=None):
        SCElement.__init__(self)
        self.setLinkedEmote(linkedEmote)

        scGui = loader.loadModel(SCMenu.GuiModelName)
        self.emotionIcon = scGui.find('**/emotionIcon')
        self.setDisabled(False)
        self.__numCharges = -1

        # should we listen for whisper mode changes?
        self._handleWhisperModeSV = StateVar(False)
        # can't set this up until we're ready to have the handler func called
        self._handleWhisperModeFC = None

    def destroy(self):
        self._handleWhisperModeSV.set(False)
        if self._handleWhisperModeFC:
            self._handleWhisperModeFC.destroy()
        self._handleWhisperModeSV.destroy()
        SCElement.destroy(self)

    def privSetSettingsRef(self, settingsRef):
        SCElement.privSetSettingsRef(self, settingsRef)
        if self._handleWhisperModeFC is None:
            self._handleWhisperModeFC = FunctionCall(self._handleWhisperModeSVChanged,
                                                     self._handleWhisperModeSV)
            self._handleWhisperModeFC.pushCurrentState()
        # if this terminal is not whisperable, we need to listen for whisper mode changes
        self._handleWhisperModeSV.set((self.settingsRef is not None) and
                                      (not self.isWhisperable()))

    def _handleWhisperModeSVChanged(self, handleWhisperMode):
        if handleWhisperMode:
            # this terminal can't be whispered. we need to reconstruct
            # our GUI element when the whisper mode changes
            # listen for that mode change
            # create a DirectObject to avoid conflicts with other parts of this
            # object that are listening for this event
            self._wmcListener = DirectObject()
            self._wmcListener.accept(self.getEventName(SCWhisperModeChangeEvent),
                                     self._handleWhisperModeChange)
        else:
            if hasattr(self, '_wmcListener'):
                # we no longer need to listen for whisper mode changes
                self._wmcListener.ignoreAll()
                del self._wmcListener
                # make sure our GUI element is appropriate
                self.invalidate()

    def _handleWhisperModeChange(self, whisperMode):
        # whisper mode changed, we need to change our GUI element
        self.invalidate()

    # the meat of SCTerminal; inheritors should override this
    # and perform the appropriate action
    def handleSelect(self):
        """ called when the user selects this node """
        # send the generic 'something was selected' event
        messenger.send(self.getEventName(SCTerminalSelectedEvent))

        # if we have a linked emote, and it isn't disabled, generate a msg
        if self.hasLinkedEmote() and self.linkedEmoteEnabled():
                messenger.send(self.getEventName(SCTerminalLinkedEmoteEvent),
                               [self.linkedEmote])

    def isWhisperable(self):
        # can this terminal be sent as a whisper message?
        return True

    # Some terminal nodes have an emote associated with them, which
    # should be invoked when the node is selected.
    def getLinkedEmote(self):
        return self.linkedEmote
    def setLinkedEmote(self, linkedEmote):
        self.linkedEmote = linkedEmote
        # TODO: we should make sure we're listening for emote
        # enable state changes if this is set while we're visible
        self.invalidate()
    def hasLinkedEmote(self):
        return (self.linkedEmote is not None)
    def linkedEmoteEnabled(self):
        if Emote.globalEmote:
            return Emote.globalEmote.isEnabled(self.linkedEmote)

    def getCharges(self):
        return self.__numCharges
    
    def setCharges(self, nCharges):
        self.__numCharges = nCharges
        if (nCharges is 0):
            self.setDisabled(True)
    
    # support for disabled terminals
    def isDisabled(self):
        return self.__disabled or (self.isWhispering() and not self.isWhisperable())

    def setDisabled(self, bDisabled):
        # make the button 'unclickable'
        self.__disabled = bDisabled

    # from SCElement
    def onMouseClick(self, event):
        if not self.isDisabled():
            SCElement.onMouseClick(self, event)
            self.handleSelect()

    def getMinDimensions(self):
        width, height = SCElement.getMinDimensions(self)
        if self.hasLinkedEmote():
            # add space for the emotion icon
            width += 1.3
        return width, height

    def finalize(self, dbArgs={}):
        """ catch this call and influence the appearance of our button """
        if not self.isDirty():
            return

        args = {}

        if self.hasLinkedEmote():
            self.lastEmoteIconColor = self.getEmoteIconColor()
            self.emotionIcon.setColorScale(*self.lastEmoteIconColor)
            args.update({
                'image':         self.emotionIcon,
                'image_pos':     (self.width-.6,0,-self.height*.5),
                })

        if self.isDisabled():
            args.update({
                'rolloverColor': (0,0,0,0),
                'pressedColor': (0,0,0,0),
                'rolloverSound': None,
                'clickSound': None,
                'text_fg': self.getColorScheme().getTextDisabledColor()+(1,),
                })

        args.update(dbArgs)
        SCElement.finalize(self, dbArgs=args)

    def getEmoteIconColor(self):
        if self.linkedEmoteEnabled() and (not self.isWhispering()):
            r,g,b = self.getColorScheme().getEmoteIconColor()
        else:
            r,g,b = self.getColorScheme().getEmoteIconDisabledColor()
        return (r,g,b,1)

    def updateEmoteIcon(self):
        if hasattr(self, 'button'):
            self.lastEmoteIconColor = self.getEmoteIconColor()
            for i in range(self.button['numStates']):
                self.button['image%s_image' % i].setColorScale(
                    *self.lastEmoteIconColor)
        else:
            self.invalidate()

    # from SCObject
    def enterVisible(self):
        SCElement.enterVisible(self)

        # Check if the emote state has changed since the last time
        # we were finalized, and invalidate if it's different.
        if hasattr(self, 'lastEmoteIconColor'):
            if self.getEmoteIconColor() != self.lastEmoteIconColor:
                self.invalidate()

        # listen for whisper-mode changes
        def handleWhisperModeChange(whisperMode, self=self):
            if self.hasLinkedEmote():
                # we are leaving or entering whisper mode;
                # the appearance of our emote icon needs to change
                # (no linked emotes on whispers)
                if self.isVisible() and not self.isWhispering():
                    self.updateEmoteIcon()
        self.accept(self.getEventName(SCWhisperModeChangeEvent),
                    handleWhisperModeChange)

        # listen for emote-enable state changes
        def handleEmoteEnableStateChange(self=self):
            if self.hasLinkedEmote():
                # emotions have just become enabled/disabled
                # update our emote icon
                # (no emotes when whispering)
                if self.isVisible() and not self.isWhispering():
                    self.updateEmoteIcon()
        if self.hasLinkedEmote():
            if Emote.globalEmote:
                self.accept(Emote.globalEmote.EmoteEnableStateChanged,
                            handleEmoteEnableStateChange)

    def exitVisible(self):
        SCElement.exitVisible(self)
        self.ignore(self.getEventName(SCWhisperModeChangeEvent))
        if Emote.globalEmote:
            self.ignore(Emote.globalEmote.EmoteEnableStateChanged)

    def getDisplayText(self):
        if self.getCharges() is not -1:
            return self.text + " (%s)" % self.getCharges()
        else:
            return self.text
예제 #14
0
class FrameProfiler():
    __module__ = __name__
    notify = directNotify.newCategory('FrameProfiler')
    Minute = 60
    Hour = 60 * Minute
    Day = 24 * Hour

    def __init__(self):
        Hour = FrameProfiler.Hour
        self._period = 2 * FrameProfiler.Minute
        if config.GetBool('frequent-frame-profiles', 0):
            self._period = 1 * FrameProfiler.Minute
        self._jitterMagnitude = self._period * 0.75
        self._logSchedule = [1 * FrameProfiler.Hour,
         4 * FrameProfiler.Hour,
         12 * FrameProfiler.Hour,
         1 * FrameProfiler.Day]
        if config.GetBool('frequent-frame-profiles', 0):
            self._logSchedule = [1 * FrameProfiler.Minute,
             4 * FrameProfiler.Minute,
             12 * FrameProfiler.Minute,
             24 * FrameProfiler.Minute]
        for t in self._logSchedule:
            pass

        for i in xrange(len(self._logSchedule)):
            e = self._logSchedule[i]
            for j in xrange(i, len(self._logSchedule)):
                pass

        self._enableFC = FunctionCall(self._setEnabled, taskMgr.getProfileFramesSV())
        self._enableFC.pushCurrentState()

    def destroy(self):
        self._enableFC.set(False)
        self._enableFC.destroy()

    def _setEnabled(self, enabled):
        if enabled:
            self.notify.info('frame profiler started')
            self._startTime = globalClock.getFrameTime()
            self._profileCounter = 0
            self._jitter = None
            self._period2aggregateProfile = {}
            self._id2session = {}
            self._id2task = {}
            self._task = taskMgr.doMethodLater(self._period, self._scheduleNextProfileDoLater, 'FrameProfilerStart-%s' % serialNum())
        else:
            self._task.remove()
            del self._task
            for session in self._period2aggregateProfile.itervalues:
                session.release()

            del self._period2aggregateProfile
            for task in self._id2task.itervalues():
                task.remove()

            del self._id2task
            for session in self._id2session.itervalues():
                session.release()

            del self._id2session
            self.notify.info('frame profiler stopped')
        return

    def _scheduleNextProfileDoLater(self, task):
        self._scheduleNextProfile()
        return task.done

    def _scheduleNextProfile(self):
        self._profileCounter += 1
        self._timeElapsed = self._profileCounter * self._period
        time = self._startTime + self._timeElapsed
        jitter = self._jitter
        if jitter is None:
            jitter = normalDistrib(-self._jitterMagnitude, self._jitterMagnitude)
            time += jitter
        else:
            time -= jitter
            jitter = None
        self._jitter = jitter
        sessionId = serialNum()
        session = taskMgr.getProfileSession('FrameProfile-%s' % sessionId)
        self._id2session[sessionId] = session
        taskMgr.profileFrames(num=1, session=session, callback=Functor(self._analyzeResults, sessionId))
        delay = max(time - globalClock.getFrameTime(), 0.0)
        self._task = taskMgr.doMethodLater(delay, self._scheduleNextProfileDoLater, 'FrameProfiler-%s' % serialNum())
        return

    def _analyzeResults(self, sessionId):
        self._id2task[sessionId] = taskMgr.add(Functor(self._doAnalysis, sessionId), 'FrameProfilerAnalysis-%s' % sessionId)

    def _doAnalysis(self, sessionId, task):
        if hasattr(task, '_generator'):
            gen = task._generator
        else:
            gen = self._doAnalysisGen(sessionId)
            task._generator = gen
        result = gen.next()
        if result == Task.done:
            del task._generator
        return result

    def _doAnalysisGen--- This code section failed: ---
예제 #15
0
class TaskProfiler():
    __module__ = __name__
    notify = directNotify.newCategory('TaskProfiler')

    def __init__(self):
        self._enableFC = FunctionCall(self._setEnabled, taskMgr.getProfileTasksSV())
        self._enableFC.pushCurrentState()
        self._namePrefix2tracker = {}
        self._task = None
        return

    def destroy(self):
        if taskMgr.getProfileTasks():
            self._setEnabled(False)
        self._enableFC.destroy()
        for tracker in self._namePrefix2tracker.itervalues():
            tracker.destroy()

        del self._namePrefix2tracker
        del self._task

    @staticmethod
    def GetDefaultSpikeThreshold():
        return config.GetFloat('profile-task-spike-threshold', 5.0)

    @staticmethod
    def SetSpikeThreshold(spikeThreshold):
        TaskTracker.SpikeThreshold = spikeThreshold

    @staticmethod
    def GetSpikeThreshold():
        return TaskTracker.SpikeThreshold

    def logProfiles(self, name = None):
        if name:
            name = name.lower()
        for namePrefix, tracker in self._namePrefix2tracker.iteritems():
            if name and name not in namePrefix.lower():
                continue
            tracker.log()

    def flush(self, name):
        if name:
            name = name.lower()
        for namePrefix, tracker in self._namePrefix2tracker.iteritems():
            if name and name not in namePrefix.lower():
                continue
            tracker.flush()

    def _setEnabled(self, enabled):
        if enabled:
            self.notify.info('task profiler started')
            self._taskName = 'profile-tasks-%s' % id(self)
            taskMgr.add(self._doProfileTasks, self._taskName, priority=-200)
        else:
            taskMgr.remove(self._taskName)
            del self._taskName
            self.notify.info('task profiler stopped')

    def _doProfileTasks(self, task = None):
        if self._task is not None and taskMgr._hasProfiledDesignatedTask():
            session = taskMgr._getLastTaskProfileSession()
            if session.profileSucceeded():
                namePrefix = self._task.getNamePrefix()
                if namePrefix not in self._namePrefix2tracker:
                    self._namePrefix2tracker[namePrefix] = TaskTracker(namePrefix)
                tracker = self._namePrefix2tracker[namePrefix]
                tracker.addProfileSession(session)
        self._task = taskMgr._getRandomTask()
        taskMgr._setProfileTask(self._task)
        return task.cont