from __future__ import absolute_import

from . import _selectloop


class Value(object):
    __slots__ = "_value", "_listeners"

    _UNDEFINED = object()
    _ERROR = ValueError("value has not been set")

    def __init__(self, value=_UNDEFINED):
        self._value = value
        self._listeners = None

    def unsafe_is_set(self):
        return self._value is not self._UNDEFINED

    def unsafe_get(self):
        value = self._value
        if value is self._UNDEFINED:
            raise self._ERROR
        return value

    def unsafe_set(self, value=None):
        if self._value is not self._UNDEFINED:
            return False
        self._value = value

        listeners = self._listeners
        if listeners is None:
            return True
        self._listeners = None

        for callback in listeners:
            _selectloop.asap(callback, value)
        return True

    def unsafe_listen(self, callback):
        if self._value is self._UNDEFINED:
            listeners = self._listeners
            if listeners is None:
                listeners = set()
                self._listeners = listeners
            listeners.add(callback)
            return

        _selectloop.asap(callback, self._value)

    def unsafe_unlisten(self, callback):
        listeners = self._listeners
        if listeners is not None:
            listeners.discard(callback)

    def set(self, value=None):
        _selectloop.asap(self.unsafe_set, value)

    def listen(self, callback):
        _selectloop.asap(self.unsafe_listen, callback)

    def unlisten(self, callback):
        _selectloop.asap(self.unsafe_unlisten, callback)

@@ -39,24 +39,16 @@
 %0A%0Afrom .
- import 
 _selectl
@@ -50,16 +50,52 @@
 lectloop
+ import asap%0A%0A%0A_UNDEFINED = object()
 %0A%0A%0Aclass
@@ -154,85 +154,8 @@
 s%22%0A%0A
-    _UNDEFINED = object()%0A    _ERROR = ValueError(%22value has not been set%22)%0A%0A
     
@@ -307,37 +307,32 @@
 f._value is not 
-self.
 _UNDEFINED%0A%0A    
@@ -393,37 +393,32 @@
     if value is 
-self.
 _UNDEFINED:%0A    
@@ -435,19 +435,44 @@
 ise 
-self._ERROR
+ValueError(%22value has not been set%22)
 %0A   
@@ -558,21 +558,16 @@
  is not 
-self.
 _UNDEFIN
@@ -789,36 +789,24 @@
             
-_selectloop.
 asap(callbac
@@ -901,21 +901,16 @@
 alue is 
-self.
 _UNDEFIN
@@ -1125,36 +1125,24 @@
 rn%0A%0A        
-_selectloop.
 asap(callbac
@@ -1345,36 +1345,24 @@
 e):%0A        
-_selectloop.
 asap(self.un
@@ -1415,36 +1415,24 @@
 k):%0A        
-_selectloop.
 asap(self.un
@@ -1501,20 +1501,8 @@
     
-_selectloop.
 asap

Clean up.