<commit_before>/*
-----------------------------------------------------------------------------
This source file is part of OGRE
(Object-oriented Graphics Rendering Engine)
For the latest info, see http://www.ogre3d.org/

Copyright (c) 2000-2010 Torus Knot Software Ltd

Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
-----------------------------------------------------------------------------
*/
#include "PlayPenSamples.h"

//---------------------------------------------------------------------
PlayPen_testManualBlend::PlayPen_testManualBlend()
{
	mInfo["Title"] = "PlayPen: Manual Blend";
	mInfo["Description"] = "Manual blending";

}
void PlayPen_testManualBlend::setupContent()
{
	// create material
	MaterialPtr mat = MaterialManager::getSingleton().create("TestMat",
		TRANSIENT_RESOURCE_GROUP);
	Pass * p = mat->getTechnique(0)->getPass(0);
	p->setLightingEnabled(false);
	p->createTextureUnitState("Dirt.jpg");
	TextureUnitState* t = p->createTextureUnitState("ogrelogo.png");
	t->setColourOperationEx(LBX_BLEND_MANUAL, LBS_TEXTURE, LBS_CURRENT,
		ColourValue::White, ColourValue::White, 0.75);

	Entity *planeEnt = mSceneMgr->createEntity("Plane", SceneManager::PT_PLANE);
	mSceneMgr->getRootSceneNode()->createChildSceneNode()->attachObject(planeEnt);
	planeEnt->setMaterialName("TestMat");

	mCamera->setPosition(0,0,600);
	mCamera->lookAt(Vector3::ZERO);
}
//---------------------------------------------------------------------
PlayPen_testProjectSphere::PlayPen_testProjectSphere()
{
	mInfo["Title"] = "PlayPen: Project Sphere";
	mInfo["Description"] = "Projecting a sphere's bounds onto the camera";

}
void PlayPen_testProjectSphere::setupContent()
{
	mSceneMgr->setAmbientLight(ColourValue::White);

	Plane plane;
	plane.normal = Vector3::UNIT_Y;
	plane.d = 0;
	MeshManager::getSingleton().createPlane("Myplane",
		TRANSIENT_RESOURCE_GROUP, plane,
		4500,4500,10,10,true,1,5,5,Vector3::UNIT_Z);
	Entity* pPlaneEnt = mSceneMgr->createEntity( "plane", "Myplane" );
	pPlaneEnt->setMaterialName("Examples/GrassFloor");
	pPlaneEnt->setCastShadows(false);
	mSceneMgr->getRootSceneNode()->createChildSceneNode()->attachObject(pPlaneEnt);

	mProjectionSphere = new Sphere(Vector3(0, 2000, 0), 1500.0);

	ManualObject* debugSphere = mSceneMgr->createManualObject("debugSphere");
	debugSphere->begin("BaseWhiteNoLighting", RenderOperation::OT_LINE_STRIP);
	for (int i = 0; i <= 20; ++i)
	{
		Vector3 basePos(mProjectionSphere->getRadius(), 0, 0);
		Quaternion quat;
		quat.FromAngleAxis(Radian(((float)i/(float)20)*Math::TWO_PI), Vector3::UNIT_Y);
		basePos = quat * basePos;
		debugSphere->position(basePos);
	}
	for (int i = 0; i <= 20; ++i)
	{
		Vector3 basePos(mProjectionSphere->getRadius(), 0, 0);
		Quaternion quat;
		quat.FromAngleAxis(Radian(((float)i/(float)20)*Math::TWO_PI), Vector3::UNIT_Z);
		basePos = quat * basePos;
		debugSphere->position(basePos);
	}
	debugSphere->end();

	mSceneMgr->getRootSceneNode()->createChildSceneNode(Vector3(0,2000,0))->attachObject(debugSphere);

	MaterialPtr mat = MaterialManager::getSingleton().create("scissormat",
		TRANSIENT_RESOURCE_GROUP);
	Pass* p = mat->getTechnique(0)->getPass(0);
	p->setDepthWriteEnabled(false);
	p->setSceneBlending(SBT_TRANSPARENT_ALPHA);
	TextureUnitState* t = p->createTextureUnitState();
	t->setColourOperationEx(LBX_SOURCE1, LBS_MANUAL, LBS_CURRENT,
		ColourValue::Red);
	t->setAlphaOperation(LBX_SOURCE1, LBS_MANUAL, LBS_CURRENT, 0.5f);

	mScissorRect = mSceneMgr->createManualObject("mScissorRect");
	mScissorRect->setUseIdentityProjection(true);
	mScissorRect->setUseIdentityView(true);
	AxisAlignedBox aabb;
	aabb.setInfinite();
	mScissorRect->setBoundingBox(aabb);
	mScissorRect->begin(mat->getName());
	mScissorRect->position(Vector3::ZERO);
	mScissorRect->position(Vector3::ZERO);
	mScissorRect->position(Vector3::ZERO);
	mScissorRect->quad(0, 1, 2, 3);
	mScissorRect->end();
	mSceneMgr->getRootSceneNode()->createChildSceneNode()->attachObject(mScissorRect);

	mCamera->setPosition(0,3000,5000);
	mCamera->lookAt(mProjectionSphere->getCenter());

}
bool PlayPen_testProjectSphere::frameStarted(const Ogre::FrameEvent& evt)
{
	Real left, top, right, bottom;
	mCamera->projectSphere(*mProjectionSphere, &left, &top, &right, &bottom);

	mScissorRect->beginUpdate(0);
	mScissorRect->position(left, top, 0);
	mScissorRect->position(left, bottom, 0);
	mScissorRect->position(right, bottom, 0);
	mScissorRect->position(right, top, 0);
	mScissorRect->quad(0,1,2,3);
	mScissorRect->end();

	return PlayPenBase::frameStarted(evt);

}

//---------------------------------------------------------------------
PlayPen_testCameraSetDirection::PlayPen_testCameraSetDirection()
: mUseParentNode(false)
, mUseFixedYaw(true)
, mFocus(100,200,-300)
{
	mInfo["Title"] = "PlayPen: Camera Set Direction";
	mInfo["Description"] = "Testing various settings for Camera::setDirection";

}
void PlayPen_testCameraSetDirection::setupContent()
{
	mSceneMgr->setAmbientLight(ColourValue::White);

	Entity* e = mSceneMgr->createEntity("1", "knot.mesh");
	mSceneMgr->getRootSceneNode()->createChildSceneNode(mFocus)->attachObject(e);

	mCamera->setPosition(200,1000,1000);
	mCamera->lookAt(mFocus);

	mTrayMgr->createButton(OgreBites::TL_BOTTOM, "Look At", "Look At");
	mTrayMgr->createCheckBox(OgreBites::TL_BOTTOM, "tglParent", "Use Parent Node");
	OgreBites::CheckBox* chk = mTrayMgr->createCheckBox(OgreBites::TL_BOTTOM, "tglFixedYaw", "Use Fixed Yaw");
	chk->setChecked(true, false);
	mTrayMgr->showCursor();
	setDragLook(true);

	mParentNode = mSceneMgr->getRootSceneNode()->createChildSceneNode(Vector3(1000, 2000, -1000));

}
void PlayPen_testCameraSetDirection::buttonHit(OgreBites::Button* button)
{
	mCamera->lookAt(mFocus);
}

void PlayPen_testCameraSetDirection::checkBoxToggled(OgreBites::CheckBox* box)
{
	if (box->getName() == "tglParent")
	{
		mUseParentNode = !mUseParentNode;

		if (mUseParentNode)
			mParentNode->attachObject(mCamera);
		else
			mParentNode->detachAllObjects();
	}
	else if (box->getName() == "tglFixedYaw")
	{
		mUseFixedYaw = !mUseFixedYaw;
		if (mUseFixedYaw)
			mCamera->setFixedYawAxis(true);
		else
			mCamera->setFixedYawAxis(false);

	}
}
//---------------------------------------------------------------------
PlayPen_testManualLOD::PlayPen_testManualLOD()
{
	mInfo["Title"] = "PlayPen: Test Manual LOD";
	mInfo["Description"] = "Testing meshes with manual LODs assigned";
}
//---------------------------------------------------------------------
String PlayPen_testManualLOD::getLODMesh()
{
	MeshPtr msh1 = (MeshPtr)MeshManager::getSingleton().load("robot.mesh",
		ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME);

	msh1->createManualLodLevel(200, "razor.mesh");
	msh1->createManualLodLevel(500, "sphere.mesh");

	return msh1->getName();

}
//---------------------------------------------------------------------
void PlayPen_testManualLOD::setupContent()
{
	String meshName = getLODMesh();

	Entity *ent;
	for (int i = 0; i < 5; ++i)
	{
		ent = mSceneMgr->createEntity("robot" + StringConverter::toString(i), meshName);
		// Add entity to the scene node
		mSceneMgr->getRootSceneNode()->createChildSceneNode(
			Vector3(0,0,(i*50)-(5*50/2)))->attachObject(ent);
	}
	mAnimState = ent->getAnimationState("Walk");
	mAnimState->setEnabled(true);

	// Give it a little ambience with lights
	Light* l;
	l = mSceneMgr->createLight("BlueLight");
	l->setPosition(-200,-80,-100);
	l->setDiffuseColour(0.5, 0.5, 1.0);

	l = mSceneMgr->createLight("GreenLight");
	l->setPosition(0,0,-100);
	l->setDiffuseColour(0.5, 1.0, 0.5);

	// Position the camera
	mCamera->setPosition(100,50,100);
	mCamera->lookAt(-50,50,0);

	mSceneMgr->setAmbientLight(ColourValue::White);

}
//---------------------------------------------------------------------
bool PlayPen_testManualLOD::frameStarted(const Ogre::FrameEvent& evt)
{
	mAnimState->addTime(evt.timeSinceLastFrame);

	return PlayPenBase::frameStarted(evt);
}
//---------------------------------------------------------------------
PlayPen_testManualLODFromFile::PlayPen_testManualLODFromFile()
{
	mInfo["Title"] = "PlayPen: Test Manual LOD (file)";
	mInfo["Description"] = "Testing meshes with manual LODs assigned, loaded from a file";
}
//---------------------------------------------------------------------
String PlayPen_testManualLODFromFile::getLODMesh()
{
	MeshPtr msh1 = (MeshPtr)MeshManager::getSingleton().load("robot.mesh",
		ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME);

	msh1->createManualLodLevel(200, "razor.mesh");
	msh1->createManualLodLevel(500, "sphere.mesh");

	// this time, we save this data to a file and re-load it

	MeshSerializer ser;
	const ResourceGroupManager::LocationList& ll =
		ResourceGroupManager::getSingleton().getResourceLocationList(ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME);
	String prefix;
	for (ResourceGroupManager::LocationList::const_iterator i = ll.begin(); i != ll.end(); ++i)
	{
		if (StringUtil::endsWith((*i)->archive->getName(), "media"))
		{
			prefix = (*i)->archive->getName();
		}
	}
	ser.exportMesh(msh1.get(), prefix + "/testlod.mesh");

	return "testlod.mesh";

}

<commit_msg>Just make sure meshes are being reloaded in LOD test<commit_after>/*
-----------------------------------------------------------------------------
This source file is part of OGRE
(Object-oriented Graphics Rendering Engine)
For the latest info, see http://www.ogre3d.org/

Copyright (c) 2000-2010 Torus Knot Software Ltd

Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
-----------------------------------------------------------------------------
*/
#include "PlayPenSamples.h"

