-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathmain.cpp
279 lines (236 loc) · 12.3 KB
/
main.cpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
/* TODO: Implement Output Logs.*/
#include <iostream>
#include <string>
#include <vector>
#include <fstream>
#include <thread>
#include <mutex>
std::mutex CRITICALSECTION;
#define SIZEMAXCUSTOMERS 300
#define COMPANYCOUNT 5
#define MACHINECOUNT 10+1
std::string inputFileName="input1.txt";
int CUSTOMERCOUNT ;
static int customersCreated=0;
enum customerStatus{processing, ready, done};
enum banks{bob, dave, kevin, otto, stuart, null};
void createNewMachine(int GenerationLoopCounter);
void createNewCustomerThread(int GenerationLoopCounter, int id, int sleepDuration, int payFromMachineID, std::string payToCompany, int payAmount);
void printDetailsOfMachineWithIndex(int i);
void printDetailsOfCustomerWithIndex(int i);
std::vector<std::string> parseStringToArray(std::string s);
banks hashit (std::string const& inString);
class Transaction {
private:
int _id;
int _issuedByMachineID;
std::string _issuedByCompanyName;
int _requestedFromCustomerID;
public:
Transaction(int id,int issuedByMachineID, std::string issuedByCompanyName, int requestedFromCustomerID){
_id = id;
_issuedByMachineID = issuedByMachineID;
_issuedByCompanyName = issuedByCompanyName;
_requestedFromCustomerID = requestedFromCustomerID;
}
void toConsole(){ std::cout<<"Transaction "<< _id << " | " << "ByMachine:" << _issuedByMachineID << " , ByCompany:" << _issuedByCompanyName << " , Customer:" <<_requestedFromCustomerID << std::endl ;}
};
class Company {
private:
std::string _name;
int _balance;
int _transactionCount;
std::vector<int> customersServedQUEUE;
public:
Company(std::string name){
_name = name;
_balance = 0;
_transactionCount = 0;
}
int getBalance(){return _balance;}
void receivePayment(int receiveAmount, int fromCustomerID){
_balance += receiveAmount;
_transactionCount++;
customersServedQUEUE.push_back(fromCustomerID);
std::cout << '\t'<< _name <<" Company recieved payment." << std::endl;
}
void toConsole(){ std::cout << " Company " << _name << " | Balance = " << _balance << " , Transactions = " << _transactionCount << std::endl;}
};Company* COMPANIES[COMPANYCOUNT];
class VendingMachine {
private:
int _id;
std::thread::id _threadID;
int _transactionCount;
int _requestCount;
bool _available=true;
public:
VendingMachine(int id){
_id = id;
_threadID = std::this_thread::get_id();
_transactionCount = 0;
_requestCount = 0;
if (id==0){
_available = !_available;
}
};
void toConsole(){
std::cout << " " << "MachineThreadID: "<< _threadID <<std::endl<<" ";
std::cout <<"Vending Machine " << _id << " | " << "Requests = " << _requestCount << ", Transactions = " << _transactionCount <<", status="<< _available << std::endl;
}
customerStatus processPayment(int customerID, std::string companyName, int amount){
/* TODO */
banks bank = hashit(companyName);
COMPANIES[bank] -> receivePayment(amount, customerID);
++_transactionCount;
return done;
}
};VendingMachine* MACHINES[MACHINECOUNT];
class Customer {
private:
int _id;
std::thread::id _threadID;
int _sleepDuration;
int _payFromMachineID;
std::string _payToCompany;
int _payAmount;
customerStatus _status;
Transaction* _ticket;
public:
Customer(int sleepDuration, int payFromMachineID, std::string payToCompany, int payAmount){
_id = ++customersCreated;
_sleepDuration = sleepDuration;
_payFromMachineID = payFromMachineID;
_payToCompany = payToCompany;
_payAmount = payAmount;
_status = ready;
_threadID = std::this_thread::get_id();
}
int getSleepDuration(){ return _sleepDuration;}
int getPayFromMachineID(){ return _payFromMachineID;}
std::string getPayToCompany(){ return _payToCompany;}
int getPayAmount(){ return _payAmount;}
int getID(){ return _id;}
void buyTicket(){
CRITICALSECTION.lock();
/*Critical Section*/
_status = processing;
std::cout << _sleepDuration << "ms slept."<<" Payment process started by Customer["<< _id << "]"
<< "at Machine["<< _payFromMachineID << "]" << std::endl;
_status = MACHINES[_payFromMachineID] -> processPayment(_id, _payToCompany, _payAmount);
CRITICALSECTION.unlock();
}
void toConsole(){
std::cout << " " << "CustomerThreadID: "<< _threadID <<std::endl<<" ";
std::cout << "Customer " << _id << ": [" << _sleepDuration << ","<< _payFromMachineID <<
","<< _payToCompany << ","<< _payAmount << ","<< "status="<< _status << "]"<< std::endl;
}
};Customer* CUSTOMERS[SIZEMAXCUSTOMERS];
/* main() function consists of 4 UPPERCASE fundamental parts.*/
int main(){
/* main thread */
/*std::thread::id threadID = std::this_thread::get_id();std::cout << "printThreadID: "<< threadID <<" main()\n"; */
/* -- COMPANIES--
Create 5 different service provider companies and append to array. */
Company* Bob = new Company("Bob" ) ; COMPANIES[0]=Bob;
Company* Dave = new Company("Dave" ) ; COMPANIES[1]=Dave;
Company* Kevin = new Company("Kevin" ) ; COMPANIES[2]=Kevin;
Company* Otto = new Company("Otto" ) ; COMPANIES[3]=Otto;
Company* Stuart = new Company("Stuart") ; COMPANIES[4]=Stuart;
/* -- MACHINES --
Create 10 different service provider vending machines and append to array. *///THREAD processing machine affaires.
std::vector<std::thread> threadsOfMachines; //
for(int i=0;i<MACHINECOUNT;i++){
threadsOfMachines.push_back(std::thread(createNewMachine, i)); // Create new thread and append to array.
}
for(int j=0;j<MACHINECOUNT;j++){
threadsOfMachines[j].join(); // Make threads join.
}
/* -- CUSTOMERS--
Create CUSTOMERCOUNT many Customer object instances as specified in the input file
. and keep'em in an array. */
std::ifstream ReadFile(inputFileName); // First line of input file,
std::string firstLine; // specifies customerCount.
getline(ReadFile, firstLine);
CUSTOMERCOUNT = std::stoi(firstLine);
std::vector<std::thread> threadsOfCustomers; // THREADS processing customer affaires.
//Read a new line {CUSTOMERCOUNT} many times and parse required info to construct a new object respectively.
for(int i=0; i<CUSTOMERCOUNT;i++){
std::string line; getline(ReadFile, line); std::vector<std::string> lineArray = parseStringToArray(line); // LINE CONTENT 2x2
int sleepDuration=std::stoi(lineArray[0]); int payFromMachineID=std::stoi(lineArray[1]);// |sleepDuration|payFromMachineID|
std::string payToCompany = lineArray[2]; int payAmount=std::stoi(lineArray[3]);// | payToCompany|payAmount |
// Create new thread and append to array.
threadsOfCustomers.push_back(std::thread(createNewCustomerThread, i,0, sleepDuration, payFromMachineID, payToCompany, payAmount));
};
//Join threads using void join();
for(int j=0;j<CUSTOMERCOUNT;j++){
threadsOfCustomers[j].join();
}
/* --TRANSACTIONS-- */
/* print console */
for(int i=0;i<COMPANYCOUNT;i++)
COMPANIES[i] -> toConsole();
return 0;
}
void createNewMachine(int GenerationLoopCounter){
VendingMachine* mach = new VendingMachine(GenerationLoopCounter);
MACHINES[GenerationLoopCounter]=mach;
//printDetailsOfMachineWithIndex(GenerationLoopCounter);
}
void createNewCustomerThread(int GenerationLoopCounter,int id, int sleepDuration, int payFromMachineID, std::string payToCompany, int payAmount){
Customer* customer = new Customer(sleepDuration, payFromMachineID, payToCompany, payAmount);
CUSTOMERS[GenerationLoopCounter] = customer;//printDetailsOfCustomerWithIndex(GenerationLoopCounter);
std::this_thread::sleep_for(std::chrono::milliseconds(customer -> getSleepDuration()));
customer -> buyTicket(); /*CUT std::cout << "Customer " << customer -> getID() <<" Ready!:"
<< "goToMachineID(" << customer -> getPayFromMachineID() << ") "
<< "payToCompany(" << customer -> getPayToCompany() << ") "
<< "payAmount(" << customer -> getPayAmount() << ") "<< std::endl;
CUT*/
}
void printDetailsOfCustomerWithIndex(int i){
std::thread::id threadID = std::this_thread::get_id();
std::cout << "printThreadID:"<< threadID <<" customerDetails:";
CUSTOMERS[i] -> toConsole();
}
void printDetailsOfMachineWithIndex(int i){
std::thread::id threadID = std::this_thread::get_id();
std::cout << "printThreadID: "<< threadID <<" machineDetails : ";
MACHINES[i] -> toConsole();
}
std::vector<std::string> parseStringToArray(std::string s){
std::vector<std::string> v(4);
std::string delimiter=",";
size_t pos = 0;
std::string token;
int index = 0;
while ((pos = s.find(delimiter)) != std::string::npos) {
token = s.substr(0, pos);
v[index] = token;
index++;
s.erase(0, pos + delimiter.length());
}
v[index] = s;
return v;
}
banks hashit (std::string const& inString) {
if (inString == "Bob" ) return bob;
else if (inString == "Dave" ) return dave;
else if (inString == "Kevin" ) return kevin;
else if (inString == "Otto" ) return otto;
else if (inString == "Stuart") return stuart;
return null;
};
/* void join();
. The function returns when the thread execution has completed.
. This synchronizes the moment this function returns with the completion of all the operations in the thread:
. This blocks the execution of the thread that calls this function,
. until the function called on construction returns (if it hasn't yet). */
//""" DebugTools """;
/*
"""//CutAboveLine//""";
for(int i=0;i<COMPANYCOUNT;i++)
COMPANIES[i] -> toConsole();
for(int i=0;i<MACHINECOUNT;i++)
MACHINES[i]-> toConsole();
for(int i=0;i<CUSTOMERCOUNT;i++)
CUSTOMERS[i] -> toConsole();
*/