2013-08-08 08:45:56 +04:00
|
|
|
/*
|
2019-01-14 04:13:25 +03:00
|
|
|
* Copyright 2010-2019 Branimir Karadzic. All rights reserved.
|
2016-01-01 11:11:04 +03:00
|
|
|
* License: https://github.com/bkaradzic/bgfx#license-bsd-2-clause
|
2013-08-08 08:45:56 +04:00
|
|
|
*/
|
|
|
|
|
2015-02-10 07:12:46 +03:00
|
|
|
#include <bx/allocator.h>
|
2017-01-09 02:55:14 +03:00
|
|
|
#include <bx/commandline.h>
|
2017-09-16 06:04:31 +03:00
|
|
|
#include <bx/hash.h>
|
|
|
|
#include <bx/string.h>
|
2013-08-08 08:45:56 +04:00
|
|
|
|
|
|
|
#include "dbg.h"
|
|
|
|
#include "cmd.h"
|
2015-02-08 21:25:53 +03:00
|
|
|
#include "entry_p.h"
|
2014-11-17 05:59:17 +03:00
|
|
|
|
2014-08-22 18:35:30 +04:00
|
|
|
#include <tinystl/allocator.h>
|
2014-11-17 05:59:17 +03:00
|
|
|
#include <tinystl/string.h>
|
2014-08-22 18:35:30 +04:00
|
|
|
#include <tinystl/unordered_map.h>
|
|
|
|
namespace stl = tinystl;
|
2013-08-08 08:45:56 +04:00
|
|
|
|
|
|
|
struct CmdContext
|
|
|
|
{
|
|
|
|
CmdContext()
|
|
|
|
{
|
|
|
|
}
|
|
|
|
|
|
|
|
~CmdContext()
|
|
|
|
{
|
|
|
|
}
|
|
|
|
|
|
|
|
void add(const char* _name, ConsoleFn _fn, void* _userData)
|
|
|
|
{
|
2017-09-24 02:27:16 +03:00
|
|
|
uint32_t cmd = bx::hash<bx::HashMurmur2A>(_name, (uint32_t)bx::strLen(_name) );
|
2013-08-08 08:45:56 +04:00
|
|
|
BX_CHECK(m_lookup.end() == m_lookup.find(cmd), "Command \"%s\" already exist.", _name);
|
|
|
|
Func fn = { _fn, _userData };
|
2014-08-22 18:35:30 +04:00
|
|
|
m_lookup.insert(stl::make_pair(cmd, fn) );
|
2013-08-08 08:45:56 +04:00
|
|
|
}
|
|
|
|
|
|
|
|
void exec(const char* _cmd)
|
|
|
|
{
|
2018-10-21 09:33:31 +03:00
|
|
|
for (bx::StringView next(_cmd); !next.isEmpty(); _cmd = next.getPtr() )
|
2013-08-08 08:45:56 +04:00
|
|
|
{
|
|
|
|
char commandLine[1024];
|
|
|
|
uint32_t size = sizeof(commandLine);
|
|
|
|
int argc;
|
|
|
|
char* argv[64];
|
2014-07-01 09:46:54 +04:00
|
|
|
next = bx::tokenizeCommandLine(_cmd, commandLine, size, argc, argv, BX_COUNTOF(argv), '\n');
|
2013-08-08 08:45:56 +04:00
|
|
|
if (argc > 0)
|
|
|
|
{
|
|
|
|
int err = -1;
|
2017-09-24 02:27:16 +03:00
|
|
|
uint32_t cmd = bx::hash<bx::HashMurmur2A>(argv[0], (uint32_t)bx::strLen(argv[0]) );
|
2013-08-08 08:45:56 +04:00
|
|
|
CmdLookup::iterator it = m_lookup.find(cmd);
|
|
|
|
if (it != m_lookup.end() )
|
|
|
|
{
|
|
|
|
Func& fn = it->second;
|
|
|
|
err = fn.m_fn(this, fn.m_userData, argc, argv);
|
|
|
|
}
|
|
|
|
|
|
|
|
switch (err)
|
|
|
|
{
|
|
|
|
case 0:
|
|
|
|
break;
|
|
|
|
|
|
|
|
case -1:
|
|
|
|
{
|
2018-10-21 09:33:31 +03:00
|
|
|
stl::string tmp(_cmd, next.getPtr()-_cmd - (next.isEmpty() ? 0 : 1) );
|
2013-08-08 08:45:56 +04:00
|
|
|
DBG("Command '%s' doesn't exist.", tmp.c_str() );
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
|
|
|
|
default:
|
|
|
|
{
|
2018-10-21 09:33:31 +03:00
|
|
|
stl::string tmp(_cmd, next.getPtr()-_cmd - (next.isEmpty() ? 0 : 1) );
|
2013-08-08 08:45:56 +04:00
|
|
|
DBG("Failed '%s' err: %d.", tmp.c_str(), err);
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
struct Func
|
|
|
|
{
|
|
|
|
ConsoleFn m_fn;
|
|
|
|
void* m_userData;
|
|
|
|
};
|
|
|
|
|
2014-08-22 18:35:30 +04:00
|
|
|
typedef stl::unordered_map<uint32_t, Func> CmdLookup;
|
2013-08-08 08:45:56 +04:00
|
|
|
CmdLookup m_lookup;
|
|
|
|
};
|
|
|
|
|
2015-02-10 07:12:46 +03:00
|
|
|
static CmdContext* s_cmdContext;
|
|
|
|
|
|
|
|
void cmdInit()
|
|
|
|
{
|
|
|
|
s_cmdContext = BX_NEW(entry::getAllocator(), CmdContext);
|
|
|
|
}
|
|
|
|
|
|
|
|
void cmdShutdown()
|
|
|
|
{
|
|
|
|
BX_DELETE(entry::getAllocator(), s_cmdContext);
|
|
|
|
}
|
2013-08-08 08:45:56 +04:00
|
|
|
|
|
|
|
void cmdAdd(const char* _name, ConsoleFn _fn, void* _userData)
|
|
|
|
{
|
2015-02-10 07:12:46 +03:00
|
|
|
s_cmdContext->add(_name, _fn, _userData);
|
2013-08-08 08:45:56 +04:00
|
|
|
}
|
|
|
|
|
2017-09-16 06:04:31 +03:00
|
|
|
void cmdExec(const char* _format, ...)
|
2013-08-08 08:45:56 +04:00
|
|
|
{
|
2017-09-16 06:04:31 +03:00
|
|
|
char tmp[2048];
|
|
|
|
|
|
|
|
va_list argList;
|
|
|
|
va_start(argList, _format);
|
|
|
|
bx::vsnprintf(tmp, BX_COUNTOF(tmp), _format, argList);
|
|
|
|
va_end(argList);
|
|
|
|
|
|
|
|
s_cmdContext->exec(tmp);
|
2013-08-08 08:45:56 +04:00
|
|
|
}
|