DynamicProperty(std::string name, T value, NotifierFn notifier=NotifierFn{}) : DynamicPropertyBase(std::move(name)), m_value(std::move(value)) { SetNotifier(notifier); }
DynamicProperty(std::string name, BindingFn binding, NotifierFn notifier=NotifierFn{}) : DynamicPropertyBase(std::move(name)) { SetNotifier(notifier); Bind(binding); }
DynamicProperty(T value, NotifierFn notifier=NotifierFn{}) : m_value(std::move(value)) { SetNotifier(notifier); }
DynamicProperty(BindingFn binding, NotifierFn notifier=NotifierFn{}) { SetNotifier(notifier); Bind(binding); }
ProtoChannel::ProtoChannel() : listener(NULL), notifier(NULL), notify_flags(0), blocking_status(true), #ifdef WIN32 input_handle(INVALID_HANDLE), input_ready(false), output_handle(INVALID_HANDLE), output_ready(false) #else descriptor(INVALID_HANDLE) #endif // if/else WIN32/UNIX { } ProtoChannel::~ProtoChannel() { if (notifier) SetNotifier(NULL); if (listener) { delete listener; listener = NULL; } } bool ProtoChannel::SetNotifier(ProtoChannel::Notifier* theNotifier) { if (notifier != theNotifier) { if (IsOpen()) { // 1) Detach old notifier, if any if (notifier) { notifier->UpdateChannelNotification(*this, 0); if (!theNotifier) { // Reset channel to "blocking" if(!SetBlocking(true)) PLOG(PL_ERROR, "ProtoChannel::SetNotifier() SetBlocking(true) error\n", GetErrorString()); } } else { // Set channel to "non-blocking" if(!SetBlocking(false)) { PLOG(PL_ERROR, "ProtoChannel::SetNotifier() SetBlocking(false) error\n", GetErrorString()); return false; } } // 2) Set and update new notifier (if applicable) notifier = theNotifier; if (!UpdateNotification()) { notifier = NULL; return false; } } else { notifier = theNotifier; } } return true; } // end ProtoChannel::SetNotifier() bool ProtoChannel::UpdateNotification() { if (notifier) { if (IsOpen() && !SetBlocking(false)) { PLOG(PL_ERROR, "ProtoChannel::UpdateNotification() SetBlocking() error\n"); return false; } return notifier->UpdateChannelNotification(*this, notify_flags); } return true; } // end ProtoChannel::UpdateNotification() bool ProtoChannel::SetBlocking(bool blocking) { #ifdef UNIX if (IsOpen() && (blocking_status != blocking)) { if (blocking) { if(-1 == fcntl(descriptor, F_SETFL, fcntl(descriptor, F_GETFL, 0) & ~O_NONBLOCK)) { PLOG(PL_ERROR, "ProtoChannel::SetBlocking() fcntl(F_SETFL(~O_NONBLOCK)) error: %s\n", GetErrorString()); return false; } } else { if(-1 == fcntl(descriptor, F_SETFL, fcntl(descriptor, F_GETFL, 0) | O_NONBLOCK)) { PLOG(PL_ERROR, "ProtoChannel::SetBlocking() fcntl(F_SETFL(O_NONBLOCK)) error: %s\n", GetErrorString()); return false; } } blocking_status = blocking; } #endif // UNIX return true; //Note: taken care automatically under Win32 by WSAAsyncSelect(), etc } // end ProtoChannel::SetBlocking(bool blocking)