Merge branch 'master' into new_level_refactor

# Conflicts:
#	src/c_dispatch.cpp
This commit is contained in:
Christoph Oelckers 2019-01-27 10:26:23 +01:00
commit 22939aade7
9 changed files with 133 additions and 138 deletions

View file

@ -60,38 +60,119 @@
// TYPES -------------------------------------------------------------------
class DWaitingCommand : public DThinker
class UnsafeExecutionScope
{
DECLARE_CLASS (DWaitingCommand, DThinker)
const bool wasEnabled;
public:
DWaitingCommand (const char *cmd, int tics, bool unsafe);
~DWaitingCommand ();
void Serialize(FSerializer &arc);
void Tick ();
explicit UnsafeExecutionScope(const bool enable = true)
: wasEnabled(UnsafeExecutionContext)
{
UnsafeExecutionContext = enable;
}
private:
DWaitingCommand ();
~UnsafeExecutionScope()
{
UnsafeExecutionContext = wasEnabled;
}
};
char *Command;
class FDelayedCommand
{
protected:
virtual bool Tick() = 0;
friend class FDelayedCommandQueue;
};
class FWaitingCommand : public FDelayedCommand
{
public:
FWaitingCommand(const char *cmd, int tics, bool unsafe)
: Command(cmd), TicsLeft(tics+1), IsUnsafe(unsafe)
{}
bool Tick() override
{
if (--TicsLeft == 0)
{
UnsafeExecutionScope scope(IsUnsafe);
AddCommandString(Command);
return true;
}
return false;
}
FString Command;
int TicsLeft;
bool IsUnsafe;
};
class DStoredCommand : public DThinker
class FStoredCommand : public FDelayedCommand
{
DECLARE_CLASS (DStoredCommand, DThinker)
public:
DStoredCommand (FConsoleCommand *com, const char *cmd);
~DStoredCommand ();
void Tick ();
FStoredCommand(FConsoleCommand *com, const char *cmd)
: Command(com), Text(cmd)
{}
bool Tick() override
{
if (Text.IsNotEmpty() && Command != nullptr)
{
FCommandLine args(Text);
Command->Run(args, players[consoleplayer].mo, 0);
}
return true;
}
private:
DStoredCommand ();
FConsoleCommand *Command;
char *Text;
FString Text;
};
class FDelayedCommandQueue
{
TDeletingArray<FDelayedCommand *> delayedCommands;
public:
void Run()
{
for (unsigned i = 0; i < delayedCommands.Size(); i++)
{
if (delayedCommands[i]->Tick())
{
delete delayedCommands[i];
delayedCommands.Delete(i);
i--;
}
}
}
void Clear()
{
delayedCommands.DeleteAndClear();
}
void AddCommand(FDelayedCommand * cmd)
{
delayedCommands.Push(cmd);
}
};
static FDelayedCommandQueue delayedCommandQueue;
void C_RunDelayedCommands()
{
delayedCommandQueue.Run();
}
void C_ClearDelayedCommands()
{
delayedCommandQueue.Clear();
}
struct FActionMap
{
FButtonStatus *Button;
@ -128,22 +209,6 @@ FButtonStatus Button_Mlook, Button_Klook, Button_Use, Button_AltAttack,
bool ParsingKeyConf, UnsafeExecutionContext;
class UnsafeExecutionScope
{
const bool wasEnabled;
public:
explicit UnsafeExecutionScope(const bool enable = true)
: wasEnabled(UnsafeExecutionContext)
{
UnsafeExecutionContext = enable;
}
~UnsafeExecutionScope()
{
UnsafeExecutionContext = wasEnabled;
}
};
// To add new actions, go to the console and type "key <action name>".
// This will give you the key value to use in the first column. Then
@ -206,79 +271,6 @@ static const char *KeyConfCommands[] =
// CODE --------------------------------------------------------------------
IMPLEMENT_CLASS(DWaitingCommand, false, false)
void DWaitingCommand::Serialize(FSerializer &arc)
{
Super::Serialize (arc);
arc("command", Command)
("ticsleft", TicsLeft)
("unsafe", IsUnsafe);
}
DWaitingCommand::DWaitingCommand ()
{
Command = NULL;
TicsLeft = 1;
IsUnsafe = false;
}
DWaitingCommand::DWaitingCommand (const char *cmd, int tics, bool unsafe)
{
Command = copystring (cmd);
TicsLeft = tics+1;
IsUnsafe = unsafe;
}
DWaitingCommand::~DWaitingCommand ()
{
if (Command != NULL)
{
delete[] Command;
}
}
void DWaitingCommand::Tick ()
{
if (--TicsLeft == 0)
{
UnsafeExecutionScope scope(IsUnsafe);
AddCommandString (Command);
Destroy ();
}
}
IMPLEMENT_CLASS(DStoredCommand, false, false)
DStoredCommand::DStoredCommand ()
{
Text = NULL;
Destroy ();
}
DStoredCommand::DStoredCommand (FConsoleCommand *command, const char *args)
{
Command = command;
Text = copystring (args);
}
DStoredCommand::~DStoredCommand ()
{
if (Text != NULL)
{
delete[] Text;
}
}
void DStoredCommand::Tick ()
{
if (Text != NULL && Command != NULL)
{
FCommandLine args (Text);
Command->Run (args, players[consoleplayer].mo, 0);
}
Destroy ();
}
static int ListActionCommands (const char *pattern)
{
@ -657,7 +649,8 @@ void C_DoCommand (const char *cmd, int keynum)
}
else
{
currentUILevel->CreateThinker<DStoredCommand> (com, beg);
auto cmd = new FStoredCommand(com, beg);
delayedCommandQueue.AddCommand(cmd);
}
}
}
@ -697,8 +690,12 @@ DEFINE_ACTION_FUNCTION(DOptionMenuItemCommand, DoCommand)
return 0;
}
void AddCommandString (char *cmd, int keynum)
void AddCommandString (const char *text, int keynum)
{
// Operate on a local copy instead of messing around with the data that's being passed in here.
TArray<char> buffer(strlen(text) + 1, true);
memcpy(buffer.Data(), text, buffer.Size());
char *cmd = buffer.Data();
char *brkpt;
int more;
@ -753,7 +750,8 @@ void AddCommandString (char *cmd, int keynum)
// Note that deferred commands lose track of which key
// (if any) they were pressed from.
*brkpt = ';';
currentUILevel->CreateThinker<DWaitingCommand> (brkpt, tics, UnsafeExecutionContext);
auto cmd = new FWaitingCommand(brkpt, tics, UnsafeExecutionContext);
delayedCommandQueue.AddCommand(cmd);
}
return;
}
@ -1478,8 +1476,7 @@ void FConsoleAlias::Run (FCommandLine &args, AActor *who, int key)
}
bRunning = true;
AddCommandString (mycommand.LockBuffer(), key);
mycommand.UnlockBuffer();
AddCommandString (mycommand, key);
bRunning = false;
if (m_Command[index].IsEmpty())
{ // The alias is unchanged, so put the command back so it can be used again.
@ -1555,8 +1552,7 @@ void FExecList::ExecCommands() const
{
for (unsigned i = 0; i < Commands.Size(); ++i)
{
AddCommandString(Commands[i].LockBuffer());
Commands[i].UnlockBuffer();
AddCommandString(Commands[i]);
}
}