@@ -171,8 +171,8 @@ namespace geode::cocos {
171171 GEODE_DLL bool fileExistsInSearchPaths (const char * filename);
172172
173173
174- template <class T >
175- struct GEODE_DLL CCArrayIterator {
174+ template <typename T>
175+ struct CCArrayIterator {
176176 public:
177177 CCArrayIterator (T* p) : m_ptr(p) {}
178178 T* m_ptr;
@@ -416,69 +416,6 @@ namespace geode::cocos {
416416 return m_dict->allKeys (key)->count ();
417417 }
418418 };
419-
420- template <typename R, typename ...Args>
421- class SelectorWrapperImpl : public cocos2d ::CCObject {
422- protected:
423- std::function<R(Args...)> m_inner;
424- public:
425- static SelectorWrapperImpl<R, Args...>* create (std::function<R(Args...)> fn) {
426- auto ret = new SelectorWrapperImpl<R, Args...>();
427- ret->m_inner = fn;
428- ret->autorelease ();
429- return ret;
430- }
431-
432- R invoke (Args... args) {
433- return m_inner (args...);
434- }
435- };
436-
437- template <typename R, typename ...Args>
438- class SelectorWrapper {
439- protected:
440- using Target = SelectorWrapperImpl<R, Args...>;
441- bool m_tied;
442- Target* m_impl;
443- public:
444- SelectorWrapper (std::function<R(Args...)> fn) {
445- m_impl = Target::create (fn);
446- m_impl->retain ();
447- }
448-
449- ~SelectorWrapper () {
450- if (!m_tied)
451- m_impl->release ();
452- }
453-
454- Target* target () {
455- return m_impl;
456- }
457-
458- auto selector () {
459- return reinterpret_cast <R (cocos2d::CCObject::*)(Args...)>(&Target::invoke);
460- }
461-
462- SelectorWrapper<R, Args...>& leak () {
463- m_impl->retain ();
464- return *this ;
465- }
466-
467- SelectorWrapper<R, Args...> tieToNode (cocos2d::CCNode* node) {
468- if (!m_tied) {
469- node->addChild (m_impl);
470- m_impl->release ();
471- m_tied = true ;
472- }
473-
474- return *this ;
475- }
476- };
477-
478- template <typename F>
479- auto selectorFromFn (std::function<F> fn) {
480- return SelectorWrapper (fn);
481- }
482419
483420 // namespace for storing implementation stuff for
484421 // inline member functions
@@ -499,6 +436,9 @@ namespace geode::cocos {
499436 m_lambda.~F ();
500437 }
501438 }
439+ LambdaHolder (F&& func) {
440+ this ->assign (std::forward<F>(func));
441+ }
502442 Ret operator ()(Args... args) {
503443 if (m_assigned) {
504444 return m_lambda (std::forward<Args>(args)...);
@@ -531,13 +471,18 @@ namespace geode::cocos {
531471
532472 template <class Base , class Func , class ... Args>
533473 struct InlineMemberFunction <Base, Func, std::tuple<Args...>> : public Base {
534- // this class isn't instantiated anywhere, and is
535- // just used as a proxy to redirect the member function
536- // to the lambda
537- static inline LambdaHolder<Func, typename ExtractLambda<Func>::Ret, Args...> s_selector {};
538- typename ExtractLambda<Func>::Ret onSelector (Args... args) {
474+ using Ret = typename ExtractLambda<Func>::Ret;
475+ using Selector = Ret(Base::*)(Args...);
476+ using Holder = LambdaHolder<Func, Ret, Args...>;
477+
478+ static inline Holder s_selector {};
479+ Ret selector (Args... args) {
539480 return s_selector (std::forward<Args>(args)...);
540481 }
482+ static Selector get (Func&& function) {
483+ s_selector.assign (std::move (function));
484+ return static_cast <Selector>(&InlineMemberFunction::selector);
485+ }
541486 };
542487 }
543488
@@ -554,9 +499,14 @@ namespace geode::cocos {
554499 * same captured values.
555500 */
556501 template <class Base , class Func >
502+ [[deprecated(
503+ " Due to too many implementation problems, "
504+ " makeMemberFunction will be removed in the future."
505+ )]]
557506 static auto makeMemberFunction (Func&& function) {
558- InlineMemberFunction<Base, Func, typename ExtractLambda<Func>::Params>::s_selector.assign (std::move (function));
559- return &InlineMemberFunction<Base, Func, typename ExtractLambda<Func>::Params>::onSelector;
507+ return InlineMemberFunction<
508+ Base, Func, typename ExtractLambda<Func>::Params
509+ >::get (std::move (function));
560510 }
561511
562512 /* *
@@ -566,16 +516,22 @@ namespace geode::cocos {
566516 * for even more concise code.
567517 *
568518 * Do note that due to implementation problems, captures may have
569- * unexpected side-effects. In practice, lambda member functions with
570- * captures do not work properly in loops. If you assign the same
571- * member lambda to multiple different targets, they will share the
572- * same captured values.
519+ * unexpected side-effects. In practice, **you should not expect to be able
520+ * to pass any more information than you can pass to a normal menu selector
521+ * through captures**. If you assign the same member lambda to multiple
522+ * different targets, they will share the same captured values.
573523 */
574524 template <class Func >
525+ [[deprecated(
526+ " Due to too many implementation problems, "
527+ " makeMenuSelector will be removed in the future."
528+ )]]
575529 static cocos2d::SEL_MenuHandler makeMenuSelector (Func&& selector) {
576- return (cocos2d::SEL_MenuHandler)(makeMemberFunction<cocos2d::CCObject, Func>(std::move (selector)));
530+ return reinterpret_cast <cocos2d::SEL_MenuHandler>(
531+ makeMemberFunction<cocos2d::CCObject, Func>(std::move (selector))
532+ );
577533 }
578534
579535 #define GEODE_MENU_SELECTOR (senderArg, ...) \
580- makeMenuSelector ([= ](senderArg) { __VA_ARGS__; })
536+ makeMenuSelector ([this ](senderArg) { __VA_ARGS__; })
581537}
0 commit comments