//---------------------------------------------------------------------
PlayPen_testManualBlend::PlayPen_testManualBlend()
{
	mInfo["Title"] = "PlayPen: Manual Blend";
	mInfo["Description"] = "Manual blending";

}
void PlayPen_testManualBlend::setupContent()
{
	// create material
	MaterialPtr mat = MaterialManager::getSingleton().create("TestMat",
		TRANSIENT_RESOURCE_GROUP);
	Pass * p = mat->getTechnique(0)->getPass(0);
	p->setLightingEnabled(false);
	p->createTextureUnitState("Dirt.jpg");
	TextureUnitState* t = p->createTextureUnitState("ogrelogo.png");
	t->setColourOperationEx(LBX_BLEND_MANUAL, LBS_TEXTURE, LBS_CURRENT,
		ColourValue::White, ColourValue::White, 0.75);

	Entity *planeEnt = mSceneMgr->createEntity("Plane", SceneManager::PT_PLANE);
	mSceneMgr->getRootSceneNode()->createChildSceneNode()->attachObject(planeEnt);
	planeEnt->setMaterialName("TestMat");

	mCamera->setPosition(0,0,600);
	mCamera->lookAt(Vector3::ZERO);
}
//---------------------------------------------------------------------
PlayPen_testProjectSphere::PlayPen_testProjectSphere()
{
	mInfo["Title"] = "PlayPen: Project Sphere";
	mInfo["Description"] = "Projecting a sphere's bounds onto the camera";

}
void PlayPen_testProjectSphere::setupContent()
{
	mSceneMgr->setAmbientLight(ColourValue::White);

	Plane plane;
	plane.normal = Vector3::UNIT_Y;
	plane.d = 0;
	MeshManager::getSingleton().createPlane("Myplane",
		TRANSIENT_RESOURCE_GROUP, plane,
		4500,4500,10,10,true,1,5,5,Vector3::UNIT_Z);
	Entity* pPlaneEnt = mSceneMgr->createEntity( "plane", "Myplane" );
	pPlaneEnt->setMaterialName("Examples/GrassFloor");
	pPlaneEnt->setCastShadows(false);
	mSceneMgr->getRootSceneNode()->createChildSceneNode()->attachObject(pPlaneEnt);

	mProjectionSphere = new Sphere(Vector3(0, 2000, 0), 1500.0);

	ManualObject* debugSphere = mSceneMgr->createManualObject("debugSphere");
	debugSphere->begin("BaseWhiteNoLighting", RenderOperation::OT_LINE_STRIP);
	for (int i = 0; i <= 20; ++i)
	{
		Vector3 basePos(mProjectionSphere->getRadius(), 0, 0);
		Quaternion quat;
		quat.FromAngleAxis(Radian(((float)i/(float)20)*Math::TWO_PI), Vector3::UNIT_Y);
		basePos = quat * basePos;
		debugSphere->position(basePos);
	}
	for (int i = 0; i <= 20; ++i)
	{
		Vector3 basePos(mProjectionSphere->getRadius(), 0, 0);
		Quaternion quat;
		quat.FromAngleAxis(Radian(((float)i/(float)20)*Math::TWO_PI), Vector3::UNIT_Z);
		basePos = quat * basePos;
		debugSphere->position(basePos);
	}
	debugSphere->end();

	mSceneMgr->getRootSceneNode()->createChildSceneNode(Vector3(0,2000,0))->attachObject(debugSphere);

	MaterialPtr mat = MaterialManager::getSingleton().create("scissormat",
		TRANSIENT_RESOURCE_GROUP);
	Pass* p = mat->getTechnique(0)->getPass(0);
	p->setDepthWriteEnabled(false);
	p->setSceneBlending(SBT_TRANSPARENT_ALPHA);
	TextureUnitState* t = p->createTextureUnitState();
	t->setColourOperationEx(LBX_SOURCE1, LBS_MANUAL, LBS_CURRENT,
		ColourValue::Red);
	t->setAlphaOperation(LBX_SOURCE1, LBS_MANUAL, LBS_CURRENT, 0.5f);

	mScissorRect = mSceneMgr->createManualObject("mScissorRect");
	mScissorRect->setUseIdentityProjection(true);
	mScissorRect->setUseIdentityView(true);
	AxisAlignedBox aabb;
	aabb.setInfinite();
	mScissorRect->setBoundingBox(aabb);
	mScissorRect->begin(mat->getName());
	mScissorRect->position(Vector3::ZERO);
	mScissorRect->position(Vector3::ZERO);
	mScissorRect->position(Vector3::ZERO);
	mScissorRect->quad(0, 1, 2, 3);
	mScissorRect->end();
	mSceneMgr->getRootSceneNode()->createChildSceneNode()->attachObject(mScissorRect);

	mCamera->setPosition(0,3000,5000);
	mCamera->lookAt(mProjectionSphere->getCenter());

}
bool PlayPen_testProjectSphere::frameStarted(const Ogre::FrameEvent& evt)
{
	Real left, top, right, bottom;
	mCamera->projectSphere(*mProjectionSphere, &left, &top, &right, &bottom);

	mScissorRect->beginUpdate(0);
	mScissorRect->position(left, top, 0);
	mScissorRect->position(left, bottom, 0);
	mScissorRect->position(right, bottom, 0);
	mScissorRect->position(right, top, 0);
	mScissorRect->quad(0,1,2,3);
	mScissorRect->end();

	return PlayPenBase::frameStarted(evt);

}

//---------------------------------------------------------------------
PlayPen_testCameraSetDirection::PlayPen_testCameraSetDirection()
: mUseParentNode(false)
, mUseFixedYaw(true)
, mFocus(100,200,-300)
{
	mInfo["Title"] = "PlayPen: Camera Set Direction";
	mInfo["Description"] = "Testing various settings for Camera::setDirection";

}
void PlayPen_testCameraSetDirection::setupContent()
{
	mSceneMgr->setAmbientLight(ColourValue::White);

	Entity* e = mSceneMgr->createEntity("1", "knot.mesh");
	mSceneMgr->getRootSceneNode()->createChildSceneNode(mFocus)->attachObject(e);

	mCamera->setPosition(200,1000,1000);
	mCamera->lookAt(mFocus);

	mTrayMgr->createButton(OgreBites::TL_BOTTOM, "Look At", "Look At");
	mTrayMgr->createCheckBox(OgreBites::TL_BOTTOM, "tglParent", "Use Parent Node");
	OgreBites::CheckBox* chk = mTrayMgr->createCheckBox(OgreBites::TL_BOTTOM, "tglFixedYaw", "Use Fixed Yaw");
	chk->setChecked(true, false);
	mTrayMgr->showCursor();
	setDragLook(true);

	mParentNode = mSceneMgr->getRootSceneNode()->createChildSceneNode(Vector3(1000, 2000, -1000));

}
void PlayPen_testCameraSetDirection::buttonHit(OgreBites::Button* button)
{
	mCamera->lookAt(mFocus);
}

void PlayPen_testCameraSetDirection::checkBoxToggled(OgreBites::CheckBox* box)
{
	if (box->getName() == "tglParent")
	{
		mUseParentNode = !mUseParentNode;

		if (mUseParentNode)
			mParentNode->attachObject(mCamera);
		else
			mParentNode->detachAllObjects();
	}
	else if (box->getName() == "tglFixedYaw")
	{
		mUseFixedYaw = !mUseFixedYaw;
		if (mUseFixedYaw)
			mCamera->setFixedYawAxis(true);
		else
			mCamera->setFixedYawAxis(false);

	}
}
//---------------------------------------------------------------------
PlayPen_testManualLOD::PlayPen_testManualLOD()
{
	mInfo["Title"] = "PlayPen: Test Manual LOD";
	mInfo["Description"] = "Testing meshes with manual LODs assigned";
}
//---------------------------------------------------------------------
String PlayPen_testManualLOD::getLODMesh()
{
	MeshPtr msh1 = (MeshPtr)MeshManager::getSingleton().load("robot.mesh",
		ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME);

	msh1->createManualLodLevel(200, "razor.mesh");
	msh1->createManualLodLevel(500, "sphere.mesh");

	return msh1->getName();

}
//---------------------------------------------------------------------
void PlayPen_testManualLOD::setupContent()
{
	String meshName = getLODMesh();

	Entity *ent;
	for (int i = 0; i < 5; ++i)
	{
		ent = mSceneMgr->createEntity("robot" + StringConverter::toString(i), meshName);
		// Add entity to the scene node
		mSceneMgr->getRootSceneNode()->createChildSceneNode(
			Vector3(0,0,(i*50)-(5*50/2)))->attachObject(ent);
	}
	mAnimState = ent->getAnimationState("Walk");
	mAnimState->setEnabled(true);

	// Give it a little ambience with lights
	Light* l;
	l = mSceneMgr->createLight("BlueLight");
	l->setPosition(-200,-80,-100);
	l->setDiffuseColour(0.5, 0.5, 1.0);

	l = mSceneMgr->createLight("GreenLight");
	l->setPosition(0,0,-100);
	l->setDiffuseColour(0.5, 1.0, 0.5);

	// Position the camera
	mCamera->setPosition(100,50,100);
	mCamera->lookAt(-50,50,0);

	mSceneMgr->setAmbientLight(ColourValue::White);

}
//---------------------------------------------------------------------
bool PlayPen_testManualLOD::frameStarted(const Ogre::FrameEvent& evt)
{
	mAnimState->addTime(evt.timeSinceLastFrame);

	return PlayPenBase::frameStarted(evt);
}
//---------------------------------------------------------------------
PlayPen_testManualLODFromFile::PlayPen_testManualLODFromFile()
{
	mInfo["Title"] = "PlayPen: Test Manual LOD (file)";
	mInfo["Description"] = "Testing meshes with manual LODs assigned, loaded from a file";
}
//---------------------------------------------------------------------
String PlayPen_testManualLODFromFile::getLODMesh()
{
	MeshPtr msh1 = (MeshPtr)MeshManager::getSingleton().load("robot.mesh",
		ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME);

	msh1->createManualLodLevel(200, "razor.mesh");
	msh1->createManualLodLevel(500, "sphere.mesh");

	// this time, we save this data to a file and re-load it

	MeshSerializer ser;
	const ResourceGroupManager::LocationList& ll =
		ResourceGroupManager::getSingleton().getResourceLocationList(ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME);
	String prefix;
	for (ResourceGroupManager::LocationList::const_iterator i = ll.begin(); i != ll.end(); ++i)
	{
		if (StringUtil::endsWith((*i)->archive->getName(), "media"))
		{
			prefix = (*i)->archive->getName();
		}
	}
	ser.exportMesh(msh1.get(), prefix + "/testlod.mesh");

	MeshManager::getSingleton().removeAll();

	return "testlod.mesh";

}

<|endoftext|>


<commit_before><commit_msg>decrease query count before dispatching callback<commit_after><|endoftext|>


<commit_before><commit_msg>more than one seed<commit_after><|endoftext|>


<commit_before><commit_msg>Fixing a small error.<commit_after><|endoftext|>


<commit_before><commit_msg>moved the callback before client connect<commit_after><|endoftext|>


<commit_before><commit_msg>fix(specializer): check number of args before reusing function<commit_after><|endoftext|>


<commit_before><commit_msg>try fix  start new  network problem<commit_after><|endoftext|>


<commit_before>// Copyright (c) 2022 PaddlePaddle Authors. All Rights Reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

#include "paddle/fluid/framework/op_registry.h"
#include "paddle/fluid/framework/operator.h"

namespace paddle {
namespace framework {
class OpDesc;
class Scope;
template <typename T>
class EmptyGradOpMaker;
}  // namespace framework
namespace imperative {
class OpBase;
}  // namespace imperative
}  // namespace paddle

namespace paddle {
namespace operators {

class DependOp : public framework::OperatorBase {
 public:
  DependOp(const std::string &type,
           const framework::VariableNameMap &inputs,
           const framework::VariableNameMap &outputs,
           const framework::AttributeMap &attrs)
      : OperatorBase(type, inputs, outputs, attrs) {}

