/* * All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or * its licensors. * * For complete copyright and license terms please see the LICENSE at the root of this * distribution (the "License"). All use of this software is governed by the License, * or, if provided, by the license below or the license accompanying this file. Do not * remove or modify any license notices. This file is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * */ // Original file Copyright Crytek GMBH or its affiliates, used under license. // Description : Classes to deal with commands #ifndef CRYINCLUDE_EDITOR_INCLUDE_COMMAND_H #define CRYINCLUDE_EDITOR_INCLUDE_COMMAND_H #pragma once inline string ToString(const QString& s) { return s.toUtf8().data(); } class CCommand { public: CCommand( const string& module, const string& name, const string& description, const string& example) : m_module(module) , m_name(name) , m_description(description) , m_example(example) , m_bAlsoAvailableInScripting(false) {} virtual ~CCommand() {} // Class for storing function parameters as a type-erased string struct CArgs { public: CArgs() : m_stringFlags(0) {} template void Add(T p) { assert(m_args.size() < 8 * sizeof(m_stringFlags)); m_args.push_back(ToString(p)); } void Add(const char* p) { assert(m_args.size() < 8 * sizeof(m_stringFlags)); m_stringFlags |= 1 << m_args.size(); m_args.push_back(p); } bool IsStringArg(int i) const { if (i < 0 || i >= GetArgCount()) { return false; } if (m_stringFlags & (1 << i)) { return true; } else { return false; } } int GetArgCount() const { return m_args.size(); } const string& GetArg(int i) const { assert(0 <= i && i < GetArgCount()); return m_args[i]; } private: DynArray m_args; unsigned char m_stringFlags; // This is needed to quote string parameters when logging a command. }; const string& GetName() const { return m_name; } const string& GetModule() const { return m_module; } const string& GetDescription() const { return m_description; } const string& GetExample() const { return m_example; } void SetAvailableInScripting() { m_bAlsoAvailableInScripting = true; }; bool IsAvailableInScripting() const { return m_bAlsoAvailableInScripting; } virtual QString Execute(const CArgs& args) = 0; // Only a command without any arguments and return value can be a UI command. virtual bool CanBeUICommand() const { return false; } protected: friend class CEditorCommandManager; string m_module; string m_name; string m_description; string m_example; bool m_bAlsoAvailableInScripting; template static string ToString_(T t) { return ::ToString(t); } static inline string ToString_(const char* val) { return val; } template static bool FromString_(T& t, const char* s) { return ::FromString(t, s); } static inline bool FromString_(const char*& val, const char* s) { return (val = s) != 0; } void PrintHelp() { CryLogAlways("%s.%s:", m_module.c_str(), m_name.c_str()); if (m_description.length() > 0) { CryLogAlways(" %s", m_description.c_str()); } if (m_example.length() > 0) { CryLogAlways(" Usage: %s", m_example.c_str()); } } }; class CCommand0 : public CCommand { public: CCommand0(const string& module, const string& name, const string& description, const string& example, const Functor0& functor) : CCommand(module, name, description, example) , m_functor(functor) {} // UI metadata for this command, if any struct SUIInfo { string caption; string tooltip; string description; string iconFilename; int iconIndex; int commandId; // Windows command id SUIInfo() : iconIndex(0) , commandId(0) {} }; inline QString Execute(const CArgs& args) { assert(args.GetArgCount() == 0); m_functor(); return ""; } const SUIInfo& GetUIInfo() const { return m_uiInfo; } virtual bool CanBeUICommand() const { return true; } protected: friend class CEditorCommandManager; Functor0 m_functor; SUIInfo m_uiInfo; }; template class CCommand0wRet : public CCommand { public: CCommand0wRet(const string& module, const string& name, const string& description, const string& example, const Functor0wRet& functor); QString Execute(const CArgs& args); protected: friend class CEditorCommandManager; Functor0wRet m_functor; }; template class CCommand1 : public CCommand { public: CCommand1(const string& module, const string& name, const string& description, const string& example, const Functor1& functor); QString Execute(const CArgs& args); protected: friend class CEditorCommandManager; Functor1 m_functor; }; template class CCommand1wRet : public CCommand { public: CCommand1wRet(const string& module, const string& name, const string& description, const string& example, const Functor1wRet& functor); QString Execute(const CArgs& args); protected: friend class CEditorCommandManager; Functor1wRet m_functor; }; template class CCommand2 : public CCommand { public: CCommand2(const string& module, const string& name, const string& description, const string& example, const Functor2& functor); QString Execute(const CArgs& args); protected: friend class CEditorCommandManager; Functor2 m_functor; }; template class CCommand2wRet : public CCommand { public: CCommand2wRet(const string& module, const string& name, const string& description, const string& example, const Functor2wRet& functor); QString Execute(const CArgs& args); protected: friend class CEditorCommandManager; Functor2wRet m_functor; }; template class CCommand3 : public CCommand { public: CCommand3(const string& module, const string& name, const string& description, const string& example, const Functor3& functor); QString Execute(const CArgs& args); protected: friend class CEditorCommandManager; Functor3 m_functor; }; template class CCommand3wRet : public CCommand { public: CCommand3wRet(const string& module, const string& name, const string& description, const string& example, const Functor3wRet& functor); QString Execute(const CArgs& args); protected: friend class CEditorCommandManager; Functor3wRet m_functor; }; template class CCommand4 : public CCommand { public: CCommand4(const string& module, const string& name, const string& description, const string& example, const Functor4& functor); QString Execute(const CArgs& args); protected: friend class CEditorCommandManager; Functor4 m_functor; }; template class CCommand4wRet : public CCommand { public: CCommand4wRet(const string& module, const string& name, const string& description, const string& example, const Functor4wRet& functor); QString Execute(const CArgs& args); protected: friend class CEditorCommandManager; Functor4wRet m_functor; }; template class CCommand5 : public CCommand { public: CCommand5(const string& module, const string& name, const string& description, const string& example, const Functor5& functor); QString Execute(const CArgs& args); protected: friend class CEditorCommandManager; Functor5 m_functor; }; template class CCommand6 : public CCommand { public: CCommand6(const string& module, const string& name, const string& description, const string& example, const Functor6& functor); QString Execute(const CArgs& args); protected: friend class CEditorCommandManager; Functor6 m_functor; }; ////////////////////////////////////////////////////////////////////////// template CCommand0wRet::CCommand0wRet(const string& module, const string& name, const string& description, const string& example, const Functor0wRet& functor) : CCommand(module, name, description, example) , m_functor(functor) { } template QString CCommand0wRet::Execute(const CCommand::CArgs& args) { assert(args.GetArgCount() == 0); RT ret = m_functor(); return ToString_(ret).c_str(); } ////////////////////////////////////////////////////////////////////////// template CCommand1::CCommand1(const string& module, const string& name, const string& description, const string& example, const Functor1& functor) : CCommand(module, name, description, example) , m_functor(functor) { } template QString CCommand1::Execute(const CCommand::CArgs& args) { assert(args.GetArgCount() == 1); if (args.GetArgCount() < 1) { CryLogAlways("Cannot execute the command %s.%s! One argument required.", m_module.c_str(), m_name.c_str()); PrintHelp(); return ""; } P1 p1; bool ok = FromString_(p1, args.GetArg(0).c_str()); if (ok) { m_functor(p1); } else { CryLogAlways("Cannot execute the command %s.%s(%s)! Invalid argument type.", m_module, m_name, args.GetArg(0).c_str()); PrintHelp(); } return ""; } ////////////////////////////////////////////////////////////////////////// template CCommand1wRet::CCommand1wRet(const string& module, const string& name, const string& description, const string& example, const Functor1wRet& functor) : CCommand(module, name, description, example) , m_functor(functor) { } template QString CCommand1wRet::Execute(const CCommand::CArgs& args) { assert(args.GetArgCount() == 1); if (args.GetArgCount() < 1) { CryLogAlways("Cannot execute the command %s.%s! One argument required.", m_module.c_str(), m_name.c_str()); PrintHelp(); return ""; } P1 p1; bool ok = FromString_(p1, args.GetArg(0).c_str()); if (ok) { RT ret = m_functor(p1); return ToString_(ret).c_str(); } else { CryLogAlways("Cannot execute the command %s.%s(%s)! Invalid argument type.", m_module, m_name, args.GetArg(0).c_str()); PrintHelp(); } return ""; } ////////////////////////////////////////////////////////////////////////// template CCommand2::CCommand2(const string& module, const string& name, const string& description, const string& example, const Functor2& functor) : CCommand(module, name, description, example) , m_functor(functor) { } template QString CCommand2::Execute(const CCommand::CArgs& args) { assert(args.GetArgCount() == 2); if (args.GetArgCount() < 2) { CryLogAlways("Cannot execute the command %s.%s! Two arguments required.", m_module.c_str(), m_name.c_str()); PrintHelp(); return ""; } P1 p1; P2 p2; bool ok = FromString_(p1, args.GetArg(0).c_str()) && FromString_(p2, args.GetArg(1).c_str()); if (ok) { m_functor(p1, p2); } else { CryLogAlways("Cannot execute the command %s.%s(%s,%s)! Invalid argument type(s).", m_module, m_name, args.GetArg(0).c_str(), args.GetArg(1).c_str()); PrintHelp(); } return ""; } ////////////////////////////////////////////////////////////////////////// template CCommand2wRet::CCommand2wRet(const string& module, const string& name, const string& description, const string& example, const Functor2wRet& functor) : CCommand(module, name, description, example) , m_functor(functor) { } template QString CCommand2wRet::Execute(const CCommand::CArgs& args) { assert(args.GetArgCount() == 2); if (args.GetArgCount() < 2) { CryLogAlways("Cannot execute the command %s.%s! Two arguments required.", m_module.c_str(), m_name.c_str()); PrintHelp(); return ""; } P1 p1; P2 p2; bool ok = FromString_(p1, args.GetArg(0).c_str()) && FromString_(p2, args.GetArg(1).c_str()); if (ok) { RT ret = m_functor(p1, p2); return ToString_(ret).c_str(); } else { CryLogAlways("Cannot execute the command %s.%s(%s,%s)! Invalid argument type(s).", m_module, m_name, args.GetArg(0).c_str(), args.GetArg(1).c_str()); PrintHelp(); } return ""; } ////////////////////////////////////////////////////////////////////////// template CCommand3::CCommand3(const string& module, const string& name, const string& description, const string& example, const Functor3& functor) : CCommand(module, name, description, example) , m_functor(functor) { } template QString CCommand3::Execute(const CCommand::CArgs& args) { assert(args.GetArgCount() == 3); if (args.GetArgCount() < 3) { CryLogAlways("Cannot execute the command %s.%s! Three arguments required.", m_module.c_str(), m_name.c_str()); PrintHelp(); return ""; } P1 p1; P2 p2; P3 p3; bool ok = FromString_(p1, args.GetArg(0).c_str()) && FromString_(p2, args.GetArg(1).c_str()) && FromString_(p3, args.GetArg(2).c_str()); if (ok) { m_functor(p1, p2, p3); } else { CryLogAlways("Cannot execute the command %s.%s(%s,%s,%s)! Invalid argument type(s).", m_module, m_name, args.GetArg(0).c_str(), args.GetArg(1).c_str(), args.GetArg(2).c_str()); PrintHelp(); } return ""; } ////////////////////////////////////////////////////////////////////////// template CCommand3wRet::CCommand3wRet(const string& module, const string& name, const string& description, const string& example, const Functor3wRet& functor) : CCommand(module, name, description, example) , m_functor(functor) { } template QString CCommand3wRet::Execute(const CCommand::CArgs& args) { assert(args.GetArgCount() == 3); if (args.GetArgCount() < 3) { CryLogAlways("Cannot execute the command %s.%s! Three arguments required.", m_module.c_str(), m_name.c_str()); PrintHelp(); return ""; } P1 p1; P2 p2; P3 p3; bool ok = FromString_(p1, args.GetArg(0).c_str()) && FromString_(p2, args.GetArg(1).c_str()) && FromString_(p3, args.GetArg(2).c_str()); if (ok) { RT ret = m_functor(p1, p2, p3); return ToString_(ret).c_str(); } else { CryLogAlways("Cannot execute the command %s.%s(%s,%s,%s)! Invalid argument type(s).", m_module, m_name, args.GetArg(0).c_str(), args.GetArg(1).c_str(), args.GetArg(2).c_str()); PrintHelp(); } return ""; } ////////////////////////////////////////////////////////////////////////// template CCommand4::CCommand4(const string& module, const string& name, const string& description, const string& example, const Functor4& functor) : CCommand(module, name, description, example) , m_functor(functor) { } template QString CCommand4::Execute(const CCommand::CArgs& args) { assert(args.GetArgCount() == 4); if (args.GetArgCount() < 4) { CryLogAlways("Cannot execute the command %s.%s! Four arguments required.", m_module.c_str(), m_name.c_str()); PrintHelp(); return ""; } P1 p1; P2 p2; P3 p3; P4 p4; bool ok = FromString_(p1, args.GetArg(0).c_str()) && FromString_(p2, args.GetArg(1).c_str()) && FromString_(p3, args.GetArg(2).c_str()) && FromString_(p4, args.GetArg(3).c_str()); if (ok) { m_functor(p1, p2, p3, p4); } else { CryLogAlways("Cannot execute the command %s.%s(%s,%s,%s,%s)! Invalid argument type(s).", m_module, m_name, args.GetArg(0).c_str(), args.GetArg(1).c_str(), args.GetArg(2).c_str(), args.GetArg(3).c_str()); PrintHelp(); } return ""; } ////////////////////////////////////////////////////////////////////////// template CCommand4wRet::CCommand4wRet(const string& module, const string& name, const string& description, const string& example, const Functor4wRet& functor) : CCommand(module, name, description, example) , m_functor(functor) { } template QString CCommand4wRet::Execute(const CCommand::CArgs& args) { assert(args.GetArgCount() == 4); if (args.GetArgCount() < 4) { CryLogAlways("Cannot execute the command %s.%s! Four arguments required.", m_module.c_str(), m_name.c_str()); PrintHelp(); return ""; } P1 p1; P2 p2; P3 p3; P4 p4; bool ok = FromString_(p1, args.GetArg(0).c_str()) && FromString_(p2, args.GetArg(1).c_str()) && FromString_(p3, args.GetArg(2).c_str()) && FromString_(p4, args.GetArg(3).c_str()); if (ok) { RT ret = m_functor(p1, p2, p3, p4); return ToString_(ret).c_str(); } else { CryLogAlways("Cannot execute the command %s.%s(%s,%s,%s,%s)! Invalid argument type(s).", m_module, m_name, args.GetArg(0).c_str(), args.GetArg(1).c_str(), args.GetArg(2).c_str(), args.GetArg(3).c_str()); PrintHelp(); } return ""; } ////////////////////////////////////////////////////////////////////////// template CCommand5::CCommand5(const string& module, const string& name, const string& description, const string& example, const Functor5& functor) : CCommand(module, name, description, example) , m_functor(functor) { } template QString CCommand5::Execute(const CCommand::CArgs& args) { assert(args.GetArgCount() == 5); if (args.GetArgCount() < 5) { CryLogAlways("Cannot execute the command %s.%s! Five arguments required.", m_module.c_str(), m_name.c_str()); PrintHelp(); return ""; } P1 p1; P2 p2; P3 p3; P4 p4; P5 p5; bool ok = FromString_(p1, args.GetArg(0).c_str()) && FromString_(p2, args.GetArg(1).c_str()) && FromString_(p3, args.GetArg(2).c_str()) && FromString_(p4, args.GetArg(3).c_str()) && FromString_(p5, args.GetArg(4).c_str()); if (ok) { m_functor(p1, p2, p3, p4, p5); } else { CryLogAlways("Cannot execute the command %s.%s(%s,%s,%s,%s,%s)! Invalid argument type(s).", m_module, m_name, args.GetArg(0).c_str(), args.GetArg(1).c_str(), args.GetArg(2).c_str(), args.GetArg(3).c_str(), args.GetArg(4).c_str()); PrintHelp(); } return ""; } ////////////////////////////////////////////////////////////////////////// template CCommand6::CCommand6(const string& module, const string& name, const string& description, const string& example, const Functor6& functor) : CCommand(module, name, description, example) , m_functor(functor) { } template QString CCommand6::Execute(const CCommand::CArgs& args) { assert(args.GetArgCount() == 6); if (args.GetArgCount() < 6) { CryLogAlways("Cannot execute the command %s.%s! Six arguments required.", m_module.c_str(), m_name.c_str()); PrintHelp(); return ""; } P1 p1; P2 p2; P3 p3; P4 p4; P5 p5; P6 p6; bool ok = FromString_(p1, args.GetArg(0).c_str()) && FromString_(p2, args.GetArg(1).c_str()) && FromString_(p3, args.GetArg(2).c_str()) && FromString_(p4, args.GetArg(3).c_str()) && FromString_(p5, args.GetArg(4).c_str()) && FromString_(p6, args.GetArg(5).c_str()); if (ok) { m_functor(p1, p2, p3, p4, p5, p6); } else { CryLogAlways("Cannot execute the command %s.%s(%s,%s,%s,%s,%s,%s)! Invalid argument type(s).", m_module, m_name, args.GetArg(0).c_str(), args.GetArg(1).c_str(), args.GetArg(2).c_str(), args.GetArg(3).c_str(), args.GetArg(4).c_str(), args.GetArg(5).c_str()); PrintHelp(); } return ""; } #endif // CRYINCLUDE_EDITOR_INCLUDE_COMMAND_H