Wrap conditional into a function or not represent it at all in a sequence diagram? - uml

I've this PHP controller class (belongs to Symfony2 bundle):
class ReptoolController extends PageController
{
// ...
private function _get($request, $action, $case)
{
$app_id = $this->getRequested('app_id');
if( ( $repappConfig = $this->getDoctrine()->getRepository('PDOneBundle:RepappConfig')->findOneBy(array("app_id"=>$app_id))) )
{
$current_timestamp = new \DateTime(date('Y-m-d'));
if($repappConfig->getExpireDate())
$expire_date = $repappConfig->getExpireDate()->getTimestamp();
else
{
$temp = $current_timestamp;
$temp->modify("+7 day");
$temp->format("Y-m-d");
$expire_date = $temp->getTimestamp();
}
if($expire_date < $current_timestamp->getTimestamp())
{
$response = new \stdClass();
$response->status = FormUtilities::RESPONSE_STATUS_BAD;
$controller_response = new Response( json_encode($response) );
$controller_response->headers->set('Content-Type', 'application/json; charset=utf-8');
return $controller_response;
}
}
switch($case)
{
// ...
case FormUtilities::CASE_BRAND_CUSTOM_MESSAGES:
return $this->getBrandCustomMessages($request, $action, $case);
break;
// ...
default:
$response = new \stdClass();
$response->status = FormUtilities::RESPONSE_STATUS_BAD;
$controller_response = new Response( json_encode($response) );
$controller_response->headers->set('Content-Type', 'application/json; charset=utf-8');
return $controller_response;
break;
}
}
// ...
private function getBrandCustomMessages($request, $action, $case)
{
$id = $this->getRequested('app_id');
$reptool_records = $this->getRequestedSync();
$response = new \stdClass();
$response->status = FormUtilities::RESPONSE_STATUS_BAD;
$repappConfig = new RepappConfig();
$repappConfig = $this->getDoctrine()->getRepository('PDOneBundle:RepappConfig')->findOneBy(array("app_id"=>$id));
$project_id = $repappConfig->getProjectId();
$brand_table = $this->getDoctrine()->getRepository('PDOneBundle:Brand')->findBy(array("project"=>$project_id));
if($brand_table)
{
foreach($brand_table as $bt)
{
$brand_id = $bt->getID();
$brandCustomMessages = new BrandCustomMessages();
if( $brandCustomMessages = $this->getDoctrine()->getRepository('PDOneBundle:BrandCustomMessages')->findBy(array("brand_id"=>$brand_id) ))
{
$sync = array();
foreach ($brandCustomMessages as $brandCustomMessage)
{
$response->status = FormUtilities::RESPONSE_STATUS_VALID;
$brandCustMess = new PDOneResponse(
$brandCustomMessage->getID(),
strtotime($brandCustomMessage->getModifiedAt()->format("Y-m-d H:i:s"))
);
$brandCustMess->id = $brandCustomMessage->getID();
$brandCustMess->message_text = $brandCustomMessage->getMessageText();
$brandCustMess->message_code = $brandCustomMessage->getMessageCode();
$brandCustMess->brand_id = (int)$brandCustomMessage->getBrandId();
$reptool_records = $brandCustMess->setRecordStatus($reptool_records);
// ADD BACKEND RECORD TO SYNC
if($brandCustMess->status != FormUtilities::RESPONSE_STATUS_OK ) $sync[] = $brandCustMess;
}
// COMPOSITE SYNC WITH REPTOOL RECORDS
$sync = PDOneResponse::compositeSync($sync, $reptool_records);
$response->sync = $sync;
}
}
}
$controller_response = new Response( json_encode($response) );
$controller_response->headers->set('Content-Type', 'application/json; charset=utf-8');
return $controller_response;
}
// ...
I need to build a sequence diagram (SD) for the flow from the actor PDOneApp (which is an iPad application making get|set request to that controller). This is what I have done in the SD Version1, SD Version 2:
Version 1
Version 2
About the diagrams shown above I have the following doubts and taking as example the code shown above also:
Which diagram is the right one?
The calls (meaning the representation at diagram) for the entities: RepappConfig and Brand are right? In the code this calls are made from within the method getBrandCustomMessages() and I have them directly from the controller ReptoolController which makes me think that's wrong. If this is the case how they should be represented?
I know that SD is not mean to be for represent code as it is but, how do you represent conditionals on the function? Perhaps I can wrap the conditional in a function and call that function from within the getBrandCustomMessages() is this one the right way? What did you recommend me on this doubt?
As you will see on the function the last return is a Response object, is that part right on the diagram? Or the line should be dashed with return label?
Can any give some help for finish this diagram and understand the conditional part for UML SD?

Your 2nd diagram shows the internal call to getBrandCustomMessages correctly.
If you really want to show if then use fragments (http://www.uml-diagrams.org/sequence-diagrams-combined-fragment.html). You can divide fragments into single partitions (if/else or case; whatever fits).
The last response should not go to an entity but as return message (from after the internal call) to the actor. That's likely what you intend to show.

Related

Silverstripe 4 PaginatedList get Page-number - Link (Backlink)

In Silverstripe 4 I have a
DataObject 'PublicationObject',
a 'PublicationPage' and
a 'PublicationPageController'
PublicationObjects are displayed on PublicationPage through looping a PaginatedList. There is also a Pagination, showing the PageNumbers and Prev & Next - Links.
The Detail of PublicationObject is shown as 'Dataobject as Pages' using the UrlSegment.
If users are on the Detail- PublicationObject i want them to get back to the PublicationPage (the paginated list) with a Back - Link.
Two situations:
The user came from PublicationPage
and
The User came from a Search - Engine (Google) directly to the
DataObject- Detail.
I have done this like so:
$parentPage = Page::get()->Filter(array('UrlSegment' => $request->param('pageID')))->First();
$back = $_SERVER['HTTP_REFERER'];
if ((isset($_SERVER['HTTP_REFERER']) && !empty($_SERVER['HTTP_REFERER']))) {
if (strtolower(parse_url($_SERVER['HTTP_REFERER'], PHP_URL_HOST)) != strtolower($_SERVER['HTTP_HOST'])) {
// referer not from the same domain
$back = $parentPage->Link();
}
}
Thats not satisfying.
Question:
How do i get the Pagination - Link ( e.g: ...publicationen?start=20 ) when we are on the Detail - DataObject? How can we find the Position of the current Dataobject in that paginatedList in correlation with the Items per Page? (The Page- Link This Dataobject is on)
<?php
use SilverStripe\Control\Controller;
use SilverStripe\Control\HTTPRequest;
use SilverStripe\View\Requirements;
use SilverStripe\Core\Convert;
use SilverStripe\SiteConfig\SiteConfig;
use SilverStripe\ORM\PaginatedList;
use SilverStripe\Control\Director;
use SilverStripe\ORM\DataObject;
use SilverStripe\ErrorPage\ErrorPage;
use SilverStripe\Dev\Debug;
use SilverStripe\Dev\Backtrace;
class PublicationPageController extends PageController
{
private static $allowed_actions = ['detail'];
private static $url_handlers = array(
);
public static $current_Publication_id;
public function init() {
parent::init();
}
public function detail(HTTPRequest $request)
{
$publication = PublicationObject::get_by_url_segment(Convert::raw2sql($request->param('ID')));
if (!$publication) {
return ErrorPage::response_for(404);
}
// HERE I WANT TO FIND THE POSITION OF THE DATAOBJECT IN THE PAGINATEDLIST OR RATHER THE PAGE - LINK THIS DATAOBJECT IS IN
//$paginatedList = $this->getPaginatedPublicationObjects();
//Debug::show($paginatedList->find('URLSegment', Convert::raw2sql($request->param('ID'))));
//Debug::show($paginatedList->toArray());
$parentPage = Page::get()->Filter(array('UrlSegment' => $request->param('pageID')))->First();
$back = $_SERVER['HTTP_REFERER'];
if ((isset($_SERVER['HTTP_REFERER']) && !empty($_SERVER['HTTP_REFERER']))) {
if (strtolower(parse_url($_SERVER['HTTP_REFERER'], PHP_URL_HOST)) != strtolower($_SERVER['HTTP_HOST'])) {
// referer not from the same domain
$back = $parentPage->Link();
}
}
static::$current_Publication_id = $publication->ID;
$id = $publication->ID;
if($publication){
$arrayData = array (
'Publication' => $publication,
'Back' => $back,
'SubTitle' => $publication->Title,
'MetaTitle' => $publication->Title,
);
return $this->customise($arrayData)->renderWith(array('PublicationDetailPage', 'Page'));
}else{
return $this->httpError(404, "Not Found");
}
}
public function getPaginatedPublicationObjects()
{
$list = $this->PublicationObjects()->sort('SortOrder');
return PaginatedList::create($list, $this->getRequest()); //->setPageLength(4)->setPaginationGetVar('start');
}
}
EDIT:
is there a more simple solution ? than this ? :
public function detail(HTTPRequest $request)
{
$publication = PublicationObject::get_by_url_segment(Convert::raw2sql($request->param('ID')));
if (!$publication) {
return ErrorPage::response_for(404);
}
//*******************************************************
// CREATE BACK - LINK
$paginatedList = $this->getPaginatedPublicationObjects();
$dO = PublicationObject::get();
$paginationVar = $paginatedList->getPaginationGetVar();
$sqlQuery = new SQLSelect();
$sqlQuery->setFrom('PublicationObject');
$sqlQuery->selectField('URLSegment');
$sqlQuery->setOrderBy('SortOrder');
$rawSQL = $sqlQuery->sql($parameters);
$result = $sqlQuery->execute();
$list = [];
foreach($result as $row) {
$list[]['URLSegment'] = $row['URLSegment'];
}
$list = array_chunk($list, $paginatedList->getPageLength(), true);
$start = '';
$back = '';
$i = 0;
$newArray = [];
foreach ($list as $k => $subArr) {
$newArray[$i] = $subArr;
unset($subArr[$k]['URLSegment']);
foreach ($newArray[$i] as $key => $val) {
if ($val['URLSegment'] === Convert::raw2sql($request->param('ID'))) {
$start = '?'.$paginationVar.'='.$i;
}
}
$i = $i + $paginatedList->getPageLength();
}
$back = Controller::join_links($this->Link(), $start);
// END CREATE BACK - LINK
//*****************************************************
static::$current_Publication_id = $publication->ID;
$id = $publication->ID;
if($publication){
$arrayData = array (
'Publication' => $publication,
'Back' => $back,
'MyLinkMode' => 'active',
'SubTitle' => $publication->Title,
'MetaTitle' => $publication->Title,
);
return $this->customise($arrayData)->renderWith(array('PublicationDetailPage', 'Page'));
}else{
return $this->httpError(404, "Not Found");
}
}
You can simply pass the page number as a get var in the URL from the PublicationPage. The detail() method can then grab the get var and if there's a value for the page number passed in, add it to the back link's URL.
In the template:
<% loop $MyPaginatedList %>
Click me
<% end_loop %>
In your controller's detail() method:
$pageNum = $request->getVar('onPage');
if ($pageNum) {
// Add the pagenum to the back link here
}
Edit
You've expressed that you want this to use the page start offset (so you can just plug it into the url using ?start=[offset]), and that you want an example that also covers people coming in from outside your site. I therefore propose the following:
Do as above, but using PageStart instead of CurrentPage - this will mean you don't have to re-compute the offset any time someone clicks the link from your paginated list.
If there is no onPage (or pageOffset as I've renamed it below, assuming you'll use PageStart) get variable, then assuming you can ensure your SortOrder values are all unique, you can check how many items are in the list before the current item - which gives you your item offset. From that you can calculate what page it's on, and what the page offset is for that page, which is your start value.
public function detail(HTTPRequest $request)
{
$publication = PublicationObject::get_by_url_segment(Convert::raw2sql($request->param('ID')));
$paginatedList = $this->getPaginatedPublicationObjects();
// Back link logic starts here
$pageOffset = $request->getVar('pageOffset');
if ($pageOffset === null) {
$recordOffset = $paginatedList->filter('SortOrder:LessThan', $publication->SortOrder)->count() + 1;
$perPage = $paginatedList->getPageLength();
$page = floor($recordOffset / $perPage) + 1;
$pageOffset = ($page - 1) * $perPage;
}
$back = $this->Link() . '?' . $paginatedList->getPaginationGetVar() . '=' . $pageOffset;
// Back link logic ends here
//.....
}

What is the Best way to creat multiple object Autocad?

I am learning about ObjectArx and as far as I know there are 3 common ways to create objects in Arx:
use acdbEntMake
use record.append (entity)
use a combination of record.append and transaction
so, my questions is:
can someone help me when I should use them in each case?
Do they have a big difference in performance with each other?
I am hesitant to use acdbentmake when the number of objects is large compared to the following two methods because I see very few examples that mention it.
I don't know what kind of entity You are creating but:
You don't need to use acdbEntMake in most cases. I'm using ObjectARX since about 8 years and never used it ;)
Transaction is used in .Net version of ObjectARX but You tagged visual-c++ so I suppose it's not this case.
If You warring about drawing large number of entities just test it. draw in the way You know and measure needed time. As long as You and Your clients accept drawing time, the way You are using is OK. In the future You always can refactor the code to get better performance if necessary.
To create for example line You may use this sample:
Acad::ErrorStatus AddLine(const AcGePoint3d SP , const AcGePoint3d EP , AcDbObjectId& id , AcDbObjectId Block )
{
AcDbLine* Line = new AcDbLine();
Line->setStartPoint(SP);
Line->setEndPoint(EP);
Acad::ErrorStatus es = Add( Line , Block );
if (es != Acad::eOk) { return es ;}
es = Line->close();
id = Line->objectId();
return es ;
}
Acad::ErrorStatus Add( AcDbEntity * pEnt, AcDbObjectId parent)
{
if ( !pEnt ) {
return Acad::eNullEntityPointer ;
}
Acad::ErrorStatus es;
if (parent.isNull()) {
parent = getActiveSpace()->objectId();
}
AcDbObject* pObj = NULL;
es = acdbOpenObject(pObj, parent , AcDb::kForWrite) ;
if (es != Acad::eOk) {
return es;
}
if (!pObj->isKindOf(AcDbBlockTableRecord::desc())) {
pObj->close();
return Acad::eWrongObjectType;
}
AcDbBlockTableRecord* Blok = AcDbBlockTableRecord::cast(pObj);
if ((es = Blok->appendAcDbEntity(pEnt)) != Acad::eOk )
{
Blok->close();
return es;
}
Blok->close();
return Acad::eOk;
}
AcDbBlockTableRecord* getActiveSpace()
{
AcDbBlockTableRecord* pOutVal = NULL;
AcDbDatabase * pDb = acdbHostApplicationServices()->workingDatabase();
if (!pDb) return NULL;
AcDbObjectId ActiveStpaceId = pDb->currentSpaceId();
AcDbObject* pObj = NULL;
Acad::ErrorStatus es;
es = acdbOpenObject(pObj, ActiveStpaceId , AcDb::kForRead);
if( es == Acad::eOk)
{
pOutVal = AcDbBlockTableRecord::cast(pObj);
es = pObj->close();
}
return pOutVal;
}

Flow for conditionals inside sequence diagram

I need to document in UML sequence diagram the method setRepresentative. This is the code method:
class ReptoolController extends PageController {
private function setRepresentative($request, $action, $case)
{
...
$repappConfig = new RepappConfig();
$repappConfig = $this->getDoctrine()->getRepository('AppBundle:RepappConfig')->findOneBy(array("app_id"=>$id));
$project_id = $repappConfig->getProjectId();
$company_id = $repappConfig->getCompanyId();
$project = $this->getDoctrine()->getRepository('AppBundle:Project')->find($project_id);
$brand = $this->getDoctrine()->getRepository('AppBundle:Brand')->findOneBy(array("project"=>$project_id));
$company = $this->getDoctrine()->getRepository('AppBundle:Company')->find($company_id);
$territory = new Territory();
if(is_numeric($territory_name))
{
$tempName = "ID";
}
else
{
$tempName = "territory";
}
if($territory = $this->getDoctrine()->getRepository('AppBundle:Territory')->findOneBy(array($tempName=>$territory_name)))
{
$territory_id = $territory->getID();
$response->territory_id = $territory_id;
if($brand)
{
$is_enabled = 1;
$position = 1;
$brand_id = $brand->getID();
$terr_brand_xrf = $this->getDoctrine()->getRepository('AppBundle:TerritoryBrandXref')->findOneBy(array("territory"=>$territory_id, "brand"=>$brand_id));
if(!$terr_brand_xrf)
{
$terr_brand_xref = new TerritoryBrandXref($territory,$brand,$position);
$terr_brand_xref->setIsEnabled($is_enabled);
$terr_brand_xref->updateTimestamps();
$em = $this->getDoctrine()->getEntityManager();
$em->persist($terr_brand_xref);
$em->flush();
}
}
}
else
{
$territory->setTerritory($territory_name);
$territory->setProject($project);
$em = $this->getDoctrine()->getEntityManager();
$em->persist($territory);
$em->flush();
$territory_id = $territory->getID();
$response->territory_id = $territory_id;
if($brand)
{
$is_enabled = 1;
$position = 1;
$brand_id = $brand->getID();
$response->brand_id= $brand_id;
$terr_brand_xref = new TerritoryBrandXref($territory,$brand,$position);
$terr_brand_xref->setIsEnabled($is_enabled);
$terr_brand_xref->updateTimestamps();
$em = $this->getDoctrine()->getEntityManager();
$em->persist($terr_brand_xref);
$em->flush();
}
}
$controller_response = new Response( json_encode($response) );
$controller_response->headers->set('Content-Type', 'application/json; charset=utf-8');
return $controller_response;
}
}
This is the diagram as I have it now:
How do I diagram the conditionals inside this piece of code:
if($territory = $this->getDoctrine()->getRepository('PDOneBundle:Territory')->findOneBy(array($tempName=>$territory_name)))
{
...
} else {
...
}
How do I call the inside methods?
Actually what you are asking does not make sense (see my comment here: UML Sequence Diagram help needed). SDs are not meant to repeat algorithms in graphical notation. Code is much better for that purpose. The possibility to show loops and if conditions inside SDs is meant to be used only for a high level view of the system.
In your case you should concentrate on certain aspects of the runtime. Just like an important snapshot. Create a SD for the tech use case with a really sequential message flow. Eventually create more than one SD to light different aspects. But do NOT try to press the whole algorithm in a single SD.

How to properly delete a box2d body in version: Box2dWeb-2.1.a.3, Box2D_v2.3.1r3? Box2D bug?

Update
Since the problem has been found I've also find out that Box2D for web is leaking on every side :/
To show this I made a simple circle moving in a static polygon and here is the result after some time.
Notice how the following items are leaking as I'm not creating any body or changing the world in any way:
b2Vec2
Features
b2ManifoldPoint
b2ContactID
b2Manifold
b2ContactEdge
b2PolyAndCircleContact
Array
...
Original post
I have a problem because I'm profiling my game and the garbage collector doesnt' delete my bodies, contacts and other stuff. Then I've looked at what are they keeping from the GC and was the Box2D itself. This might lead to 2 options: I'm doing it bad or Box2D is leaking. I consider is my cause.
What exactly is keeping it?
contact.m_nodeA.other was appearing to be the most used to keep it from GC.
other times: m_fixtureB in a contact... see image
You can see that the body has a __destroyed property. That is set manually before deleting it with world.DestroyBody(body)
When I destroy a body I call it after I call the step method on the world.
As you can see from the box2d method it doesn't get rid of the other variable nor it changes it to another body and my body is not GC.
Any idea of what I'm missing here?
Now I can fix the problem only if the world.Step is not ran:
var gravity = new Box2D.Vec2(0, 0);
var doSleep = true;
var world = new Box2D.World(gravity, doSleep);
var step = false;
var fixtureDef = new Box2D.FixtureDef();
fixtureDef.density = 1.0;
fixtureDef.friction = 0.5;
fixtureDef.restitution = 0.2;
fixtureDef.shape = new Box2D.PolygonShape();
fixtureDef.shape.SetAsBox(1, 1);
var bodyDef = new Box2D.BodyDef;
bodyDef.type = Box2D.Body.b2_dynamicBody;
bodyDef.position.x = 0.4;
bodyDef.position.y = 0.4;
var bodies = []
var fix = [];
window.c = function(){
for(var i = 0; i < 100; i++){
var body = world.CreateBody(bodyDef);
body._id = i;
fix.push(body.CreateFixture(fixtureDef));
bodies.push(body);
}
if(step){world.Step(1/60, 3, 3); world.ClearForces();}
console.log('Created', bodies)
fixtureDef = null;
bodyDef = null;
}
window.d = function(){
_.each(bodies, function(body, i){
body.DestroyFixture(fix[i]);
world.DestroyBody(body);
fix[i] = null;
bodies[i] = null;
})
if(step){world.Step(1/60, 3, 3); world.ClearForces();}
bodies = null;
fix = null;
}
Change the step to true and the memory leak problem appears again.
Reproduce the memory leak problem:
Code in your file:
var gravity = new Box2D.Vec2(0, 0);
var doSleep = true;
var world = new Box2D.World(gravity, doSleep);
var bodies = []
window.c = function(){
for(var i = 0; i < 100; i++){
var bodyDef = new Box2D.BodyDef();
bodyDef.type = 2;
var shape = new Box2D.PolygonShape();
shape.SetAsBox(1, 1);
var fixtureDef = new Box2D.FixtureDef();
fixtureDef.shape = shape;
var body = world.CreateBody(bodyDef);
body._id = i;
body.CreateFixture(fixtureDef);
bodies.push(body);
}
world.Step(0.3, 3, 3);
console.log('Created', bodies)
}
window.d = function(){
_.each(bodies, function(body, i){
world.DestroyBody(body);
bodies[i] = null;
})
world.Step(0.3, 3, 3);
bodies = null;
}
Open google chrome:
Then open your profile and make a snapshot.
Now run the c() method in your console to create 100 bodies
Now snapshot 2
Search in snapshot for b2Body and you'll find 100 Object count
Now run d() to delete all your bodies;
Force Garbage collection by clicking on the garbage can
Make a snapshot 3
Search for b2Body and you'll also find 100 Object count
At the last step should only be 0 objects as they have been destroyed. Instead of this you'll find this:
Now you can see there are a lot of references from b2ContactEdge. Now if you remove the world.Step part of the code you will only see 2 references to the body.
If you remove this line
body.CreateFixture(fixtureDef);
or making the body static is not leaking anymore.
My game loop
...gameLoop = function(o){
// used a lot here
var world = o.world;
// calculate the new positions
var worldStepSeconds = o.worldStepMs / 1000;
// step world
world.Step(worldStepSeconds, o.velocityIterations, o.positionIterations)
// render debug
if(o.renderDebug){
world.DrawDebugData();
}
// always to not accumulate forces, maybe some bug occurs
world.ClearForces();
// tick all ticking entities
_.each(o.getTickEntitiesFn(), function(actor){
if(!actor) return;
actor.tick(o.worldStepMs, o.lastFrameMs);
})
// update PIXI entities
var body = world.GetBodyList();
var worldScale = world.SCALE;
var destroyBody = world.DestroyBody.bind(world);
while(body){
var actor = null;
var visualEntity = null;
var box2DEntity = o.getBox2DEntityByIdFn(body.GetUserData());
if(box2DEntity){
visualEntity = o.getVisualEntityByIdFn(box2DEntity.getVisualEntityId());
if(box2DEntity.isDestroying()){
// optimization
body.__destroyed = true;
world.DestroyBody(body);
box2DEntity.completeDestroy();
}
}
if(visualEntity){
if(visualEntity.isDestroying()){
visualEntity.completeDestroy();
}else{
var inverseY = true;
var bodyDetails = Utils.getScreenPositionAndRotationOfBody(world, body, inverseY);
visualEntity.updateSprite(bodyDetails.x, bodyDetails.y, bodyDetails.rotation);
}
}
// this delegates out functionality for each body processed
if(o.triggersFn.eachBody) o.triggersFn.eachBody(world, body, visualEntity);
body = body.GetNext();
}
// when a joint is created is then also created it's visual counterpart and then set to userData.
var joint = world.GetJointList();
while(joint){
var pixiGraphics = joint.GetUserData();
if(pixiGraphics){
// In order to draw a distance joint we need to know the start and end positions.
// The joint saves the global (yes) anchor positions for each body.
// After that we need to scale to our screen and invert y axis.
var anchorA = joint.GetAnchorA();
var anchorB = joint.GetAnchorB();
var screenPositionA = anchorA.Copy();
var screenPositionB = anchorB.Copy();
// scale
screenPositionA.Multiply(world.SCALE);
screenPositionB.Multiply(world.SCALE);
// invert y
screenPositionA.y = world.CANVAS_HEIGHT - screenPositionA.y
screenPositionB.y = world.CANVAS_HEIGHT - screenPositionB.y
// draw a black line
pixiGraphics.clear();
pixiGraphics.lineStyle(1, 0x000000, 0.7);
pixiGraphics.moveTo(screenPositionA.x, screenPositionA.y);
pixiGraphics.lineTo(screenPositionB.x, screenPositionB.y);
}
joint = joint.GetNext();
}
// render the PIXI scene
if(o.renderPixi){
o.renderer.render(o.stage)
}
// render next frame
requestAnimFrame(o.requestAnimFrameFn);
}
Code from Box2d:
b2ContactManager.prototype.Destroy = function (c) {
var fixtureA = c.GetFixtureA();
var fixtureB = c.GetFixtureB();
var bodyA = fixtureA.GetBody();
var bodyB = fixtureB.GetBody();
if (c.IsTouching()) {
this.m_contactListener.EndContact(c);
}
if (c.m_prev) {
c.m_prev.m_next = c.m_next;
}
if (c.m_next) {
c.m_next.m_prev = c.m_prev;
}
if (c == this.m_world.m_contactList) {
this.m_world.m_contactList = c.m_next;
}
if (c.m_nodeA.prev) {
c.m_nodeA.prev.next = c.m_nodeA.next;
}
if (c.m_nodeA.next) {
c.m_nodeA.next.prev = c.m_nodeA.prev;
}
if (c.m_nodeA == bodyA.m_contactList) {
bodyA.m_contactList = c.m_nodeA.next;
}
if (c.m_nodeB.prev) {
c.m_nodeB.prev.next = c.m_nodeB.next;
}
if (c.m_nodeB.next) {
c.m_nodeB.next.prev = c.m_nodeB.prev;
}
if (c.m_nodeB == bodyB.m_contactList) {
bodyB.m_contactList = c.m_nodeB.next;
}
this.m_contactFactory.Destroy(c);
--this.m_contactCount;
}
b2ContactFactory.prototype.Destroy = function (contact) {
if (contact.m_manifold.m_pointCount > 0) {
contact.m_fixtureA.m_body.SetAwake(true);
contact.m_fixtureB.m_body.SetAwake(true);
}
var type1 = parseInt(contact.m_fixtureA.GetType());
var type2 = parseInt(contact.m_fixtureB.GetType());
var reg = this.m_registers[type1][type2];
if (true) {
reg.poolCount++;
contact.m_next = reg.pool;
reg.pool = contact;
}
var destroyFcn = reg.destroyFcn;
destroyFcn(contact, this.m_allocator);
}
I have the same problem, but I think I find out from where it comes.
Instead of m_* try functions, like GetFixtureA() instead of m_fixtureA.
Totti did you ever figure this out? It looks like box2dweb requires manual destruction and memory management.
I think I have found your leaks, un-implemented ( static class ) destruction functions:
b2Joint.Destroy = function (joint, allocator) {}
b2CircleContact.Destroy = function (contact, allocator) {}<
b2PolygonContact.Destroy = function (contact, allocator) {}
b2EdgeAndCircleContact.Destroy = function (contact, allocator) {}<
b2PolyAndCircleContact.Destroy = function (contact, allocator) {}
b2PolyAndEdgeContact.Destroy = function (contact, allocator) {}
[UPDATE...]
b2DestructionListener.b2DestructionListener = function () {};
b2DestructionListener.prototype.SayGoodbyeJoint = function (joint) {}
b2DestructionListener.prototype.SayGoodbyeFixture = function (fixture) {}
b2Contact.prototype.Reset(fixtureA, fixtureB)
called with with one/both fixture arguments resets passed in fixture/s BUT ALSO pass in NO arguments and it 'nulls' all the the b2Contact properties! (UNTESTED:) but I suggest set your YOURcontactListener class up to handle all contact callbacks EVERY call with Reset(??) dynamically configureable as logic requies EVERY call (there are more than you'd imagine each and every world step).
Also take Colt McAnlis clever advice and strategically pre allocate all the memory the life of your game will need (by creating game and box2d object pools now you know objects can be reset) so the garbage collector NEVER runs until, you destroy object pools at times of your own convenience.... i.e when you close the tab, or your device needs recharging! ;D [...UPDATE]
// you can define and assign your own contact listener ...via...
YOUR.b2world.b2ContactManager.m_world.m_contactList = new YOURcontactlistener();<br>[edit]...if you dont it actually does have Box2D.Dynamics.b2ContactListener.b2_defaultListener.
// box2d in the worldStep calls YOURcontactlistener.update() via:
this.b2world.b2ContactManager.m_world.m_contactList.Update(this.m_contactListener) // this.m_contactListener being YOURS || b2_defaultListener;
// which instantiates ALL your listed leaking object like so:
{b2Contact which instantiates {b2ContactEdge} and {b2Manifold which instantiates {b2ManifoldPoint{which instantiates m_id.key == ContactID{which instantiates Features}}}} along with {B2Vec2} are instantiated in b2ContactResult ...which I can not actually find but assume it must be instantiated in the Solver.
// There is a Contacts.destroyFcn callback is CREATED in....
b2ContactFactory.prototype.Destroy = function (contact) {...}
// then Contacts.destroyFcn callback(s) are privately REGISTERED in....
b2ContactFactory.prototype.InitializeRegisters() {...}
...via...
this.AddType = function (createFcn, destroyFcn, type1, type2) {...}
...BUT... THOSE privately registered ARE four of the un-implimented static class function from above...
b2PolygonContact.Destroy = function (contact, allocator) {}
b2EdgeAndCircleContact.Destroy = function (contact, allocator) {}
b2PolyAndCircleContact.Destroy = function (contact, allocator) {}
b2PolyAndEdgeContact.Destroy = function (contact, allocator) {}
So I havn't tested it yet but it looks like box2dweb just gives you the Destroy callback/handler functions and you have to read the source to find all the properties you need to null. [Edit] In combination with b2Contact.prototype.Reset(fixtureA, fixtureB)
But either way pretty confident the functions above(possibly incomplete) are callback/handlers, and can be used to null your way back to performance for anyone else who stumbles across this problem. Pretty sure Totti's moved on(dont forget to handle your 'this' scope in callbacks).

Can't display block in panel

I'm new to drupal, and very new to panels. I have a custom module which displays rss feed items based on user taxonomy. It displays the correct info as a block, but it needs to be on the users' dashboard page, which uses panels. When I try to insert it, it is always blank.
The code inserts a default view I already created, showing all feed items (1_feeds_defaults_feed_items) into a block. I can't edit it to work in a panel. I imagine that there are 10 different things I may have done wrong, but have tried every permutation I can think of.
<?php
//.this function generates a block and calls the second
//function for the content of this block
function custom_block($op = 'list', $delta = 0, $edit = array()) {
switch ($op) {
case 'list':
$block[0]['info'] = 'Custom View';
$block[2]['cache'] = BLOCK_NO_CACHE;
return $block;
break;
case 'view':
switch ($delta) {
case 0:
$block['subject'] = '';
$block['content'] = custom_userfeeds() ;
break;
}
return $block;
}
}
function custom_userfeeds() {
//finds the user id from argument on user page.
//You can also find the user id the way the page you linked me to did,
//but if you do it the way I am below it would allow admins
//to view other users feeds
$uid = arg(1);
//loads the profile node -- 'profile' is the profile content type.
$node = content_profile_load('profile', $uid);
//find the terms associated with the user's profile
if ($node && $node->taxonomy) {
foreach($node->taxonomy as $term) {
$terms[] = $term->tid;
}
}
//embeds a view with those terms passed to it.
View display is something like block_1 or page_1
if($terms) {
$t = implode('+',$terms);
return views_embed_view("1_feeds_defaults_feed_items","page_1", $t);
}
}
Here is how I fixed it in a view:
-Add Argument -> Taxonomy -> Taxonomy Term ID
-Provide default argument
-PHP Code
-PHP argument code:
global $user;
$query = "SELECT tid FROM {term_user} WHERE uid = %d";
$result = db_query($query, $user->uid);
if ($result) {
$terms = array();
while ($term = db_fetch_array($result)) {
$terms[] = $term['tid'];
}
if ($terms) {
$termargs = implode("+", $terms);
return $termargs;
}
}
else {
return FALSE;
}
-Check "Allow multiple terms per argument."

Resources