void UserActions::Init()
{
m_actionNames.clear();
m_actionNames.push_back(_("none"));
m_actionNames.push_back(_("highlight"));
m_actionNames.push_back(_("notify login/out"));
m_actionNames.push_back(_("ignore chat"));
m_actionNames.push_back(_("ignore pm"));
m_actionNames.push_back(_("autokick"));
m_actionNames.push_back(_("notify hosted battle"));
m_actionNames.push_back(_("notify status change"));
m_configActionNames.clear();
m_configActionNames.push_back(_T("none"));
m_configActionNames.push_back(_T("highlight"));
m_configActionNames.push_back(_T("notify_login"));
m_configActionNames.push_back(_T("ignore_chat"));
m_configActionNames.push_back(_T("ignore_pm"));
m_configActionNames.push_back(_T("autokick"));
m_configActionNames.push_back(_T("notify_hosted"));
m_configActionNames.push_back(_T("notify_status"));
m_actionTooltips.clear();
m_actionTooltips.push_back(_("no action at all"));
m_actionTooltips.push_back(_("highlight user in nick list and battles he participates in"));
m_actionTooltips.push_back(_("popup a message box when user logs in/out from the server"));
m_actionTooltips.push_back(_("you won't see message by these users in normal channels"));
m_actionTooltips.push_back(_("ignore private messages of these users, no pm window will open if any of these try to contact you privately"));
m_actionTooltips.push_back(_("automatically kick users from battles hosted by yourself"));
m_actionTooltips.push_back(_("popup a message box when user hosts a new battle"));
m_actionTooltips.push_back(_("popup a message box when user changes away status"));
// setup if empty
if (!cfg().Exists(_T( "/Groups"))) {
AddGroup(_("Default"));
AddGroup(_("Ignore PM"));
ChangeAction(_("Ignore PM"), UserActions::ActIgnorePM);
AddGroup(_("Ignore chat"));
ChangeAction(_("Ignore chat"), UserActions::ActIgnoreChat);
AddGroup(_("Battle Autokick"));
ChangeAction(_("Battle Autokick"), UserActions::ActAutokick);
AddGroup(_("Friends"));
ChangeAction(_("Friends"), UserActions::ActNotifBattle);
ChangeAction(_("Friends"), UserActions::ActHighlight);
ChangeAction(_("Friends"), UserActions::ActNotifLogin);
// TODO select better color
SetGroupColor(_("Friends"), wxColour(0, 0, 255));
}
// read
m_groupNames = GetGroups();
m_groupMap.clear();
m_groupActions.clear();
m_actionsGroups.clear();
m_actionsPeople.clear();
m_knownUsers.Clear();
for (unsigned int i = 0; i < m_groupNames.GetCount(); ++i) {
wxString name = m_groupNames[i];
m_groupMap[name] = GetPeopleList(name);
for (unsigned int k = 0; k < m_groupMap[name].GetCount(); ++k) {
wxString user = m_groupMap[name][k];
m_knownUsers.Add(user);
m_peopleGroup[user] = name;
}
m_groupActions[name] = GetGroupActions(name);
}
for (size_t i = 0; i < m_actionNames.size(); ++i) {
UserActions::ActionType cur = (UserActions::ActionType)(1 << i);
wxArrayString tmp;
for (unsigned int j = 0; j < m_groupNames.GetCount(); ++j) {
wxString name = m_groupNames[j];
if ((m_groupActions[name] & cur) != 0) {
tmp.Add(name);
for (unsigned int k = 0; k < m_groupMap[name].GetCount(); ++k) {
m_actionsPeople[cur].Add((m_groupMap[name])[k]);
}
}
}
tmp.Sort();
m_actionsGroups[cur] = tmp;
}
m_actionsGroups[ActNone] = m_groupNames;
m_groupNames.Sort();
m_knownUsers.Sort();
}
/**
* Regionize a func, so that each node and each arc in its TransCFG is
* "covered". A node is covered if any region contains it. An arc T1->T2
* is covered if either:
*
* a) T1 and T2 are in the same region R and T2 immediately follows
* T1 in R.
* b) T2 is the head (first translation) of a region.
*
* Basic algorithm:
*
* 1) sort nodes in decreasing weight order
* 2) for each node N:
* 2.1) if N and all its incoming arcs are covered, then continue
* 2.2) select a region starting at this node and mark nodes/arcs as
* covered appropriately
*/
void regionizeFunc(const Func* func,
JIT::TranslatorX64* tx64,
RegionVec& regions) {
assert(RuntimeOption::EvalJitPGO);
FuncId funcId = func->getFuncId();
ProfData* profData = tx64->profData();
TransCFG cfg(funcId, profData, tx64->getSrcDB(), tx64->getJmpToTransIDMap());
if (Trace::moduleEnabled(HPHP::Trace::pgo, 5)) {
string dotFileName = folly::to<string>("/tmp/func-cfg-", funcId, ".dot");
cfg.print(dotFileName, funcId, profData, nullptr);
FTRACE(5, "regionizeFunc: initial CFG for func {} saved to file {}\n",
funcId, dotFileName);
}
TransCFG::ArcPtrVec arcs = cfg.arcs();
vector<TransID> nodes = cfg.nodes();
std::sort(nodes.begin(), nodes.end(),
[&](TransID tid1, TransID tid2) -> bool {
if (cfg.weight(tid1) != cfg.weight(tid2)) {
return cfg.weight(tid1) > cfg.weight(tid2);
}
// In case of ties, pick older translations first, in an
// attempt to start loops at their headers.
return tid1 < tid2;
});
TransCFG::ArcPtrSet coveredArcs;
TransIDSet coveredNodes;
TransIDSet heads;
TransIDToRegionMap headToRegion;
RegionToTransIDsMap regionToTransIds;
regions.clear();
for (auto node : nodes) {
if (!setContains(coveredNodes, node) ||
!allArcsCovered(cfg.inArcs(node), coveredArcs)) {
TransID newHead = node;
FTRACE(6, "regionizeFunc: selecting trace to cover node {}\n", newHead);
TransIDSet selectedSet;
TransIDVec selectedVec;
RegionDescPtr region = selectHotTrace(newHead, profData, cfg,
selectedSet, &selectedVec);
profData->setOptimized(profData->transSrcKey(newHead));
assert(selectedVec.size() > 0 && selectedVec[0] == newHead);
regions.push_back(region);
heads.insert(newHead);
markCovered(cfg, selectedVec, heads, coveredNodes, coveredArcs);
regionToTransIds[region] = selectedVec;
headToRegion[newHead] = region;
FTRACE(6, "regionizeFunc: selected trace: {}\n",
folly::join(", ", selectedVec));
}
}
assert(coveredNodes.size() == cfg.nodes().size());
assert(coveredArcs.size() == arcs.size());
sortRegion(regions, func, cfg, profData, headToRegion, regionToTransIds);
if (debug && Trace::moduleEnabled(HPHP::Trace::pgo, 5)) {
FTRACE(5, "\n--------------------------------------------\n"
"regionizeFunc({}): computed regions:\n", funcId);
for (auto region : regions) {
FTRACE(5, "{}\n\n", show(*region));
}
}
}
void Parachute::Refresh()
{
if (Game::GetInstance()->GetRemainingTime() <= 0)
return;
if (Game::GetInstance()->ReadState() != Game::PLAYING)
return;
Character& active = ActiveCharacter();
Double speed = active.GetSpeedXY().Norm();
if (active.FootsInVacuum() && speed.IsNotZero()) { // We are falling
if (!open && (speed > GameMode::GetInstance()->safe_fall)) { // with a sufficient speed
if (EnoughAmmo() && !m_used_this_turn) { // We have enough ammo => start opening the parachute
if (!m_used_this_turn) {
UseAmmo();
m_used_this_turn = true;
}
active.SetAirResistFactor(cfg().air_resist_factor);
active.SetWindFactor(cfg().wind_factor);
open = true;
img->animation.SetPlayBackward(false);
img->Start();
active.SetSpeedXY(Point2d(0,0));
active.SetMovement("parachute");
Camera::GetInstance()->FollowObject(&active);
}
}
} else { // We are on the ground
if (open) { // The parachute is opened
active.SetMovement("walk");
if (!closing) { // We have just hit the ground. Start closing animation
img->animation.SetPlayBackward(true);
img->animation.SetShowOnFinish(SpriteAnimation::show_blank);
img->Start();
closing = true;
return;
} else { // The parachute is closing
if (img->IsFinished()) {
// The animation is finished... We are done with the parachute
open = false;
closing = false;
UseAmmoUnit();
}
}
}
m_used_this_turn = false;
}
if (open) {
active.UpdateLastMovingTime();
// If parachute is open => character can move a little to the left or to the right
const LRMoveIntention * lr_move_intention = active.GetLastLRMoveIntention();
if (lr_move_intention) {
LRDirection direction = lr_move_intention->GetDirection();
active.SetDirection(direction);
if (direction == DIRECTION_LEFT)
active.SetExternForce(-cfg().force_side_displacement, 0.0);
else
active.SetExternForce(cfg().force_side_displacement, 0.0);
}
}
}
bool AggressiveDCEPass::AggressiveDCE(Function* func) {
// Mark function parameters as live.
AddToWorklist(&func->DefInst());
func->ForEachParam(
[this](const Instruction* param) {
AddToWorklist(const_cast<Instruction*>(param));
},
false);
// Compute map from block to controlling conditional branch
std::list<BasicBlock*> structuredOrder;
cfg()->ComputeStructuredOrder(func, &*func->begin(), &structuredOrder);
ComputeBlock2HeaderMaps(structuredOrder);
bool modified = false;
// Add instructions with external side effects to worklist. Also add branches
// EXCEPT those immediately contained in an "if" selection construct or a loop
// or continue construct.
// TODO(greg-lunarg): Handle Frexp, Modf more optimally
call_in_func_ = false;
func_is_entry_point_ = false;
private_stores_.clear();
// Stacks to keep track of when we are inside an if- or loop-construct.
// When immediately inside an if- or loop-construct, we do not initially
// mark branches live. All other branches must be marked live.
std::stack<bool> assume_branches_live;
std::stack<uint32_t> currentMergeBlockId;
// Push sentinel values on stack for when outside of any control flow.
assume_branches_live.push(true);
currentMergeBlockId.push(0);
for (auto bi = structuredOrder.begin(); bi != structuredOrder.end(); ++bi) {
// If exiting if or loop, update stacks
if ((*bi)->id() == currentMergeBlockId.top()) {
assume_branches_live.pop();
currentMergeBlockId.pop();
}
for (auto ii = (*bi)->begin(); ii != (*bi)->end(); ++ii) {
SpvOp op = ii->opcode();
switch (op) {
case SpvOpStore: {
uint32_t varId;
(void)GetPtr(&*ii, &varId);
// Mark stores as live if their variable is not function scope
// and is not private scope. Remember private stores for possible
// later inclusion. We cannot call IsLocalVar at this point because
// private_like_local_ has not been set yet.
if (IsVarOfStorage(varId, SpvStorageClassPrivate) ||
IsVarOfStorage(varId, SpvStorageClassWorkgroup))
private_stores_.push_back(&*ii);
else if (!IsVarOfStorage(varId, SpvStorageClassFunction))
AddToWorklist(&*ii);
} break;
case SpvOpCopyMemory:
case SpvOpCopyMemorySized: {
uint32_t varId;
(void)GetPtr(ii->GetSingleWordInOperand(kCopyMemoryTargetAddrInIdx),
&varId);
if (IsVarOfStorage(varId, SpvStorageClassPrivate) ||
IsVarOfStorage(varId, SpvStorageClassWorkgroup))
private_stores_.push_back(&*ii);
else if (!IsVarOfStorage(varId, SpvStorageClassFunction))
AddToWorklist(&*ii);
} break;
case SpvOpLoopMerge: {
assume_branches_live.push(false);
currentMergeBlockId.push(
ii->GetSingleWordInOperand(kLoopMergeMergeBlockIdInIdx));
} break;
case SpvOpSelectionMerge: {
assume_branches_live.push(false);
currentMergeBlockId.push(
ii->GetSingleWordInOperand(kSelectionMergeMergeBlockIdInIdx));
} break;
case SpvOpSwitch:
case SpvOpBranch:
case SpvOpBranchConditional:
case SpvOpUnreachable: {
if (assume_branches_live.top()) {
AddToWorklist(&*ii);
}
} break;
default: {
// Function calls, atomics, function params, function returns, etc.
// TODO(greg-lunarg): function calls live only if write to non-local
if (!ii->IsOpcodeSafeToDelete()) {
AddToWorklist(&*ii);
}
// Remember function calls
if (op == SpvOpFunctionCall) call_in_func_ = true;
} break;
}
}
}
// See if current function is an entry point
for (auto& ei : get_module()->entry_points()) {
if (ei.GetSingleWordInOperand(kEntryPointFunctionIdInIdx) ==
func->result_id()) {
func_is_entry_point_ = true;
break;
}
}
//.........这里部分代码省略.........
请发表评论