Advertisement
  1. This site uses cookies. By continuing to use this site, you are agreeing to our use of cookies. Learn More.

when to clone?

Comments in 'Plugin Development' started by udwarf, Jun 7, 2016.

  1. udwarf
    Offline

    udwarf Active Member

    Joined:
    Apr 17, 2016
    Posts:
    61
    Minecraft User:
    1Zaza
    Hi guys!
    I understand that my question kind lame but hope that there will be another answers, not just a "go-learn-php"

    Actually, I cant understand when we really need to clone an object
    For examle I saw such code in on of plugins:
    PHP:
        public function onMove(PlayerMoveEvent $event)
        {
                   ...
                    
    $to = clone $event->getFrom();
                    
    $event->setTo($to);
        }
    Do we really need here to use clone? Why?

    Another example:
    PHP:
                    $item Item::get(Item::ARROW01);
                    
    $this->inventory->addItem(clone $item);
    As I see, Item::get creates new object. So why do use clone here?

    Can you give me some hints please?
  2. Extreme_Heat
    Offline

    Extreme_Heat Active Member

    Joined:
    Apr 19, 2016
    Posts:
    76
    Minecraft User:
    Extreme_Heat
    In PHP, objects are passed by reference (two variables point to the same memory address) by default so cloning is basically "copying" an object (two different copies of the variable are stored in memory) instead of passing it by reference.

    For example,

    PHP:
    $item = new Item(Item::CARROT01);
    $item_ref $item;
    $item_ref->setCount(20);
    echo 
    $item->getCount();
    Equals 20 -- whereas if you added the "clone" construct:

    PHP:
    $item = new Item(Item::CARROT01);
    $item_ref = clone $item;
    $item_ref->setCount(20);
    echo 
    $item->getCount();
    It would equal 1.

    In the second example, the cloning does appear to be redundant as PocketMine already clones them when addItem() is called. Generally this shouldn't be too much of an issue other than the added overhead.
    MyNameIsTriXz likes this.
  3. Legoboy0215
    Offline

    Legoboy0215 Notable Member

    Joined:
    Nov 1, 2014
    Posts:
    1,724
    Minecraft User:
    Legoboy0215
    Just a FYI, using Item::get is better than constructing a new item.
  4. SOFe
    Offline

    SOFe Banned

    Joined:
    May 28, 2016
    Posts:
    386
    Minecraft User:
    Herobrine
    Usually, clone should only be used when the object is used as a struct.

    An object used as a struct when it is only used to pass multiple data. For example, an Item object passes multiple data: item ID, item damage, item count, extra item data.

    An object that is multiple-referenced and each instance has its unique meaning, such as a Player object, should not be cloned. Without cloning, you cannot naturally find two instances of Player object that are equal and represent the same thing.
  5. udwarf
    Offline

    udwarf Active Member

    Joined:
    Apr 17, 2016
    Posts:
    61
    Minecraft User:
    1Zaza
    So if I, for example want to store broken blocks list in onBlockBreak event handler
    after $b = $event->getBlock();
    should I do
    $this->store[] = $b or $this->store[] = clone $b; ?

    And as I understood, while adding item (created by Item::get) to an inventory - cloning not needed, right?
    But why do we have such cloning in PocketMines's Player.php in checkNearEntities function ?
  6. SOFe
    Offline

    SOFe Banned

    Joined:
    May 28, 2016
    Posts:
    386
    Minecraft User:
    Herobrine
    It is not advisable to store Block objects directly, because a Block object is actually a Position object (Block extends Position) too, which contains a strong reference to a Level object. Therefore, it is better to simply store an array of [$b->getId(), $b->getDamage()]. If you also want to store the position, make it save the level name instead of a reference to the level object so that PHP GC releases the memory for the level gracefully. (This is possibly a cause to many memory exhaustion issues)

    About checkNearEntities: it is not needed, but it is quite harmless to do it. After all, cloning an object, especially a small one like an Item object, is really a minor operation to the CPU.

Share This Page

Advertisement