 private:
  void RunImpl(const framework::Scope &scope,
               const platform::Place &place) const override {
    // NOTE(zhiqiu): depend op has empty compute, and it
    // can be skiped in the executor.
    OP_INOUT_CHECK(HasInputs("X"), "Input", "X", "Feed");
    OP_INOUT_CHECK(HasOutputs("Out"), "Output", "Out", "Feed");

    auto x_name = Input("X");
    auto out_name = Output("Out");
    PADDLE_ENFORCE_EQ(x_name,
                      out_name,
                      platform::errors::PreconditionNotMet(
                          "Input(X) and Output(Out) varibale should be the "
                          "same, but got Input is %s and Output is %s.",
                          x_name,
                          out_name));
    return;
  }
};

class DependOpProtoMaker : public framework::OpProtoAndCheckerMaker {
 public:
  void Make() override {
    AddInput("X", "Tensor, the dependence is added for.");
    AddInput("Dep", "The tensors that should be generated before X.")
        .AsDuplicable();
    AddOutput("Out", "Tensor, the same as input X");
    AddComment(R"DOC(
Depend Operator, allows to add explicit dependency between tensors.
For example, given two ops:
b = opA(a)
y = opB(x)

if tensor b and tensor x has some inner dependency, for example, x share data with b,
we need to add explicit dependency for x <- b, otherwise the these two operators may
be executed parellel in static graph. We can use depend op as below,

b = opA(a)
x = depend(x, b)
y = opB(x)

)DOC");
  }
};

DECLARE_NO_NEED_BUFFER_VARS_INFERER(DependNoNeedBufferVarsInferer, "X", "Dep");

}  // namespace operators
}  // namespace paddle

namespace ops = paddle::operators;

REGISTER_OPERATOR(
    depend,
    ops::DependOp,
    paddle::framework::EmptyGradOpMaker<paddle::framework::OpDesc>,
    paddle::framework::EmptyGradOpMaker<paddle::imperative::OpBase>,
    ops::DependOpProtoMaker,
    ops::DependNoNeedBufferVarsInferer);
