Completed
Branch 0.4-dev (3e8fde)
by Evgenij
17:21
created

ReadWriteOperation::__construct()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 7
Code Lines 4

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
dl 0
loc 7
rs 9.4285
c 0
b 0
f 0
cc 2
eloc 4
nc 2
nop 2
1
<?php
2
/**
3
 * Async sockets
4
 *
5
 * @copyright Copyright (c) 2015-2017, Efimov Evgenij <[email protected]>
6
 *
7
 * This source file is subject to the MIT license that is bundled
8
 * with this source code in the file LICENSE.
9
 */
10
11
namespace AsyncSockets\Operation;
12
13
/**
14
 * Class ReadWriteOperation. Provides reading and writing at the same time
15
 */
16
class ReadWriteOperation implements OperationInterface
17
{
18
    /**
19
     * Flag if read operations must be processed before write
20
     */
21
    const READ_FIRST = true;
22
23
    /**
24
     * Flag if write operations must be processed before read
25
     */
26
    const WRITE_FIRST = false;
27
28
    /**
29
     * Operation queue indexed by operation type
30
     *
31
     * @var OperationInterface[][]
32
     */
33
    private $queue = [];
34
35
    /**
36
     * Flag whether read operation must be fired before write
37
     *
38
     * @var bool
39
     */
40
    private $isReadFirst;
41
42
    /**
43
     * ReadWriteOperation constructor.
44
     *
45
     * @param bool                 $isReadFirst Flag whether read operation must be fired before write
46
     * @param OperationInterface[] $operations  Array of operations to schedule
47
     */
48
    public function __construct($isReadFirst, array $operations = [])
49
    {
50
        $this->isReadFirst = $isReadFirst;
51
        foreach ($operations as $operation) {
52
            $this->scheduleOperation($operation);
53
        }
54
    }
55
56
    /**
57
     * Set read or write operation
58
     *
59
     * @param OperationInterface $operation Operation to set
60
     *
61
     * @return void
62
     */
63
    public function scheduleOperation(OperationInterface $operation)
64
    {
65
        $key = spl_object_hash($operation);
66
        switch (true) {
67
            case $operation instanceof ReadOperation:
68
                $this->queue[OperationInterface::OPERATION_READ][$key] = $operation;
69
                break;
70
            case $operation instanceof WriteOperation:
71
                $this->queue[OperationInterface::OPERATION_WRITE][$key] = $operation;
72
                break;
73
            default:
74
                // no action
75
        }
76
    }
77
78
    /**
79
     * Mark operation as completed
80
     *
81
     * @param OperationInterface $operation Operation to mark as done
82
     *
83
     * @return void
84
     */
85
    public function markCompleted(OperationInterface $operation)
86
    {
87
        $key = spl_object_hash($operation);
88
        switch (true) {
89
            case $operation instanceof ReadOperation:
90
                unset($this->queue[OperationInterface::OPERATION_READ][$key]);
91
                break;
92
            case $operation instanceof WriteOperation:
93
                unset($this->queue[OperationInterface::OPERATION_WRITE][$key]);
94
                break;
95
            default:
96
                // no action
97
        }
98
    }
99
100
    /**
101
     * Return current read operation
102
     *
103
     * @return ReadOperation|null
104
     */
105
    public function getReadOperation()
106
    {
107
        return !empty($this->queue[OperationInterface::OPERATION_READ]) ?
108
            reset($this->queue[OperationInterface::OPERATION_READ]) :
109
            null;
110
    }
111
112
    /**
113
     * Return current write operation
114
     *
115
     * @return WriteOperation|null
116
     */
117
    public function getWriteOperation()
118
    {
119
        return !empty($this->queue[OperationInterface::OPERATION_WRITE]) ?
120
            reset($this->queue[OperationInterface::OPERATION_WRITE]) :
121
            null;
122
    }
123
124
    /**
125
     * Return true if read must be handled before write
126
     *
127
     * @return bool
128
     */
129
    public function isReadFirst()
130
    {
131
        return $this->isReadFirst;
132
    }
133
134
    /**
135
     * @inheritDoc
136
     */
137
    public function getTypes()
138
    {
139
        $result = [];
140
        foreach ($this->queue as $type => $operations) {
141
            if (!empty($operations)) {
142
                $result[] = $type;
143
            }
144
        }
145
146
        return $result;
147
    }
148
}
149