| 2968 | } |
| 2969 | |
| 2970 | bool ObjectInstance::connect_impl(JSContext* cx, const JS::CallArgs& args, |
| 2971 | bool after, bool object) { |
| 2972 | GQuark signal_detail; |
| 2973 | const char* func_name = connect_func_name(after, object); |
| 2974 | |
| 2975 | gjs_debug_gsignal("connect obj %p priv %p", m_wrapper.get(), this); |
| 2976 | |
| 2977 | if (!check_gobject_disposed_or_finalized("connect to any signal on")) { |
| 2978 | args.rval().setInt32(0); |
| 2979 | return true; |
| 2980 | } |
| 2981 | |
| 2982 | JS::UniqueChars signal_name; |
| 2983 | JS::RootedObject callback{cx}; |
| 2984 | JS::RootedObject associate_obj{cx}; |
| 2985 | GConnectFlags flags; |
| 2986 | if (object) { |
| 2987 | if (!gjs_parse_call_args(cx, func_name, args, "sooi", "signal name", |
| 2988 | &signal_name, "callback", &callback, "gobject", |
| 2989 | &associate_obj, "connect_flags", &flags)) |
| 2990 | return false; |
| 2991 | |
| 2992 | if (flags & G_CONNECT_SWAPPED) { |
| 2993 | gjs_throw(cx, "Unsupported connect flag G_CONNECT_SWAPPED"); |
| 2994 | return false; |
| 2995 | } |
| 2996 | |
| 2997 | after = flags & G_CONNECT_AFTER; |
| 2998 | } else { |
| 2999 | if (!gjs_parse_call_args(cx, func_name, args, "so", "signal name", |
| 3000 | &signal_name, "callback", &callback)) |
| 3001 | return false; |
| 3002 | } |
| 3003 | |
| 3004 | std::string dynamic_string{GJS_PROFILER_DYNAMIC_STRING( |
| 3005 | cx, format_name() + '.' + func_name + "('" + signal_name.get() + "')")}; |
| 3006 | AutoProfilerLabel label{cx, "", dynamic_string}; |
| 3007 | |
| 3008 | if (!JS::IsCallable(callback)) { |
| 3009 | gjs_throw(cx, "second arg must be a callback"); |
| 3010 | return false; |
| 3011 | } |
| 3012 | |
| 3013 | unsigned signal_id; |
| 3014 | if (!g_signal_parse_name(signal_name.get(), gtype(), &signal_id, |
| 3015 | &signal_detail, true)) { |
| 3016 | gjs_throw(cx, "No signal '%s' on object '%s'", signal_name.get(), |
| 3017 | type_name()); |
| 3018 | return false; |
| 3019 | } |
| 3020 | |
| 3021 | GClosure* closure = Gjs::Closure::create_for_signal( |
| 3022 | cx, callback, "signal callback", signal_id); |
| 3023 | if (closure == nullptr) |
| 3024 | return false; |
| 3025 | |
| 3026 | if (associate_obj.get() != nullptr) { |
| 3027 | ObjectInstance* obj = ObjectInstance::for_js(cx, associate_obj); |
no test coverage detected