<commit_msg>Add InferShape for Depend OP (#47907)<commit_after>// Copyright (c) 2022 PaddlePaddle Authors. All Rights Reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

#include "paddle/fluid/framework/op_registry.h"
#include "paddle/fluid/framework/operator.h"

namespace paddle {
namespace framework {
class OpDesc;
class Scope;
template <typename T>
class EmptyGradOpMaker;
}  // namespace framework
namespace imperative {
class OpBase;
}  // namespace imperative
}  // namespace paddle

namespace paddle {
namespace operators {

class DependOp : public framework::OperatorBase {
 public:
  DependOp(const std::string &type,
           const framework::VariableNameMap &inputs,
           const framework::VariableNameMap &outputs,
           const framework::AttributeMap &attrs)
      : OperatorBase(type, inputs, outputs, attrs) {}

 private:
  void RunImpl(const framework::Scope &scope,
               const platform::Place &place) const override {
    // NOTE(zhiqiu): depend op has empty compute, and it
    // can be skiped in the executor.
    OP_INOUT_CHECK(HasInputs("X"), "Input", "X", "Feed");
    OP_INOUT_CHECK(HasOutputs("Out"), "Output", "Out", "Feed");

    auto x_name = Input("X");
    auto out_name = Output("Out");
    PADDLE_ENFORCE_EQ(x_name,
                      out_name,
                      platform::errors::PreconditionNotMet(
                          "Input(X) and Output(Out) varibale should be the "
                          "same, but got Input is %s and Output is %s.",
                          x_name,
                          out_name));
    return;
  }
};

class DependOpShapeInference : public framework::InferShapeBase {
 public:
  void operator()(framework::InferShapeContext *ctx) const override {}
};

class DependOpProtoMaker : public framework::OpProtoAndCheckerMaker {
 public:
  void Make() override {
    AddInput("X", "Tensor, the dependence is added for.");
    AddInput("Dep", "The tensors that should be generated before X.")
        .AsDuplicable();
    AddOutput("Out", "Tensor, the same as input X");
    AddComment(R"DOC(
Depend Operator, allows to add explicit dependency between tensors.
For example, given two ops:
b = opA(a)
y = opB(x)

if tensor b and tensor x has some inner dependency, for example, x share data with b,
we need to add explicit dependency for x <- b, otherwise the these two operators may
be executed parellel in static graph. We can use depend op as below,

b = opA(a)
x = depend(x, b)
y = opB(x)

)DOC");
  }
};

DECLARE_NO_NEED_BUFFER_VARS_INFERER(DependNoNeedBufferVarsInferer, "X", "Dep");

}  // namespace operators
}  // namespace paddle

namespace ops = paddle::operators;

REGISTER_OPERATOR(
    depend,
    ops::DependOp,
    paddle::framework::EmptyGradOpMaker<paddle::framework::OpDesc>,
    paddle::framework::EmptyGradOpMaker<paddle::imperative::OpBase>,
    ops::DependOpProtoMaker,
    ops::DependOpShapeInference,
    ops::DependNoNeedBufferVarsInferer);
<|endoftext|>


<commit_before><commit_msg>drop checkpoints<commit_after><|endoftext|>


<commit_before><commit_msg>Slowallel but works<commit_after><|endoftext|>


<commit_before><commit_msg>~ realignment<commit_after><|endoftext|>


<commit_before>/*
 * Copyright (C) 2011 Scott MacDonald. All rights reserved.
 *
 * This program is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program. If not, see <http://www.gnu.org/licenses/>.
 */
#include "worldgen/levelgenerator.h"
#include "worldgen/roomgenerator.h"
#include "worldgen/roomdata.h"
#include "common/utils.h"
#include "common/random.h"

#include "level.h"

#include "room.h"

/**
 * Level generator constructor. Creates a new level generator that is ready
 * to construct as many random levels as you wish.
 *
 * \param  random  Reference to the dungeon generator's random
 * \param  width   Width of the level
 * \param  height  Height of the level
 */
LevelGenerator::LevelGenerator( Random& random,
                                int width,
                                int height )
    : mRandom( random ),
      mLevelWidth( width ),
      mLevelHeight( height ),
      mTileGrid( width, height )
{
    assert( width > 5 );
    assert( height > 5 );
}

/**
 * Destructor
 */
LevelGenerator::~LevelGenerator()
{
}

/**
 * Generates and returns a random level
 */
Level* LevelGenerator::generate()
{
    RoomGenerator roomGenerator( mRandom );
    std::vector<RoomData*> levelRooms;

    // Turn the level border tiles into impassable bedrock tiles to prevent
    // the player (or anyone really) from escaping into the void
    mTileGrid.carveRoom( Rect( 1, 1, mLevelWidth-2, mLevelHeight-2 ),
                         1,
                         Tile( TILE_IMPASSABLE ),
                         Tile( TILE_EMPTY ) );

    // Generate the requested number of rooms
    for ( int i = 0; i < 150; ++i )
    {
        // Generate a random room
        ERoomSize roomSize  = generateRandomRoomSize( ROOM_SIZE_LARGE );
        RoomData *pRoomData = roomGenerator.generate( roomSize );

        // Generate a random position to place it in
        Point placeAt = findRandomPointFor( deref(pRoomData) );

        // Try to place the room's tile grid into our level's tile grid. If it
        // doesn't succeed, make sure to delete the room data before trying
        // another room
        if ( canPlaceRoomAt( deref(pRoomData), placeAt ) )
        {
            mTileGrid.insert( placeAt, pRoomData->tiles );
            levelRooms.push_back( pRoomData );
        }
        else
        {
            Delete( pRoomData );
        }
    }

    // Show debug stats about rooms generated and whatnot

    // Hook everything up

    // Return the generated level
    return new Level( mTileGrid );
}

ERoomSize LevelGenerator::generateRandomRoomSize( ERoomSize maxRoomSize ) const
{
    // This needs to be improved
    int whichOne = mRandom.randInt( 0, 100 );

    if ( whichOne < 10 )
    {
        return ROOM_SIZE_TINY;
    }
    else if ( whichOne < 30 )
    {
        return ROOM_SIZE_SMALL;
    }
    else if ( whichOne < 90 )
    {
        return ROOM_SIZE_MEDIUM;
    }
    else
    {
        return ROOM_SIZE_LARGE;
    }
}

/**
 * Finds a random position to attempt to place a room at
 *
 * \param  roomData  The room you are trying to place
 * \return A randomly determined position
 */
Point LevelGenerator::findRandomPointFor( const RoomData& roomData ) const
{
    int maxX = mLevelWidth  - roomData.totalArea.width() - 2;
    int maxY = mLevelHeight - roomData.totalArea.height() - 2;

    return Point( mRandom.randInt( 1, maxX ),
                  mRandom.randInt( 1, maxY ) );
}

/**
 * Checks if the given room can be placed at the requested location
 *
 * \param  roomData  Data for the room you are trying to place
 * \param  pos       Position you are trying to place the room at
 * \return True if the room can be positioned there, false otherwise
 */
bool LevelGenerator::canPlaceRoomAt( const RoomData& roomData,
                                     const Point& pos ) const
{
    return mTileGrid.isAreaEmpty( roomData.totalArea.translate( pos ) );
}<commit_msg>changed a comment<commit_after>/*
 * Copyright (C) 2011 Scott MacDonald. All rights reserved.
 *
 * This program is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program. If not, see <http://www.gnu.org/licenses/>.
 */
#include "worldgen/levelgenerator.h"
#include "worldgen/roomgenerator.h"
#include "worldgen/roomdata.h"
#include "common/utils.h"
#include "common/random.h"

#include "level.h"

#include "room.h"

/**
 * Level generator constructor. Creates a new level generator that is ready
 * to construct as many random levels as you wish.
 *
 * \param  random  Reference to the dungeon generator's random
 * \param  width   Width of the level
 * \param  height  Height of the level
 */
LevelGenerator::LevelGenerator( Random& random,
                                int width,
                                int height )
    : mRandom( random ),
      mLevelWidth( width ),
      mLevelHeight( height ),
      mTileGrid( width, height )
{
    assert( width > 5 );
    assert( height > 5 );
}

/**
 * Destructor
 */
LevelGenerator::~LevelGenerator()
{
}

/**
 * Generates and returns a random level
 */
Level* LevelGenerator::generate()
{
    RoomGenerator roomGenerator( mRandom );
    std::vector<RoomData*> levelRooms;

    // Turn the level border tiles into impassable bedrock tiles to prevent
    // the player (or anyone really) from escaping into the void
    mTileGrid.carveRoom( Rect( 1, 1, mLevelWidth-2, mLevelHeight-2 ),
                         1,
                         Tile( TILE_IMPASSABLE ),
                         Tile( TILE_EMPTY ) );

    // Generate the requested number of rooms
    for ( int i = 0; i < 150; ++i )
    {
        // Generate a random room
        ERoomSize roomSize  = generateRandomRoomSize( ROOM_SIZE_LARGE );
        RoomData *pRoomData = roomGenerator.generate( roomSize );

        // Generate a random position to place it in
        Point placeAt = findRandomPointFor( deref(pRoomData) );

        // Try to place the room's tile grid into our level's tile grid. If it
        // doesn't succeed, make sure to delete the room data before trying
        // another room
        if ( canPlaceRoomAt( deref(pRoomData), placeAt ) )
        {
            mTileGrid.insert( placeAt, pRoomData->tiles );
            levelRooms.push_back( pRoomData );
        }
        else
        {
            Delete( pRoomData );
        }
    }

    // Show debug stats about rooms generated and whatnot

    // Connect rooms together

    // Return the generated level
    return new Level( mTileGrid );
}

/**
 * Creates a random room size, depending on the maximum room size passed
 */
ERoomSize LevelGenerator::generateRandomRoomSize( ERoomSize maxRoomSize ) const
{
    // This needs to be improved
    int whichOne = mRandom.randInt( 0, 100 );

    if ( whichOne < 10 )
    {
        return ROOM_SIZE_TINY;
    }
    else if ( whichOne < 30 )
    {
        return ROOM_SIZE_SMALL;
    }
    else if ( whichOne < 90 )
    {
        return ROOM_SIZE_MEDIUM;
    }
    else
    {
        return ROOM_SIZE_LARGE;
    }
}

/**
 * Finds a random position to attempt to place a room at
 *
 * \param  roomData  The room you are trying to place
 * \return A randomly determined position
 */
Point LevelGenerator::findRandomPointFor( const RoomData& roomData ) const
{
    int maxX = mLevelWidth  - roomData.totalArea.width() - 2;
    int maxY = mLevelHeight - roomData.totalArea.height() - 2;

    return Point( mRandom.randInt( 1, maxX ),
                  mRandom.randInt( 1, maxY ) );
}

/**
 * Checks if the given room can be placed at the requested location
 *
 * \param  roomData  Data for the room you are trying to place
 * \param  pos       Position you are trying to place the room at
 * \return True if the room can be positioned there, false otherwise
 */
bool LevelGenerator::canPlaceRoomAt( const RoomData& roomData,
                                     const Point& pos ) const
{
    return mTileGrid.isAreaEmpty( roomData.totalArea.translate( pos ) );
}<|endoftext|>


<commit_before>/**
 ******************************************************************************
 * Xenia : Xbox 360 Emulator Research Project                                 *
 ******************************************************************************
 * Copyright 2013 Ben Vanik. All rights reserved.                             *
 * Released under the BSD license - see LICENSE in the root for more details. *
 ******************************************************************************
 */

#include "xenia/base/logging.h"
#include "xenia/kernel/kernel_state.h"
#include "xenia/kernel/objects/xthread.h"
#include "xenia/kernel/objects/xsemaphore.h"
#include "xenia/kernel/util/shim_utils.h"
#include "xenia/kernel/xboxkrnl_private.h"
#include "xenia/kernel/xobject.h"
#include "xenia/xbox.h"

namespace xe {
namespace kernel {

SHIM_CALL ObOpenObjectByName_shim(PPCContext* ppc_context,
                                  KernelState* kernel_state) {
  // r3 = ptr to info?
  //   +0 = -4
  //   +4 = name ptr
  //   +8 = 0
  // r4 = ExEventObjectType | ExSemaphoreObjectType | ExTimerObjectType
  // r5 = 0
  // r6 = out_ptr (handle?)
  uint32_t obj_attributes_ptr = SHIM_GET_ARG_32(0);
  uint32_t object_type_ptr = SHIM_GET_ARG_32(1);
  uint32_t unk = SHIM_GET_ARG_32(2);
  uint32_t handle_ptr = SHIM_GET_ARG_32(3);

  auto name =
      X_ANSI_STRING::to_string_indirect(SHIM_MEM_BASE, obj_attributes_ptr + 4);

  XELOGD("ObOpenObjectByName(%.8X(name=%s), %.8X, %.8X, %.8X)",
         obj_attributes_ptr, name.c_str(), object_type_ptr, unk, handle_ptr);

  X_HANDLE handle = X_INVALID_HANDLE_VALUE;
  X_STATUS result =
      kernel_state->object_table()->GetObjectByName(name, &handle);
  if (XSUCCEEDED(result)) {
    SHIM_SET_MEM_32(handle_ptr, handle);
  }

  SHIM_SET_RETURN_32(result);
}

SHIM_CALL ObReferenceObjectByHandle_shim(PPCContext* ppc_context,
                                         KernelState* kernel_state) {
  uint32_t handle = SHIM_GET_ARG_32(0);
  uint32_t object_type_ptr = SHIM_GET_ARG_32(1);
  uint32_t out_object_ptr = SHIM_GET_ARG_32(2);

  XELOGD("ObReferenceObjectByHandle(%.8X, %.8X, %.8X)", handle, object_type_ptr,
         out_object_ptr);

  X_STATUS result = X_STATUS_SUCCESS;

  auto object = kernel_state->object_table()->LookupObject<XObject>(handle);
  if (object) {
    // TODO(benvanik): verify type with object_type_ptr

    // TODO(benvanik): get native value, if supported.
    uint32_t native_ptr;
    switch (object_type_ptr) {
      case 0x00000000: {  // whatever?
        switch (object->type()) {
          // TODO(benvanik): need to track native_ptr in XObject, allocate as
          // needed?
          /*case XObject::kTypeEvent: {
            XEvent* ev = (XEvent*)object;
          } break;*/
          case XObject::kTypeThread: {
            auto thread = object.get<XThread>();
            native_ptr = thread->guest_object();
          } break;
          default: {
            assert_unhandled_case(object->type());
            native_ptr = 0xDEADF00D;
          } break;
        }
      } break;
      case 0xD017BEEF: {  // ExSemaphoreObjectType
        assert(object->type() == XObject::kTypeSemaphore);
        auto sem = object.get<XSemaphore>();

        native_ptr = sem->guest_object();
      } break;
      case 0xD01BBEEF: {  // ExThreadObjectType
        assert(object->type() == XObject::kTypeThread);
        auto thread = object.get<XThread>();

        native_ptr = thread->guest_object();
      } break;
      default: {
        assert_unhandled_case(object_type_ptr);
        native_ptr = 0xDEADF00D;
      } break;
    }

    // Caller takes the reference.
    // It's released in ObDereferenceObject.
    object->Retain();
    if (out_object_ptr) {
      SHIM_SET_MEM_32(out_object_ptr, native_ptr);
    }
  } else {
    result = X_STATUS_INVALID_HANDLE;
  }

  SHIM_SET_RETURN_32(result);
}

SHIM_CALL ObDereferenceObject_shim(PPCContext* ppc_context,
                                   KernelState* kernel_state) {
  uint32_t native_ptr = SHIM_GET_ARG_32(0);

  XELOGD("ObDereferenceObject(%.8X)", native_ptr);

  // Check if a dummy value from ObReferenceObjectByHandle.
  if (native_ptr == 0xDEADF00D) {
    SHIM_SET_RETURN_32(0);
    return;
  }

  void* object_ptr = SHIM_MEM_ADDR(native_ptr);
  auto object = XObject::GetNativeObject<XObject>(kernel_state, object_ptr);
  if (object) {
    object->Release();
  }

  SHIM_SET_RETURN_32(0);
}

dword_result_t NtDuplicateObject(dword_t handle, lpdword_t new_handle_ptr,
                                 dword_t options) {
  // NOTE: new_handle_ptr can be zero to just close a handle.
  // NOTE: this function seems to be used to get the current thread handle
  //       (passed handle=-2).
  // This function actually just creates a new handle to the same object.
  // Most games use it to get real handles to the current thread or whatever.

  X_HANDLE new_handle = X_INVALID_HANDLE_VALUE;
  X_STATUS result =
      kernel_state()->object_table()->DuplicateHandle(handle, &new_handle);

  if (new_handle_ptr) {
    *new_handle_ptr = new_handle;
  }

  if (options == 1 /* DUPLICATE_CLOSE_SOURCE */) {
    // Always close the source object.
    kernel_state()->object_table()->RemoveHandle(handle);
  }

  return result;
}
DECLARE_XBOXKRNL_EXPORT(NtDuplicateObject, ExportTag::kImplemented);

dword_result_t NtClose(dword_t handle) {
  return kernel_state()->object_table()->RemoveHandle(handle);
}
DECLARE_XBOXKRNL_EXPORT(NtClose, ExportTag::kImplemented);

}  // namespace kernel
}  // namespace xe

void xe::kernel::xboxkrnl::RegisterObExports(
    xe::cpu::ExportResolver* export_resolver, KernelState* kernel_state) {
  SHIM_SET_MAPPING("xboxkrnl.exe", ObOpenObjectByName, state);
  SHIM_SET_MAPPING("xboxkrnl.exe", ObReferenceObjectByHandle, state);
  SHIM_SET_MAPPING("xboxkrnl.exe", ObDereferenceObject, state);
}
<commit_msg>ObLookupThreadByThreadId / ObOpenObjectByPointer<commit_after>/**
 ******************************************************************************
 * Xenia : Xbox 360 Emulator Research Project                                 *
 ******************************************************************************
 * Copyright 2013 Ben Vanik. All rights reserved.                             *
 * Released under the BSD license - see LICENSE in the root for more details. *
 ******************************************************************************
 */

#include "xenia/base/logging.h"
#include "xenia/kernel/kernel_state.h"
#include "xenia/kernel/objects/xthread.h"
#include "xenia/kernel/objects/xsemaphore.h"
#include "xenia/kernel/util/shim_utils.h"
#include "xenia/kernel/xboxkrnl_private.h"
#include "xenia/kernel/xobject.h"
#include "xenia/xbox.h"

namespace xe {
namespace kernel {

SHIM_CALL ObOpenObjectByName_shim(PPCContext* ppc_context,
                                  KernelState* kernel_state) {
  // r3 = ptr to info?
  //   +0 = -4
  //   +4 = name ptr
  //   +8 = 0
  // r4 = ExEventObjectType | ExSemaphoreObjectType | ExTimerObjectType
  // r5 = 0
  // r6 = out_ptr (handle?)
  uint32_t obj_attributes_ptr = SHIM_GET_ARG_32(0);
  uint32_t object_type_ptr = SHIM_GET_ARG_32(1);
  uint32_t unk = SHIM_GET_ARG_32(2);
  uint32_t handle_ptr = SHIM_GET_ARG_32(3);

  auto name =
      X_ANSI_STRING::to_string_indirect(SHIM_MEM_BASE, obj_attributes_ptr + 4);

  XELOGD("ObOpenObjectByName(%.8X(name=%s), %.8X, %.8X, %.8X)",
         obj_attributes_ptr, name.c_str(), object_type_ptr, unk, handle_ptr);

  X_HANDLE handle = X_INVALID_HANDLE_VALUE;
  X_STATUS result =
      kernel_state->object_table()->GetObjectByName(name, &handle);
  if (XSUCCEEDED(result)) {
    SHIM_SET_MEM_32(handle_ptr, handle);
  }

  SHIM_SET_RETURN_32(result);
}

SHIM_CALL ObReferenceObjectByHandle_shim(PPCContext* ppc_context,
                                         KernelState* kernel_state) {
  uint32_t handle = SHIM_GET_ARG_32(0);
  uint32_t object_type_ptr = SHIM_GET_ARG_32(1);
  uint32_t out_object_ptr = SHIM_GET_ARG_32(2);

  XELOGD("ObReferenceObjectByHandle(%.8X, %.8X, %.8X)", handle, object_type_ptr,
         out_object_ptr);

  X_STATUS result = X_STATUS_SUCCESS;

  auto object = kernel_state->object_table()->LookupObject<XObject>(handle);
  if (object) {
    // TODO(benvanik): verify type with object_type_ptr

    // TODO(benvanik): get native value, if supported.
    uint32_t native_ptr;
    switch (object_type_ptr) {
      case 0x00000000: {  // whatever?
        switch (object->type()) {
          // TODO(benvanik): need to track native_ptr in XObject, allocate as
          // needed?
          /*case XObject::kTypeEvent: {
            XEvent* ev = (XEvent*)object;
          } break;*/
          case XObject::kTypeThread: {
            auto thread = object.get<XThread>();
            native_ptr = thread->guest_object();
          } break;
          default: {
            assert_unhandled_case(object->type());
            native_ptr = 0xDEADF00D;
          } break;
        }
      } break;
      case 0xD017BEEF: {  // ExSemaphoreObjectType
        assert(object->type() == XObject::kTypeSemaphore);
        auto sem = object.get<XSemaphore>();

        native_ptr = sem->guest_object();
      } break;
      case 0xD01BBEEF: {  // ExThreadObjectType
        assert(object->type() == XObject::kTypeThread);
        auto thread = object.get<XThread>();

        native_ptr = thread->guest_object();
      } break;
      default: {
        assert_unhandled_case(object_type_ptr);
        native_ptr = 0xDEADF00D;
      } break;
    }

    // Caller takes the reference.
    // It's released in ObDereferenceObject.
    object->Retain();
    if (out_object_ptr) {
      SHIM_SET_MEM_32(out_object_ptr, native_ptr);
    }
  } else {
    result = X_STATUS_INVALID_HANDLE;
  }

  SHIM_SET_RETURN_32(result);
}

SHIM_CALL ObDereferenceObject_shim(PPCContext* ppc_context,
                                   KernelState* kernel_state) {
  uint32_t native_ptr = SHIM_GET_ARG_32(0);

  XELOGD("ObDereferenceObject(%.8X)", native_ptr);

  // Check if a dummy value from ObReferenceObjectByHandle.
  if (native_ptr == 0xDEADF00D) {
    SHIM_SET_RETURN_32(0);
    return;
  }

  void* object_ptr = SHIM_MEM_ADDR(native_ptr);
  auto object = XObject::GetNativeObject<XObject>(kernel_state, object_ptr);
  if (object) {
    object->Release();
  }

  SHIM_SET_RETURN_32(0);
}

dword_result_t ObLookupThreadByThreadId(dword_t thread_id, lpdword_t out_object_ptr) {
  auto thread = kernel_state()->GetThreadByID(thread_id);
  if (!thread) {
    return X_STATUS_NOT_FOUND;
  }

  // Retain the object. Will be released in ObDereferenceObject.
  thread->Retain();
  *out_object_ptr = thread->guest_object();
  auto hdr = kernel_memory()->TranslateVirtual<X_DISPATCH_HEADER*>(thread->guest_object());
  assert_true(hdr->type == 6);

  return X_STATUS_SUCCESS;
}
DECLARE_XBOXKRNL_EXPORT(ObLookupThreadByThreadId, ExportTag::kStub);

dword_result_t ObOpenObjectByPointer(lpvoid_t object_ptr, lpdword_t out_handle_ptr) {
  auto object = XObject::GetNativeObject<XObject>(kernel_state(), object_ptr);
  if (!object) {
    return X_STATUS_UNSUCCESSFUL;
  }

  // Retain the handle. Will be released in NtClose.
  object->RetainHandle();
  *out_handle_ptr = object->handle();
  return X_STATUS_SUCCESS;
}
DECLARE_XBOXKRNL_EXPORT(ObOpenObjectByPointer, ExportTag::kStub);

dword_result_t NtDuplicateObject(dword_t handle, lpdword_t new_handle_ptr,
                                 dword_t options) {
  // NOTE: new_handle_ptr can be zero to just close a handle.
  // NOTE: this function seems to be used to get the current thread handle
  //       (passed handle=-2).
  // This function actually just creates a new handle to the same object.
  // Most games use it to get real handles to the current thread or whatever.

  X_HANDLE new_handle = X_INVALID_HANDLE_VALUE;
  X_STATUS result =
      kernel_state()->object_table()->DuplicateHandle(handle, &new_handle);

  if (new_handle_ptr) {
    *new_handle_ptr = new_handle;
  }

  if (options == 1 /* DUPLICATE_CLOSE_SOURCE */) {
    // Always close the source object.
    kernel_state()->object_table()->RemoveHandle(handle);
  }

  return result;
}
DECLARE_XBOXKRNL_EXPORT(NtDuplicateObject, ExportTag::kImplemented);

dword_result_t NtClose(dword_t handle) {
  // FIXME: This needs to be removed once handle count reaches 0!
  return kernel_state()->object_table()->RemoveHandle(handle);
}
DECLARE_XBOXKRNL_EXPORT(NtClose, ExportTag::kImplemented);

}  // namespace kernel
}  // namespace xe

void xe::kernel::xboxkrnl::RegisterObExports(
    xe::cpu::ExportResolver* export_resolver, KernelState* kernel_state) {
  SHIM_SET_MAPPING("xboxkrnl.exe", ObOpenObjectByName, state);
  SHIM_SET_MAPPING("xboxkrnl.exe", ObReferenceObjectByHandle, state);
  SHIM_SET_MAPPING("xboxkrnl.exe", ObDereferenceObject, state);
}
<|endoftext|>


<commit_before>#include <cstdio>
#include "submodular-flow.hpp"
#include <algorithm>
#include <limits>
#include <queue>

SubmodularFlow::SubmodularFlow()
    : m_constant_term(0),
    m_num_nodes(0),
    m_c_si(),
    m_c_it(),
    m_phi_si(),
    m_phi_it(),
    m_labels(),
    m_num_cliques(0),
    m_cliques(),
    m_neighbors()
{ }

SubmodularFlow::NodeId SubmodularFlow::AddNode(int n) {
    ASSERT(n >= 1);
    NodeId first_node = m_num_nodes;
    for (int i = 0; i < n; ++i) {
        m_c_si.push_back(0);
        m_c_it.push_back(0);
        m_phi_si.push_back(0);
        m_phi_it.push_back(0);
        m_labels.push_back(-1);
        m_neighbors.push_back(NeighborList());
        m_num_nodes++;
    }
    return first_node;
}

int SubmodularFlow::GetLabel(NodeId n) const {
    return m_labels[n];
}

void SubmodularFlow::AddUnaryTerm(NodeId n, REAL E0, REAL E1) {
    // Reparametize so that E0, E1 >= 0
    if (E0 < 0) {
        AddConstantTerm(E0);
        E0 = 0;
        E1 -= E0;
    }
    if (E1 < 0) {
        AddConstantTerm(E1);
        E1 = 0;
        E0 -= E1;
    }
    m_c_si[n] += E0;
    m_c_it[n] += E1;
}

void SubmodularFlow::AddUnaryTerm(NodeId n, REAL coeff) {
    AddUnaryTerm(n, 0, coeff);
}

void SubmodularFlow::AddClique(const CliquePtr& cp) {
    m_cliques.push_back(cp);
    for (NodeId i : cp->Nodes()) {
        ASSERT(0 <= i && i < m_num_nodes);
        m_neighbors[i].push_back(m_num_cliques);
    }
    m_num_cliques++;
    cp->NormalizeEnergy(*this);
}

void SubmodularFlow::AddClique(const std::vector<NodeId>& nodes, const std::vector<REAL>& energyTable) {
    CliquePtr cp(new EnergyTableClique(nodes, energyTable));
    AddClique(cp);
}

//////// Push Relabel methods ///////////

void SubmodularFlow::add_to_active_list(NodeId u, Layer& layer) {
    // BOOST_USING_STD_MIN();
    // BOOST_USING_STD_MAX();
    layer.active_vertices.push_front(u);
    max_active = std::max BOOST_PREVENT_MACRO_SUBSTITUTION(dis[u], max_active);
    min_active = std::min BOOST_PREVENT_MACRO_SUBSTITUTION(dis[u], min_active);
    layer_list_ptr[u] = layer.active_vertices.begin();
}

void SubmodularFlow::remove_from_active_list(NodeId u) {
    layers[dis[u]].active_vertices.erase(layer_list_ptr[u]);
}

void SubmodularFlow::PushRelabelInit()
{
    // super source and sink
    s = m_num_nodes; t = m_num_nodes + 1;
    max_active = 0; min_active = m_num_nodes + 2; // n

    dis.clear(); excess.clear(); current_arc_index.clear();
    m_arc_list.clear(); layers.clear();

    // init data structures
    for (int i = 0; i < m_num_nodes + 2; ++i) {
        dis.push_back(0);
        excess.push_back(0);
        current_arc_index.push_back(0);
        std::vector<Arc> arc_list;
        m_arc_list.push_back(arc_list);
        Layer layer;
        layers.push_back(layer);
    }
    dis[s] = m_num_nodes + 2; // n = m_num_nodes + 2

    for (int i = 0; i < 2 * (m_num_nodes + 2); ++i) {
        Layer layer;
        layers.push_back(layer);
    }

    // saturate arcs out of s.
    for (NodeId i = 0; i < m_num_nodes; ++i) {
        m_phi_si[i] = m_c_si[i];
        if (m_c_si[i] > 0) {
            excess[s] -= m_c_si[i];
            excess[i] += m_c_si[i];
	        add_to_active_list(i, layers[0]);
        }
    }

    // initialize arc lists
    Arc arc;
    for (NodeId i = 0; i < m_num_nodes; ++i) {
        // arcs from source
        arc.i = s;
        arc.j = i;
        arc.c = -1;
        m_arc_list[arc.i].push_back(arc);

        // arcs to source
        arc.i = i;
        arc.j = s;
        m_arc_list[arc.i].push_back(arc);

        // arcs to sink
        arc.j = t;
        m_arc_list[arc.i].push_back(arc);

        // arcs from sink
        arc.i = t;
        arc.j = i;
        m_arc_list[arc.i].push_back(arc);
    }

    // Arcs between nodes of clique
    for (int cid = 0; cid < m_num_cliques; ++cid) {
        CliquePtr cp = m_cliques[cid];
        for (NodeId i : cp->Nodes()) {
            for (NodeId j : cp->Nodes()) {
                if (i == j) continue;
                arc.i = i;
                arc.j = j;
                arc.c = cid;
                m_arc_list[i].push_back(arc);
            }
        }
    }
}

void SubmodularFlow::PushRelabelStep()
{
    Layer& layer = layers[max_active];
    list_iterator u_iter = layer.active_vertices.begin();

    if (u_iter == layer.active_vertices.end())
        --max_active;
    else {
        NodeId i = *u_iter;
        remove_from_active_list(i);
        boost::optional<Arc> arc = FindPushableEdge(i);
        if (arc)
            Push(*arc);
        else
            Relabel(i);
    }
}

bool SubmodularFlow::PushRelabelNotDone()
{
    return max_active >= min_active;
}

void SubmodularFlow::PushRelabel()
{
    PushRelabelInit();

    // find active i w/ largest distance
    while (PushRelabelNotDone()) {
        PushRelabelStep();
    }
}

REAL SubmodularFlow::ResCap(Arc arc) {
    if (arc.i == s) {
        return m_c_si[arc.j] - m_phi_it[arc.j];
    } else if (arc.j == s) {
        return m_phi_si[arc.i];
    } else if (arc.i == t) {
        return m_phi_it[arc.j];
    } else if (arc.j == t) {
        return m_c_it[arc.i] - m_phi_it[arc.i];
    } else {
        return m_cliques[arc.c]->ExchangeCapacity(arc.i, arc.j);
    }
}

boost::optional<SubmodularFlow::Arc> SubmodularFlow::FindPushableEdge(NodeId i) {
    // Use current arc?
    for (Arc arc : m_arc_list[i]) {
        if (dis[i] == dis[arc.j] + 1 && ResCap(arc) > 0) {
	        return boost::optional<SubmodularFlow::Arc>(arc);
        }
    }
    return boost::optional<SubmodularFlow::Arc>();
}

void SubmodularFlow::Push(Arc arc) {
    REAL delta; // amount to push

    // Note, we never have arc.i == s or t
    if (arc.j == s) {  // reverse arc
        delta = std::min(excess[arc.i], m_phi_si[arc.i]);
        m_phi_si[arc.i] -= delta;
    } else if (arc.j == t) {
        delta = std::min(excess[arc.i], m_c_it[arc.i] - m_phi_it[arc.i]);
        m_phi_it[arc.i] += delta;
    } else { // Clique arc
        std::cout << "Pushing on clique arc" << std::endl;
        delta = std::min(excess[arc.i], m_cliques[arc.c]->ExchangeCapacity(arc.i, arc.j));
        std::vector<REAL>& alpha_ci = m_cliques[arc.c]->AlphaCi();
        alpha_ci[arc.i] += delta;
        alpha_ci[arc.j] -= delta;
    }
    // Update (residual capacities) and excesses
    excess[arc.i] -= delta;
    excess[arc.j] += delta;
    if (excess[arc.j] > 0 && arc.j != s && arc.j != t) {
        remove_from_active_list(arc.j);
        add_to_active_list(arc.j, layers[dis[arc.j]]);
    }
    if (excess[arc.i] > 0) {
        add_to_active_list(arc.i, layers[dis[arc.i]]);
    }
}

void SubmodularFlow::Relabel(NodeId i) {
    dis[i] = std::numeric_limits<int>::max();
    for(Arc arc : m_arc_list[i]) {
        if (ResCap(arc) > 0) {
            dis[i] = std::min (dis[i], dis[arc.j] + 1);
        }
    }
    // if (dis[i] < dis[s])
        add_to_active_list(i, layers[dis[i]]);
}

///////////////    end of push relabel    ///////////////////

void SubmodularFlow::ComputeMinCut() {
    for (NodeId i = 0; i < m_num_nodes; ++i) {
        dis[i] = std::numeric_limits<int>::max();
        m_labels[i] = 1;
    }
    dis[t] = 0;
    // curr is the current level of nodes to be visited;
    // next is the next layer to visit.
    std::queue<NodeId> curr, next;
    next.push(t);

    int level = 1;
    while (!next.empty()) {
        // Next becomes curr; empty next
        std::swap(curr, next);
        std::queue<NodeId> empty;
        std::swap(next, empty);

        while (!curr.empty()) {
            NodeId u = curr.front();
            curr.pop();
            for (Arc arc : m_arc_list[u]) {
                arc.i = arc.j;
                arc.j = u;
                if (ResCap(arc) > 0 && arc.i != s && arc.i != t
                        && dis[arc.i] == std::numeric_limits<int>::max()) {
                    m_labels[arc.i] = 0;
                    next.push(arc.i);
                    dis[arc.i] = level;
                }
            }
        }
        ++level;
    }
    for (int label : m_labels)
        std::cout << label << std::endl;
}

REAL SubmodularFlow::ComputeEnergy() const {
    return ComputeEnergy(m_labels);
}

REAL SubmodularFlow::ComputeEnergy(const std::vector<int>& labels) const {
    REAL total = m_constant_term;
    for (NodeId i = 0; i < m_num_nodes; ++i) {
        if (labels[i] == 1) total += m_c_it[i];
        else total += m_c_si[i];
    }
    for (const CliquePtr& cp : m_cliques) {
        total += cp->ComputeEnergy(labels);
    }
    return total;
}

void EnergyTableClique::NormalizeEnergy(SubmodularFlow& sf) {
    const size_t n = this->m_nodes.size();
    const Assignment num_assignments = 1 << n;
    const REAL constant_term = m_energy[num_assignments - 1];
    std::vector<REAL> marginals;
    Assignment assgn = num_assignments - 1; // The all 1 assignment
    for (size_t i = 0; i < n; ++i) {
        Assignment next_assgn = assgn ^ (1 << i);
        marginals.push_back(m_energy[assgn] - m_energy[next_assgn]);
        assgn = next_assgn;
    }

    for (Assignment a = 0; a < num_assignments; ++a) {
        m_energy[a] -= constant_term;
        for (size_t i = 0; i < n; ++i) {
            if (!(a & (1 << i))) m_energy[a] += marginals[i];
        }
    }

    sf.AddConstantTerm(constant_term);
    for (size_t i = 0; i < n; ++i) {
        sf.AddUnaryTerm(this->m_nodes[i], -marginals[i], 0);
    }
}

REAL EnergyTableClique::ComputeEnergy(const std::vector<int>& labels) const {
    Assignment assgn = 0;
    for (size_t i = 0; i < this->m_nodes.size(); ++i) {
        NodeId n = this->m_nodes[i];
        if (labels[n] == 1) {
            assgn |= 1 << i;
        }
    }
    return m_energy[assgn];
}

REAL EnergyTableClique::ExchangeCapacity(NodeId u, NodeId v) const {
    // This is not the most efficient way to do things, but it works
    const size_t u_idx = std::find(this->m_nodes.begin(), this->m_nodes.end(), u) - this->m_nodes.begin();
    const size_t v_idx = std::find(this->m_nodes.begin(), this->m_nodes.end(), v) - this->m_nodes.begin();

    REAL min_energy = std::numeric_limits<REAL>::max();
    Assignment num_assgns = 1 << this->m_nodes.size();
    for (Assignment assgn = 0; assgn < num_assgns; ++assgn) {
        REAL alpha_C = 0;
        for (size_t i = 0; i < this->m_alpha_Ci.size(); ++i) {
            if (assgn & (1 << i)) alpha_C += this->m_alpha_Ci[i];
        }
        if (assgn & (1 << u_idx) && !(assgn & (1 << v_idx))) {
            // then assgn is a set separating u from v
            REAL energy = m_energy[assgn] - alpha_C;
            if (energy < min_energy) min_energy = energy;
        }
    }
    return min_energy;
}
<commit_msg>Changed the remove behavior to something inefficient but something I understand to remove segfault.<commit_after>#include <cstdio>
#include "submodular-flow.hpp"
#include <algorithm>
#include <limits>
#include <queue>

SubmodularFlow::SubmodularFlow()
    : m_constant_term(0),
    m_num_nodes(0),
    m_c_si(),
    m_c_it(),
    m_phi_si(),
    m_phi_it(),
    m_labels(),
    m_num_cliques(0),
    m_cliques(),
    m_neighbors()
{ }

SubmodularFlow::NodeId SubmodularFlow::AddNode(int n) {
    ASSERT(n >= 1);
    NodeId first_node = m_num_nodes;
    for (int i = 0; i < n; ++i) {
        m_c_si.push_back(0);
        m_c_it.push_back(0);
        m_phi_si.push_back(0);
        m_phi_it.push_back(0);
        m_labels.push_back(-1);
        m_neighbors.push_back(NeighborList());
        m_num_nodes++;
    }
    return first_node;
}

int SubmodularFlow::GetLabel(NodeId n) const {
    return m_labels[n];
}

void SubmodularFlow::AddUnaryTerm(NodeId n, REAL E0, REAL E1) {
    // Reparametize so that E0, E1 >= 0
    if (E0 < 0) {
        AddConstantTerm(E0);
        E0 = 0;
        E1 -= E0;
    }
    if (E1 < 0) {
        AddConstantTerm(E1);
        E1 = 0;
        E0 -= E1;
    }
    m_c_si[n] += E0;
    m_c_it[n] += E1;
}

void SubmodularFlow::AddUnaryTerm(NodeId n, REAL coeff) {
    AddUnaryTerm(n, 0, coeff);
}

void SubmodularFlow::AddClique(const CliquePtr& cp) {
    m_cliques.push_back(cp);
    for (NodeId i : cp->Nodes()) {
        ASSERT(0 <= i && i < m_num_nodes);
        m_neighbors[i].push_back(m_num_cliques);
    }
    m_num_cliques++;
    cp->NormalizeEnergy(*this);
}

void SubmodularFlow::AddClique(const std::vector<NodeId>& nodes, const std::vector<REAL>& energyTable) {
    CliquePtr cp(new EnergyTableClique(nodes, energyTable));
    AddClique(cp);
}

//////// Push Relabel methods ///////////

void SubmodularFlow::add_to_active_list(NodeId u, Layer& layer) {
    layer.active_vertices.push_front(u);
    max_active = std::max BOOST_PREVENT_MACRO_SUBSTITUTION(dis[u], max_active);
    min_active = std::min BOOST_PREVENT_MACRO_SUBSTITUTION(dis[u], min_active);
    layer_list_ptr[u] = layer.active_vertices.begin();
}

// Inefficient but doing the remove manually since
// I don't have a perfect understanding/translation of the boost code.
void SubmodularFlow::remove_from_active_list(NodeId u) {
    std::list<NodeId> temp;
    for (NodeId i : layers[dis[u]].active_vertices) {
        if (u != i) temp.push_back(i);
    }
    std::swap(layers[dis[u]].active_vertices, temp);
}

void SubmodularFlow::PushRelabelInit()
{
    // super source and sink
    s = m_num_nodes; t = m_num_nodes + 1;
    max_active = 0; min_active = m_num_nodes + 2; // n

    dis.clear(); excess.clear(); current_arc_index.clear();
    m_arc_list.clear(); layers.clear();

    // init data structures
    for (int i = 0; i < m_num_nodes + 2; ++i) {
        dis.push_back(0);
        excess.push_back(0);
        current_arc_index.push_back(0);
        std::vector<Arc> arc_list;
        m_arc_list.push_back(arc_list);
        Layer layer;
        layers.push_back(layer);
    }
    dis[s] = m_num_nodes + 2; // n = m_num_nodes + 2

    // Adding extra layers
    for (int i = 0; i < 2 * (m_num_nodes + 2); ++i) {
        Layer layer;
        layers.push_back(layer);
    }

    // saturate arcs out of s.
    for (NodeId i = 0; i < m_num_nodes; ++i) {
        m_phi_si[i] = m_c_si[i];
        if (m_c_si[i] > 0) {
            excess[s] -= m_c_si[i];
            excess[i] += m_c_si[i];
	        add_to_active_list(i, layers[0]);
        }
    }

    // initialize arc lists
    Arc arc;
    for (NodeId i = 0; i < m_num_nodes; ++i) {
        // arcs from source
        arc.i = s;
        arc.j = i;
        arc.c = -1;
        m_arc_list[arc.i].push_back(arc);

        // arcs to source
        arc.i = i;
        arc.j = s;
        m_arc_list[arc.i].push_back(arc);

        // arcs to sink
        arc.j = t;
        m_arc_list[arc.i].push_back(arc);

        // arcs from sink
        arc.i = t;
        arc.j = i;
        m_arc_list[arc.i].push_back(arc);
    }

    // Arcs between nodes of clique
    for (int cid = 0; cid < m_num_cliques; ++cid) {
        CliquePtr cp = m_cliques[cid];
        for (NodeId i : cp->Nodes()) {
            for (NodeId j : cp->Nodes()) {
                if (i == j) continue;
                arc.i = i;
                arc.j = j;
                arc.c = cid;
                m_arc_list[i].push_back(arc);
            }
        }
    }
}

void SubmodularFlow::PushRelabelStep()
{
    Layer& layer = layers[max_active];
    list_iterator u_iter = layer.active_vertices.begin();

    if (u_iter == layer.active_vertices.end())
        --max_active;
    else {
        NodeId i = *u_iter;
        remove_from_active_list(i);
        boost::optional<Arc> arc = FindPushableEdge(i);
        if (arc)
            Push(*arc);
        else
            Relabel(i);
    }
}

bool SubmodularFlow::PushRelabelNotDone()
{
    return max_active >= min_active;
}

void SubmodularFlow::PushRelabel()
{
    PushRelabelInit();

    // find active i w/ largest distance
    while (PushRelabelNotDone()) {
        PushRelabelStep();
    }
}

REAL SubmodularFlow::ResCap(Arc arc) {
    if (arc.i == s) {
        return m_c_si[arc.j] - m_phi_it[arc.j];
    } else if (arc.j == s) {
        return m_phi_si[arc.i];
    } else if (arc.i == t) {
        return m_phi_it[arc.j];
    } else if (arc.j == t) {
        return m_c_it[arc.i] - m_phi_it[arc.i];
    } else {
        return m_cliques[arc.c]->ExchangeCapacity(arc.i, arc.j);
    }
}

boost::optional<SubmodularFlow::Arc> SubmodularFlow::FindPushableEdge(NodeId i) {
    // Use current arc?
    for (Arc arc : m_arc_list[i]) {
        if (dis[i] == dis[arc.j] + 1 && ResCap(arc) > 0) {
	        return boost::optional<SubmodularFlow::Arc>(arc);
        }
    }
    return boost::optional<SubmodularFlow::Arc>();
}

void SubmodularFlow::Push(Arc arc) {
    REAL delta; // amount to push

    // Note, we never have arc.i == s or t
    if (arc.j == s) {  // reverse arc
        delta = std::min(excess[arc.i], m_phi_si[arc.i]);
        m_phi_si[arc.i] -= delta;
    } else if (arc.j == t) {
        delta = std::min(excess[arc.i], m_c_it[arc.i] - m_phi_it[arc.i]);
        m_phi_it[arc.i] += delta;
    } else { // Clique arc
        std::cout << "Pushing on clique arc" << std::endl;
        delta = std::min(excess[arc.i], m_cliques[arc.c]->ExchangeCapacity(arc.i, arc.j));
        std::vector<REAL>& alpha_ci = m_cliques[arc.c]->AlphaCi();
        alpha_ci[arc.i] += delta;
        alpha_ci[arc.j] -= delta;
    }
    // Update (residual capacities) and excesses
    excess[arc.i] -= delta;
    excess[arc.j] += delta;
    if (excess[arc.j] > 0 && arc.j != s && arc.j != t) {
        remove_from_active_list(arc.j);
        add_to_active_list(arc.j, layers[dis[arc.j]]);
    }
    if (excess[arc.i] > 0) {
        add_to_active_list(arc.i, layers[dis[arc.i]]);
    }
}

void SubmodularFlow::Relabel(NodeId i) {
    dis[i] = std::numeric_limits<int>::max();
    for(Arc arc : m_arc_list[i]) {
        if (ResCap(arc) > 0) {
            dis[i] = std::min (dis[i], dis[arc.j] + 1);
        }
    }
    // if (dis[i] < dis[s])
    // Adding all active vertices back for now.
    add_to_active_list(i, layers[dis[i]]);
}

///////////////    end of push relabel    ///////////////////

void SubmodularFlow::ComputeMinCut() {
    for (NodeId i = 0; i < m_num_nodes; ++i) {
        dis[i] = std::numeric_limits<int>::max();
        m_labels[i] = 1;
    }
    dis[t] = 0;
    // curr is the current level of nodes to be visited;
    // next is the next layer to visit.
    std::queue<NodeId> curr, next;
    next.push(t);

    int level = 1;
    while (!next.empty()) {
        // Next becomes curr; empty next
        std::swap(curr, next);
        std::queue<NodeId> empty;
        std::swap(next, empty);

        while (!curr.empty()) {
            NodeId u = curr.front();
            curr.pop();
            for (Arc arc : m_arc_list[u]) {
                arc.i = arc.j;
                arc.j = u;
                if (ResCap(arc) > 0 && arc.i != s && arc.i != t
                        && dis[arc.i] == std::numeric_limits<int>::max()) {
                    m_labels[arc.i] = 0;
                    next.push(arc.i);
                    dis[arc.i] = level;
                }
            }
        }
        ++level;
    }
    for (int label : m_labels)
        std::cout << label << std::endl;
}

REAL SubmodularFlow::ComputeEnergy() const {
    return ComputeEnergy(m_labels);
}

REAL SubmodularFlow::ComputeEnergy(const std::vector<int>& labels) const {
    REAL total = m_constant_term;
    for (NodeId i = 0; i < m_num_nodes; ++i) {
        if (labels[i] == 1) total += m_c_it[i];
        else total += m_c_si[i];
    }
    for (const CliquePtr& cp : m_cliques) {
        total += cp->ComputeEnergy(labels);
    }
    return total;
}

void EnergyTableClique::NormalizeEnergy(SubmodularFlow& sf) {
    const size_t n = this->m_nodes.size();
    const Assignment num_assignments = 1 << n;
    const REAL constant_term = m_energy[num_assignments - 1];
    std::vector<REAL> marginals;
    Assignment assgn = num_assignments - 1; // The all 1 assignment
    for (size_t i = 0; i < n; ++i) {
        Assignment next_assgn = assgn ^ (1 << i);
        marginals.push_back(m_energy[assgn] - m_energy[next_assgn]);
        assgn = next_assgn;
    }

    for (Assignment a = 0; a < num_assignments; ++a) {
        m_energy[a] -= constant_term;
        for (size_t i = 0; i < n; ++i) {
            if (!(a & (1 << i))) m_energy[a] += marginals[i];
        }
    }

    sf.AddConstantTerm(constant_term);
    for (size_t i = 0; i < n; ++i) {
        sf.AddUnaryTerm(this->m_nodes[i], -marginals[i], 0);
    }
}

REAL EnergyTableClique::ComputeEnergy(const std::vector<int>& labels) const {
    Assignment assgn = 0;
    for (size_t i = 0; i < this->m_nodes.size(); ++i) {
        NodeId n = this->m_nodes[i];
        if (labels[n] == 1) {
            assgn |= 1 << i;
        }
    }
    return m_energy[assgn];
}

REAL EnergyTableClique::ExchangeCapacity(NodeId u, NodeId v) const {
    // This is not the most efficient way to do things, but it works
    const size_t u_idx = std::find(this->m_nodes.begin(), this->m_nodes.end(), u) - this->m_nodes.begin();
    const size_t v_idx = std::find(this->m_nodes.begin(), this->m_nodes.end(), v) - this->m_nodes.begin();

    REAL min_energy = std::numeric_limits<REAL>::max();
    Assignment num_assgns = 1 << this->m_nodes.size();
    for (Assignment assgn = 0; assgn < num_assgns; ++assgn) {
        REAL alpha_C = 0;
        for (size_t i = 0; i < this->m_alpha_Ci.size(); ++i) {
            if (assgn & (1 << i)) alpha_C += this->m_alpha_Ci[i];
        }
        if (assgn & (1 << u_idx) && !(assgn & (1 << v_idx))) {
            // then assgn is a set separating u from v
            REAL energy = m_energy[assgn] - alpha_C;
            if (energy < min_energy) min_energy = energy;
        }
    }
    return min_energy;
}
<|endoftext|>


<commit_before><commit_msg>Expand route tests to unroute existing routes.<commit_after><|endoftext|>


<commit_before>#include "SyntaxTree.h"

#include <list>
#include <vector>
#include <sstream>
#include <iostream>
#include <stdexcept>
#include <assert.h>

#include <boost/format.hpp>

#include "parser.tab.hh"

#include "template.common.h"
#include "template.cs.h"

using namespace std;
using namespace Rakjin::Krystal;

// class Node
// {
// public:
    Node::Node(Rakjin::Context* _context)
    {
        context = _context;
    }

    Node::~Node()
    {
    }

    int Node::getType() { return 0; } //TODO: remove getType() if unnecessary
    size_t Node::getHash(vector<Node*>* referencingStack) { return 0; }
    string* Node::getParsed(int as) { return 0; }

// };

// class NodeKst : public Node
// {
    // list<Node*>* commands;
    // string* fileName;
    // public:
    NodeKst::NodeKst(Rakjin::Context* _context, list<Node*>* _commands, string* _fileName) : Node(_context)
    {
        commands = _commands;
        fileName = _fileName;
    }

    int NodeKst::getType()
    {
       return CsNodeType::kst;
    }

    size_t NodeKst::getHash(vector<Node*>* referencingStack)
    {
        return 0;
    }

    string* NodeKst::getParsed(int as)
    {
        stringstream parsed;

        parsed << boost::format(TCS_HEADER) % *fileName;
        parsed << TCS_USINGS;

        string namespaceByFileName = fileName->substr(0, fileName->find("."));

        parsed << boost::format(TCS_NAMESPACE_BEGIN) % namespaceByFileName;

        list<Node*>::iterator i = commands->begin();
        list<Node*>::iterator end = commands->end();

        string* temp;

        for (; i != end; ++i)
        {
            temp = (*i)->getParsed(CsParseAs::Default);
            temp = indent(temp);
            parsed << *temp;
            parsed << "\n";
        }

        parsed << TCS_NAMESPACE_END;

        parsed << "\n\n";

        return new string(parsed.str());
    }
// };

// class NodeInclude : public Node
// {
//     string* value;
//     public:
    NodeInclude::NodeInclude(Rakjin::Context* _context, string* _value) : Node(_context)
    {
        value = _value;
    }

    int NodeInclude::getType()
    {
       return CsNodeType::include;
    }

    size_t NodeInclude::getHash(vector<Node*>* referencingStack)
    {
        return 0;
    }

    string* NodeInclude::getParsed(int as)
    {
        stringstream parsed;

        parsed << "#include \"";
        parsed << *(value);
        parsed << "\"";

        return new string(parsed.str());
    }
// };

// class NodePacket : public Node
// {
//     string* packetName;
//     list<Node*>* packetMembers;
//     public:
    NodePacket::NodePacket(Rakjin::Context* _context, string* _packetName, list<Node*>* _packetMembers) : Node(_context)
    {
        packetName = _packetName;
        packetMembers = _packetMembers;
    }

    int NodePacket::getType()
    {
       return CsNodeType::packet;
    }

    size_t NodePacket::getHash(vector<Node*>* referencingStack)
    {
        if (referencingStack == NULL)
        {
            referencingStack = new vector<Node*>();
        }
        else // check circular reference
        {
            vector<Node*>::iterator end = referencingStack->end();
            for (vector<Node*>::iterator i = referencingStack->begin(); i != end; i++)
            {
                if (*i == this)
                {
                    throw(runtime_error("Circular reference between packets"));
                }
            }
        }

        referencingStack->push_back(this);

        size_t packetHash = getHashCode(packetName);

        list<Node*>::iterator i = packetMembers->begin();
        list<Node*>::iterator end = packetMembers->end();
        for (; i != end; ++i)
        {
            combineHashCode(packetHash, (*i)->getHash(referencingStack));
        }

        referencingStack->pop_back();

        return packetHash;
    }

    string* NodePacket::getParsed(int as)
    {
        stringstream parsed;

        switch (as)
        {
            case CsParseAs::Default:
            {
                parsed << boost::format(TCS_PACKET_BEGIN) % *packetName;
                parsed << "\t<temp> packet hash: " << getHash(NULL) << "\n";
                list<Node*>::iterator i = packetMembers->begin();
                list<Node*>::iterator end = packetMembers->end();
                for (; i != end; ++i)
                {
                    parsed << "\t" << *((*i)->getParsed(CsParseAs::Default));
                }
                parsed << TCS_PACKET_END;
            }
            break;
        }

        return new string(parsed.str());
    }
// };

// class NodePacketMember : public Node
// {
//     Node* memberType;
//     Node* memberName;
//     public:
    NodePacketMember::NodePacketMember(Rakjin::Context* _context, Node* _memberType, Node* _memberName) : Node(_context)
    {
        memberType = _memberType;
        memberName = _memberName;
    }

    int NodePacketMember::getType()
    {
       return CsNodeType::packetMember;
    }

    size_t NodePacketMember::getHash(vector<Node*>* referencingStack)
    {
        assert(referencingStack != NULL);

        size_t packetMemberHash = memberType->getHash(referencingStack);
        combineHashCode(packetMemberHash, memberName->getHash(referencingStack));

        return packetMemberHash;
    }

    string* NodePacketMember::getParsed(int as)
    {
        stringstream parsed;

        switch (as)
        {
            case CsParseAs::Default:
            {
                parsed << boost::format(TCS_PACKET_MEMBER_AS_DEFAULT)
                    % *(memberType->getParsed(CsParseAs::Default))
                    % *(memberName->getParsed(CsParseAs::Default));
            }
            break;
        }

        return new string(parsed.str());
    }
// };

// class NodePacketMemberType : public Node
// {
//     int typeType; // one of PRIMITIVE_DATA_TYPE, REFERENCE_DATA_TYPE, MAP, LIST
//     string* value; // "int", "bool", ..., "MyPacket", "Skill" or NULL when type is MAP or LIST
//     Node* generic1; // LIST<generic1>
//     Node* generic2; // MAP <generic1, generic2>
//     Node* generic3; // reserved
//     public:
    NodePacketMemberType::NodePacketMemberType(Rakjin::Context* _context, int _type, string* _value) : Node(_context)
    {
        typeType = _type;
        value = _value;
        generic1 = NULL;
        generic2 = NULL;
        generic3 = NULL;
    }

    NodePacketMemberType::NodePacketMemberType(Rakjin::Context* _context, int _type, Node* _generic1) : Node(_context)
    {
        typeType = _type;
        value = NULL;
        generic1 = _generic1;
        generic2 = NULL;
        generic3 = NULL;
    }

    NodePacketMemberType::NodePacketMemberType(Rakjin::Context* _context, int _type, Node* _generic1, Node* _generic2) : Node(_context)
    {
        typeType = _type;
        value = NULL;
        generic1 = _generic1;
        generic2 = _generic2;
        generic3 = NULL;
    }

    NodePacketMemberType::NodePacketMemberType(Rakjin::Context* _context, int _type, Node* _generic1, Node* _generic2, Node* _generic3) : Node(_context)
    {
        typeType = _type;
        value = NULL;
        generic1 = _generic1;
        generic2 = _generic2;
        generic3 = _generic3;
    }

    int NodePacketMemberType::getType()
    {
       return CsNodeType::packetMemberType;
    }

    size_t NodePacketMemberType::getHash(vector<Node*>* referencingStack)
    {
        assert(referencingStack != NULL);

        size_t packetMemberTypeHash = 0;
        switch(typeType)
        {
            case Parser::token::PRIMITIVE_DATA_TYPE:
            packetMemberTypeHash = getHashCode(value);
            break;

            case Parser::token::REFERENCE_DATA_TYPE:
            // lookup Context::declarations table
            Node* typePacketNode = context->getDeclarationNode(value);
            if (typePacketNode == NULL)
            {
                throw(runtime_error("No such packet type."));
            }
            packetMemberTypeHash = typePacketNode->getHash(referencingStack);
            break;
        }

        return packetMemberTypeHash;
    }

    string* NodePacketMemberType::getParsed(int as)
    {
        stringstream parsed;

        switch (typeType) {

            case Parser::token::PRIMITIVE_DATA_TYPE:
            parsed << *value;
            break;

            case Parser::token::REFERENCE_DATA_TYPE:
            parsed << *value;
            break;

            case Parser::token::MAP:
            parsed << "Dictionary";
            parsed << "<" << *(generic1->getParsed(CsParseAs::Default)) << ", " << *(generic2->getParsed(CsParseAs::Default)) << ">";
            break;

            case Parser::token::LIST:
            parsed << "List";
            parsed << "<" << *(generic1->getParsed(CsParseAs::Default)) << ">";
            break;

            default:
            throw(runtime_error("Unknown NodePacketMemberType type."));
            break;
        }

        return new string(parsed.str());
    }
// };

// class NodePacketMemberName : public Node
// {
//     string* value;
//     public:
    NodePacketMemberName::NodePacketMemberName(Rakjin::Context* _context, string* _value) : Node(_context)
    {
        value = _value;
    }

    int NodePacketMemberName::getType()
    {
       return CsNodeType::packetMemberName;
    }

    size_t NodePacketMemberName::getHash(vector<Node*>* referencingStack)
    {
        size_t packetMemberNameHash = getHashCode(value);
        return packetMemberNameHash;
    }

    string* NodePacketMemberName::getParsed(int as)
    {
       return value;
    }
// };

<commit_msg>add blocks to switch-case<commit_after>#include "SyntaxTree.h"

#include <list>
#include <vector>
#include <sstream>
#include <iostream>
#include <stdexcept>
#include <assert.h>

#include <boost/format.hpp>

#include "parser.tab.hh"

#include "template.common.h"
#include "template.cs.h"

using namespace std;
using namespace Rakjin::Krystal;

// class Node
// {
// public:
    Node::Node(Rakjin::Context* _context)
    {
        context = _context;
    }

    Node::~Node()
    {
    }

    int Node::getType() { return 0; } //TODO: remove getType() if unnecessary
    size_t Node::getHash(vector<Node*>* referencingStack) { return 0; }
    string* Node::getParsed(int as) { return 0; }

// };

// class NodeKst : public Node
// {
    // list<Node*>* commands;
    // string* fileName;
    // public:
    NodeKst::NodeKst(Rakjin::Context* _context, list<Node*>* _commands, string* _fileName) : Node(_context)
    {
        commands = _commands;
        fileName = _fileName;
    }

    int NodeKst::getType()
    {
       return CsNodeType::kst;
    }

    size_t NodeKst::getHash(vector<Node*>* referencingStack)
    {
        return 0;
    }

    string* NodeKst::getParsed(int as)
    {
        stringstream parsed;

        parsed << boost::format(TCS_HEADER) % *fileName;
        parsed << TCS_USINGS;

        string namespaceByFileName = fileName->substr(0, fileName->find("."));

        parsed << boost::format(TCS_NAMESPACE_BEGIN) % namespaceByFileName;

        list<Node*>::iterator i = commands->begin();
        list<Node*>::iterator end = commands->end();

        string* temp;

        for (; i != end; ++i)
        {
            temp = (*i)->getParsed(CsParseAs::Default);
            temp = indent(temp);
            parsed << *temp;
            parsed << "\n";
        }

        parsed << TCS_NAMESPACE_END;

        parsed << "\n\n";

        return new string(parsed.str());
    }
// };

// class NodeInclude : public Node
// {
//     string* value;
//     public:
    NodeInclude::NodeInclude(Rakjin::Context* _context, string* _value) : Node(_context)
    {
        value = _value;
    }

    int NodeInclude::getType()
    {
       return CsNodeType::include;
    }

    size_t NodeInclude::getHash(vector<Node*>* referencingStack)
    {
        return 0;
    }

    string* NodeInclude::getParsed(int as)
    {
        stringstream parsed;

        parsed << "#include \"";
        parsed << *(value);
        parsed << "\"";

        return new string(parsed.str());
    }
// };

// class NodePacket : public Node
// {
//     string* packetName;
//     list<Node*>* packetMembers;
//     public:
    NodePacket::NodePacket(Rakjin::Context* _context, string* _packetName, list<Node*>* _packetMembers) : Node(_context)
    {
        packetName = _packetName;
        packetMembers = _packetMembers;
    }

    int NodePacket::getType()
    {
       return CsNodeType::packet;
    }

    size_t NodePacket::getHash(vector<Node*>* referencingStack)
    {
        if (referencingStack == NULL)
        {
            referencingStack = new vector<Node*>();
        }
        else // check circular reference
        {
            vector<Node*>::iterator end = referencingStack->end();
            for (vector<Node*>::iterator i = referencingStack->begin(); i != end; i++)
            {
                if (*i == this)
                {
                    throw(runtime_error("Circular reference between packets"));
                }
            }
        }

        referencingStack->push_back(this);

        size_t packetHash = getHashCode(packetName);

        list<Node*>::iterator i = packetMembers->begin();
        list<Node*>::iterator end = packetMembers->end();
        for (; i != end; ++i)
        {
            combineHashCode(packetHash, (*i)->getHash(referencingStack));
        }

        referencingStack->pop_back();

        return packetHash;
    }

    string* NodePacket::getParsed(int as)
    {
        stringstream parsed;

        switch (as)
        {
            case CsParseAs::Default:
            {
                parsed << boost::format(TCS_PACKET_BEGIN) % *packetName;
                parsed << "\t<temp> packet hash: " << getHash(NULL) << "\n";
                list<Node*>::iterator i = packetMembers->begin();
                list<Node*>::iterator end = packetMembers->end();
                for (; i != end; ++i)
                {
                    parsed << "\t" << *((*i)->getParsed(CsParseAs::Default));
                }
                parsed << TCS_PACKET_END;
            }
            break;
        }

        return new string(parsed.str());
    }
// };

// class NodePacketMember : public Node
// {
//     Node* memberType;
//     Node* memberName;
//     public:
    NodePacketMember::NodePacketMember(Rakjin::Context* _context, Node* _memberType, Node* _memberName) : Node(_context)
    {
        memberType = _memberType;
        memberName = _memberName;
    }

    int NodePacketMember::getType()
    {
       return CsNodeType::packetMember;
    }

    size_t NodePacketMember::getHash(vector<Node*>* referencingStack)
    {
        assert(referencingStack != NULL);

        size_t packetMemberHash = memberType->getHash(referencingStack);
        combineHashCode(packetMemberHash, memberName->getHash(referencingStack));

        return packetMemberHash;
    }

    string* NodePacketMember::getParsed(int as)
    {
        stringstream parsed;

        switch (as)
        {
            case CsParseAs::Default:
            {
                parsed << boost::format(TCS_PACKET_MEMBER_AS_DEFAULT)
                    % *(memberType->getParsed(CsParseAs::Default))
                    % *(memberName->getParsed(CsParseAs::Default));
            }
            break;
        }

        return new string(parsed.str());
    }
// };

// class NodePacketMemberType : public Node
// {
//     int typeType; // one of PRIMITIVE_DATA_TYPE, REFERENCE_DATA_TYPE, MAP, LIST
//     string* value; // "int", "bool", ..., "MyPacket", "Skill" or NULL when type is MAP or LIST
//     Node* generic1; // LIST<generic1>
//     Node* generic2; // MAP <generic1, generic2>
//     Node* generic3; // reserved
//     public:
    NodePacketMemberType::NodePacketMemberType(Rakjin::Context* _context, int _type, string* _value) : Node(_context)
    {
        typeType = _type;
        value = _value;
        generic1 = NULL;
        generic2 = NULL;
        generic3 = NULL;
    }

    NodePacketMemberType::NodePacketMemberType(Rakjin::Context* _context, int _type, Node* _generic1) : Node(_context)
    {
        typeType = _type;
        value = NULL;
        generic1 = _generic1;
        generic2 = NULL;
        generic3 = NULL;
    }

    NodePacketMemberType::NodePacketMemberType(Rakjin::Context* _context, int _type, Node* _generic1, Node* _generic2) : Node(_context)
    {
        typeType = _type;
        value = NULL;
        generic1 = _generic1;
        generic2 = _generic2;
        generic3 = NULL;
    }

    NodePacketMemberType::NodePacketMemberType(Rakjin::Context* _context, int _type, Node* _generic1, Node* _generic2, Node* _generic3) : Node(_context)
    {
        typeType = _type;
        value = NULL;
        generic1 = _generic1;
        generic2 = _generic2;
        generic3 = _generic3;
    }

    int NodePacketMemberType::getType()
    {
       return CsNodeType::packetMemberType;
    }

    size_t NodePacketMemberType::getHash(vector<Node*>* referencingStack)
    {
        assert(referencingStack != NULL);

        size_t packetMemberTypeHash = 0;
        switch(typeType)
        {
            case Parser::token::PRIMITIVE_DATA_TYPE:
            {
                packetMemberTypeHash = getHashCode(value);
            }
            break;

            case Parser::token::REFERENCE_DATA_TYPE:
            {
                // lookup Context::declarations table
                Node* typePacketNode = context->getDeclarationNode(value);
                if (typePacketNode == NULL)
                {
                    throw(runtime_error("No such packet type."));
                }
                packetMemberTypeHash = typePacketNode->getHash(referencingStack);
            }
            break;
        }

        return packetMemberTypeHash;
    }

    string* NodePacketMemberType::getParsed(int as)
    {
        stringstream parsed;

        switch (typeType) {

            case Parser::token::PRIMITIVE_DATA_TYPE:
            parsed << *value;
            break;

            case Parser::token::REFERENCE_DATA_TYPE:
            parsed << *value;
            break;

            case Parser::token::MAP:
            parsed << "Dictionary";
            parsed << "<" << *(generic1->getParsed(CsParseAs::Default)) << ", " << *(generic2->getParsed(CsParseAs::Default)) << ">";
            break;

            case Parser::token::LIST:
            parsed << "List";
            parsed << "<" << *(generic1->getParsed(CsParseAs::Default)) << ">";
            break;

            default:
            throw(runtime_error("Unknown NodePacketMemberType type."));
            break;
        }

        return new string(parsed.str());
    }
// };

// class NodePacketMemberName : public Node
// {
//     string* value;
//     public:
    NodePacketMemberName::NodePacketMemberName(Rakjin::Context* _context, string* _value) : Node(_context)
    {
        value = _value;
    }

    int NodePacketMemberName::getType()
    {
       return CsNodeType::packetMemberName;
    }

    size_t NodePacketMemberName::getHash(vector<Node*>* referencingStack)
    {
        size_t packetMemberNameHash = getHashCode(value);
        return packetMemberNameHash;
    }

    string* NodePacketMemberName::getParsed(int as)
    {
       return value;
    }
// };

<|endoftext|>