pyalgotrade源码阅读:事件驱动的机制,observer.py

# PyAlgoTrade
#
# Copyright 2011-2018 Gabriel Martin Becedillas Ruiz
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
#   http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.

"""
.. moduleauthor:: Gabriel Martin Becedillas Ruiz <gabriel.becedillas@gmail.com>
"""

import abc

import six

from pyalgotrade import dispatchprio


class Event(object):
    def __init__(self):
        # 待处理的事件
        self.__handlers = []
        # 缓存中的事件
        self.__deferred = []
        # 是否放出的状态
        self.__emitting = 0

    def __subscribeImpl(self, handler):
        # 如果当前不是要放出的状态
        assert not self.__emitting
        # 如果这个事件没有在待处理的事件列表中
        if handler not in self.__handlers:
            # 添加这个事件到事件列表
            self.__handlers.append(handler)

    def __unsubscribeImpl(self, handler):
        # 如果当前不是要放出的状态
        assert not self.__emitting
        # 从事件列表中删除
        self.__handlers.remove(handler)

    def __applyChanges(self):
        # 如果当前不是要放出的状态
        assert not self.__emitting
        # 对缓存中的时间进行处理,先遍历需要处理的事件
        for action, param in self.__deferred:
            action(param)
        # 处理完后,缓存中的事件变为0
        self.__deferred = []

    def subscribe(self, handler):
        # 如果当前是要放出的状态
        if self.__emitting:
            # 把需要处理的函数名和参数放到缓存当中去
            self.__deferred.append((self.__subscribeImpl, handler))
        # 另外如果当前不是要放出的状态
        elif handler not in self.__handlers:
            self.__subscribeImpl(handler)

    def unsubscribe(self, handler):
        # 取消订阅
        # 如果当前的状态是放出
        if self.__emitting:
            self.__deferred.append((self.__unsubscribeImpl, handler))
        # 如果不是
        else:
            self.__unsubscribeImpl(handler)

    def emit(self, *args, **kwargs):
        # 完整运行一个事件?
        # 试运行
        try:
            # 当前的状态变为发射、放出
            self.__emitting += 1
            # 循环处理每个handler
            for handler in self.__handlers:
                handler(*args, **kwargs)
        # 最终运行
        finally:
            # 当前的状态变为非发射或者放出的状态
            self.__emitting -= 1
            # 如果是非发射或者放出的状态
            if not self.__emitting:
                # 做出来相应的改变
                self.__applyChanges()


@six.add_metaclass(abc.ABCMeta)
class Subject(object):

    def __init__(self):
        # dispatchprio.LAST=None
        self.__dispatchPrio = dispatchprio.LAST

    # This may raise.
    @abc.abstractmethod
    def start(self):
        pass

    # This should not raise.
    @abc.abstractmethod
    def stop(self):
        raise NotImplementedError()

    # This should not raise.
    @abc.abstractmethod
    def join(self):
        raise NotImplementedError()

    # Return True if there are not more events to dispatch.
    @abc.abstractmethod
    def eof(self):
        raise NotImplementedError()

    # Dispatch events. If True is returned, it means that at least one event was dispatched.
    @abc.abstractmethod
    def dispatch(self):
        raise NotImplementedError()

    @abc.abstractmethod
    def peekDateTime(self):
        # Return the datetime for the next event.
        # This is needed to properly synchronize non-realtime subjects.
        # Return None since this is a realtime subject.
        raise NotImplementedError()

    def getDispatchPriority(self):
        # Returns a priority used to sort subjects within the dispatch queue.
        # The return value should never change once this subject is added to the dispatcher.
        return self.__dispatchPrio

    def setDispatchPriority(self, dispatchPrio):
        self.__dispatchPrio = dispatchPrio

    def onDispatcherRegistered(self, dispatcher):
        # Called when the subject is registered with a dispatcher.
        pass

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值