···11+/*
22+This file is part of Darling.
33+44+Copyright (C) 2020 Lubos Dolezel
55+66+Darling is free software: you can redistribute it and/or modify
77+it under the terms of the GNU General Public License as published by
88+the Free Software Foundation, either version 3 of the License, or
99+(at your option) any later version.
1010+1111+Darling is distributed in the hope that it will be useful,
1212+but WITHOUT ANY WARRANTY; without even the implied warranty of
1313+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
1414+GNU General Public License for more details.
1515+1616+You should have received a copy of the GNU General Public License
1717+along with Darling. If not, see <http://www.gnu.org/licenses/>.
1818+*/
1919+2020+#ifndef _COMPONENT_DISPATCH_H
2121+#define _COMPONENT_DISPATCH_H
2222+#include "AudioComponentManager.h"
2323+#include <CoreServices/Components.h>
2424+2525+template <typename First, typename... Rest>
2626+void assignParams(ComponentParameters* cp, size_t totalArgs, size_t argumentIndex, First arg, Rest... rest)
2727+{
2828+#if __LP64__
2929+ cp->params[argumentIndex] = long(arg);
3030+#else
3131+ cp->params[totalArgs - argumentIndex - 1] = long(arg);
3232+#endif
3333+3434+ if constexpr (sizeof...(Rest) > 0)
3535+ assignParams(cp, totalArgs, argumentIndex+1, rest...);
3636+}
3737+3838+template <typename ...Args>
3939+OSStatus dispatchCall(AudioComponentInstance inUnit, SInt16 sel, Args... args)
4040+{
4141+ if (AudioComponentManager::isOurInstance(inUnit))
4242+ {
4343+ AudioComponentPlugInInterface* iface = AudioComponentManager::instance()->instanceInterface(inUnit);
4444+ AudioComponentMethod method = iface->Lookup(sel);
4545+ if (method != nullptr)
4646+ return method(iface, args...);
4747+ else
4848+ return badComponentSelector;
4949+ }
5050+ else
5151+ {
5252+ ComponentParameters* cp = (ComponentParameters*) alloca(sizeof(ComponentParameters) + sizeof...(Args) * sizeof(long));
5353+ constexpr size_t totalArgs = sizeof...(Args)+1;
5454+5555+ assignParams(cp, totalArgs, 0, inUnit);
5656+5757+ if constexpr (totalArgs > 1)
5858+ assignParams(cp, totalArgs, 1, args...);
5959+6060+ cp->paramSize = totalArgs * sizeof(long);
6161+ cp->what = sel;
6262+ cp->flags = 0;
6363+6464+ return CallComponentDispatch(cp);
6565+ }
6666+}
6767+6868+#endif
6969+