static void remove_object_listener_target_from_list(MCObjectListenerTarget *&p_target, MCObjectListenerTarget *p_prev_target, MCObjectListener* &p_listener, MCObjectListener* p_prev_listener) { p_target -> target -> Release(); if (p_prev_target != nil) p_prev_target -> next = p_target -> next; else p_listener -> targets = p_target -> next; if (p_listener -> targets == nil) remove_object_listener_from_list(p_listener, p_prev_listener); MCMemoryDelete(p_target); p_target = p_prev_target; }
void MCInternalObjectListenerListListeners(MCExecPoint &ep) { ep . clear(); MCObjectHandle *t_current_object; t_current_object = ep . getobj() -> gethandle(); bool t_first; t_first = true; MCObjectListener *t_prev_listener; t_prev_listener = nil; MCObjectListener *t_listener; t_listener = s_object_listeners; while(t_listener != nil) { if (!t_listener -> object -> Exists()) remove_object_listener_from_list(t_listener, t_prev_listener); else { MCObjectListenerTarget *t_target; t_target = nil; MCObjectListenerTarget *t_prev_target; t_prev_target = nil; MCExecPoint ep1(ep); t_listener -> object -> Get() -> getprop(0, P_LONG_ID, ep1, false); for (t_target = t_listener -> targets; t_target != nil; t_target = t_target -> next) { if (!t_target -> target -> Exists()) remove_object_listener_target_from_list(t_target, t_prev_target, t_listener, t_prev_listener); else if (t_target -> target == t_current_object) { ep . concatmcstring(ep1 . getsvalue(), EC_RETURN, t_first); t_first = false; } } t_prev_listener = t_listener; } if (t_listener != nil) t_listener = t_listener -> next; else t_listener = s_object_listeners; } }
void MCInternalObjectListenerGetListeners(MCExecContext& ctxt, MCStringRef*& r_listeners, uindex_t& r_count) { MCObjectHandle *t_current_object; t_current_object = ctxt . GetObject() -> gethandle(); MCObjectListener *t_prev_listener; t_prev_listener = nil; MCObjectListener *t_listener; t_listener = s_object_listeners; MCAutoArray<MCStringRef> t_listeners; while(t_listener != nil) { MCStringRef t_string; if (!t_listener -> object -> Exists()) remove_object_listener_from_list(t_listener, t_prev_listener); else { MCObjectListenerTarget *t_target; t_target = nil; MCObjectListenerTarget *t_prev_target; t_prev_target = nil; MCAutoValueRef t_long_id; t_listener -> object -> Get() -> names(P_LONG_ID, &t_long_id); for (t_target = t_listener -> targets; t_target != nil; t_target = t_target -> next) { if (!t_target -> target -> Exists()) remove_object_listener_target_from_list(t_target, t_prev_target, t_listener, t_prev_listener); else if (t_target -> target == t_current_object) { ctxt . ConvertToString(*t_long_id, t_string); t_listeners . Push(t_string); } } t_prev_listener = t_listener; } if (t_listener != nil) t_listener = t_listener -> next; else t_listener = s_object_listeners; } t_listeners . Take(r_listeners, r_count); }
static void remove_object_listener_target_from_list(MCObjectListenerTarget *&p_target, MCObjectListenerTarget *p_prev_target, MCObjectListener* &p_listener, MCObjectListener* p_prev_listener) { p_target -> target -> Release(); if (p_prev_target != nil) p_prev_target -> next = p_target -> next; else p_listener -> targets = p_target -> next; if (p_listener -> targets == nil) remove_object_listener_from_list(p_listener, p_prev_listener); // MW-2013-08-27: [[ Bug 11126 ]] If this pointer is going away, make sure we fetch the next // target into the static. if (p_target == s_next_listener_target_to_process) s_next_listener_target_to_process = p_target -> next; MCMemoryDelete(p_target); p_target = p_prev_target; }
void MCInternalObjectListenerMessagePendingListeners(void) { if (MCobjectpropertieschanged) { MCobjectpropertieschanged = False; MCObjectListener *t_prev_listener; t_prev_listener = nil; MCObjectListener *t_listener; t_listener = s_object_listeners; while(t_listener != nil) { // MW-2013-08-27: [[ Bug 11126 ]] This static is updated by the remove_* functions // to ensure we don't get any dangling pointers. s_next_listener_to_process = t_listener -> next; if (!t_listener -> object -> Exists()) remove_object_listener_from_list(t_listener, t_prev_listener); else { uint8_t t_properties_changed; t_properties_changed = t_listener -> object -> Get() -> propertieschanged(); if (t_properties_changed != kMCPropertyChangedMessageTypeNone) { MCExecPoint ep(nil, nil, nil); t_listener -> object -> Get() -> getprop(0, P_LONG_ID, ep, False); MCObjectListenerTarget *t_target; t_target = nil; MCObjectListenerTarget *t_prev_target; t_prev_target = nil; double t_new_time; t_new_time = MCS_time(); if (t_listener -> last_update_time + MCpropertylistenerthrottletime / 1000.0 < t_new_time) { t_listener -> last_update_time = t_new_time; t_target = t_listener->targets; while (t_target != nil) { // MW-2013-08-27: [[ Bug 11126 ]] This static is updated by the remove_* functions // to ensure we don't get any dangling pointers. s_next_listener_target_to_process = t_target -> next; if (!t_target -> target -> Exists()) remove_object_listener_target_from_list(t_target, t_prev_target, t_listener, t_prev_listener); else { // MM-2012-11-06: Added resizeControl(Started/Ended) and gradientEdit(Started/Ended) messages. if (t_properties_changed & kMCPropertyChangedMessageTypePropertyChanged) t_target -> target -> Get() -> message_with_args(MCM_property_changed, ep . getsvalue()); if (t_properties_changed & kMCPropertyChangedMessageTypeResizeControlStarted) t_target -> target -> Get() -> message_with_args(MCM_resize_control_started, ep . getsvalue()); if (t_properties_changed & kMCPropertyChangedMessageTypeResizeControlEnded) t_target -> target -> Get() -> message_with_args(MCM_resize_control_ended, ep . getsvalue()); if (t_properties_changed & kMCPropertyChangedMessageTypeGradientEditStarted) t_target -> target -> Get() -> message_with_args(MCM_gradient_edit_started, ep . getsvalue()); if (t_properties_changed & kMCPropertyChangedMessageTypeGradientEditEnded) t_target -> target -> Get() -> message_with_args(MCM_gradient_edit_ended, ep . getsvalue()); t_prev_target = t_target; } t_target = s_next_listener_target_to_process; } } else t_listener -> object -> Get() -> signallistenerswithmessage(t_properties_changed); } t_prev_listener = t_listener; } // MW-2013-08-27: [[ Bug 11126 ]] Use the static as the next in the chain. t_listener = s_next_listener_to_process; } } }