├── .gitattributes
├── .gitignore
├── .gitmodules
├── C++
├── 01 C++ - Introduction.md
├── 02 C++ - Functions and File IO.md
├── 03 C++ - Object-Oriented Syntax.md
├── 04 C++ - Pointers and Memory.md
├── 05 C++ - Data Structures (Containers).md
├── 06 C++ - Templates.md
├── 07 C++ - Threading and Concurrency.md
├── 08 C++ - Linkages and Preprocessor Directives.md
├── 09 C++ - Tips and Tricks.md
├── Bonus Notes
│ └── BONUS C++ - Headers.md
└── assets
│ ├── 1562761542554.png
│ ├── 1562814980420.png
│ ├── 1562934941151.png
│ ├── 1562935061068.png
│ ├── 192px-Binary_tree.svg.png
│ ├── 1_FH2BzH1l5D7C18Fd7U0JVQ.png
│ ├── C_Iterator.jpg
│ ├── GCC_CompilationProcess.png
│ ├── Linkedlist.png
│ ├── QullW.png
│ ├── Selection_101.png
│ ├── SharedMutable.png
│ ├── ZWg39.png
│ ├── array.png
│ ├── compilation.gif
│ ├── concurrency_vs_parallelism-1562918749730.png
│ ├── concurrency_vs_parallelism.png
│ ├── copy.jpg
│ ├── deadlock.png
│ ├── giphy-1562828095877.gif
│ ├── giphy.gif
│ ├── main-qimg-0b429780923c55f6a803405694c5b7af.webp
│ ├── memory-management-in-cpp-2.png
│ ├── memoryLayoutC.jpg
│ ├── mindblow.gif
│ ├── move.jpg
│ ├── pointers-in-c.jpg
│ ├── priority_queue.png
│ ├── promise.png
│ ├── queue.png
│ ├── selection.gif
│ ├── sfinae_compiling.png
│ ├── stack-1562909159143.jpg
│ ├── stack.jpg
│ ├── templates-cpp.jpg
│ └── threads-as-control-flow.png
├── CMake
├── 01 CMake - Basics and Scripting.md
├── 02 CMake - Building with CMake.md
├── 03 CMake - Advanced Scripting and Modules.md
└── assets
│ ├── 1565761777925.png
│ ├── 1565761892848.png
│ ├── 1565763864160.png
│ ├── 1565764747746.png
│ ├── 1565764814617.png
│ ├── 1565773573410.png
│ ├── 1565773727787.png
│ ├── 1565773781724.png
│ ├── 1565775582248.png
│ ├── 1565847804604.png
│ ├── 1565855200577.png
│ ├── 1566144489572.png
│ ├── 1566146742207.png
│ ├── 1566149145967.png
│ ├── cmake-simpler-flowchart.png
│ ├── cmake-variable-scopes.png
│ ├── compilation.gif
│ └── ezgif-3-92cffd6c4e0f.gif
├── DDS
└── OpenSplice DDS (C++ API)
│ ├── 01 DDS - Introduction.md
│ ├── 02 DDS - Writing Nodes Practically.md
│ └── Starter Code and Resources
│ ├── Note.txt
│ ├── opensplice_boilerplate
│ ├── .gitignore
│ ├── .travis.yml
│ ├── CMakeLists.txt
│ ├── README.md
│ ├── cmake
│ │ ├── FindOpenSplice.cmake
│ │ ├── MacroOpenSplice.cmake
│ │ └── osmacros.cmake
│ ├── compile
│ ├── gencode
│ ├── idl
│ │ └── Boilerplate.idl
│ ├── lib
│ │ └── boilerplate
│ │ │ └── template
│ │ │ ├── Boilerplate.cpp
│ │ │ ├── Boilerplate.h
│ │ │ ├── CMakeLists.txt
│ │ │ ├── CheckStatus.cpp
│ │ │ ├── CheckStatus.h
│ │ │ ├── Participant.cpp
│ │ │ └── Participant.h
│ └── src
│ │ ├── pubsub_1.cpp
│ │ └── pubsub_2.cpp
│ └── opensplice_minimal
│ ├── .gitignore
│ ├── .travis.yml
│ ├── CMakeLists.txt
│ ├── README.md
│ ├── cmake
│ ├── FindOpenSplice.cmake
│ ├── MacroOpenSplice.cmake
│ └── osmacros.cmake
│ ├── compile
│ ├── gencode
│ ├── idl
│ └── HelloWorld.idl
│ └── src
│ ├── .pub.cpp.swp
│ ├── CheckStatus.cpp
│ ├── CheckStatus.h
│ ├── DDSEntityManager.cpp
│ ├── DDSEntityManager.h
│ ├── pub.cpp
│ └── sub.cpp
├── Java
├── 01 Java - Introduction (WIP).md
└── assets
│ ├── 01 Java - Introduction (WIP)
│ ├── access-modifier.png
│ ├── image-20210224233948818.png
│ ├── image-20210224234856306.png
│ ├── image-20210224235651731.png
│ ├── image-20210224235752129.png
│ ├── java_array.jpg
│ ├── multiple.jpg
│ └── typesofinheritance.jpg
│ ├── 1568361459025.png
│ ├── animalClasses.PNG
│ └── java-arch.png
├── LICENSE
├── MATLAB
├── MATLAB Crash Course.md
└── assets
│ ├── 1553825732887.png
│ └── COFFEE BUTTON ヾ(°∇°^).png
├── MySQL
├── 01 MySQL - Introduction.md
└── assets
│ ├── MySQL Table.png
│ ├── Student Schemas.PNG
│ └── Student Table.PNG
├── PHP
├── 01 PHP - Syntax and DB Interactions.md
└── 02 PHP - Object-Oriented Syntax.md
├── Python 3
├── 01 Python 3 - Introduction.md
├── 02 Python 3 - Functions and File IO.md
├── 03 Python 3 - Object-Oriented Syntax.md
├── 04 Python 3 - Advanced Concepts.md
├── 05 Python 3 - Data Structures.md
└── assets
│ ├── 1563086409015.png
│ ├── 1563125439057.png
│ ├── 1_PTC18sgXqar4aS-_C_uzRQ.png
│ ├── 1_YUMW7F-pm3bXmSnr1owcMg.png
│ ├── 1_kvOnNBfiEn-WdiQbcElpEA.png
│ ├── memory-management-in-python-the-basics-75-638.jpg
│ ├── priority_queue.png
│ ├── probing.png
│ ├── py_memory1.2b6e5f8e5bc9.png
│ ├── py_memory3_1.ea43471d3bf6.png
│ ├── queue.png
│ ├── singly-ll.png
│ └── stack.jpg
├── README.md
├── Regular Expressions
├── Regex Cheatsheets.md
└── assets
│ ├── Another Cheat Sheet.png
│ └── Cheat Sheet.jpg
├── Rust (WIP)
├── 01 Rust - Introduction.md
├── 02 Rust - Loops, Custom Types, and Errors.md
├── TODOS
└── assets
│ └── 01 Rust - Introduction
│ └── ferris.gif
├── WordPress
└── 01 WordPress - Introduction.md
└── _assets
└── COFFEE BUTTON ヾ(°∇°^).png
/.gitattributes:
--------------------------------------------------------------------------------
1 | # Auto detect text files and perform LF normalization
2 | * text=auto
3 |
4 | # Custom for Visual Studio
5 | *.cs diff=csharp
6 |
7 | # Standard to msysgit
8 | *.doc diff=astextplain
9 | *.DOC diff=astextplain
10 | *.docx diff=astextplain
11 | *.DOCX diff=astextplain
12 | *.dot diff=astextplain
13 | *.DOT diff=astextplain
14 | *.pdf diff=astextplain
15 | *.PDF diff=astextplain
16 | *.rtf diff=astextplain
17 | *.RTF diff=astextplain
18 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | *.swp
2 | *.swap
3 | *.save
4 | *.bak
5 |
6 | *.no_toc
7 |
--------------------------------------------------------------------------------
/.gitmodules:
--------------------------------------------------------------------------------
1 | [submodule "VBA"]
2 | path = VBA
3 | url = https://github.com/09x09/VBA-crash-course
4 |
--------------------------------------------------------------------------------
/C++/02 C++ - Functions and File IO.md:
--------------------------------------------------------------------------------
1 | # Function C++ Crash Course
2 |
3 | Author: methylDragon
4 | Contains a syntax reference for C++
5 | This time, we'll be going through Functions and File I/O!
6 | I'll be adapting it from the ever amazing Derek Banas: https://www.youtube.com/watch?v=Rub-JsjMhWY
7 |
8 | ------
9 |
10 | ## Pre-Requisites
11 |
12 | **Assumed knowledge (This is a C++ crash course, not a basic coding tutorial)**
13 |
14 | - How **variables, loops, conditionals, etc**. work (Basic coding fundamentals will help a lot!)
15 | - Linux (**Terminal/Console proficiency**) (We're going to need to compile our stuff)
16 | - Gone through the all preceding parts of the tutorial
17 |
18 | ## Table Of Contents
19 |
20 | 1. [Introduction](#1)
21 | 2. [Function C++ Syntax Reference](#2)
22 | 2.1 [Functions](#2.1)
23 | 2.2 [Function Overloading](#2.2)
24 | 2.3 [Recursive Functions](#2.3)
25 | 2.4 [File I/O](#2.4)
26 | 2.5 [Lambda Functions](#2.5)
27 | 2.6 [Inline Functions](#2.6)
28 |
29 | ## 1. Introduction
30 |
31 | We've gone through the basics of C++. Now let's throw in some functions and file interactions!
32 |
33 | ## 2. Function C++ Syntax Reference
34 |
35 | ### 2.1 Functions
36 |
37 | [go to top](#top)
38 |
39 | Declare your functions **BEFORE** the main function!
40 |
41 | `int addNumbers(int firstNum, int secondNum = 0)`
42 | firstNum and secondNum are attributes. We set secondNum's default value if no value is given to be 0.
43 |
44 | `int` on the `addNumbers` function is the RETURN value's datatype, in other words, the data type of the function's output.
45 |
46 | ```c++
47 | int addNumbers(int firstNum, int secondNum = 0) {
48 | int combinedValue = firstNum + secondNum;
49 |
50 | return combinedValue;
51 |
52 | }
53 | ```
54 |
55 | > **Note**: combinedValue is not accessible anywhere else other than in addNumbers, as it is a **LOCAL** variable defined WITHIN a function.
56 |
57 | **Calling Functions**
58 |
59 | ```c++
60 | // So, we've made a function called addNumbers above
61 | // Call it like this
62 |
63 | addNumbers(1, 2); // It'll return 3
64 |
65 | // Simple eh?
66 | ```
67 |
68 | > **Note:**
69 | >
70 | > - When you write the data-type infront of the function name, you're defining a new function **prototype**
71 | > - If you don't, you're calling it.
72 | >
73 | > Remember the distinction!
74 |
75 | #### **Returning arrays**
76 |
77 | Read more + code source: https://www.geeksforgeeks.org/return-local-array-c-function/
78 |
79 | Turns out you **can't return arrays** from functions just like that. It's not so simple.
80 |
81 | This is a little premature since we have to go into OOP and/or pointers to do it.. but.. Here are the several ways to "return an array" from a function.
82 |
83 | **Return a dynamically allocated array pointer**
84 |
85 | Like so: `int *arr = new int[100];`
86 |
87 | ```c++
88 | int *fun()
89 | {
90 | int *arr = new int[100]; // HERE IT IS!
91 |
92 | arr[0] = 10;
93 | arr[1] = 20;
94 |
95 | return arr; // Return the pointer to the array!
96 | }
97 |
98 | int main()
99 | {
100 | int *ptr = fun();
101 | cout << ptr[0] << " " << ptr[1]; // Prints 10 20
102 | return 0;
103 | }
104 | ```
105 |
106 | **Return a static array**
107 |
108 | Like so: `static int arr[100];`
109 |
110 | ```c++
111 | int *fun()
112 | {
113 | static int arr[100] // HERE IT IS!
114 |
115 | arr[0] = 10;
116 | arr[1] = 20;
117 |
118 | return arr; // Return the pointer to the array!
119 | }
120 |
121 | int main()
122 | {
123 | int *ptr = fun();
124 | cout << ptr[0] << " " << ptr[1]; // Prints 10 20
125 | return 0;
126 | }
127 | ```
128 |
129 | **Use Structs** (Probably my preferred method)
130 |
131 | ```c++
132 | struct arrWrap
133 | {
134 | int arr[100];
135 | };
136 |
137 | struct arrWrap fun() // Function returns the struct
138 | {
139 | struct arrWrap x;
140 |
141 | x.arr[0] = 10;
142 | x.arr[1] = 20;
143 |
144 | return x;
145 | }
146 |
147 | int main()
148 | {
149 | struct arrWrap x = fun();
150 | cout << x.arr[0] << " " << x.arr[1]; // And you can access the struct members
151 | return 0;
152 | }
153 | ```
154 |
155 | ### 2.2 Function Overloading
156 |
157 | [go to top](#top)
158 |
159 | > C++ allows specification of more than one function of the same name in the same scope. These are called overloaded functions and are described in detail in Overloading. Overloaded functions enable programmers to supply different semantics for a function, depending on the types and number of arguments.
160 |
161 | > For example, a print function that takes a string (or char *) argument performs very different tasks than one that takes an argument of type double. Overloading permits uniform naming and prevents programmers from having to invent names such as print_sz or print_d. The following table shows what parts of a function declaration C++ uses to differentiate between groups of functions with the same name in the same scope. - Microsoft
162 |
163 | ```c++
164 | void sameFunction(int a){
165 | // do stuff;
166 | }
167 |
168 | int sameFunction(float a){
169 | // do something else;
170 | }
171 |
172 | void sameFunction(int a, float b){
173 | // do something different;
174 | }
175 | ```
176 |
177 | Functions can have the same name, but do DIFFERENT THINGS depending on what gets passed to them!
178 |
179 | ### 2.3 Recursive Functions
180 |
181 | [go to top](#top)
182 |
183 | These are functions that call THEMSELVES. Trippy.
184 |
185 | ```c++
186 | int getFactorial(int number){
187 | int sum;
188 | if(number == 1)
189 | sum = 1; //Yeah you can do this
190 | else
191 | sum = getFactorial(number - 1) * number;
192 | return sum;
193 | )
194 | ```
195 |
196 | This function returns the factorial of itself, and it keeps calling itself which results in it calling itself until it stops, then it resolves one by one till all are resolved.
197 |
198 | The last function calls to go on the stack are resolved first! USE THE STACK! Play some Magic!
199 |
200 | ### 2.4 File I/O
201 |
202 | [go to top](#top)
203 |
204 | File input output.
205 |
206 | Remember to `#include ` and `#include `
207 |
208 | ```c++
209 | string dragonQuote = "Rawr. But I can talk. Sup."; // Define the string to be written
210 |
211 | ofstream writer("dragonQuote.txt"); //Open a .txt file called dragonQuote, this is an OUTPUT filestream
212 |
213 | if(! writer) { //Check to see if the filestream is open
214 |
215 | cout << "Error opening file" << endl;
216 | return -1; // Return -1 if failed
217 |
218 | } else {
219 |
220 | writer << dragonQuote << endl; // Write dragonQuote to writer, which causes dragonQuote.txt to contain only dragonQuote
221 | writer.close(); // Close the file
222 |
223 | }
224 |
225 | ofstream writer2("dragonQuote.txt", ios::app); //Create a writer object that appends to dragonQuote.txt
226 |
227 | // Open a stream to append to what's there with ios::app
228 | // ios::binary : Treat the file as binary
229 | // ios::in : Open a file to read input
230 | // ios::trunc : Default
231 | // ios::out : Open a file to write output
232 |
233 | if(! writer2) { //Check to see if the filestream is open
234 |
235 | cout << "Error opening file" << endl;
236 | return -1; // Return -1 if failed
237 |
238 | } else {
239 |
240 | writer2 << "\n -methylDragon" << endl; // Append "\n -methylDragon"
241 | writer2.close(); // Close the file
242 |
243 | }
244 |
245 | {
246 | char letter;
247 |
248 | ifstream reader("dragonQuote.txt"); // Open an input filestream that reads dragonQuote.txt
249 |
250 | if(! reader){
251 |
252 | cout << "Error opening file" << endl;
253 | return -1;
254 |
255 | } else {
256 |
257 | for(int i = 0; ! reader.eof(); i++) { // Read until end of file
258 | reader.get(letter); // Get the next letter
259 | cout << letter; // And print it
260 | }
261 |
262 | }
263 |
264 | cout << endl;
265 | reader.close();
266 | }
267 | ```
268 |
269 | ### 2.5 Lambda Functions
270 |
271 | Lambda functions are great for creating anonymous functions that are not meant for reuse.
272 |
273 | Lambdas help to replace **functors.** That is, classes where `operator()` is hidden. So you can call the classes just like normal functions. They're normal classes that override operator, so they can be called like so `someFunctor(SOME_VALUES_IF_THE_FUNCTOR_TAKES_THEM);`
274 |
275 | So before we can meaningfully go through lambdas, we need to go through functors.
276 |
277 | **Functor**
278 |
279 | So for example, this is an example of a functor class.
280 |
281 | ```c++
282 | // Source: https://dev.to/sandordargo/lambda-expressions-in-c-4pj4
283 | class IsBetweenZeroAndTen {
284 | public:
285 | bool operator()(int value) {
286 | return 0 < value && value < 10;
287 | }
288 | };
289 |
290 | // Usage
291 | IsBetweenZeroAndTen some_functor;
292 | some_functor(10); // This should return false
293 | ```
294 |
295 | Some methods or functions take in functors, which forces you to define these. But it can get a little messy, but luckily with lambdas there is a better way!
296 |
297 | #### **Lambda Syntax**
298 |
299 | ```c++
300 | // This is the barebones lambda expression
301 | []() {}
302 |
303 | // Whereas this is the full one
304 | []() mutable -> T { }
305 |
306 | // Example
307 | auto lambda = []() { cout << "Rawr" << endl; };
308 | lambda(); // This prints Rawr
309 | ```
310 |
311 | Where:
312 |
313 | - `[ ]` is the capture list
314 | - `( )` is the argument list
315 | - `{ }` is the function body
316 |
317 | #### **Capture List**
318 |
319 | The capture list allows for the capture of variables (by reference or value) outside the actual lambda, and which are not passed in to the function that is defined!
320 |
321 | ```c++
322 | // Capture nothing
323 | []
324 |
325 | // Capture by value
326 | [some_referenced_value]
327 |
328 | // Capture by reference
329 | [&some_referenced_value]
330 |
331 | // Capture all variables in scope by value
332 | [=]
333 |
334 | // Capture all variables in scope by value, but some by reference
335 | [=, &but_me_by_reference, &me_too]
336 |
337 | // Capture all variables in scope by reference
338 | [&]
339 |
340 | // Capture all variables in scope by reference, but some by value
341 | [&, but_me_by_value, me_too]
342 |
343 | // Capture the surrounding object
344 | [this]
345 | ```
346 |
347 | #### **Argument List and Function Body**
348 |
349 | Argument lists work exactly like standard C++ function argument lists. They define what variables are passed into the actual function body of the lambda.
350 |
351 | Same thing for the function body.
352 |
353 | #### **Return Type**
354 |
355 | Specify the return type of the lambda by using the `->` operator.
356 |
357 | You normally can omit this if there is only one return statement, since it's implicitly inferred. But if not, leave it in.
358 |
359 | ```c++
360 | // So we can see that this lambda returns an int
361 | []() -> int {}
362 | ```
363 |
364 | #### **Mutable**
365 |
366 | If a lambda is marked `mutable`, it is able to mutate the values that are passed in by value.
367 |
368 | #### **Putting Some Of It Together**
369 |
370 | ```c++
371 | auto upperBound = 42;
372 | [upperBound](int value) -> bool {
373 | return 0 < value && value < upperBound;
374 | }
375 | ```
376 |
377 | #### **Example Lambda Usage**
378 |
379 | A particularly good usage of lambdas is in iteration.
380 |
381 | ```c++
382 | #include
383 | #include
384 | #include
385 |
386 | vector numbers {1, 2, 3, 4, 5, 6, 7, 8, 9, 10};
387 |
388 | for_each(numbers.begin(),
389 | numbers.end(),
390 | [] (int y)
391 | {
392 | cout << y << endl;
393 | });
394 | ```
395 |
396 | Here's another example. Here we define the lambda and immediately use it.
397 |
398 | ```c++
399 | int x = 4;
400 | auto y = [&r = x, x = x+1]()->int {
401 | r += 2;
402 | return x+2;
403 | }(); // Updates x to 6, and initializes y to 7.
404 | ```
405 |
406 | ### 2.6 Inline Functions
407 |
408 | Inline functions help to avoid the overhead of function calls. When you compile the code, the entire call to an inline function is instead replaced with the code inside the function call itself.
409 |
410 | They're especially good if used on small functions (usually one-liner function bodies.)
411 |
412 | In order to define an inline function, just write `inline` in front of your function definition.
413 |
414 | ```c++
415 | // Source https://www.geeksforgeeks.org/inline-functions-cpp/
416 |
417 | #include
418 | using namespace std;
419 | inline int cube(int s)
420 | {
421 | return s*s*s;
422 | }
423 | int main()
424 | {
425 | cout << "The cube of 3 is: " << cube(3) << "\n";
426 | return 0;
427 | } //Output: The cube of 3 is: 27
428 |
429 | // The inline function makes the function call line equivalent to
430 | cout << "The cube of 3 is: " << 3 * 3 * 3 << "\n";
431 | ```
432 |
433 | > Note, all functions defined inside a class body are inline functions. If you need the function to be explicitly inline, define the function prototype in the class, then declare the actual function definition outside the class with an inline.
434 |
435 | ```c++
436 | // Source: https://www.geeksforgeeks.org/inline-functions-cpp/
437 |
438 | class S
439 | {
440 | public:
441 | int square(int s); // declare the function
442 | };
443 |
444 | inline int S::square(int s) // use inline prefix
445 | {
446 |
447 | }
448 | ```
449 |
450 | ```
451 | . .
452 | . |\-^-/| .
453 | /| } O.=.O { |\
454 | ```
455 |
456 |
457 |
458 | ---
459 |
460 | [.png)](https://www.buymeacoffee.com/methylDragon)
461 |
--------------------------------------------------------------------------------
/C++/09 C++ - Tips and Tricks.md:
--------------------------------------------------------------------------------
1 | # C++ Tips and Tricks
2 |
3 | Author: methylDragon
4 | Let's go!! Pro-tip time!
5 | I'll be adapting it from The Happie Cat's "Top 10 Things I Wish I Had Known When Learning C++": https://www.youtube.com/watch?v=9zgAcSEmwNo (The original video got removed :( )
6 |
7 | ------
8 |
9 | ## Pre-Requisites
10 |
11 | **Assumed knowledge (This is a C++ crash course, not a basic coding tutorial)**
12 |
13 | - How **variables, loops, conditionals, etc**. work (Basic coding fundamentals will help a lot!)
14 | - Linux (**Terminal/Console proficiency**) (We're going to need to compile our stuff)
15 | - Gone through the all preceding parts of the tutorial
16 |
17 |
18 |
19 | ## Table Of Contents
20 |
21 | 1. [Introduction](#1)
22 | 2. [Tips and Tricks](#2)
23 | 2.1 [C++ is NOT C](#2.1)
24 | 2.2 [C++ is just moving memory around](#2.2)
25 | 2.3 [Plan your code before your write it](#2.3)
26 | 2.4 [The Rubber Ducky Method](#2.4)
27 | 2.5 [Organise your code](#2.5)
28 | 2.6 [Pointer Arithmetic](#2.6)
29 | 2.7 [Use const and scoping](#2.7)
30 | 2.8 [Header Guards](#2.8)
31 | 2.9 [Try using a UNIX platform](#2.9)
32 | 2.10 [Effective C++](#2.10)
33 |
34 |
35 |
36 | ## 1. Introduction
37 |
38 | Alright! Now let's deal with some issues that might pop up or random problems you might come across (that are due to C++'s quirks instead of your own user errors) and spend waaaaay too long solving!
39 |
40 |
41 |
42 | ## 2. Tips and Tricks
43 |
44 | ### 2.1 C++ is NOT C
45 |
46 | [go to top](#top)
47 |
48 | It might have been very closely related in the past, but they're more or less very different now. C++ has extra stuff like references, and virtual functions, whereas C does not.
49 |
50 | Don't make yourself look dumb!
51 |
52 |
53 |
54 | ### 2.2 C++ is just moving memory around
55 |
56 | [go to top](#top)
57 |
58 | If C++ is too hard to get your head around, go look up a tutorial on computer architecture! (Binary, to Assembly, opcodes, and the like.) If you want a game to play to learn it, I recommend **Human Resource Machine**.
59 |
60 |
61 |
62 | ### 2.3 Plan your code before you write it
63 |
64 | [go to top ](#top)
65 |
66 | Go old school, with pen and paper. Draw your program-flow charts and what you intend the program to do BEFORE actually getting to writing it!
67 |
68 | It'll help you debug faster, and help you actually make sure you implement everything you wanted to to begin with.
69 |
70 |
71 |
72 | ### 2.4 The Rubber Ducky Method
73 |
74 | [go to top](#top)
75 |
76 | So it turns out there's a secret weapon in the programmer's arsenal for whenever they encounter a horrific bug.
77 |
78 | Get a small toy, or a friend. AND EXPAIN YOUR CODE TO THEM. Or maybe explain your problem to them, framing it as a question. Sometimes flaws in your logic suddenly become obvious. Woo.
79 |
80 |
81 |
82 | ### 2.5 Organise your code
83 |
84 | [go to top](#top)
85 |
86 | - Classes should do ONE THING (Chessboards shouldn't have methods for every single chess-PIECE)
87 | - Functions should be 25 lines OR LESS. Makes it easier to debug. If they're longer, split it up.
88 | - COMMENT YOUR CODE. You and your peers will thank me in a couple years' time. It's very easy to forget what you wanted to do a couple of weeks or months after leaving or finishing a project. Comments help a lot.
89 |
90 |
91 |
92 | ### 2.6 Pointer Arithmetic
93 |
94 | [go to top](#top)
95 |
96 | POP QUIZ. If you don't understand what's going on here... get a refresher, and check out the pointer section.
97 |
98 | Pointers are arguably the most important part of C++!
99 |
100 | ```c++
101 | int x = 3;
102 | int* y = 4;
103 | *y = 2;
104 | y = &x;
105 | ```
106 |
107 |
108 |
109 | ### 2.7 Use const and scoping
110 |
111 | [go to top](#top)
112 |
113 | Use them to protect your variables even if it seems like it doesn't matter!!
114 |
115 | const is a keyword! Make variables that are supposed to be constant IMMUTABLE!
116 |
117 | Example of scoping:
118 |
119 | ```c++
120 | blah(){ // THE BRACKETS ARE THE SCOPE. They prevent naming conflicts by keeping them LOCAL
121 | // stuff
122 | }
123 | ```
124 |
125 |
126 |
127 | ### 2.8 Header Guards
128 |
129 | [go to top](#top)
130 |
131 | > Beware the difference between #define and #include !
132 | >
133 | > \#define tells the compiler that you're defining something
134 | >
135 | > YOU MUST INCLUDE IT TO USE HEADER GUARDS!
136 | >
137 | > \#include includes the stuff... pretty self-explanatory
138 |
139 | Code examples from: http://faculty.cs.niu.edu/~mcmahon/CS241/c241man/node90.html
140 |
141 | `#ifdef` and `#ifndef` are conditional compilation macros used in C++
142 |
143 | Basically, they allow you to ask C++ to ignore certain parts of code IF a particular name, or keyword has been, or has not been defined.
144 |
145 | ```c++
146 | #ifdef myIdentifier
147 | // Compile this if myIdentifier is defined
148 | #else
149 | // Otherwise compile this
150 | #endif // Otherwise it'll just skip it
151 | ```
152 |
153 | Why is this useful? Let's get the example from the link I pasted.
154 |
155 | Two classes and their header files are shown below:
156 |
157 | ```c++
158 | #include "A.h" #include "A.h"
159 | class A class B #include "B.h"
160 | { {
161 | int x; A a;
162 | public: int y; A a;
163 | }; public: B b;
164 | };
165 |
166 |
167 | A.h B.h htest.cc
168 | ```
169 |
170 | ```c++
171 | // Running it gives errors!
172 |
173 | /* ERRORS:
174 | In file included from B.h:1,
175 | from htest.cc:2:
176 | A.h:2: error: redefinition of `class A'
177 | A.h:2: error: previous definition of `class A'
178 | */
179 |
180 | // Because #include "A.h" was defined twice
181 | ```
182 |
183 | We could either solve this problem by manually removing the double inclusion, but that might break certain file relations (for example, if B is no longer initialised, then htest.cc will throw up an error because the identifier for class A didn't get defined.)
184 |
185 | You can see here then, that conditional compilation using the header guards `#ifndef` and `#enddef` will be perfect for this, more or less! That way, you can include the `#include` lines but without having to worry about repeats!
186 |
187 | Using the example above, the files become:
188 |
189 | ```c++
190 | #ifndef A_H #ifndef B_H
191 | #define A_H #define B_H
192 |
193 | #include "A.h" #include "A.h"
194 | class A class B #include "B.h"
195 | { {
196 | int x; A a;
197 | public: int y; A a;
198 | }; public: B b;
199 | };
200 |
201 | #endif /* A_H */ #endif /* B_H */
202 |
203 | A.h B.h htest.cc
204 | ```
205 |
206 |
207 |
208 | ### 2.9 Try using a UNIX platform
209 |
210 | [go to top](#top)
211 |
212 | Instead of using fancy tools! Start from a simpler tool first to get better acquainted with C++
213 |
214 |
215 |
216 | ### 2.10 Effective C++
217 |
218 | [go to top](#top)
219 |
220 | ^^^^^^^^^^^^^^^^^^ This book is nice.
221 |
222 |
223 |
224 | ```
225 | . .
226 | . |\-^-/| .
227 | /| } O.=.O { |\
228 | ```
229 |
230 |
231 |
232 | ---
233 |
234 | [.png)](https://www.buymeacoffee.com/methylDragon)
--------------------------------------------------------------------------------
/C++/Bonus Notes/BONUS C++ - Headers.md:
--------------------------------------------------------------------------------
1 | # C++ Headers
2 |
3 | Author: methylDragon
4 | Header files!
5 | Information source: http://www.cplusplus.com/articles/Gw6AC542/
6 |
7 | ------
8 |
9 | ## Pre-Requisites
10 |
11 | ### Assumed knowledge (This is a C++ crash course, not a basic coding tutorial)
12 |
13 | - How **variables, loops, conditionals, etc**. work (Basic coding fundamentals will help a lot!)
14 | - Linux (**Terminal/Console proficiency**) (We're going to need to compile our stuff)
15 | - Gone through the all preceding parts of the tutorial
16 |
17 |
18 |
19 | ## Table Of Contents
20 |
21 | 1. [Introduction](#1)
22 | 2. [Header Files](#2)
23 | 2.1 [Introduction](#2.1)
24 | 2.2 [Header Files](#2.2)
25 | 2.3 [Header Guards](#2.3)
26 | 2.4 [Tips on #Including](#2.4)
27 | 2.5 [Inline Functions](#2.5)
28 |
29 |
30 |
31 | ## 1. Introduction
32 |
33 | So sometimes you see .hpp or .h files appearing instead of .cpp in other people's source code. Those are header files! Ever wondered what they were for?
34 |
35 | >If you're just starting out in C++, you might be wondering why you need to #include files and why you would want to have multiple .cpp files for a program. The reasons for this are simple:
36 | >
37 | >**(1)** It speeds up compile time. As your program grows, so does your code, and if everything is in a single file, then everything must be fully recompiled every time you make any little change. This might not seem like a big deal for small programs (and it isn't), but when you have a project of reasonable size, compile times can take *several minutes* to compile the entire program. Can you imagine having to wait that long between every minor change?
38 | >
39 | >Compile / wait 8 minutes / "oh crap, forgot a semicolon" / compile / wait 8 minutes / debug / compile / wait 8 minutes / etc
40 | >
41 | >**(2)** It keeps your code more organized. If you seperate concepts into specific files, it's easier to find the code you are looking for when you want to make modifications (or just look at it to remember how to use it and/or how it works).
42 | >
43 | >**(3)** It allows you to separate *interface* from *implementation*. If you don't understand what that means, don't worry, we'll see it in action throughout this article.
44 | >
45 | >Source: http://www.cplusplus.com/articles/Gw6AC542/ (Why we need header files)
46 |
47 | The whole point of header files is to continue the tradition of avoiding as much instances of needing to copy-paste code as possible, since that leaves the door open for bugs and a much harsher time spent maintaining code.
48 |
49 | Bottom line is, you'll start seeing header files get more and more useful once you move beyond writing just a single .cpp file, and start writing multiple source files that talk to each other (which is far more efficient anyway...)
50 |
51 |
52 |
53 | ## 2. Header Files
54 |
55 | ### 2.1 Introduction
56 |
57 | [go to top](#top)
58 |
59 | So the thing about C++ is that it's a bit finicky at times because of how programs are compiled. What happens is each individual source file (.cpp file) is compiled alone, and THEN linked together by the compiler to form the final binary.
60 |
61 | This is problematic because the individual .cpp files don't know what's going on in the other .cpp files, so you can get import or declaration errors!
62 |
63 | Let's look at this example from http://www.cplusplus.com/articles/Gw6AC542/
64 |
65 | ```c++
66 | // in myclass.cpp
67 |
68 | class MyClass
69 | {
70 | public:
71 | void foo();
72 | int bar;
73 | };
74 |
75 | void MyClass::foo()
76 | {
77 | // do stuff
78 | }
79 | ```
80 |
81 | ```c++
82 | // in main.cpp
83 |
84 | int main()
85 | {
86 | MyClass a; // Compiler error: 'MyClass' is unidentified
87 | return 0;
88 | }
89 | ```
90 |
91 | Since MyClass was not defined in main.cpp, you'll get a compiler error even though you made provisions for it in myclass.cpp!
92 |
93 | How do we get around that? Funny you'd ask that...
94 |
95 |
96 |
97 | ### 2.2 Header Files
98 |
99 | [go to top](#top)
100 |
101 | Header files are used to make an **interface** separate from implementation. Think OOP PHP interfaces (check my tutorial for that.) This allows you to speed up compile time because you can just resettle the interface instead of redoing every source file.
102 |
103 | Again, the header files are the **interface** which allow other source files to **interact with the implementation** defined in the source (.cpp) files that are associated with their relevant header files.
104 |
105 | Here's the example from: http://www.cplusplus.com/articles/Gw6AC542/
106 |
107 | **The Header File Definition**
108 |
109 | ```c++
110 | // in myclass.h
111 |
112 | class MyClass
113 | {
114 | public:
115 | void foo();
116 | int bar;
117 | };
118 | ```
119 |
120 | You can now include it in the other source files using #include "myclass.h"! (#include works like a copy paste operation, whatever you wrote in myclass.h ends up getting copy-pasted in the spot.)
121 |
122 | Notice how the header file doesn't actually say what the data types or methods store, but just the names and types. This is how it is an interface, it's a box for the individual source files to fill.
123 |
124 | As such
125 |
126 | ```c++
127 | // in myclass.cpp
128 | #include "myclass.h"
129 |
130 | void MyClass::foo()
131 | {
132 | // some implementation
133 | }
134 | ```
135 |
136 | ```c++
137 | //in main.cpp
138 | #include "myclass.h" // defines MyClass
139 |
140 | int main()
141 | {
142 | MyClass a; // no longer produces an error, because MyClass is defined
143 | return 0;
144 | }
145 | ```
146 |
147 | Remember! Each individual .cpp is compiled independently, and then linked together. Including the header file in the main.cpp source file lets it play with the interface (so you've declared it and it's aware of it), but leaves the implementation to be done by the myclass.cpp source file, which will eventually get linked to main.cpp once the entire program is compiled.
148 |
149 |
150 |
151 | ### 2.3 Header Guards
152 |
153 | [go to top ](#top)
154 |
155 | Course, you might run into problems if you try to included stuff that's already been included. So use header guards!
156 |
157 | I already went through this in section 05 of this tutorial - Tips and Tricks
158 |
159 | Here's a refresher. Remember to use #define !
160 |
161 | ```c++
162 | #ifdef myIdentifier
163 | // Compile this if myIdentifier is defined
164 | // Put your #define and then the #include here!
165 | #else
166 | // Otherwise compile this
167 | #endif // Otherwise it'll just skip it
168 | ```
169 |
170 |
171 |
172 |
173 |
174 | ### 2.4 Tips on #Including
175 |
176 | [go to top](#top)
177 |
178 | This section I'm just taking wholesale from http://www.cplusplus.com/articles/Gw6AC542/ because it's handy enough...
179 |
180 | > There are two basic kinds of dependencies you need to be aware of:
181 | > 1) stuff that can be forward declared
182 | > 2) stuff that needs to be #included
183 | >
184 | > If, for example, class A uses class B, then class B is one of class A's dependencies. Whether it can be forward declared or needs to be included depends on how B is used within A:
185 | >
186 | > - **do nothing if:** A makes no references at all to B
187 | > - **do nothing if:** The only reference to B is in a friend declaration
188 | > - **forward declare B if:** A contains a B pointer or reference: B* myb;
189 | > - **forward declare B if:** one or more functions has a B object/pointer/referenceas a parementer, or as a return type: B MyFunction(B myb);
190 | > - **\#include "b.h" if:** B is a parent class of A
191 | > - **\#include "b.h" if:** A contains a B object: B myb;`
192 | >
193 | > You want to do the least drastic option possible. Do nothing if you can, but if you can't, forward declare if you can. But if it's necessary, then #include the other header.
194 | >
195 | > Ideally, the dependencies for the class should be layed out in the header. Here is a typical outline of how a "right way" header might look:
196 | >
197 | > **myclass.h**
198 | >
199 | > ```c++
200 | > //=================================
201 | > // include guard
202 | > #ifndef __MYCLASS_H_INCLUDED__
203 | > #define __MYCLASS_H_INCLUDED__
204 | >
205 | > //=================================
206 | > // forward declared dependencies
207 | > class Foo;
208 | > class Bar;
209 | >
210 | > //=================================
211 | > // included dependencies
212 | > #include
213 | > #include "parent.h"
214 | >
215 | > //=================================
216 | > // the actual class
217 | > class MyClass : public Parent // Parent object, so #include "parent.h"
218 | > {
219 | > public:
220 | > std::vector avector; // vector object, so #include
221 | > Foo* foo; // Foo pointer, so forward declare Foo
222 | > void Func(Bar& bar); // Bar reference, so forward declare Bar
223 | >
224 | > friend class MyFriend; // friend declaration is not a dependency
225 | > // don't do anything about MyFriend
226 | > };
227 | >
228 | > #endif // __MYCLASS_H_INCLUDED__
229 | > ```
230 | >
231 | > This shows the two different kinds of dependencies and how to handle them. Because MyClass only uses a pointer to Foo and not a full Foo object, we can forward declare Foo, and don't need to #include "foo.h". *You should always forward declare what you can -- don't #include unless it's necessary*. Unnecessary #includes can lead to trouble.
232 | >
233 | > If you stick to this system, you will bulletproof yourself, and will minimize #include related hazards.
234 |
235 | > The "right way" I illustrated above is all about encapsulation. Files that want to use MyClass don't need to be aware of what MyClass uses in order for it to work, and don't need to #include any MyClass dependencies. All you need to do to get MyClass to work is #include "myclass.h". Period. The header file is set up to be completely self contained. It's all very OO friendly, very easy to use, and very easy to maintain.
236 | >
237 | > Source: http://www.cplusplus.com/articles/Gw6AC542/
238 |
239 | ### 2.5 Inline Functions
240 |
241 | [go to top](#top)
242 |
243 | Next problem! If you have functions defined in source files that are meant to be used in other source files, you're going to have to copy paste the same function definition into every file that uses them!
244 |
245 | So it turns out you can just put function definitions inside your header as well since the #include of the header means the definitions get copied in. You do this by specifying the `inline` keyword, which tells C++ to use the definition wherever its called!
246 |
247 | And you do this by defining the functions OUTSIDE of any class definitions that you specified in the header file!
248 |
249 | Example:
250 |
251 | ```c++
252 | // b.h (assume its guarded)
253 |
254 | //------------------
255 | class A; // forward declared dependency
256 |
257 | //------------------
258 | class B
259 | {
260 | public:
261 | void Func(const A& a); // okay, A is forward declared
262 | };
263 |
264 | //------------------
265 | #include "a.h" // A is now an include dependency
266 |
267 | inline void B::Func(const A& a)
268 | {
269 | a.DoSomething(); // okay! a.h has been included
270 | }
271 | ```
272 |
273 | **Or if you don't like seeing function definitions at the end of a header file**, just write ANOTHER header file and stick it there!
274 |
275 | ```c++
276 | // b.h
277 |
278 | // blah blah
279 |
280 | class B { /* blah blah */ };
281 |
282 | #include "b_inline.h" // or I sometimes use "b.hpp"
283 | ```
284 |
285 | ```c++
286 | // b_inline.h (or b.hpp -- whatever)
287 |
288 | #include "a.h"
289 | #include "b.h" // not necessary, but harmless
290 | // you can do this to make this "feel" like a source
291 | // file, even though it isn't
292 |
293 | inline void B::Func(const A& a)
294 | {
295 | a.DoSomething();
296 | }
297 | ```
298 |
299 |
300 |
301 | ```
302 | . .
303 | . |\-^-/| .
304 | /| } O.=.O { |\
305 | ```
306 |
307 |
308 |
309 | ------
310 |
311 | [.png)](https://www.buymeacoffee.com/methylDragon)
--------------------------------------------------------------------------------
/C++/assets/1562761542554.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/methylDragon/coding-notes/b9dcabff04e0a29160728aeaaad18f1364067493/C++/assets/1562761542554.png
--------------------------------------------------------------------------------
/C++/assets/1562814980420.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/methylDragon/coding-notes/b9dcabff04e0a29160728aeaaad18f1364067493/C++/assets/1562814980420.png
--------------------------------------------------------------------------------
/C++/assets/1562934941151.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/methylDragon/coding-notes/b9dcabff04e0a29160728aeaaad18f1364067493/C++/assets/1562934941151.png
--------------------------------------------------------------------------------
/C++/assets/1562935061068.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/methylDragon/coding-notes/b9dcabff04e0a29160728aeaaad18f1364067493/C++/assets/1562935061068.png
--------------------------------------------------------------------------------
/C++/assets/192px-Binary_tree.svg.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/methylDragon/coding-notes/b9dcabff04e0a29160728aeaaad18f1364067493/C++/assets/192px-Binary_tree.svg.png
--------------------------------------------------------------------------------
/C++/assets/1_FH2BzH1l5D7C18Fd7U0JVQ.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/methylDragon/coding-notes/b9dcabff04e0a29160728aeaaad18f1364067493/C++/assets/1_FH2BzH1l5D7C18Fd7U0JVQ.png
--------------------------------------------------------------------------------
/C++/assets/C_Iterator.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/methylDragon/coding-notes/b9dcabff04e0a29160728aeaaad18f1364067493/C++/assets/C_Iterator.jpg
--------------------------------------------------------------------------------
/C++/assets/GCC_CompilationProcess.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/methylDragon/coding-notes/b9dcabff04e0a29160728aeaaad18f1364067493/C++/assets/GCC_CompilationProcess.png
--------------------------------------------------------------------------------
/C++/assets/Linkedlist.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/methylDragon/coding-notes/b9dcabff04e0a29160728aeaaad18f1364067493/C++/assets/Linkedlist.png
--------------------------------------------------------------------------------
/C++/assets/QullW.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/methylDragon/coding-notes/b9dcabff04e0a29160728aeaaad18f1364067493/C++/assets/QullW.png
--------------------------------------------------------------------------------
/C++/assets/Selection_101.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/methylDragon/coding-notes/b9dcabff04e0a29160728aeaaad18f1364067493/C++/assets/Selection_101.png
--------------------------------------------------------------------------------
/C++/assets/SharedMutable.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/methylDragon/coding-notes/b9dcabff04e0a29160728aeaaad18f1364067493/C++/assets/SharedMutable.png
--------------------------------------------------------------------------------
/C++/assets/ZWg39.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/methylDragon/coding-notes/b9dcabff04e0a29160728aeaaad18f1364067493/C++/assets/ZWg39.png
--------------------------------------------------------------------------------
/C++/assets/array.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/methylDragon/coding-notes/b9dcabff04e0a29160728aeaaad18f1364067493/C++/assets/array.png
--------------------------------------------------------------------------------
/C++/assets/compilation.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/methylDragon/coding-notes/b9dcabff04e0a29160728aeaaad18f1364067493/C++/assets/compilation.gif
--------------------------------------------------------------------------------
/C++/assets/concurrency_vs_parallelism-1562918749730.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/methylDragon/coding-notes/b9dcabff04e0a29160728aeaaad18f1364067493/C++/assets/concurrency_vs_parallelism-1562918749730.png
--------------------------------------------------------------------------------
/C++/assets/concurrency_vs_parallelism.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/methylDragon/coding-notes/b9dcabff04e0a29160728aeaaad18f1364067493/C++/assets/concurrency_vs_parallelism.png
--------------------------------------------------------------------------------
/C++/assets/copy.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/methylDragon/coding-notes/b9dcabff04e0a29160728aeaaad18f1364067493/C++/assets/copy.jpg
--------------------------------------------------------------------------------
/C++/assets/deadlock.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/methylDragon/coding-notes/b9dcabff04e0a29160728aeaaad18f1364067493/C++/assets/deadlock.png
--------------------------------------------------------------------------------
/C++/assets/giphy-1562828095877.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/methylDragon/coding-notes/b9dcabff04e0a29160728aeaaad18f1364067493/C++/assets/giphy-1562828095877.gif
--------------------------------------------------------------------------------
/C++/assets/giphy.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/methylDragon/coding-notes/b9dcabff04e0a29160728aeaaad18f1364067493/C++/assets/giphy.gif
--------------------------------------------------------------------------------
/C++/assets/main-qimg-0b429780923c55f6a803405694c5b7af.webp:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/methylDragon/coding-notes/b9dcabff04e0a29160728aeaaad18f1364067493/C++/assets/main-qimg-0b429780923c55f6a803405694c5b7af.webp
--------------------------------------------------------------------------------
/C++/assets/memory-management-in-cpp-2.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/methylDragon/coding-notes/b9dcabff04e0a29160728aeaaad18f1364067493/C++/assets/memory-management-in-cpp-2.png
--------------------------------------------------------------------------------
/C++/assets/memoryLayoutC.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/methylDragon/coding-notes/b9dcabff04e0a29160728aeaaad18f1364067493/C++/assets/memoryLayoutC.jpg
--------------------------------------------------------------------------------
/C++/assets/mindblow.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/methylDragon/coding-notes/b9dcabff04e0a29160728aeaaad18f1364067493/C++/assets/mindblow.gif
--------------------------------------------------------------------------------
/C++/assets/move.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/methylDragon/coding-notes/b9dcabff04e0a29160728aeaaad18f1364067493/C++/assets/move.jpg
--------------------------------------------------------------------------------
/C++/assets/pointers-in-c.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/methylDragon/coding-notes/b9dcabff04e0a29160728aeaaad18f1364067493/C++/assets/pointers-in-c.jpg
--------------------------------------------------------------------------------
/C++/assets/priority_queue.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/methylDragon/coding-notes/b9dcabff04e0a29160728aeaaad18f1364067493/C++/assets/priority_queue.png
--------------------------------------------------------------------------------
/C++/assets/promise.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/methylDragon/coding-notes/b9dcabff04e0a29160728aeaaad18f1364067493/C++/assets/promise.png
--------------------------------------------------------------------------------
/C++/assets/queue.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/methylDragon/coding-notes/b9dcabff04e0a29160728aeaaad18f1364067493/C++/assets/queue.png
--------------------------------------------------------------------------------
/C++/assets/selection.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/methylDragon/coding-notes/b9dcabff04e0a29160728aeaaad18f1364067493/C++/assets/selection.gif
--------------------------------------------------------------------------------
/C++/assets/sfinae_compiling.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/methylDragon/coding-notes/b9dcabff04e0a29160728aeaaad18f1364067493/C++/assets/sfinae_compiling.png
--------------------------------------------------------------------------------
/C++/assets/stack-1562909159143.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/methylDragon/coding-notes/b9dcabff04e0a29160728aeaaad18f1364067493/C++/assets/stack-1562909159143.jpg
--------------------------------------------------------------------------------
/C++/assets/stack.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/methylDragon/coding-notes/b9dcabff04e0a29160728aeaaad18f1364067493/C++/assets/stack.jpg
--------------------------------------------------------------------------------
/C++/assets/templates-cpp.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/methylDragon/coding-notes/b9dcabff04e0a29160728aeaaad18f1364067493/C++/assets/templates-cpp.jpg
--------------------------------------------------------------------------------
/C++/assets/threads-as-control-flow.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/methylDragon/coding-notes/b9dcabff04e0a29160728aeaaad18f1364067493/C++/assets/threads-as-control-flow.png
--------------------------------------------------------------------------------
/CMake/assets/1565761777925.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/methylDragon/coding-notes/b9dcabff04e0a29160728aeaaad18f1364067493/CMake/assets/1565761777925.png
--------------------------------------------------------------------------------
/CMake/assets/1565761892848.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/methylDragon/coding-notes/b9dcabff04e0a29160728aeaaad18f1364067493/CMake/assets/1565761892848.png
--------------------------------------------------------------------------------
/CMake/assets/1565763864160.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/methylDragon/coding-notes/b9dcabff04e0a29160728aeaaad18f1364067493/CMake/assets/1565763864160.png
--------------------------------------------------------------------------------
/CMake/assets/1565764747746.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/methylDragon/coding-notes/b9dcabff04e0a29160728aeaaad18f1364067493/CMake/assets/1565764747746.png
--------------------------------------------------------------------------------
/CMake/assets/1565764814617.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/methylDragon/coding-notes/b9dcabff04e0a29160728aeaaad18f1364067493/CMake/assets/1565764814617.png
--------------------------------------------------------------------------------
/CMake/assets/1565773573410.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/methylDragon/coding-notes/b9dcabff04e0a29160728aeaaad18f1364067493/CMake/assets/1565773573410.png
--------------------------------------------------------------------------------
/CMake/assets/1565773727787.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/methylDragon/coding-notes/b9dcabff04e0a29160728aeaaad18f1364067493/CMake/assets/1565773727787.png
--------------------------------------------------------------------------------
/CMake/assets/1565773781724.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/methylDragon/coding-notes/b9dcabff04e0a29160728aeaaad18f1364067493/CMake/assets/1565773781724.png
--------------------------------------------------------------------------------
/CMake/assets/1565775582248.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/methylDragon/coding-notes/b9dcabff04e0a29160728aeaaad18f1364067493/CMake/assets/1565775582248.png
--------------------------------------------------------------------------------
/CMake/assets/1565847804604.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/methylDragon/coding-notes/b9dcabff04e0a29160728aeaaad18f1364067493/CMake/assets/1565847804604.png
--------------------------------------------------------------------------------
/CMake/assets/1565855200577.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/methylDragon/coding-notes/b9dcabff04e0a29160728aeaaad18f1364067493/CMake/assets/1565855200577.png
--------------------------------------------------------------------------------
/CMake/assets/1566144489572.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/methylDragon/coding-notes/b9dcabff04e0a29160728aeaaad18f1364067493/CMake/assets/1566144489572.png
--------------------------------------------------------------------------------
/CMake/assets/1566146742207.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/methylDragon/coding-notes/b9dcabff04e0a29160728aeaaad18f1364067493/CMake/assets/1566146742207.png
--------------------------------------------------------------------------------
/CMake/assets/1566149145967.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/methylDragon/coding-notes/b9dcabff04e0a29160728aeaaad18f1364067493/CMake/assets/1566149145967.png
--------------------------------------------------------------------------------
/CMake/assets/cmake-simpler-flowchart.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/methylDragon/coding-notes/b9dcabff04e0a29160728aeaaad18f1364067493/CMake/assets/cmake-simpler-flowchart.png
--------------------------------------------------------------------------------
/CMake/assets/cmake-variable-scopes.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/methylDragon/coding-notes/b9dcabff04e0a29160728aeaaad18f1364067493/CMake/assets/cmake-variable-scopes.png
--------------------------------------------------------------------------------
/CMake/assets/compilation.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/methylDragon/coding-notes/b9dcabff04e0a29160728aeaaad18f1364067493/CMake/assets/compilation.gif
--------------------------------------------------------------------------------
/CMake/assets/ezgif-3-92cffd6c4e0f.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/methylDragon/coding-notes/b9dcabff04e0a29160728aeaaad18f1364067493/CMake/assets/ezgif-3-92cffd6c4e0f.gif
--------------------------------------------------------------------------------
/DDS/OpenSplice DDS (C++ API)/01 DDS - Introduction.md:
--------------------------------------------------------------------------------
1 | # OpenSplice DDS Crash Course
2 |
3 | Author: methylDragon
4 | Let's get acquainted with DDS, fast!
5 | Compiling my notes from a whole variety of sources (mainly https://www.slideshare.net/Angelo.Corsaro/getting-started-with-dds-in-c-java-and-scala and http://download.prismtech.com/docs/Vortex/pdfs/OpenSplice_DDSTutorial.pdf)
6 |
7 | ------
8 |
9 | ## Pre-Requisites
10 |
11 | ### Assumed knowledge
12 |
13 | - C++! We're using the C++ API for OpenSplice DDS. Read my C++ tutorial! It's only 5 parts long, and you really only need like the first three, well four parts...
14 | - Install OpenSplice DDS: https://github.com/grassjelly/opensplice-install
15 |
16 |
17 |
18 | ## Table Of Contents
19 |
20 | 1. [Introduction](#1)
21 | 2. [OpenSplice DDS In A Nutshell](#2)
22 | 2.1 [Architecture](#2.1)
23 | 2.2 [Domain Participants](#2.2)
24 | 2.3 [Topics](#2.3)
25 | 2.4 [A Basic DDS Application](#2.4)
26 | 2.5 [Reading and Writing Data (Alternate Example)](#2.5)
27 |
28 |
29 |
30 |
31 | ## 1. Introduction
32 |
33 | So what's DDS exactly?
34 |
35 | DDS stands for **Data Distribution Service** (for real-time systems.) DDS is used very widely nowadays, with applications in Defense and Aerospace, Commercial sectors, etc. And is recommended by key administration worldwide!
36 |
37 | So think **ROS** and Publisher/Subscribers as opposed to monolithic server-client architectures like stuff using the LAMP stack (the standard web service stuff.) This allows for more fault resilient network architectures that support decentralisation and decoupling (both spatially and temporally) of processing and data instead of hard-coded relations like in the standard server-client model.
38 |
39 | **OpenSplice DDS** is one of the implementations of the OMG (Object Management Group) DDS standards. It offers Pub/Sub functionality as well as Quality Of Service (QoS) parameters that you can choose (i.e. choosing metaparameters for you data like data longevity, transience, timeliness, etc.)
40 |
41 | OpenSplice DDS can be implemented using the Scala programming language, but it has an interface that uses C++, which is what we're going to be using.
42 |
43 | > To the question ‘What is DDS?’ one answer is:
44 | > **It is a Pub/Sub technology for ubiquitous, polyglot, efficient and secure data sharing.**
45 | >
46 | > Another way of answering this question is to say that:
47 | > **DDS is Pub/Sub on steroids.**
48 |
49 |
50 |
51 | ## 2. OpenSplice DDS In A Nutshell
52 |
53 | This is the short version to get started real quick! We'll do more elaborations in a later section.
54 |
55 |
56 |
57 | ### 2.1 Architecture
58 |
59 | [go to top](#top)
60 |
61 | I mentioned before DDS is based off of pub-sub architecture.
62 |
63 | But specifically, it's a form of Topic-Based Pub-Sub abstraction that includes
64 |
65 | - Topics: The subject of data distribution (think ROS!)
66 | - DataWriters: The writers/producers of data
67 | - DataReaders: The consumers of data
68 |
69 | DDS matches DataWriters and DataReaders automatically using its Dynamic Discovery service, and the behaviour of the system allows for tweaking of QoS parameters.
70 |
71 | Publishers and Subscribers are free to join or leave the cloud (called the Global Data Space (GDS)) anytime they want, since they're dynamically discovered (or locally defined.)
72 |
73 | Additionally, the GDS is, unlike in ROS, decentralised, so there's literally no single point of failure, even with individual applications crashing. The system as a whole will carry on.
74 |
75 |
76 |
77 | ### 2.2 Domain Participants
78 |
79 | [go to top](#top)
80 |
81 | **Domain Participants** grant you access to the **Global Data Space** (GDS) also called the **domain** in DDS.
82 |
83 | Domain IDs are defined by **integers**
84 |
85 | ```c++
86 | // create a Domain Participant, -1 defaults to value defined in configuration file
87 | dds::domain::DomainParticipant dp(-1);
88 | ```
89 |
90 |
91 |
92 | ### 2.3 Topics
93 |
94 | [go to top](#top)
95 |
96 | Topics in DDS define **classes of streams**
97 |
98 | They have the following properties:
99 |
100 | - Unique Name
101 | - Type (user-defined)
102 | - QoS Policies
103 |
104 | Example topic definition (**this should go in a header file!**):
105 |
106 | ```c++
107 | // C++ refresher: Structs are like classes, but the elements are public by default
108 | // People tend to use Structs to just store plain-old-data types (POD) as opposed to methods
109 |
110 | struct ShapeType{
111 | // (Here we're defining color as the topic key! It should preferably be an ID number though)
112 | string color; //@key
113 | long x;
114 | long y;
115 | long shapesize;
116 | };
117 | ```
118 |
119 | #### **Creating a topic**
120 |
121 | ```c++
122 | // Create a topic (we're creating one with the name Circle now)
123 | // Yes you need the < >
124 | dds::topic::Topic topic(dp, "Circle");
125 | ```
126 |
127 |
128 |
129 | The keys of the topic, defines a unique **stream** or instance of data, which is dealt with by DDS (including lifecycle information as per QoS)
130 |
131 | Each DataWriter can write multiple instances/streams of data.
132 |
133 |
134 |
135 | ### 2.4 A Basic DDS Application
136 |
137 | [go to top](#top)
138 |
139 | Every DDS application should include the following things:
140 |
141 | - Domain Participant
142 | - Topic
143 | - Publishers and Subscribers
144 | - DataWriters and DataReaders
145 |
146 | Remember that **DataWriters** and **DataReaders** write and consume data, but you need **Publishers** and **Subscribers** to push and fetch data that's being produced! And all from **topics**! Under a **domain**!
147 |
148 | Here's a example from: http://download.prismtech.com/docs/Vortex/pdfs/OpenSplice_DDSTutorial.pdf
149 |
150 | #### **Let's make a topic first**
151 |
152 | ```c++
153 | // TempControl.idl
154 | enum TemperatureScale {
155 | CELSIUS,
156 | FAHRENHEIT,
157 | KELVIN
158 | };
159 |
160 | struct TempSensorType {
161 | short id;
162 | float temp;
163 | float hum;
164 | TemperatureScale scale;
165 | };
166 |
167 | #pragma keylist TempSensorType id
168 | ```
169 |
170 | #### **Writing Data in DDS**
171 |
172 | Now we can make our Domain Participants, Topics, Publishers, and Data Writers!
173 |
174 | ```c++
175 | // create a Domain Participant, -1 defaults to value defined in configuration file
176 | // Note: this is equivalent to
177 | // auto dp = dds::domain::DomainParticipant(-1)
178 | dds::domain::DomainParticipant dp(-1);
179 |
180 | // Create the topic
181 | // Same with the dp, this is like topic =
182 | dds::topic::Topic topic(dp, "TTempSensor");
183 |
184 | // Create the Publisher and DataWriter
185 | // So on and so forth.. pub = and dw =
186 | dds::pub::Publisher pub(dp);
187 | dds::pub::DataWriter dw(pub, topic);
188 |
189 | // Write the data
190 | tutorial::TempSensorType sensor(1, 26.0F, 70.0F, tutorial::CELSIUS);
191 | dw.write(sensor);
192 |
193 | // Write data using streaming operators (same as calling dw.write(...))
194 | dw << tutorial::TempSensorType(2, 26.5F, 74.0F, tutorial::CELSIUS);
195 | ```
196 |
197 | #### **Reading Data in DDS**
198 |
199 | ```c++
200 | // create a Domain Participant, -1 defaults to value defined in configuration file
201 | dds::domain::DomainParticipant dp(-1);
202 |
203 | // create the Topic
204 | dds::topic::Topic topic(dp, "TTempSensor");
205 |
206 | // create a Subscriber
207 | dds::sub::Subscriber sub(dp);
208 |
209 | // create a DataReader
210 | dds::sub::DataReader dr(sub, topic);
211 |
212 | // keep outputting anything read
213 | while (true) {
214 | auto samples = dr.read();
215 |
216 | std::for_each(samples.begin(), samples.end(), [](const dds::sub::Sample& s) {
217 | std::cout << s.data() << std::endl;
218 | });
219 |
220 | std::this_thread::sleep_for(std::chrono::seconds(1));
221 | }
222 | ```
223 |
224 | You might be wondering what's up with the std::chrono seconds() call. Basically, the .read() function reads immediately (it is non-blocking, google that.)
225 |
226 | So we're intentionally introducing a delay to make sure we don't spin the loop too quickly.
227 |
228 | Other than read (polling), there are also two other ways to inform the application that data is available though:
229 |
230 | - Polling
231 | - Listeners
232 | - Think of it like an eventHandler in JS. They can be registered with readers for receiving notifications of available data, status changes, and QoS related stuff
233 | - Waitsets
234 | - Wait for specified events to occur, then trigger a callback
235 |
236 |
237 |
238 | Anyway, notice how the DataReader and DataWriters aren't coupled. How do they find each other? DDS did it for you!
239 |
240 | > Noticed how we used dr.read() to read the data?
241 | >
242 | > There's actually another method called .take() that does the same thing, except it deletes it from the local cache so other readers can't access it. Gasp.
243 |
244 |
245 |
246 | ### 2.5 Reading and Writing Data (Alternate Example)
247 |
248 | [go to top](#top)
249 |
250 | Alternative Code examples from: https://www.slideshare.net/Angelo.Corsaro/getting-started-with-dds-in-c-java-and-scala
251 |
252 | ```c++
253 | // Example DDS application declaration
254 |
255 | // Specify the domain
256 | // Remember that the domain ID is an INTEGER!
257 | auto dp = DomainParticipant(domainId);
258 |
259 | // Create a topic
260 | // Yes, again you need the < >
261 | auto topic = Topic(dp, "Circle");
262 |
263 | // Create a Publisher and Subscriber
264 | auto pub = Publisher(dp);
265 | auto sub = Subscriber(dp);
266 |
267 | // Create a DataWriter and DataReader
268 | auto writer = DatWriter(pub, topic);
269 | auto reader = DataReader(sub, topic);
270 | ```
271 |
272 | Now we can write and read some data!
273 |
274 | ```c++
275 | // Write Data
276 | writer.write(ShapeType("RED", 131, 107, 89));
277 | // Alternate write statement
278 | writer << ShapeType("RED", 131, 107, 89);
279 |
280 | // Read new data
281 | auto data = reader.read();
282 | ```
283 |
284 | > Note:
285 | >
286 | > Again, depending on your namespaces, you might have to use
287 | >
288 | > `dds::domain::` : When declaring domains
289 | >
290 | > `dds::topic::`: When declaring topics
291 | >
292 | > `dds::pub::` : When declaring publishers and DataWriters
293 | >
294 | > `dds::sub::` : When declaring subscribers and DataReaders
295 |
296 |
297 |
298 | ```
299 | . .
300 | . |\-^-/| .
301 | /| } O.=.O { |\
302 | ```
303 |
304 |
305 |
306 | ------
307 |
308 | [.png)](https://www.buymeacoffee.com/methylDragon)
--------------------------------------------------------------------------------
/DDS/OpenSplice DDS (C++ API)/02 DDS - Writing Nodes Practically.md:
--------------------------------------------------------------------------------
1 | # OpenSplice DDS Crash Course
2 |
3 | Author: methylDragon
4 | Let's get acquainted with DDS, fast!
5 | Compiling my notes from a whole variety of sources (mainly https://www.slideshare.net/Angelo.Corsaro/getting-started-with-dds-in-c-java-and-scala and http://download.prismtech.com/docs/Vortex/pdfs/OpenSplice_DDSTutorial.pdf)
6 |
7 | ------
8 |
9 | ## Pre-Requisites
10 |
11 | ### Assumed knowledge
12 |
13 | - C++! We're using the C++ API for OpenSplice DDS. Read my C++ tutorial! It's only 5 parts long, and you really only need like the first three, well four parts...
14 | - Install OpenSplice DDS: https://github.com/grassjelly/opensplice-install
15 |
16 |
17 |
18 | ## Table Of Contents
19 |
20 | 1. [Introduction](#1)
21 | 2. [Writing OpenSplice DDS Nodes](#2)
22 | 2.1 [Minimal Version (Not Recommended)](#2.1)
23 | 2.2 [Abstracted Version (Recommended)](#2.2)
24 |
25 |
26 |
27 |
28 | ## 1. Introduction
29 |
30 | So you roughly get what's going on with DDS now. Let's actually get to writing nodes effectively and efficiently!
31 |
32 | We're going to be using custom message types as well!
33 |
34 |
35 |
36 | ## 2. Writing OpenSplice DDS Nodes
37 |
38 | ### 2.1 Minimal Version (Not Recommended)
39 |
40 | [go to top](#top)
41 |
42 | Let's base this off of a pre-existing codebase: https://github.com/grassjelly/opensplice_minimal
43 |
44 | You'll find the simplest starter-code version of the project in the resources folder. I've edited out extrenuous information and added to the README.md. **You may use the README.md in the package for further guidance.**
45 |
46 | It is important to note that just this minimal version already abstracts a bit of important DDS configurations and commands, exposing them as methods for CheckStatus and DDSEntityManager (in the src folder.) Things like memory freeing and a bit of optimisation.
47 |
48 | However, I **strongly recommend** that you use the [abstracted version](#2.2) of this tutorial so you avoid most of the boilerplate code.
49 |
50 | To use it, follow the following steps:
51 |
52 | 1. Edit the idl file in the idl folder. (You can call it anything you want.)
53 |
54 | - Define the message types you'd like to use in the form of structs and modules
55 |
56 | - You MAY define multiple message types in that single idl file!
57 |
58 | - Modules will define namespaces (optional)
59 |
60 | - Structs will define the message type name, and the contents will be the contents of the message
61 |
62 | ```idl
63 | module HelloWorld
64 | {
65 | struct Msg
66 | {
67 | /** User ID */
68 | long userID;
69 | /** message */
70 | string message;
71 | };
72 | #pragma keylist Msg userID
73 | };
74 |
75 | struct standaloneMsg
76 | {
77 | /** User ID */
78 | long userID;
79 | /** message */
80 | string message;
81 | };
82 | #pragma keylist standaloneMsg userID
83 | ```
84 |
85 | 2. Generate the message headers using `./gencode` (Remember to source your Opensplice DDS directory!!)
86 |
87 | 3. Edit your src code
88 |
89 | - Leave DDSEntityManager and CheckStatus **ALONE**
90 | - You will need to leave the boilerplate code in (like create participant, type creation, etc.)
91 | - Be sure to include your message headers that were generated! (In this case it was ccpp_HelloWorld.h), but it'll actually be ccpp_.h)
92 |
93 | ```c++
94 | // -- Std C/C++ Include
95 | #include
96 | #include
97 | #include
98 |
99 | #include "ccpp_HelloWorld.h"
100 | #include // std::thread, std::this_thread::sleep_for
101 | #include
102 | #include "DDSEntityManager.h"
103 |
104 | using namespace DDS;
105 | using namespace HelloWorld;
106 |
107 | int main(int argc, char* argv[])
108 | {
109 | os_time delay_1s = { 1, 0 };
110 | DDSEntityManager mgr;
111 |
112 | // create domain participant
113 | mgr.createParticipant("HelloWorld example");
114 |
115 | //create type
116 | MsgTypeSupport_var mt = new MsgTypeSupport();
117 | mgr.registerType(mt.in());
118 |
119 | //create Topic
120 | char topic_name[] = "HelloWorldData_Msg";
121 | mgr.createTopic(topic_name);
122 |
123 | //create Publisher
124 | mgr.createPublisher();
125 |
126 | // create DataWriter :
127 | // If autodispose_unregistered_instances is set to true (default value),
128 | // you will have to start the subscriber before the publisher
129 | bool autodispose_unregistered_instances = false;
130 | mgr.createWriter(autodispose_unregistered_instances);
131 |
132 | // Publish Events
133 | DataWriter_var dwriter = mgr.getWriter();
134 | MsgDataWriter_var HelloWorldWriter = MsgDataWriter::_narrow(dwriter.in());
135 |
136 | Msg msgInstance; /* Example on Stack */
137 | msgInstance.userID = 1;
138 | msgInstance.message = DDS::string_dup("Hello World");
139 | cout << "=== [Publisher] writing a message containing :" << endl;
140 | cout << " userID : " << msgInstance.userID << endl;
141 | cout << " Message : \"" << msgInstance.message << "\"" << endl;
142 |
143 | ReturnCode_t status = HelloWorldWriter->write(msgInstance, DDS::HANDLE_NIL);
144 | checkStatus(status, "MsgDataWriter::write");
145 | os_nanoSleep(delay_1s);
146 |
147 | /* Remove the DataWriters */
148 | mgr.deleteWriter();
149 |
150 | /* Remove the Publisher. */
151 | mgr.deletePublisher();
152 |
153 | /* Remove the Topics. */
154 | mgr.deleteTopic();
155 |
156 | /* Remove Participant. */
157 | mgr.deleteParticipant();
158 |
159 | return 0;
160 | }
161 | ```
162 |
163 | 4. Edit the CMakeLists.txt file
164 |
165 | - Specifically changing the name of the included .cpp files for the messages
166 |
167 | ```cmake
168 | ADD_LIBRARY(GEN_SRC
169 | gen/.cpp
170 | gen/Dcps.cpp
171 | gen/Dcps_impl.cpp
172 | gen/SplDcps.cpp
173 | )
174 | ```
175 |
176 | - Also remember to add in the executables to be compiled! So for example, if you had an executable called pub, then add in these lines.
177 |
178 | ```cmake
179 | ADD_EXECUTABLE (pub
180 | src/pub.cpp
181 | )
182 |
183 | TARGET_LINK_LIBRARIES (pub
184 | GEN_SRC
185 | MGR_SRC
186 | ${OpenSplice_LIBRARIES}
187 | )
188 | ```
189 |
190 | 5. Run `./compile` to compile the code.
191 |
192 | 6. Then you can go try out the executables by executing them from the build directory
193 |
194 | - Again, remember to source your Opensplice DDS directory!
195 | - `./build/pub`
196 |
197 |
198 |
199 | ### 2.2 Abstracted Version (Recommended)
200 |
201 | [go to top](#top)
202 |
203 | Let's base this off of a pre-existing codebase: https://github.com/grassjelly/opensplice_boilerplate
204 |
205 | You'll find the simplest starter-code version of the project in the resources folder. I've edited out extrenuous information and added to the README.md. **You may use the README.md in the package for further guidance.**
206 |
207 | The reason why I went through the minimal way of doing things first is to allow you to have a greater appreciation of why the abstracted way of doing things is better, and to also give you some background about what's actually going on.
208 |
209 | This version uses a codebase that's designed to allow for multiple publishers and subscribers to be easily added to your source code with minimal extra writing, and exposes a ROS-like interface for the publishers and subscribers.
210 |
211 | To use it, follow the following steps:
212 |
213 | 1. Edit the idl file in the idl folder. (You can call it anything you want.)
214 |
215 | - Define the message types you'd like to use in the form of structs and modules
216 |
217 | - You MAY define multiple message types in that single idl file!
218 |
219 | - Modules will define namespaces (optional)
220 |
221 | - Structs will define the message type name, and the contents will be the contents of the message
222 |
223 | ```idl
224 | struct Template
225 | {
226 | long userID;
227 | string message;
228 | };
229 | #pragma keylist Template userID
230 |
231 | struct Sensor
232 | {
233 | long userID;
234 | string message;
235 | };
236 | #pragma keylist Sensor userID
237 | ```
238 |
239 | 2. Generate the message headers using `./gencode` (Remember to source your Opensplice DDS directory!!)
240 |
241 | 3. Edit your src code
242 |
243 | - The boilerplate header files should have abstracted away most of the fluff!
244 | - Be sure to include your message boilerplate headers that were generated! (In this case it was Sensor.h, and Template.h) As well as the Participant header, which will greatly help with abstraction!
245 | - Notice that there isn't any more random hard to understand code, no more event handlers, topic creation, etc.! All of it is abstracted away, and you can just deal with the publisher and subscriber!
246 |
247 | ```c++
248 | #include "Participant.h"
249 | #include "Template.h"
250 | #include "Sensor.h"
251 |
252 | // This particular node publishes a Sensor msg, and reads a Template msg coming in from the other node!
253 |
254 | int main(int argc, char* argv[])
255 | {
256 | os_time delay_200ms = { 0, 200000000 };
257 |
258 | // Create participant
259 | // Note that the string argument is the Partition name, not the node name
260 | // It should be the same across all participants you intend to have communicate
261 | Participant par("HelloWorld example", 1);
262 |
263 | // Create pub-sub
264 | SensorMsg::Publisher pub(par, (char*)"HelloWorldData_Msg2");
265 | TemplateMsg::Subscriber sub(par, (char*)"HelloWorldData_Msg");
266 |
267 | for(;;){
268 | // Create msg
269 | Sensor testmsg;
270 | testmsg.userID = 1;
271 | testmsg.message = DDS::string_dup("Hello World");
272 | pub.publish(testmsg);
273 |
274 | // Read incoming msg
275 | sub.read();
276 | for (DDS::ULong j = 0; j < sub.msg_list.length(); j++)
277 | {
278 | cout << "=== [Subscriber] message received :" << endl;
279 | cout << " userID : " << sub.msg_list[j].userID << endl;
280 | cout << " Message : \"" << sub.msg_list[j].message << "\"" << endl;
281 | }
282 | }
283 |
284 | // Delete publisher
285 | pub.kill();
286 | sub.kill();
287 |
288 | // Delete participant
289 | par.kill();
290 |
291 | return 0;
292 | }
293 | ```
294 |
295 | 4. Edit the CMakeLists.txt file
296 |
297 | - Add the extra lines to include the new message type definitions that were generated!
298 |
299 | ```cmake
300 | include(lib/boilerplate/types//CMakeLists.txt) # Here!
301 |
302 | ADD_LIBRARY (MGR_SRC
303 | lib/boilerplate/template/CheckStatus.cpp
304 | lib/boilerplate/template/Participant.cpp
305 | ${} # Here!
306 | )
307 | ```
308 |
309 | - Also remember to add in the executables to be compiled! So for example, if you had an executable called pub, then add in these lines.
310 |
311 | **NOTE:** If you want to use these nodes with ROS in a catkin workspace, please prepend all instances of GEN_SRC and MGR_SRC with some unique identifier (like the package name), so as to avoid namespace clashes and allow everything to compile smoothly. Beyond that, it's just going to require strategic splicing of the DDS and ROS CMakeLists.txt files.
312 |
313 | ```cmake
314 | ADD_EXECUTABLE (pubsub_1
315 | src/pubsub_1.cpp
316 | )
317 |
318 | TARGET_LINK_LIBRARIES (pubsub_1
319 | GEN_SRC
320 | MGR_SRC
321 | ${OpenSplice_LIBRARIES}
322 | )
323 |
324 | ADD_EXECUTABLE (pubsub_2
325 | src/pubsub_1.cpp
326 | )
327 |
328 | TARGET_LINK_LIBRARIES (pubsub_2
329 | GEN_SRC
330 | MGR_SRC
331 | ${OpenSplice_LIBRARIES}
332 | )
333 | ```
334 |
335 | 5. Run `./compile` to compile the code.
336 |
337 | 6. Then you can go try out the executables by executing them from the build directory
338 |
339 | - Again, remember to source your Opensplice DDS directory!
340 | - `./build/pubsub_1` `./build/pubsub_2`
341 |
342 |
343 |
344 | ```
345 | . .
346 | . |\-^-/| .
347 | /| } O.=.O { |\
348 | ```
349 |
350 |
351 |
352 | ------
353 |
354 | [.png)](https://www.buymeacoffee.com/methylDragon)
--------------------------------------------------------------------------------
/DDS/OpenSplice DDS (C++ API)/Starter Code and Resources/Note.txt:
--------------------------------------------------------------------------------
1 | These packages are slightly edited versions of the following:
2 | https://github.com/grassjelly/opensplice_minimal
3 | https://github.com/grassjelly/opensplice_boilerplate
4 |
5 | CH3EERS!
6 |
--------------------------------------------------------------------------------
/DDS/OpenSplice DDS (C++ API)/Starter Code and Resources/opensplice_boilerplate/.gitignore:
--------------------------------------------------------------------------------
1 | *.log
2 | build
--------------------------------------------------------------------------------
/DDS/OpenSplice DDS (C++ API)/Starter Code and Resources/opensplice_boilerplate/.travis.yml:
--------------------------------------------------------------------------------
1 | sudo: required
2 | dist: trusty
3 | language: generic
4 |
5 | compiler:
6 | - gcc
7 |
8 | install:
9 | - cd $HOME
10 | - git clone https://github.com/grassjelly/opensplice-install
11 | - cd opensplice-install
12 | - ./install
13 |
14 | script:
15 | - source $HOME/opensplice/install/HDE/x86_64.linux-dev/release.com
16 | - cd $HOME
17 | - git clone https://github.com/grassjelly/opensplice_boilerplate
18 | - cd opensplice_boilerplate
19 | - ./gencode
20 | - ./compile
21 |
22 | notifications:
23 | email:
24 | - jimenojmm@gmail.com
--------------------------------------------------------------------------------
/DDS/OpenSplice DDS (C++ API)/Starter Code and Resources/opensplice_boilerplate/CMakeLists.txt:
--------------------------------------------------------------------------------
1 | cmake_minimum_required (VERSION 2.8)
2 | set(CMAKE_MODULE_PATH ${CMAKE_CURRENT_SOURCE_DIR}/cmake)
3 | project (opensplice_minimal)
4 |
5 | include (MacroOpenSplice)
6 | include (osmacros)
7 |
8 | include(CheckCXXCompilerFlag)
9 | if(CMAKE_COMPILER_IS_GNUCXX OR CMAKE_COMPILER_IS_CLANG OR
10 | CMAKE_CXX_COMPILER_ID MATCHES "Clang")
11 | check_cxx_compiler_flag(--std=c++11 SUPPORTS_CXX11)
12 | if(SUPPORTS_CXX11)
13 | add_compile_options(--std=c++11)
14 | else()
15 | message(FATAL_ERROR "Compiler doesn't support C++11")
16 | endif()
17 | endif()
18 |
19 | find_package (OpenSplice REQUIRED)
20 |
21 | include_directories(
22 | ${PROJECT_SOURCE_DIR}
23 | ${OpenSplice_INCLUDE_DIRS}
24 | lib/boilerplate/template
25 | include
26 | gen
27 | )
28 |
29 | ADD_LIBRARY(GEN_SRC
30 | gen/Boilerplate.cpp
31 | gen/BoilerplateDcps.cpp
32 | gen/BoilerplateDcps_impl.cpp
33 | gen/BoilerplateSplDcps.cpp
34 | )
35 |
36 | TARGET_LINK_LIBRARIES (GEN_SRC
37 | ${OpenSplice_LIBRARIES}
38 | )
39 |
40 | include(lib/boilerplate/types/Template/CMakeLists.txt)
41 | include(lib/boilerplate/types/Sensor/CMakeLists.txt)
42 |
43 | ADD_LIBRARY (MGR_SRC
44 | lib/boilerplate/template/CheckStatus.cpp
45 | lib/boilerplate/template/Participant.cpp
46 | ${Sensor}
47 | ${Template}
48 | )
49 |
50 | TARGET_LINK_LIBRARIES (MGR_SRC
51 | ${OpenSplice_LIBRARIES}
52 | GEN_SRC
53 | )
54 |
55 | ADD_EXECUTABLE (pubsub_1
56 | src/pubsub_1.cpp
57 | )
58 |
59 | TARGET_LINK_LIBRARIES (pubsub_1
60 | GEN_SRC
61 | MGR_SRC
62 | ${OpenSplice_LIBRARIES}
63 | )
64 |
65 | ADD_EXECUTABLE (pubsub_2
66 | src/pubsub_2.cpp
67 | )
68 |
69 | TARGET_LINK_LIBRARIES (pubsub_2
70 | GEN_SRC
71 | MGR_SRC
72 | ${OpenSplice_LIBRARIES}
73 | )
74 |
--------------------------------------------------------------------------------
/DDS/OpenSplice DDS (C++ API)/Starter Code and Resources/opensplice_boilerplate/README.md:
--------------------------------------------------------------------------------
1 | # opensplice_boilerplate
2 |
3 | This package is a slightly edited version of: https://github.com/grassjelly/opensplice_boilerplate
4 |
5 | This package allows a user to create multiple instances of publishers and subscribers within a single node. The API supports instances of different message types defined in an IDL file.
6 |
7 | Use the src and idl files that currently exist as starter code for your projects!
8 |
9 |
10 |
11 | ## Adding new message types:
12 |
13 | #### 1. Use the .idl file in the idl folder as a reference to write new message types (as structs)
14 |
15 | #### 2. Generate the message headers:
16 |
17 | They will go into /gen
18 |
19 | ```bash
20 | $ ./gencode
21 | ```
22 |
23 | - (No need to delete the gen folder, the script will remove/replace pre-existing files there)
24 | - (Remember to source your Opensplice DDS directory!)
25 |
26 | This script will generate:
27 | - The message headers for the idl file you have created.
28 | - Boilerplate code specific to the message type so you can use the API.
29 | - A CMakeLists.txt for each message type boilerplates. This must be included in the main CMakeLists.txt so you can use it in the API. See No.3 .
30 |
31 | **Specifically, the generated code files are:**
32 |
33 | - All code in the /gen folder
34 | - All code in the /lib/boilerplate/types folder
35 |
36 | #### 3. Add the generated code and boilerplates in the main CMakeLists.txt:
37 |
38 | include(lib/boilerplate/types//CMakeLists.txt)
39 |
40 | ADD_LIBRARY (MGR_SRC
41 | lib/boilerplate/template/CheckStatus.cpp
42 | lib/boilerplate/template/Participant.cpp
43 | ${}
44 | )
45 |
46 | **NOTE:** If you intend to use this as a 'ROS package' (building the package with catkin_make), i.e. if you want rosrun to run it, ensure that you prepend all MGR_SRCs and GEN_SRCs with the NAME OF THE PACKAGE, or some unique identifier to prevent library namespace clashes.
47 |
48 | Otherwise once you have more than one package, the multiple MGR_SRC and GEN_SRC mentions WILL break the compilation!
49 |
50 |
51 |
52 | ## Using the API:
53 |
54 | #### 1. Include your new message type's header files:
55 |
56 | #include ".h"
57 |
58 | #### 2. Create participant:
59 |
60 | The partition name and domain ID **MUST be the same** across ALL NODES that are meant to communicate to each other. It is **not the node name.**
61 |
62 | Participant par("PARTITION_NAME", );
63 |
64 | #### 3. Creating a Publisher. Remember to add "Msg" when calling the namespace
65 |
66 | Like so: `Msg:`
67 |
68 | (Eg. SensorMsg, TemplateMsg, etc.)
69 |
70 | Msg::Publisher pub(par, (char*)"example_topic_name");
71 |
72 | #### 4. Publish:
73 |
74 | //create message object
75 | testmsg;
76 |
77 | //populate the data
78 | testmsg.userID = 1;
79 | testmsg.message = DDS::string_dup("Hello World");
80 |
81 | //publish testmsg
82 | pub.publish(testmsg);
83 |
84 | #### 5. Creating a Subscriber. Remember to add "Msg" when calling the namespace
85 |
86 | Same deal here
87 |
88 | Msg::Subscriber sub(par, (char*)"example_topic_name");
89 |
90 | #### 6. Subscribing and receiving data:
91 |
92 | sub.read();
93 | for (DDS::ULong j = 0; j < sub.msg_list.length(); j++)
94 | {
95 | cout << "=== [Subscriber] message received :" << endl;
96 | cout << " userID : " << sub.msg_list[j].userID << endl;
97 | cout << " Message : \"" << sub.msg_list[j].message << "\"" << endl;
98 | }
99 |
100 |
101 | ## Notes:
102 |
103 | - You can have MULTIPLE publishers and subscribers for **DIFFERENT** topics/message types associated with one domain participant!
104 | - You can have multiple domain participants as long as they're spread across different domain IDs. This will allow you to have multiple 'subnets' since only participants belonging to the same domain can communicate!
--------------------------------------------------------------------------------
/DDS/OpenSplice DDS (C++ API)/Starter Code and Resources/opensplice_boilerplate/cmake/FindOpenSplice.cmake:
--------------------------------------------------------------------------------
1 | ##############################################################################
2 | # Try to find OpenSplice
3 | # Once done this will define:
4 | #
5 | # OpenSplice_FOUND - system has OpenSplice.
6 | # OpenSplice_INCLUDE_DIRS - the OpenSplice include directory.
7 | # OpenSplice_LIBRARIES - Link these to use OpenSplice.
8 | # OpenSplice_IDLGEN_BINARY - Binary for the IDL compiler.
9 | #
10 | # You need the environment variable $OSPL_HOME to be set to your OpenSplice
11 | # installation directory.
12 | # This script also includes the MacroOpenSplice.cmake script, which is useful
13 | # for generating code from your idl.
14 | #
15 | ##############################################################################
16 | # Courtesy of Ivan Galvez Junquera
17 | ##############################################################################
18 | FIND_PATH(OpenSplice_INCLUDE_DIR
19 | NAMES
20 | make_files.py
21 | PATHS
22 | $ENV{OSPL_HOME}/include/dcps/C++/isocpp
23 | )
24 |
25 | SET(OpenSplice_INCLUDE_DIRS
26 | ${OpenSplice_INCLUDE_DIR}
27 | $ENV{OSPL_HOME}/include
28 | $ENV{OSPL_HOME}/include/sys
29 | $ENV{OSPL_HOME}/include/dcps/C++/SACPP
30 | $ENV{OSPL_HOME}/include/dcps/C++/isocpp2
31 | )
32 |
33 | # Find libraries
34 | FIND_LIBRARY(KERNEL_LIBRARY
35 | NAMES
36 | ddskernel
37 | PATHS
38 | $ENV{OSPL_HOME}/lib
39 | )
40 |
41 | FIND_LIBRARY(DCPSISOCPP_LIBRARY
42 | NAMES
43 | dcpsisocpp
44 | PATHS
45 | $ENV{OSPL_HOME}/lib
46 | )
47 |
48 | FIND_LIBRARY(DCPSCPP_LIBRARY
49 | NAMES
50 | dcpssacpp
51 | PATHS
52 | $ENV{OSPL_HOME}/lib
53 | )
54 |
55 | FIND_LIBRARY(DCPSISOCPP2_LIBRARY
56 | NAMES
57 | dcpsisocpp2
58 | PATHS
59 | $ENV{OSPL_HOME}/lib
60 | )
61 |
62 | SET(OpenSplice_LIBRARIES
63 | ${KERNEL_LIBRARY}
64 | ${DCPSISOCPP2_LIBRARY}
65 | ${DCPSISOCPP_LIBRARY}
66 | ${DCPSCPP_LIBRARY}
67 |
68 | )
69 |
70 | # Binary for the IDL compiler
71 | SET (OpenSplice_IDLGEN_BINARY $ENV{OSPL_HOME}/bin/idlpp)
72 |
73 | IF (OpenSplice_INCLUDE_DIRS AND OpenSplice_LIBRARIES)
74 | SET(OpenSplice_FOUND TRUE)
75 | ENDIF (OpenSplice_INCLUDE_DIRS AND OpenSplice_LIBRARIES)
76 |
77 | IF (OpenSplice_FOUND)
78 | MESSAGE(STATUS "Found OpenSplice DDS libraries: ${OpenSplice_LIBRARIES}")
79 | ELSE (OpenSplice_FOUND)
80 | IF (OpenSplice_FIND_REQUIRED)
81 | MESSAGE(FATAL_ERROR "Could not find OpenSplice DDS")
82 | ENDIF (OpenSplice_FIND_REQUIRED)
83 | ENDIF (OpenSplice_FOUND)
84 |
85 | MARK_AS_ADVANCED(OpenSplice_INCLUDE_DIRS OpenSplice_LIBRARIES OpenSplice_IDLGEN_BINARY)
86 | INCLUDE (MacroOpenSplice)
--------------------------------------------------------------------------------
/DDS/OpenSplice DDS (C++ API)/Starter Code and Resources/opensplice_boilerplate/cmake/MacroOpenSplice.cmake:
--------------------------------------------------------------------------------
1 | ##############################################################################
2 | # OpenSplice_IDLGEN(idlfilename)
3 | #
4 | # Macro to generate OpenSplice DDS sources from a given idl file with the
5 | # data structures.
6 | # You must include the extension .idl in the name of the data file.
7 | #
8 | ##############################################################################
9 | # Courtersy of Ivan Galvez Junquera
10 | ##############################################################################
11 |
12 |
13 | # Macro to create a list with all the generated source files for a given .idl filename
14 | MACRO (DEFINE_OpenSplice_SOURCES idlfilename)
15 | SET(outsources)
16 | GET_FILENAME_COMPONENT(it ${idlfilename} ABSOLUTE)
17 | GET_FILENAME_COMPONENT(nfile ${idlfilename} NAME_WE)
18 | SET(outsources ${outsources} gen/${nfile}.cpp gen/${nfile}.h)
19 | SET(outsources ${outsources} gen/${nfile}Dcps.cpp gen/${nfile}Dcps.h)
20 | SET(outsources ${outsources} gen/${nfile}Dcps_impl.cpp gen/${nfile}Dcps_impl.h)
21 | SET(outsources ${outsources} gen/${nfile}SplDcps.cpp gen/${nfile}SplDcps.h)
22 | SET(outsources ${outsources} gen/ccpp_${nfile}.h)
23 | ENDMACRO(DEFINE_OpenSplice_SOURCES)
24 |
25 | MACRO (OpenSplice_IDLGEN idlfilename)
26 | GET_FILENAME_COMPONENT(it ${idlfilename} ABSOLUTE)
27 | GET_FILENAME_COMPONENT(idlfilename ${idlfilename} NAME)
28 | DEFINE_OpenSplice_SOURCES(${ARGV})
29 | ADD_CUSTOM_COMMAND (
30 | OUTPUT ${outsources}
31 | COMMAND ${OpenSplice_IDLGEN_BINARY}
32 | ARGS -l isocpp -d gen ${idlfilename}
33 | DEPENDS ${it}
34 | )
35 | ENDMACRO (OpenSplice_IDLGEN)
36 |
--------------------------------------------------------------------------------
/DDS/OpenSplice DDS (C++ API)/Starter Code and Resources/opensplice_boilerplate/cmake/osmacros.cmake:
--------------------------------------------------------------------------------
1 | IF (WIN32)
2 | SET (DEFINITIONS "/DSIMD_NOSTARTOSPL=0")
3 | ELSE (WIN32)
4 | SET (DEFINITIONS "-DNDEBUG -g -O2 -std=c++11 -pipe -Wall")
5 | ENDIF (WIN32)
6 |
7 | # SET (DEFINITIONS "-g -O2 -pipe -std=c++0x ")
8 | # IF (WIN32)
9 | # IF(DEBUG)
10 | # SET (DEFINITIONS "-DNDEBUG -std=c++0x")
11 | # ENDIF(DEBUG)
12 | # ELSE (WIN32)
13 | # IF(DEBUG)
14 | # SET (DEFINITIONS "-ansi -g3 -pg -pipe -std=c++0x")
15 | # ELSE(DEBUG)
16 | # IF(PEDANTIC)
17 | # SET (DEFINITIONS "-ansi -g -pg -pipe -Wall -Wstrict-null-sentinel -Weffc++ -Wold-style-cast -pedantic -std=c++0x")
18 | # SET (DEBUG 1)
19 | # ELSE(PEDANTIC)
20 | # SET (DEFINITIONS "-DNDEBUG -O5 -pipe -std=c++0x")
21 | # ENDIF(PEDANTIC)
22 | # ENDIF(DEBUG)
23 | # ENDIF (WIN32)
--------------------------------------------------------------------------------
/DDS/OpenSplice DDS (C++ API)/Starter Code and Resources/opensplice_boilerplate/compile:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env bash
2 |
3 | if [ ! -d "build" ]; then
4 | mkdir build
5 | fi
6 |
7 | cd build
8 | cmake ..
9 | make
--------------------------------------------------------------------------------
/DDS/OpenSplice DDS (C++ API)/Starter Code and Resources/opensplice_boilerplate/gencode:
--------------------------------------------------------------------------------
1 | #/usr/bin/env bash
2 |
3 | if [ "$(ls -A gen)" ]; then
4 | rm gen/*.cpp
5 | rm gen/*.h
6 | fi
7 |
8 | $OSPL_HOME/bin/./idlpp -S -l cpp -d gen idl/*.idl
9 |
10 | IDL=idl/*.idl
11 | IDL_NAME=$(basename $IDL .idl)
12 |
13 | rm -rf lib/boilerplate/types
14 | mkdir -p lib/boilerplate/types
15 | TYPES=($(awk '{for(i=1;i<=NF;i++) if ($i=="struct") print $(i+1)}' $IDL));
16 | for i in ${TYPES[@]}
17 | do
18 | :
19 | MSG_LIBRARY=lib/boilerplate/types/$i
20 | mkdir -p $MSG_LIBRARY
21 |
22 | cp lib/boilerplate/template/Boilerplate.cpp $MSG_LIBRARY
23 | cp lib/boilerplate/template/Boilerplate.h $MSG_LIBRARY
24 | cp lib/boilerplate/template/CMakeLists.txt $MSG_LIBRARY
25 |
26 | perl -pi -e "s/Template/$i/g" $MSG_LIBRARY/Boilerplate.cpp
27 | perl -pi -e "s/Template/$i/g" $MSG_LIBRARY/Boilerplate.h
28 |
29 | perl -pi -e "s/Boilerplate/$i/g" $MSG_LIBRARY/Boilerplate.cpp
30 | perl -pi -e "s/Boilerplate/$i/g" $MSG_LIBRARY/Boilerplate.h
31 | perl -pi -e "s/BOILERPLATE_H/$i"_H"/g" $MSG_LIBRARY/Boilerplate.h
32 | perl -pi -e "s/"ccpp_"$i/"ccpp_"$IDL_NAME/g" $MSG_LIBRARY/Boilerplate.h
33 |
34 | perl -pi -e "s/Template/$i/g" $MSG_LIBRARY/CMakeLists.txt
35 |
36 | mv $MSG_LIBRARY/Boilerplate.cpp $MSG_LIBRARY/$i.cpp
37 | mv $MSG_LIBRARY/Boilerplate.h $MSG_LIBRARY/$i.h
38 |
39 | echo $i Boilerplate Done!
40 | done
41 |
--------------------------------------------------------------------------------
/DDS/OpenSplice DDS (C++ API)/Starter Code and Resources/opensplice_boilerplate/idl/Boilerplate.idl:
--------------------------------------------------------------------------------
1 | struct Template
2 | {
3 | long userID;
4 | string message;
5 | };
6 | #pragma keylist Template userID
7 |
8 | struct Sensor
9 | {
10 | long userID;
11 | string message;
12 | };
13 | #pragma keylist Sensor userID
14 |
15 |
--------------------------------------------------------------------------------
/DDS/OpenSplice DDS (C++ API)/Starter Code and Resources/opensplice_boilerplate/lib/boilerplate/template/Boilerplate.cpp:
--------------------------------------------------------------------------------
1 | #include "Boilerplate.h"
2 |
3 | BoilerplateMsg::Publisher::Publisher(Participant &participant_object, char * topic_name)
4 | {
5 | participant = participant_object.get_participant();
6 | partition = participant_object.get_partition();
7 | topicName = topic_name;
8 | init_publisher();
9 | }
10 |
11 | void BoilerplateMsg::Publisher::init_publisher()
12 | {
13 |
14 | //=======register type======
15 | TemplateTypeSupport_var mt = new TemplateTypeSupport();
16 | ts = mt.in();
17 |
18 | typeName = ts->get_type_name();
19 | status = ts->register_type(participant.in(), typeName);
20 | checkStatus(status, "register_type");
21 |
22 | //=======create topic=======
23 | status = participant->get_default_topic_qos(reliable_topic_qos);
24 | checkStatus(status, "DDS::DomainParticipant::get_default_topic_qos");
25 | reliable_topic_qos.reliability.kind = RELIABLE_RELIABILITY_QOS;
26 | reliable_topic_qos.durability.kind = TRANSIENT_DURABILITY_QOS;
27 |
28 | /* Make the tailored QoS the new default. */
29 | status = participant->set_default_topic_qos(reliable_topic_qos);
30 | checkStatus(status, "DDS::DomainParticipant::set_default_topic_qos");
31 |
32 | /* Use the changed policy when defining the Boilerplate topic */
33 | topic = participant->create_topic(topicName, typeName, reliable_topic_qos,
34 | NULL, STATUS_MASK_NONE);
35 | checkHandle(topic.in(), "DDS::DomainParticipant::create_topic ()");
36 |
37 | //========create publisher=======
38 | status = participant->get_default_publisher_qos(pub_qos);
39 | checkStatus(status, "DDS::DomainParticipant::get_default_publisher_qos");
40 | pub_qos.partition.name.length(1);
41 | pub_qos.partition.name[0] = partition;
42 |
43 | publisher = participant->create_publisher(pub_qos, NULL, STATUS_MASK_NONE);
44 | checkHandle(publisher.in(), "DDS::DomainParticipant::create_publisher");
45 |
46 | //========create data writer======
47 | status = publisher->get_default_datawriter_qos(dw_qos);
48 | checkStatus(status, "DDS::DomainParticipant::get_default_publisher_qos");
49 | status = publisher->copy_from_topic_qos(dw_qos, reliable_topic_qos);
50 | checkStatus(status, "DDS::Publisher::copy_from_topic_qos");
51 | // Set autodispose to false so that you can start
52 | // the subscriber after the publisher
53 | // If autodispose_unregistered_instances is set to true (default value),
54 | // you will have to start the subscriber before the publisher
55 | dw_qos.writer_data_lifecycle.autodispose_unregistered_instances = false;
56 | writer = publisher->create_datawriter(topic.in(), dw_qos, NULL,
57 | STATUS_MASK_NONE);
58 | checkHandle(writer, "DDS::Publisher::create_datawriter");
59 |
60 |
61 | //========publish events=========
62 | DataWriter_var dwriter = DataWriter::_duplicate(writer.in());
63 | myWriter = TemplateDataWriter::_narrow(dwriter.in());
64 | }
65 |
66 | void BoilerplateMsg::Publisher::publish(Template instance)
67 | {
68 | status = myWriter->write(instance, DDS::HANDLE_NIL);
69 | checkStatus(status, "TemplateDataWriter::write");
70 | }
71 |
72 | void BoilerplateMsg::Publisher::kill()
73 | {
74 |
75 | //========delete writer==========
76 | status = publisher->delete_datawriter(writer);
77 | checkStatus(status, "DDS::Publisher::delete_datawriter ");
78 |
79 | //========delete publisher=========
80 | status = participant->delete_publisher(publisher.in());
81 | checkStatus(status, "DDS::DomainParticipant::delete_publisher ");
82 |
83 | //========delete topic=========
84 | status = participant->delete_topic(topic);
85 | checkStatus(status, "DDS.DomainParticipant.delete_topic");
86 | }
87 |
88 | BoilerplateMsg::Subscriber::Subscriber(Participant &participant_object, char * topic_name)
89 | {
90 | participant = participant_object.get_participant();
91 | partition = participant_object.get_partition();
92 | topicName = topic_name;
93 | init_subscriber();
94 | }
95 |
96 | void BoilerplateMsg::Subscriber::init_subscriber()
97 | {
98 |
99 | //=======register type======
100 | TemplateTypeSupport_var mt = new TemplateTypeSupport();
101 | ts = mt.in();
102 |
103 | typeName = ts->get_type_name();
104 | status = ts->register_type(participant.in(), typeName);
105 | checkStatus(status, "register_type");
106 |
107 | //=======create topic=======
108 | status = participant->get_default_topic_qos(reliable_topic_qos);
109 | checkStatus(status, "DDS::DomainParticipant::get_default_topic_qos");
110 | reliable_topic_qos.reliability.kind = RELIABLE_RELIABILITY_QOS;
111 | reliable_topic_qos.durability.kind = TRANSIENT_DURABILITY_QOS;
112 |
113 | /* Make the tailored QoS the new default. */
114 | status = participant->set_default_topic_qos(reliable_topic_qos);
115 | checkStatus(status, "DDS::DomainParticipant::set_default_topic_qos");
116 |
117 | /* Use the changed policy when defining the Boilerplate topic */
118 | topic = participant->create_topic(topicName, typeName, reliable_topic_qos,
119 | NULL, STATUS_MASK_NONE);
120 | checkHandle(topic.in(), "DDS::DomainParticipant::create_topic ()");
121 |
122 | //========create subscriber=======
123 | status = participant->get_default_subscriber_qos(sub_qos);
124 | checkStatus(status, "DDS::DomainParticipant::get_default_subscriber_qos");
125 | sub_qos.partition.name.length(1);
126 | sub_qos.partition.name[0] = partition;
127 | subscriber = participant->create_subscriber(sub_qos, NULL, STATUS_MASK_NONE);
128 | checkHandle(subscriber.in(), "DDS::DomainParticipant::create_subscriber");
129 |
130 | // //========create data reader======
131 | reader = subscriber->create_datareader(topic.in(),
132 | DATAREADER_QOS_USE_TOPIC_QOS, NULL, STATUS_MASK_NONE);
133 | checkHandle(reader, "DDS::Subscriber::create_datareader ()");
134 |
135 | DataReader_var dreader = DataReader::_duplicate(reader.in());;
136 | myReader = TemplateDataReader::_narrow(dreader.in());
137 | checkHandle(myReader.in(), "TemplateDataReader::_narrow");
138 | }
139 |
140 | void BoilerplateMsg::Subscriber::read()
141 | {
142 | SampleInfoSeq infoSeq;
143 | TemplateSeq msgList;
144 |
145 | status = myReader->take(msgList, infoSeq, LENGTH_UNLIMITED,
146 | ANY_SAMPLE_STATE, ANY_VIEW_STATE, ANY_INSTANCE_STATE);
147 | checkStatus(status, "TemplateDataReader::take");
148 | msg_list = msgList;
149 |
150 | status = myReader->return_loan(msgList, infoSeq);
151 | checkStatus(status, "TemplateDataReader::return_loan");
152 | }
153 |
154 | void BoilerplateMsg::Subscriber::kill()
155 | {
156 | //========delete reader==========
157 | status = subscriber->delete_datareader(reader);
158 | checkStatus(status, "DDS::Subscriber::delete_datareader ");
159 |
160 | //========delete subscriber=========
161 | status = participant->delete_subscriber(subscriber);
162 | checkStatus(status, "DDS::DomainParticipant::delete_subscriber ");
163 |
164 | //========delete topic=========
165 | status = participant->delete_topic(topic);
166 | checkStatus(status, "DDS.DomainParticipant.delete_topic");
167 | }
--------------------------------------------------------------------------------
/DDS/OpenSplice DDS (C++ API)/Starter Code and Resources/opensplice_boilerplate/lib/boilerplate/template/Boilerplate.h:
--------------------------------------------------------------------------------
1 | #ifndef BOILERPLATE_H
2 | #define BOILERPLATE_H
3 |
4 | #include
5 | #include "ccpp_dds_dcps.h"
6 | #include "CheckStatus.h"
7 | #include "Participant.h"
8 | #include "ccpp_Boilerplate.h"
9 |
10 | using namespace DDS;
11 | namespace BoilerplateMsg
12 | {
13 | class Publisher
14 | {
15 | void init_publisher();
16 |
17 | DomainParticipant_var participant;
18 | ReturnCode_t status;
19 |
20 | String_var partition;
21 | char * topicName;
22 |
23 | TypeSupport * ts;
24 | DDS::String_var typeName;
25 |
26 | Topic_var topic;
27 | TopicQos reliable_topic_qos;
28 | Publisher_var publisher;
29 | PublisherQos pub_qos;
30 |
31 | DataWriterQos dw_qos;
32 | DataWriter_var writer;
33 | TemplateDataWriter_var myWriter;
34 |
35 | public:
36 | Publisher(Participant &, char * );
37 | void publish(Template);
38 | void kill();
39 | };
40 |
41 | class Subscriber
42 | {
43 | void init_subscriber();
44 |
45 | DomainParticipant_var participant;
46 | ReturnCode_t status;
47 |
48 | String_var partition;
49 | char * topicName;
50 |
51 | TypeSupport * ts;
52 | DDS::String_var typeName;
53 |
54 | Topic_var topic;
55 | TopicQos reliable_topic_qos;
56 | Subscriber_var subscriber;
57 | SubscriberQos sub_qos;
58 |
59 | DataReader_var reader;
60 | TemplateDataReader_var myReader;
61 |
62 | public:
63 | Subscriber(Participant &, char * );
64 | TemplateSeq msg_list;
65 | void read();
66 | void kill();
67 | };
68 |
69 | }
70 |
71 |
72 | #endif
73 |
--------------------------------------------------------------------------------
/DDS/OpenSplice DDS (C++ API)/Starter Code and Resources/opensplice_boilerplate/lib/boilerplate/template/CMakeLists.txt:
--------------------------------------------------------------------------------
1 | cmake_minimum_required(VERSION 2.8.3)
2 |
3 | MESSAGE("BUILDING LIBRARIES IN:")
4 | MESSAGE(${CMAKE_CURRENT_SOURCE_DIR})
5 |
6 | include_directories(
7 | ${CMAKE_CURRENT_SOURCE_DIR}/lib/boilerplate/types/Template
8 | )
9 |
10 | file(GLOB Template
11 | ${CMAKE_CURRENT_SOURCE_DIR}/lib/boilerplate/types/Template/Template.cpp
12 | )
13 |
14 |
--------------------------------------------------------------------------------
/DDS/OpenSplice DDS (C++ API)/Starter Code and Resources/opensplice_boilerplate/lib/boilerplate/template/CheckStatus.cpp:
--------------------------------------------------------------------------------
1 |
2 | /*
3 | * OpenSplice DDS
4 | *
5 | * This software and documentation are Copyright 2006 to PrismTech
6 | * Limited, its affiliated companies and licensors. All rights reserved.
7 | *
8 | * Licensed under the Apache License, Version 2.0 (the "License");
9 | * you may not use this file except in compliance with the License.
10 | * You may obtain a copy of the License at
11 | *
12 | * http://www.apache.org/licenses/LICENSE-2.0
13 | *
14 | * Unless required by applicable law or agreed to in writing, software
15 | * distributed under the License is distributed on an "AS IS" BASIS,
16 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
17 | * See the License for the specific language governing permissions and
18 | * limitations under the License.
19 | *
20 | */
21 |
22 | /************************************************************************
23 | * LOGICAL_NAME: CheckStatus.cpp
24 | * FUNCTION: OpenSplice Tutorial example code.
25 | * MODULE: Tutorial for the C++ programming language.
26 | * DATE june 2007.
27 | ************************************************************************
28 | *
29 | * This file contains the implementation for the error handling operations.
30 | *
31 | ***/
32 |
33 | #include "CheckStatus.h"
34 |
35 | /* Array to hold the names for all ReturnCodes. */
36 | string RetCodeName[13] =
37 | {
38 | "DDS_RETCODE_OK", "DDS_RETCODE_ERROR", "DDS_RETCODE_UNSUPPORTED",
39 | "DDS_RETCODE_BAD_PARAMETER", "DDS_RETCODE_PRECONDITION_NOT_MET",
40 | "DDS_RETCODE_OUT_OF_RESOURCES", "DDS_RETCODE_NOT_ENABLED",
41 | "DDS_RETCODE_IMMUTABLE_POLICY", "DDS_RETCODE_INCONSISTENT_POLICY",
42 | "DDS_RETCODE_ALREADY_DELETED", "DDS_RETCODE_TIMEOUT", "DDS_RETCODE_NO_DATA",
43 | "DDS_RETCODE_ILLEGAL_OPERATION"
44 | };
45 |
46 | /**
47 | * Returns the name of an error code.
48 | **/
49 | string getErrorName(DDS::ReturnCode_t status)
50 | {
51 | return RetCodeName[status];
52 | }
53 |
54 | /**
55 | * Check the return status for errors. If there is an error, then terminate.
56 | **/
57 | void checkStatus(DDS::ReturnCode_t status, const char *info)
58 | {
59 |
60 |
61 | if (status != DDS::RETCODE_OK && status != DDS::RETCODE_NO_DATA)
62 | {
63 | cerr << "Error in " << info << ": " << getErrorName(status).c_str() << endl;
64 | exit(1);
65 | }
66 | }
67 |
68 | /**
69 | * Check whether a valid handle has been returned. If not, then terminate.
70 | **/
71 | void checkHandle(void *handle, string info)
72 | {
73 |
74 | if (!handle)
75 | {
76 | cerr << "Error in " << info.c_str() << ": Creation failed: invalid handle" << endl;
77 | exit(1);
78 | }
79 | }
80 |
--------------------------------------------------------------------------------
/DDS/OpenSplice DDS (C++ API)/Starter Code and Resources/opensplice_boilerplate/lib/boilerplate/template/CheckStatus.h:
--------------------------------------------------------------------------------
1 |
2 | /*
3 | * OpenSplice DDS
4 | *
5 | * This software and documentation are Copyright 2006 to PrismTech
6 | * Limited, its affiliated companies and licensors. All rights reserved.
7 | *
8 | * Licensed under the Apache License, Version 2.0 (the "License");
9 | * you may not use this file except in compliance with the License.
10 | * You may obtain a copy of the License at
11 | *
12 | * http://www.apache.org/licenses/LICENSE-2.0
13 | *
14 | * Unless required by applicable law or agreed to in writing, software
15 | * distributed under the License is distributed on an "AS IS" BASIS,
16 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
17 | * See the License for the specific language governing permissions and
18 | * limitations under the License.
19 | *
20 | */
21 |
22 | /************************************************************************
23 | * LOGICAL_NAME: CheckStatus.h
24 | * FUNCTION: OpenSplice Tutorial example code.
25 | * MODULE: Tutorial for the C++ programming language.
26 | * DATE june 2007.
27 | ************************************************************************
28 | *
29 | * This file contains the headers for the error handling operations.
30 | *
31 | ***/
32 |
33 | #ifndef __CHECKSTATUS_H__
34 | #define __CHECKSTATUS_H__
35 |
36 | #include "ccpp_dds_dcps.h"
37 | #include
38 |
39 | using namespace std;
40 |
41 | /**
42 | * Returns the name of an error code.
43 | **/
44 | string getErrorName(DDS::ReturnCode_t status);
45 |
46 | /**
47 | * Check the return status for errors. If there is an error, then terminate.
48 | **/
49 | void checkStatus(DDS::ReturnCode_t status, const char *info);
50 |
51 | /**
52 | * Check whether a valid handle has been returned. If not, then terminate.
53 | **/
54 | void checkHandle(void *handle, string info);
55 |
56 | #endif
57 |
--------------------------------------------------------------------------------
/DDS/OpenSplice DDS (C++ API)/Starter Code and Resources/opensplice_boilerplate/lib/boilerplate/template/Participant.cpp:
--------------------------------------------------------------------------------
1 | #include "Participant.h"
2 |
3 | Participant::Participant(const char * partitiontName , DomainId_t domain_id)
4 | {
5 | //TODO: pass domain_id arg to domain var;
6 | domain = DOMAIN_ID_DEFAULT;
7 | dpf = DomainParticipantFactory::get_instance();
8 | checkHandle(dpf.in(), "DDS::DomainParticipantFactory::get_instance");
9 | participant = dpf->create_participant(domain, PARTICIPANT_QOS_DEFAULT, NULL,
10 | STATUS_MASK_NONE);
11 | checkHandle(participant.in(),
12 | "DDS::DomainParticipantFactory::create_participant");
13 | partition = partitiontName;
14 | }
15 |
16 | DDS::String_var Participant::get_partition()
17 | {
18 | return partition;
19 | }
20 |
21 | DomainParticipant_var Participant::get_participant()
22 | {
23 | return participant;
24 | }
25 |
26 | void Participant::kill()
27 | {
28 | status = dpf->delete_participant(participant.in());
29 | checkStatus(status, "DDS::DomainParticipant::delete_participant");
30 | }
31 |
--------------------------------------------------------------------------------
/DDS/OpenSplice DDS (C++ API)/Starter Code and Resources/opensplice_boilerplate/lib/boilerplate/template/Participant.h:
--------------------------------------------------------------------------------
1 | #ifndef PARTICIPANT_H
2 | #define PARTICIPANT_H
3 |
4 | #include "ccpp_dds_dcps.h"
5 | #include "CheckStatus.h"
6 |
7 | using namespace DDS;
8 |
9 | class Participant
10 | {
11 |
12 | String_var partition;
13 | DomainId_t domain;
14 | ReturnCode_t status;
15 | DomainParticipantFactory_var dpf;
16 | DomainParticipant_var participant;
17 |
18 | public:
19 | Participant(const char *, DomainId_t);
20 | String_var get_partition();
21 | DomainParticipant_var get_participant();
22 | void kill();
23 | };
24 |
25 | #endif
--------------------------------------------------------------------------------
/DDS/OpenSplice DDS (C++ API)/Starter Code and Resources/opensplice_boilerplate/src/pubsub_1.cpp:
--------------------------------------------------------------------------------
1 |
2 |
3 | #include "Participant.h"
4 | #include "Template.h"
5 | #include "Sensor.h"
6 |
7 | int main(int argc, char* argv[])
8 | {
9 | os_time delay_200ms = { 0, 200000000 };
10 |
11 | Participant par("HelloWorld example", 1);
12 |
13 | SensorMsg::Publisher pub(par, (char*)"HelloWorldData_Msg2");
14 |
15 | TemplateMsg::Subscriber sub(par, (char*)"HelloWorldData_Msg");
16 |
17 | for(;;){
18 | Sensor testmsg;
19 | testmsg.userID = 1;
20 | testmsg.message = DDS::string_dup("Hello World");
21 | pub.publish(testmsg);
22 |
23 | sub.read();
24 | for (DDS::ULong j = 0; j < sub.msg_list.length(); j++)
25 | {
26 | cout << "=== [Subscriber] message received :" << endl;
27 | cout << " userID : " << sub.msg_list[j].userID << endl;
28 | cout << " Message : \"" << sub.msg_list[j].message << "\"" << endl;
29 | }
30 | }
31 | //delete publisher
32 | pub.kill();
33 | sub.kill();
34 |
35 | //delete participant
36 | par.kill();
37 | return 0;
38 | }
39 |
--------------------------------------------------------------------------------
/DDS/OpenSplice DDS (C++ API)/Starter Code and Resources/opensplice_boilerplate/src/pubsub_2.cpp:
--------------------------------------------------------------------------------
1 | #include "Participant.h"
2 | #include "Template.h"
3 | #include "Sensor.h"
4 |
5 | int main(int argc, char* argv[])
6 | {
7 | os_time delay_200ms = { 0, 200000000 };
8 |
9 | Participant par("HelloWorld example", 1);
10 |
11 | SensorMsg::Subscriber sub(par, (char*)"HelloWorldData_Msg2");
12 |
13 | TemplateMsg::Publisher pub(par, (char*)"HelloWorldData_Msg");
14 |
15 | for(;;){
16 | Template testmsg;
17 | testmsg.userID = 1;
18 | testmsg.message = DDS::string_dup("Hello World");
19 | pub.publish(testmsg);
20 |
21 | sub.read();
22 | for (DDS::ULong j = 0; j < sub.msg_list.length(); j++)
23 | {
24 | cout << "=== [Subscriber] message received :" << endl;
25 | cout << " userID : " << sub.msg_list[j].userID << endl;
26 | cout << " Message : \"" << sub.msg_list[j].message << "\"" << endl;
27 | }
28 | }
29 |
30 | //delete publisher
31 | pub.kill();
32 | sub.kill();
33 |
34 | //delete participant
35 | par.kill();
36 | return 0;
37 | }
38 |
--------------------------------------------------------------------------------
/DDS/OpenSplice DDS (C++ API)/Starter Code and Resources/opensplice_minimal/.gitignore:
--------------------------------------------------------------------------------
1 | *.log
2 | build
--------------------------------------------------------------------------------
/DDS/OpenSplice DDS (C++ API)/Starter Code and Resources/opensplice_minimal/.travis.yml:
--------------------------------------------------------------------------------
1 |
2 | sudo: required
3 | dist: trusty
4 | language: generic
5 |
6 | compiler:
7 | - gcc
8 |
9 | install:
10 | - cd $HOME
11 | - git clone https://github.com/grassjelly/opensplice-install
12 | - cd opensplice-install
13 | - ./install
14 |
15 | script:
16 | - source $HOME/opensplice/install/HDE/x86_64.linux-dev/release.com
17 | - cd $HOME
18 | - git clone https://github.com/grassjelly/opensplice_minimal
19 | - cd opensplice_minimal
20 | - ./gencode
21 | - ./compile
22 |
23 | notifications:
24 | email:
25 | - jimenojmm@gmail.com
--------------------------------------------------------------------------------
/DDS/OpenSplice DDS (C++ API)/Starter Code and Resources/opensplice_minimal/CMakeLists.txt:
--------------------------------------------------------------------------------
1 | cmake_minimum_required (VERSION 2.8)
2 | set(CMAKE_MODULE_PATH ${CMAKE_CURRENT_SOURCE_DIR}/cmake)
3 | project (opensplice_minimal)
4 |
5 | include (MacroOpenSplice)
6 | include (osmacros)
7 |
8 | include(CheckCXXCompilerFlag)
9 | if(CMAKE_COMPILER_IS_GNUCXX OR CMAKE_COMPILER_IS_CLANG OR
10 | CMAKE_CXX_COMPILER_ID MATCHES "Clang")
11 | check_cxx_compiler_flag(--std=c++11 SUPPORTS_CXX11)
12 | if(SUPPORTS_CXX11)
13 | add_compile_options(--std=c++11)
14 | else()
15 | message(FATAL_ERROR "Compiler doesn't support C++11")
16 | endif()
17 | endif()
18 |
19 | find_package (OpenSplice REQUIRED)
20 |
21 | include_directories(
22 | ${PROJECT_SOURCE_DIR}
23 | ${OpenSplice_INCLUDE_DIRS}
24 | include
25 | gen
26 | )
27 |
28 | ADD_LIBRARY(GEN_SRC
29 | gen/HelloWorld.cpp
30 | gen/HelloWorldDcps.cpp
31 | gen/HelloWorldDcps_impl.cpp
32 | gen/HelloWorldSplDcps.cpp
33 | )
34 |
35 | TARGET_LINK_LIBRARIES (GEN_SRC
36 | ${OpenSplice_LIBRARIES}
37 | )
38 |
39 | ADD_LIBRARY (MGR_SRC
40 | src/DDSEntityManager.cpp
41 | src/CheckStatus.cpp
42 | )
43 |
44 | TARGET_LINK_LIBRARIES (MGR_SRC
45 | ${OpenSplice_LIBRARIES}
46 | )
47 |
48 | ADD_EXECUTABLE (pub
49 | src/pub.cpp
50 | )
51 |
52 | TARGET_LINK_LIBRARIES (pub
53 | GEN_SRC
54 | MGR_SRC
55 | ${OpenSplice_LIBRARIES}
56 | )
57 |
58 | ADD_EXECUTABLE (sub
59 | src/sub.cpp
60 | )
61 |
62 | TARGET_LINK_LIBRARIES (sub
63 | GEN_SRC
64 | MGR_SRC
65 | ${OpenSplice_LIBRARIES}
66 | )
67 |
68 |
--------------------------------------------------------------------------------
/DDS/OpenSplice DDS (C++ API)/Starter Code and Resources/opensplice_minimal/README.md:
--------------------------------------------------------------------------------
1 | # opensplice_minimal
2 |
3 | This package is a slightly edited version of: https://github.com/grassjelly/opensplice_minimal
4 |
5 | You should use this only as a reference. For actual deployment, please use opensplice_boilerplate as starter code, since it simplifies a whole lot of stuff for you and removes a lot of boilerplate code that you will have to write!
6 |
7 |
8 |
9 | ## Running the demo:
10 |
11 | 1. Generate the message headers:
12 |
13 | They will go into /gen
14 |
15 | ```
16 | ./gencode
17 | ```
18 |
19 | 2. Build the package:
20 |
21 | ./compile
22 |
23 | 3. Run the built subscriber:
24 |
25 | ./build/sub
26 |
27 | 4. On another terminal, run the built publisher:
28 |
29 | ./build/pub
--------------------------------------------------------------------------------
/DDS/OpenSplice DDS (C++ API)/Starter Code and Resources/opensplice_minimal/cmake/FindOpenSplice.cmake:
--------------------------------------------------------------------------------
1 | ##############################################################################
2 | # Try to find OpenSplice
3 | # Once done this will define:
4 | #
5 | # OpenSplice_FOUND - system has OpenSplice.
6 | # OpenSplice_INCLUDE_DIRS - the OpenSplice include directory.
7 | # OpenSplice_LIBRARIES - Link these to use OpenSplice.
8 | # OpenSplice_IDLGEN_BINARY - Binary for the IDL compiler.
9 | #
10 | # You need the environment variable $OSPL_HOME to be set to your OpenSplice
11 | # installation directory.
12 | # This script also includes the MacroOpenSplice.cmake script, which is useful
13 | # for generating code from your idl.
14 | #
15 | ##############################################################################
16 | # Courtesy of Ivan Galvez Junquera
17 | ##############################################################################
18 | FIND_PATH(OpenSplice_INCLUDE_DIR
19 | NAMES
20 | make_files.py
21 | PATHS
22 | $ENV{OSPL_HOME}/include/dcps/C++/isocpp
23 | )
24 |
25 | SET(OpenSplice_INCLUDE_DIRS
26 | ${OpenSplice_INCLUDE_DIR}
27 | $ENV{OSPL_HOME}/include
28 | $ENV{OSPL_HOME}/include/sys
29 | $ENV{OSPL_HOME}/include/dcps/C++/SACPP
30 | $ENV{OSPL_HOME}/include/dcps/C++/isocpp2
31 | )
32 |
33 | # Find libraries
34 | FIND_LIBRARY(KERNEL_LIBRARY
35 | NAMES
36 | ddskernel
37 | PATHS
38 | $ENV{OSPL_HOME}/lib
39 | )
40 |
41 | FIND_LIBRARY(DCPSISOCPP_LIBRARY
42 | NAMES
43 | dcpsisocpp
44 | PATHS
45 | $ENV{OSPL_HOME}/lib
46 | )
47 |
48 | FIND_LIBRARY(DCPSCPP_LIBRARY
49 | NAMES
50 | dcpssacpp
51 | PATHS
52 | $ENV{OSPL_HOME}/lib
53 | )
54 |
55 | FIND_LIBRARY(DCPSISOCPP2_LIBRARY
56 | NAMES
57 | dcpsisocpp2
58 | PATHS
59 | $ENV{OSPL_HOME}/lib
60 | )
61 |
62 | SET(OpenSplice_LIBRARIES
63 | ${KERNEL_LIBRARY}
64 | ${DCPSISOCPP2_LIBRARY}
65 | ${DCPSISOCPP_LIBRARY}
66 | ${DCPSCPP_LIBRARY}
67 |
68 | )
69 |
70 | # Binary for the IDL compiler
71 | SET (OpenSplice_IDLGEN_BINARY $ENV{OSPL_HOME}/bin/idlpp)
72 |
73 | IF (OpenSplice_INCLUDE_DIRS AND OpenSplice_LIBRARIES)
74 | SET(OpenSplice_FOUND TRUE)
75 | ENDIF (OpenSplice_INCLUDE_DIRS AND OpenSplice_LIBRARIES)
76 |
77 | IF (OpenSplice_FOUND)
78 | MESSAGE(STATUS "Found OpenSplice DDS libraries: ${OpenSplice_LIBRARIES}")
79 | ELSE (OpenSplice_FOUND)
80 | IF (OpenSplice_FIND_REQUIRED)
81 | MESSAGE(FATAL_ERROR "Could not find OpenSplice DDS")
82 | ENDIF (OpenSplice_FIND_REQUIRED)
83 | ENDIF (OpenSplice_FOUND)
84 |
85 | MARK_AS_ADVANCED(OpenSplice_INCLUDE_DIRS OpenSplice_LIBRARIES OpenSplice_IDLGEN_BINARY)
86 | INCLUDE (MacroOpenSplice)
--------------------------------------------------------------------------------
/DDS/OpenSplice DDS (C++ API)/Starter Code and Resources/opensplice_minimal/cmake/MacroOpenSplice.cmake:
--------------------------------------------------------------------------------
1 | ##############################################################################
2 | # OpenSplice_IDLGEN(idlfilename)
3 | #
4 | # Macro to generate OpenSplice DDS sources from a given idl file with the
5 | # data structures.
6 | # You must include the extension .idl in the name of the data file.
7 | #
8 | ##############################################################################
9 | # Courtersy of Ivan Galvez Junquera
10 | ##############################################################################
11 |
12 |
13 | # Macro to create a list with all the generated source files for a given .idl filename
14 | MACRO (DEFINE_OpenSplice_SOURCES idlfilename)
15 | SET(outsources)
16 | GET_FILENAME_COMPONENT(it ${idlfilename} ABSOLUTE)
17 | GET_FILENAME_COMPONENT(nfile ${idlfilename} NAME_WE)
18 | SET(outsources ${outsources} gen/${nfile}.cpp gen/${nfile}.h)
19 | SET(outsources ${outsources} gen/${nfile}Dcps.cpp gen/${nfile}Dcps.h)
20 | SET(outsources ${outsources} gen/${nfile}Dcps_impl.cpp gen/${nfile}Dcps_impl.h)
21 | SET(outsources ${outsources} gen/${nfile}SplDcps.cpp gen/${nfile}SplDcps.h)
22 | SET(outsources ${outsources} gen/ccpp_${nfile}.h)
23 | ENDMACRO(DEFINE_OpenSplice_SOURCES)
24 |
25 | MACRO (OpenSplice_IDLGEN idlfilename)
26 | GET_FILENAME_COMPONENT(it ${idlfilename} ABSOLUTE)
27 | GET_FILENAME_COMPONENT(idlfilename ${idlfilename} NAME)
28 | DEFINE_OpenSplice_SOURCES(${ARGV})
29 | ADD_CUSTOM_COMMAND (
30 | OUTPUT ${outsources}
31 | COMMAND ${OpenSplice_IDLGEN_BINARY}
32 | ARGS -l isocpp -d gen ${idlfilename}
33 | DEPENDS ${it}
34 | )
35 | ENDMACRO (OpenSplice_IDLGEN)
36 |
--------------------------------------------------------------------------------
/DDS/OpenSplice DDS (C++ API)/Starter Code and Resources/opensplice_minimal/cmake/osmacros.cmake:
--------------------------------------------------------------------------------
1 | IF (WIN32)
2 | SET (DEFINITIONS "/DSIMD_NOSTARTOSPL=0")
3 | ELSE (WIN32)
4 | SET (DEFINITIONS "-DNDEBUG -g -O2 -std=c++11 -pipe -Wall")
5 | ENDIF (WIN32)
6 |
7 | # SET (DEFINITIONS "-g -O2 -pipe -std=c++0x ")
8 | # IF (WIN32)
9 | # IF(DEBUG)
10 | # SET (DEFINITIONS "-DNDEBUG -std=c++0x")
11 | # ENDIF(DEBUG)
12 | # ELSE (WIN32)
13 | # IF(DEBUG)
14 | # SET (DEFINITIONS "-ansi -g3 -pg -pipe -std=c++0x")
15 | # ELSE(DEBUG)
16 | # IF(PEDANTIC)
17 | # SET (DEFINITIONS "-ansi -g -pg -pipe -Wall -Wstrict-null-sentinel -Weffc++ -Wold-style-cast -pedantic -std=c++0x")
18 | # SET (DEBUG 1)
19 | # ELSE(PEDANTIC)
20 | # SET (DEFINITIONS "-DNDEBUG -O5 -pipe -std=c++0x")
21 | # ENDIF(PEDANTIC)
22 | # ENDIF(DEBUG)
23 | # ENDIF (WIN32)
--------------------------------------------------------------------------------
/DDS/OpenSplice DDS (C++ API)/Starter Code and Resources/opensplice_minimal/compile:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env bash
2 |
3 | if [ ! -d "build" ]; then
4 | mkdir build
5 | fi
6 |
7 | cd build
8 | cmake ..
9 | make
--------------------------------------------------------------------------------
/DDS/OpenSplice DDS (C++ API)/Starter Code and Resources/opensplice_minimal/gencode:
--------------------------------------------------------------------------------
1 | #/usr/bin/env bash
2 |
3 | if [ "$(ls -A gen)" ]; then
4 | rm gen/*.cpp
5 | rm gen/*.h
6 | rm gen/*.hpp
7 | fi
8 |
9 | #idlpp -S -l c++ -I $OSPL_HOME/etc/idl -d src idl/*.idl
10 |
11 | #$OSPL_HOME/bin/./idlpp -l isoc++2 -I$OSPL_HOME/etc/idlpp -d gen idl/*.idl
12 |
13 | $OSPL_HOME/bin/./idlpp -S -l cpp -d gen idl/*.idl
14 |
15 |
--------------------------------------------------------------------------------
/DDS/OpenSplice DDS (C++ API)/Starter Code and Resources/opensplice_minimal/idl/HelloWorld.idl:
--------------------------------------------------------------------------------
1 | /** Modules mean that the Msg will be put into a corresponding namespace when the message header is generated */
2 | module HelloWorld
3 | {
4 | struct Msg
5 | {
6 | /** User ID */
7 | long userID;
8 | /** message */
9 | string message;
10 | };
11 | #pragma keylist Msg userID
12 | };
13 |
--------------------------------------------------------------------------------
/DDS/OpenSplice DDS (C++ API)/Starter Code and Resources/opensplice_minimal/src/.pub.cpp.swp:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/methylDragon/coding-notes/b9dcabff04e0a29160728aeaaad18f1364067493/DDS/OpenSplice DDS (C++ API)/Starter Code and Resources/opensplice_minimal/src/.pub.cpp.swp
--------------------------------------------------------------------------------
/DDS/OpenSplice DDS (C++ API)/Starter Code and Resources/opensplice_minimal/src/CheckStatus.cpp:
--------------------------------------------------------------------------------
1 |
2 | /*
3 | * OpenSplice DDS
4 | *
5 | * This software and documentation are Copyright 2006 to PrismTech
6 | * Limited, its affiliated companies and licensors. All rights reserved.
7 | *
8 | * Licensed under the Apache License, Version 2.0 (the "License");
9 | * you may not use this file except in compliance with the License.
10 | * You may obtain a copy of the License at
11 | *
12 | * http://www.apache.org/licenses/LICENSE-2.0
13 | *
14 | * Unless required by applicable law or agreed to in writing, software
15 | * distributed under the License is distributed on an "AS IS" BASIS,
16 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
17 | * See the License for the specific language governing permissions and
18 | * limitations under the License.
19 | *
20 | */
21 |
22 | /************************************************************************
23 | * LOGICAL_NAME: CheckStatus.cpp
24 | * FUNCTION: OpenSplice Tutorial example code.
25 | * MODULE: Tutorial for the C++ programming language.
26 | * DATE june 2007.
27 | ************************************************************************
28 | *
29 | * This file contains the implementation for the error handling operations.
30 | *
31 | ***/
32 |
33 | #include "CheckStatus.h"
34 |
35 | /* Array to hold the names for all ReturnCodes. */
36 | string RetCodeName[13] =
37 | {
38 | "DDS_RETCODE_OK", "DDS_RETCODE_ERROR", "DDS_RETCODE_UNSUPPORTED",
39 | "DDS_RETCODE_BAD_PARAMETER", "DDS_RETCODE_PRECONDITION_NOT_MET",
40 | "DDS_RETCODE_OUT_OF_RESOURCES", "DDS_RETCODE_NOT_ENABLED",
41 | "DDS_RETCODE_IMMUTABLE_POLICY", "DDS_RETCODE_INCONSISTENT_POLICY",
42 | "DDS_RETCODE_ALREADY_DELETED", "DDS_RETCODE_TIMEOUT", "DDS_RETCODE_NO_DATA",
43 | "DDS_RETCODE_ILLEGAL_OPERATION"
44 | };
45 |
46 | /**
47 | * Returns the name of an error code.
48 | **/
49 | string getErrorName(DDS::ReturnCode_t status)
50 | {
51 | return RetCodeName[status];
52 | }
53 |
54 | /**
55 | * Check the return status for errors. If there is an error, then terminate.
56 | **/
57 | void checkStatus(DDS::ReturnCode_t status, const char *info)
58 | {
59 |
60 |
61 | if (status != DDS::RETCODE_OK && status != DDS::RETCODE_NO_DATA)
62 | {
63 | cerr << "Error in " << info << ": " << getErrorName(status).c_str() << endl;
64 | exit(1);
65 | }
66 | }
67 |
68 | /**
69 | * Check whether a valid handle has been returned. If not, then terminate.
70 | **/
71 | void checkHandle(void *handle, string info)
72 | {
73 |
74 | if (!handle)
75 | {
76 | cerr << "Error in " << info.c_str() << ": Creation failed: invalid handle" << endl;
77 | exit(1);
78 | }
79 | }
80 |
--------------------------------------------------------------------------------
/DDS/OpenSplice DDS (C++ API)/Starter Code and Resources/opensplice_minimal/src/CheckStatus.h:
--------------------------------------------------------------------------------
1 |
2 | /*
3 | * OpenSplice DDS
4 | *
5 | * This software and documentation are Copyright 2006 to PrismTech
6 | * Limited, its affiliated companies and licensors. All rights reserved.
7 | *
8 | * Licensed under the Apache License, Version 2.0 (the "License");
9 | * you may not use this file except in compliance with the License.
10 | * You may obtain a copy of the License at
11 | *
12 | * http://www.apache.org/licenses/LICENSE-2.0
13 | *
14 | * Unless required by applicable law or agreed to in writing, software
15 | * distributed under the License is distributed on an "AS IS" BASIS,
16 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
17 | * See the License for the specific language governing permissions and
18 | * limitations under the License.
19 | *
20 | */
21 |
22 | /************************************************************************
23 | * LOGICAL_NAME: CheckStatus.h
24 | * FUNCTION: OpenSplice Tutorial example code.
25 | * MODULE: Tutorial for the C++ programming language.
26 | * DATE june 2007.
27 | ************************************************************************
28 | *
29 | * This file contains the headers for the error handling operations.
30 | *
31 | ***/
32 |
33 | #ifndef __CHECKSTATUS_H__
34 | #define __CHECKSTATUS_H__
35 |
36 | #include "ccpp_dds_dcps.h"
37 | #include
38 |
39 | using namespace std;
40 |
41 | /**
42 | * Returns the name of an error code.
43 | **/
44 | string getErrorName(DDS::ReturnCode_t status);
45 |
46 | /**
47 | * Check the return status for errors. If there is an error, then terminate.
48 | **/
49 | void checkStatus(DDS::ReturnCode_t status, const char *info);
50 |
51 | /**
52 | * Check whether a valid handle has been returned. If not, then terminate.
53 | **/
54 | void checkHandle(void *handle, string info);
55 |
56 | #endif
57 |
--------------------------------------------------------------------------------
/DDS/OpenSplice DDS (C++ API)/Starter Code and Resources/opensplice_minimal/src/DDSEntityManager.cpp:
--------------------------------------------------------------------------------
1 |
2 | #include "DDSEntityManager.h"
3 |
4 |
5 | void DDSEntityManager::createParticipant(const char *partitiontName)
6 | {
7 | domain = DOMAIN_ID_DEFAULT;
8 | dpf = DomainParticipantFactory::get_instance();
9 | checkHandle(dpf.in(), "DDS::DomainParticipantFactory::get_instance");
10 | participant = dpf->create_participant(domain, PARTICIPANT_QOS_DEFAULT, NULL,
11 | STATUS_MASK_NONE);
12 | checkHandle(participant.in(),
13 | "DDS::DomainParticipantFactory::create_participant");
14 | partition = partitiontName;
15 | }
16 |
17 | void DDSEntityManager::deleteParticipant()
18 | {
19 | status = dpf->delete_participant(participant.in());
20 | checkStatus(status, "DDS::DomainParticipant::delete_participant ");
21 | }
22 |
23 | void DDSEntityManager::registerType(TypeSupport *ts)
24 | {
25 | typeName = ts->get_type_name();
26 | status = ts->register_type(participant.in(), typeName);
27 | checkStatus(status, "register_type");
28 | }
29 |
30 | void DDSEntityManager::createTopic(char *topicName)
31 | {
32 | status = participant->get_default_topic_qos(reliable_topic_qos);
33 | checkStatus(status, "DDS::DomainParticipant::get_default_topic_qos");
34 | reliable_topic_qos.reliability.kind = RELIABLE_RELIABILITY_QOS;
35 | reliable_topic_qos.durability.kind = TRANSIENT_DURABILITY_QOS;
36 |
37 | /* Make the tailored QoS the new default. */
38 | status = participant->set_default_topic_qos(reliable_topic_qos);
39 | checkStatus(status, "DDS::DomainParticipant::set_default_topic_qos");
40 |
41 | /* Use the changed policy when defining the HelloWorld topic */
42 | topic = participant->create_topic(topicName, typeName, reliable_topic_qos,
43 | NULL, STATUS_MASK_NONE);
44 | checkHandle(topic.in(), "DDS::DomainParticipant::create_topic ()");
45 | }
46 |
47 | void DDSEntityManager::deleteTopic()
48 | {
49 | status = participant->delete_topic(topic);
50 | checkStatus(status, "DDS.DomainParticipant.delete_topic");
51 | }
52 |
53 | void DDSEntityManager::createPublisher()
54 | {
55 | status = participant->get_default_publisher_qos(pub_qos);
56 | checkStatus(status, "DDS::DomainParticipant::get_default_publisher_qos");
57 | pub_qos.partition.name.length(1);
58 | pub_qos.partition.name[0] = partition;
59 |
60 | publisher = participant->create_publisher(pub_qos, NULL, STATUS_MASK_NONE);
61 | checkHandle(publisher.in(), "DDS::DomainParticipant::create_publisher");
62 | }
63 |
64 | void DDSEntityManager::deletePublisher()
65 | {
66 | status = participant->delete_publisher(publisher.in());
67 | checkStatus(status, "DDS::DomainParticipant::delete_publisher ");
68 | }
69 |
70 |
71 | void DDSEntityManager::createWriter()
72 | {
73 | writer = publisher->create_datawriter(topic.in(),
74 | DATAWRITER_QOS_USE_TOPIC_QOS, NULL, STATUS_MASK_NONE);
75 | checkHandle(writer, "DDS::Publisher::create_datawriter");
76 | }
77 |
78 | void DDSEntityManager::createWriter(bool autodispose_unregistered_instances)
79 | {
80 | status = publisher->get_default_datawriter_qos(dw_qos);
81 | checkStatus(status, "DDS::DomainParticipant::get_default_publisher_qos");
82 | status = publisher->copy_from_topic_qos(dw_qos, reliable_topic_qos);
83 | checkStatus(status, "DDS::Publisher::copy_from_topic_qos");
84 | // Set autodispose to false so that you can start
85 | // the subscriber after the publisher
86 | dw_qos.writer_data_lifecycle.autodispose_unregistered_instances =
87 | autodispose_unregistered_instances;
88 | writer = publisher->create_datawriter(topic.in(), dw_qos, NULL,
89 | STATUS_MASK_NONE);
90 | checkHandle(writer, "DDS::Publisher::create_datawriter");
91 | }
92 |
93 | void DDSEntityManager::deleteWriter()
94 | {
95 | status = publisher->delete_datawriter(writer);
96 | checkStatus(status, "DDS::Publisher::delete_datawriter ");
97 | }
98 |
99 | void DDSEntityManager::createSubscriber()
100 | {
101 | int status = participant->get_default_subscriber_qos(sub_qos);
102 | checkStatus(status, "DDS::DomainParticipant::get_default_subscriber_qos");
103 | sub_qos.partition.name.length(1);
104 | sub_qos.partition.name[0] = partition;
105 | subscriber = participant->create_subscriber(sub_qos, NULL, STATUS_MASK_NONE);
106 | checkHandle(subscriber.in(), "DDS::DomainParticipant::create_subscriber");
107 | }
108 |
109 | void DDSEntityManager::deleteSubscriber()
110 | {
111 | status = participant->delete_subscriber(subscriber);
112 | checkStatus(status, "DDS::DomainParticipant::delete_subscriber ");
113 | }
114 |
115 | void DDSEntityManager::createReader()
116 | {
117 | reader = subscriber->create_datareader(topic.in(),
118 | DATAREADER_QOS_USE_TOPIC_QOS, NULL, STATUS_MASK_NONE);
119 | checkHandle(reader, "DDS::Subscriber::create_datareader ()");
120 | }
121 |
122 | void DDSEntityManager::deleteReader()
123 | {
124 | status = subscriber->delete_datareader(reader);
125 | checkStatus(status, "DDS::Subscriber::delete_datareader ");
126 | }
127 |
128 | DataReader_ptr DDSEntityManager::getReader()
129 | {
130 | return DataReader::_duplicate(reader.in());
131 | }
132 |
133 | DataWriter_ptr DDSEntityManager::getWriter()
134 | {
135 | return DataWriter::_duplicate(writer.in());
136 | }
137 |
138 | Publisher_ptr DDSEntityManager::getPublisher()
139 | {
140 | return Publisher::_duplicate(publisher.in());
141 | }
142 |
143 | Subscriber_ptr DDSEntityManager::getSubscriber()
144 | {
145 | return Subscriber::_duplicate(subscriber.in());
146 | }
147 |
148 | Topic_ptr DDSEntityManager::getTopic()
149 | {
150 | return Topic::_duplicate(topic.in());
151 | }
152 |
153 | DomainParticipant_ptr DDSEntityManager::getParticipant()
154 | {
155 | return DomainParticipant::_duplicate(participant.in());
156 | }
157 |
158 | DDSEntityManager::~DDSEntityManager(){
159 |
160 | }
161 |
--------------------------------------------------------------------------------
/DDS/OpenSplice DDS (C++ API)/Starter Code and Resources/opensplice_minimal/src/DDSEntityManager.h:
--------------------------------------------------------------------------------
1 |
2 | #ifndef _DDSENTITYMGR_
3 | #define _DDSENTITYMGR_
4 |
5 |
6 | #include "ccpp_dds_dcps.h"
7 | #include "CheckStatus.h"
8 | using namespace DDS;
9 |
10 | class DDSEntityManager
11 | {
12 |
13 | /* Generic DDS entities */
14 | DomainParticipantFactory_var dpf;
15 | DomainParticipant_var participant;
16 | Topic_var topic;
17 | Publisher_var publisher;
18 | Subscriber_var subscriber;
19 | DataWriter_var writer;
20 | DataReader_var reader;
21 |
22 | /* QosPolicy holders */
23 | TopicQos reliable_topic_qos;
24 | TopicQos setting_topic_qos;
25 | PublisherQos pub_qos;
26 | DataWriterQos dw_qos;
27 | SubscriberQos sub_qos;
28 |
29 | DomainId_t domain;
30 | ReturnCode_t status;
31 |
32 | DDS::String_var partition;
33 | DDS::String_var typeName;
34 | public:
35 | void createParticipant(const char *partitiontName);
36 | void deleteParticipant();
37 | void registerType(TypeSupport *ts);
38 | void createTopic(char *topicName);
39 | void deleteTopic();
40 | void createPublisher();
41 | void deletePublisher();
42 | void createWriter();
43 | void createWriter(bool autodispose_unregistered_instances);
44 | void deleteWriter();
45 | void createSubscriber();
46 | void deleteSubscriber();
47 | void createReader();
48 | void deleteReader();
49 | DataReader_ptr getReader();
50 | DataWriter_ptr getWriter();
51 | Publisher_ptr getPublisher();
52 | Subscriber_ptr getSubscriber();
53 | Topic_ptr getTopic();
54 | DomainParticipant_ptr getParticipant();
55 | ~DDSEntityManager();
56 | };
57 |
58 | #endif
59 |
--------------------------------------------------------------------------------
/DDS/OpenSplice DDS (C++ API)/Starter Code and Resources/opensplice_minimal/src/pub.cpp:
--------------------------------------------------------------------------------
1 |
2 | // -- Std C/C++ Include
3 | #include
4 | #include
5 | #include
6 |
7 | #include "ccpp_HelloWorld.h"
8 | #include // std::thread, std::this_thread::sleep_for
9 | #include
10 | #include "DDSEntityManager.h"
11 |
12 | using namespace DDS;
13 | using namespace HelloWorld;
14 |
15 | int main(int argc, char* argv[])
16 | {
17 | os_time delay_1s = { 1, 0 };
18 | DDSEntityManager mgr;
19 |
20 | // create domain participant
21 | mgr.createParticipant("HelloWorld example");
22 |
23 | //create type
24 | MsgTypeSupport_var mt = new MsgTypeSupport();
25 | mgr.registerType(mt.in());
26 |
27 | //create Topic
28 | char topic_name[] = "HelloWorldData_Msg";
29 | mgr.createTopic(topic_name);
30 |
31 | //create Publisher
32 | mgr.createPublisher();
33 |
34 | // create DataWriter :
35 | // If autodispose_unregistered_instances is set to true (default value),
36 | // you will have to start the subscriber before the publisher
37 | bool autodispose_unregistered_instances = false;
38 | mgr.createWriter(autodispose_unregistered_instances);
39 |
40 | // Publish Events
41 | DataWriter_var dwriter = mgr.getWriter();
42 | MsgDataWriter_var HelloWorldWriter = MsgDataWriter::_narrow(dwriter.in());
43 |
44 | Msg msgInstance; /* Example on Stack */
45 | msgInstance.userID = 1;
46 | msgInstance.message = DDS::string_dup("Hello World");
47 | cout << "=== [Publisher] writing a message containing :" << endl;
48 | cout << " userID : " << msgInstance.userID << endl;
49 | cout << " Message : \"" << msgInstance.message << "\"" << endl;
50 |
51 | ReturnCode_t status = HelloWorldWriter->write(msgInstance, DDS::HANDLE_NIL);
52 | checkStatus(status, "MsgDataWriter::write");
53 | os_nanoSleep(delay_1s);
54 |
55 | /* Remove the DataWriters */
56 | mgr.deleteWriter();
57 |
58 | /* Remove the Publisher. */
59 | mgr.deletePublisher();
60 |
61 | /* Remove the Topics. */
62 | mgr.deleteTopic();
63 |
64 | /* Remove Participant. */
65 | mgr.deleteParticipant();
66 |
67 | return 0;
68 | }
69 |
--------------------------------------------------------------------------------
/DDS/OpenSplice DDS (C++ API)/Starter Code and Resources/opensplice_minimal/src/sub.cpp:
--------------------------------------------------------------------------------
1 | // -- Std C/C++ Include
2 | #include
3 | #include
4 | #include
5 |
6 | #include "ccpp_HelloWorld.h"
7 | #include // std::thread, std::this_thread::sleep_for
8 | #include
9 | #include "DDSEntityManager.h"
10 |
11 | using namespace DDS;
12 | using namespace HelloWorld;
13 |
14 |
15 | int main(int argc, char* argv[])
16 | {
17 | os_time delay_2ms = { 0, 2000000 };
18 | os_time delay_200ms = { 0, 200000000 };
19 | MsgSeq msgList;
20 | SampleInfoSeq infoSeq;
21 |
22 | DDSEntityManager mgr;
23 |
24 | // create domain participant
25 | mgr.createParticipant("HelloWorld example");
26 |
27 | //create type
28 | MsgTypeSupport_var mt = new MsgTypeSupport();
29 | mgr.registerType(mt.in());
30 |
31 | //create Topic
32 | char topic_name[] = "HelloWorldData_Msg";
33 | mgr.createTopic(topic_name);
34 |
35 | //create Subscriber
36 | mgr.createSubscriber();
37 |
38 | // create DataReader
39 | mgr.createReader();
40 |
41 | DataReader_var dreader = mgr.getReader();
42 | MsgDataReader_var HelloWorldReader = MsgDataReader::_narrow(dreader.in());
43 | checkHandle(HelloWorldReader.in(), "MsgDataReader::_narrow");
44 |
45 | cout << "=== [Subscriber] Ready ..." << endl;
46 |
47 | bool closed = false;
48 | ReturnCode_t status = - 1;
49 | int count = 0;
50 | while (!closed && count < 1500) // We dont want the example to run indefinitely
51 | {
52 | status = HelloWorldReader->take(msgList, infoSeq, LENGTH_UNLIMITED,
53 | ANY_SAMPLE_STATE, ANY_VIEW_STATE, ANY_INSTANCE_STATE);
54 | checkStatus(status, "msgDataReader::take");
55 | for (DDS::ULong j = 0; j < msgList.length(); j++)
56 | {
57 | cout << "=== [Subscriber] message received :" << endl;
58 | cout << " userID : " << msgList[j].userID << endl;
59 | cout << " Message : \"" << msgList[j].message << "\"" << endl;
60 | closed = true;
61 | }
62 | status = HelloWorldReader->return_loan(msgList, infoSeq);
63 | checkStatus(status, "MsgDataReader::return_loan");
64 | os_nanoSleep(delay_200ms);
65 | ++count;
66 | }
67 |
68 | os_nanoSleep(delay_2ms);
69 |
70 | //cleanup
71 | mgr.deleteReader();
72 | mgr.deleteSubscriber();
73 | mgr.deleteTopic();
74 | mgr.deleteParticipant();
75 |
76 | return 0;
77 | }
--------------------------------------------------------------------------------
/Java/assets/01 Java - Introduction (WIP)/access-modifier.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/methylDragon/coding-notes/b9dcabff04e0a29160728aeaaad18f1364067493/Java/assets/01 Java - Introduction (WIP)/access-modifier.png
--------------------------------------------------------------------------------
/Java/assets/01 Java - Introduction (WIP)/image-20210224233948818.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/methylDragon/coding-notes/b9dcabff04e0a29160728aeaaad18f1364067493/Java/assets/01 Java - Introduction (WIP)/image-20210224233948818.png
--------------------------------------------------------------------------------
/Java/assets/01 Java - Introduction (WIP)/image-20210224234856306.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/methylDragon/coding-notes/b9dcabff04e0a29160728aeaaad18f1364067493/Java/assets/01 Java - Introduction (WIP)/image-20210224234856306.png
--------------------------------------------------------------------------------
/Java/assets/01 Java - Introduction (WIP)/image-20210224235651731.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/methylDragon/coding-notes/b9dcabff04e0a29160728aeaaad18f1364067493/Java/assets/01 Java - Introduction (WIP)/image-20210224235651731.png
--------------------------------------------------------------------------------
/Java/assets/01 Java - Introduction (WIP)/image-20210224235752129.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/methylDragon/coding-notes/b9dcabff04e0a29160728aeaaad18f1364067493/Java/assets/01 Java - Introduction (WIP)/image-20210224235752129.png
--------------------------------------------------------------------------------
/Java/assets/01 Java - Introduction (WIP)/java_array.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/methylDragon/coding-notes/b9dcabff04e0a29160728aeaaad18f1364067493/Java/assets/01 Java - Introduction (WIP)/java_array.jpg
--------------------------------------------------------------------------------
/Java/assets/01 Java - Introduction (WIP)/multiple.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/methylDragon/coding-notes/b9dcabff04e0a29160728aeaaad18f1364067493/Java/assets/01 Java - Introduction (WIP)/multiple.jpg
--------------------------------------------------------------------------------
/Java/assets/01 Java - Introduction (WIP)/typesofinheritance.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/methylDragon/coding-notes/b9dcabff04e0a29160728aeaaad18f1364067493/Java/assets/01 Java - Introduction (WIP)/typesofinheritance.jpg
--------------------------------------------------------------------------------
/Java/assets/1568361459025.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/methylDragon/coding-notes/b9dcabff04e0a29160728aeaaad18f1364067493/Java/assets/1568361459025.png
--------------------------------------------------------------------------------
/Java/assets/animalClasses.PNG:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/methylDragon/coding-notes/b9dcabff04e0a29160728aeaaad18f1364067493/Java/assets/animalClasses.PNG
--------------------------------------------------------------------------------
/Java/assets/java-arch.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/methylDragon/coding-notes/b9dcabff04e0a29160728aeaaad18f1364067493/Java/assets/java-arch.png
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | BSD 2-Clause License
2 |
3 | Copyright (c) 2017 methylDragon
4 | All rights reserved.
5 |
6 | Redistribution and use in source and binary forms, with or without
7 | modification, are permitted provided that the following conditions are met:
8 |
9 | * Redistributions of source code must retain the above copyright notice, this
10 | list of conditions and the following disclaimer.
11 |
12 | * Redistributions in binary form must reproduce the above copyright notice,
13 | this list of conditions and the following disclaimer in the documentation
14 | and/or other materials provided with the distribution.
15 |
16 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
17 | AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
18 | IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
19 | DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
20 | FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
21 | DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
22 | SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
23 | CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
24 | OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
25 | OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
--------------------------------------------------------------------------------
/MATLAB/assets/1553825732887.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/methylDragon/coding-notes/b9dcabff04e0a29160728aeaaad18f1364067493/MATLAB/assets/1553825732887.png
--------------------------------------------------------------------------------
/MATLAB/assets/COFFEE BUTTON ヾ(°∇°^).png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/methylDragon/coding-notes/b9dcabff04e0a29160728aeaaad18f1364067493/MATLAB/assets/COFFEE BUTTON ヾ(°∇°^).png
--------------------------------------------------------------------------------
/MySQL/01 MySQL - Introduction.md:
--------------------------------------------------------------------------------
1 | # MySQL Quickstart Guide
2 |
3 | Author: methylDragon
4 | It's quick a tutorial to get you up to speed for MySQL!
5 | I'll be adapting it from the ever amazing Derek Banas: https://www.youtube.com/watch?v=yPu6qV5byu4
6 |
7 | ------
8 |
9 | ## Pre-Requisites
10 |
11 | ### Assumed knowledge (This is a syntax reference, and an intermediate tutorial, not a basic coding tutorial)
12 |
13 | - CAN YOU LOGIC? IF SO CARRY ON HMHM
14 | - Terminal ($ are terminal commands, > are MySQL terminal commands)
15 |
16 | ### Good to know
17 |
18 | - PHP
19 | - General coding syntax (I'll use # for comments)
20 |
21 |
22 |
23 | ## Table Of Contents
24 |
25 | 1. [Introduction](#1)
26 | 1.1 [MySQL Database Architecture](#1.1)
27 | 2. [Basic Syntax Reference](#2)
28 | 2.1 [Logging In and Logging Out](#2.1)
29 | 2.2 [Database Comments](#2.2)
30 | 2.3 [Database Design](#2.3)
31 | 2.4 [Table Creaton](#2.4)
32 | 2.5 [Data Types](#2.5)
33 | 2.6 [Primary Keys](#2.6)
34 | 2.7 [Foreign Keys](#2.7)
35 | 2.8 [Inserting and Deleting Data](#2.8)
36 | 2.9 [Displaying Table Values](#2.9) (Also with filters!)
37 | 2.10 [Displaying Table Values](#2.10) (With Data Conditionals!)
38 | 2.11 [Altering Tables](#2.11)
39 | 2.12 [Renaming Tables](#2.12)
40 | 2.13 [Joins](#2.13)
41 | 2.14 [Advanced Joins](#2.14) (Inner and Left/Right)
42 | 3. [Reference Links](#3)
43 |
44 |
45 |
46 | ## 1. Introduction
47 |
48 | >MySQL is a database, used for storing information in a way that makes it easy to get at particular pieces of information when you want them. It can be used for lots of things, but in this case, it's to store data to be used for a website. (r/eli5)
49 |
50 | We're going to learn how to interface with, and alter MySQL databases in this reference! You can do so
51 |
52 | - Via **Terminal**
53 |
54 | - Via **PHP** using said terminal commands (referred to as Queries!)
55 |
56 | - Via **Python** using the mySQL.connector plugin or sqlite3
57 |
58 | - For python, a cursor object has to be initialized, after which the commands can be passed to it as is:
59 |
60 | ```python
61 | import mysql.connector
62 |
63 | # Create database connection
64 | mydb = mysql.connector.connect(
65 | host="localhost",
66 | user="username",
67 | passwd="passwd"
68 | database="mydatabase"
69 | )
70 |
71 | mycursor = mydb.cursor() # Creates the cursor
72 | mycursor.execute("INSERT SQL COMMANDS HERE") # execute desired SQL terminal commands
73 | ```
74 |
75 |
76 |
77 | If you want a GUI program to access your database, use https://www.mysql.com/products/workbench/
78 |
79 | If working on WordPress, there's a bunch of handy database plugins out here. One of which is ARI Adminer. But apparently you can also use MySQL workbench: https://www.michaelstults.com/2014/10/how-to-setup-mysql-workbench-database-for-wordpress-on-windows-server/
80 |
81 |
82 |
83 | ### 1.1 MySQL Database Architecture
84 |
85 | [go to top](#top)
86 |
87 | In MySQL, data is stored in **Tables** that are grouped within **Databases**. It works best when you can pre-define your database schemas.
88 |
89 | Within each table, each entry of data is stored in a **row** (also known as records), whereas each property that is being stored (eg. Name, Telephone Number, Index Number) define the **columns** (also known as fields.)
90 |
91 | 
92 |
93 | ## 2. Basic Syntax Reference
94 |
95 | ### 2.1 Logging In and Logging Out
96 |
97 | [go to top](#top)
98 |
99 | Naturally, in order to have write-access to a database, you have to log in.
100 |
101 | ```mysql
102 | # One of these will work depending on your mysql version to LOG IN
103 | # Key in your password when prompted
104 | $ mysql5 -u -p
105 | $ mysql -u -p
106 |
107 | # To LOG OUT
108 | > quit
109 | ```
110 |
111 |
112 |
113 | ### 2.2 Database Commands
114 |
115 | [go to top](#top)
116 |
117 | It's good practice to write your commands and keywords in upper-case. It's not required, but it's better for clarity.
118 |
119 | ```mysql
120 | # Show the list of databases
121 | > SHOW DATABASES;
122 | # Create a database
123 | > CREATE DATABASE ;
124 | > CREATE DATABASE IF NOT EXISTS ; # Creates the database if it doesn't exist
125 | # Access a database
126 | > USE ;
127 | # See which database is being used
128 | > SELECT DATABASE();
129 | # Destroy database
130 | > DROP DATABASE ;
131 | > DROP DATABASE IF EXISTS ; # Destroys the database if it exists
132 | ```
133 |
134 |
135 |
136 | ### 2.3 Database Design
137 |
138 | [go to top](#top)
139 |
140 | It's good practice to draw out your intended data input to see how you can design the schemas and tables.
141 |
142 | 
143 |
144 | Then eventually this will allow you to more easily see how to design your tables!
145 |
146 | 
147 |
148 | A nice way to design your databases is using the concept of **Atomic Tables** and **Table Templating**. You want to keep things organised so you can perform queries really quickly using your database.
149 |
150 | According to Derek Banas, this means to have
151 |
152 | - Every table focus on describing one thing (eg. dragons)
153 | - Once you decide what your table should describe, decide what properties you need to describe that thing (eg. interests, name, etc.) (these properties will then be atomic)
154 | - Write them down! If those properties require multiple inputs, pull them out and make them into separate tables (eg. things a dragon did today)
155 |
156 | Additionally:
157 |
158 | - Don't have multiple columns with the same sort of information
159 | - Don't include multiple values in one cell
160 | - Normalized tables
161 |
162 |
163 |
164 | ### 2.4 Table Creation
165 |
166 | [go to top](#top)
167 |
168 | We've run through database commands
169 |
170 | ```mysql
171 | # Create tables using the 'CREATE TABLE' command
172 | > CREATE TABLE (
173 | > );
174 |
175 | # Show the tables you've created using 'SHOW TABLES'
176 | > SHOW TABLES;
177 |
178 | # Here's an example!
179 | # I indented it for readability, but it doesn't actually get indented in terminal...
180 | > CREATE TABLE dragonsurvey(
181 | > name VARCHAR(30) NOT NULL, # Required field (NOT NULL), with expected 30 characters of data
182 | > email VARCHAR(60) NULL, # Not required field (NULL)
183 | > zip MEDIUMINT UNSIGNED NOT NULL,
184 | > likes_dragons ENUM('Y','N') NOT NULL DEFAULT 'Y', # DEFAULT VALUES WOO!
185 | > id INT UNSIGNED NOT NULL AUTO_INCREMENT PRIMARY KEY);
186 |
187 | # Now we can look at our table!
188 | > DESCRIBE dragonsurvey; # This will display the table template we just made!
189 |
190 | # Notice: The semicolon ; appeared at the end of the ENTIRE statement!
191 | ```
192 |
193 | In some instances, the backtick \` symbol might be used for table and/or column names. There are a few reasons why this is a good idea:
194 |
195 | - The desired table name goes against mySQL naming conventions (tables start with numbers, etc)
196 | - The desired table name contains symbols that can be [misinterpreted by the parser](https://stackoverflow.com/questions/7395062/mysql-insert-do-field-names-require-backtick-accent-delimination) as operators such as `-` symbols - in these cases the backtick ensures that the names are treated correctly
197 |
198 | Do take note that this would require the backtick symbol to be used when calling the table and/or columns.
199 |
200 | ### 2.5 Data Types
201 |
202 | [go to top](#top)
203 |
204 | It's a bit of a hefty list, so check here instead:
205 |
206 | https://www.w3schools.com/sql/sql_datatypes.asp
207 | https://www.techonthenet.com/mysql/datatypes.php
208 |
209 | ```mysql
210 | # The common ones are
211 |
212 | # INTEGERS
213 | TINYINT # 127 to -128
214 | SMALLINT # 32768 to -32767
215 | MEDIUMINT # 8388608 to -8388608
216 | INT # 2^31 to -2^31 -1
217 | BIGINT # 2^63 to -2^63 - 1
218 | FLOAT
219 | DOUBLE
220 |
221 | # STRINGS
222 | CHAR # Fixed length string
223 | VARCHAR # Variable length string
224 | BLOB # 2^16 bytes
225 | ENUM # Limited number of total values
226 | SET # List of possible legal character strings, can contain more than just one entry unlike ENUM
227 |
228 | # DATE and TIME
229 | DATE # YYYY-MM-DD
230 | TIME # HH:MM:SS
231 | DATETIME # YYYY-MM-DD HH:MM:SS
232 | TIMESTAMP # YYYYMMDDHHMMSS
233 | YEAR # YYYY
234 | ```
235 |
236 |
237 |
238 | ### 2.6 Primary Keys
239 |
240 | [go to top](#top)
241 |
242 | Primary keys can be thought of as **unique identifiers** for each element in a table. So think of them like serial numbers.
243 |
244 | They must be:
245 |
246 | - Unique to each row
247 | - Given a value whenever the row is created
248 | - Cannot be null
249 | - Cannot be changed
250 |
251 | It's probably best to just auto-increment the value of the key using AUTO_INCREMENT
252 |
253 |
254 |
255 | ### 2.7 Foreign Keys
256 |
257 | [go to top](#top)
258 |
259 | Foreign keys are a little bit different!
260 |
261 | In Derek Banas' words, they:
262 |
263 | - Are used to make references to the Primary Key of another table
264 | - Can have a different name from the Primary Key name
265 | - Can be NULL
266 | - Do not have to be unique
267 |
268 | Example: If a region listing and included the primary keys for all the different dragons inside (even though there's another table for dragons), those keys would be considered foreign.
269 |
270 | Another Example: Let's say you have an email server, with two tables, one for users, and one for the emails sent. The user table will have a PRIMARY KEY for user IDs, but you can reference the user IDs in the emails sent, since each email had to have been sent by a user. For the email table, the FOREIGN KEY is the user ID inputted into each row.
271 |
272 | It's a good way to ensure something exists, since multiple tables will reference it. Also a good way to set filtering constraints.
273 |
274 |
275 |
276 | ### 2.8 Inserting and Deleting Data
277 |
278 | [go to top](#top)
279 |
280 | ```mysql
281 | # Remember! If you forget how the table is structured, use DESCRIBE
282 | > DESCRIBE dragonsurvey;
283 |
284 | ####################
285 | # INSERTING VALUES #
286 | ####################
287 |
288 | # To insert a new data entry/row, use INSERT INTO VALUE
289 | > INSERT INTO dragonsurvey VALUE; # Will then create a prompt for value insertion
290 |
291 | -> ('methylDragon', 'methylDragon@gmail.com', 37771466666, 'Y', NULL); # Make sure you enter the values according to how the table is templated!
292 | # You can add multiple entires also, using the ','!
293 | # Like this: (.., ..), (..,..), (..,..);
294 | # Do note that the values to be added must ALWAYS be in tuple format - this means that if you are adding one value, it must be in the format (..,)
295 |
296 | # NULL is there for the primary key, it'll be auto-filled in since the primary key is set as AUTO_INCREMENT
297 |
298 | # Easter egg: Can you find out what methylDragon's zipcode is?
299 |
300 | # You can also specify certain columns to insert into!
301 | > INSERT INTO dragonsurvey (name, likes_dragons) VALUES;
302 | -> ('someName', 'Y');
303 |
304 | ###################
305 | # DELETING VALUES #
306 | ###################
307 |
308 | # Delete data entries/rows using DELETE FROM
309 | > DELETE FROM dragonsurvey WHERE likes_dragons="N";
310 | # HAHAHA DELETE ALL THE DRAGON HATERS
311 |
312 | ###################
313 | # UPDATING VALUES #
314 | ###################
315 |
316 | # Update entered data using UPDATE and SET
317 | > UPDATE dragonsurvey SET likes_dragons="Y" WHERE name="dragonHater";
318 | # Forces dragonHater to like dragons ... :>
319 | ```
320 |
321 |
322 |
323 | ### 2.9 Displaying Table Values (Also with filters!)
324 |
325 | [go to top](#top)
326 |
327 | ```mysql
328 | ############################
329 | # DISPLAYING AND FILTERING #
330 | ############################
331 |
332 | # Display all properties
333 | > SELECT * FROM dragonsurvey; # This will display every property of every row/data entry
334 |
335 | # Display properties selectively
336 | > SELECT , FROM dragonsurvey; # This will display the listed properties only, for all data entries
337 |
338 | # Display properties, filtering by data
339 | > SELECT , FROM dragonsurvey WHERE name="methylDragon";
340 | # Here you'll display the listed properties, for data entries where the property 'name' stores 'methylDragon'
341 |
342 | # Filter by data using a list
343 | > SELECT * FROM dragonsurvey WHERE name IN ('methylDragon', 'someName', 'anotherName');
344 | # We'll only display entries with these three names!
345 |
346 | # Filter by count using HAVING
347 | > SELECT likes_dragons, COUNT(likes_dragons) AS 'Amount' FROM dragonsurvey GROUP BY likes_dragons HAVING Amount > 1;
348 | # Displays two categories, people who like dragons and people who don't. There'll be a count for each. WILL ONLY DISPLAY THE ENTRY if the count is greater than 1.
349 |
350 | # Filter ranges of values BETWEEN certain limits
351 | > SELECT * FROM dragonsurvey WHERE zip BETWEEN '100' AND '99999'
352 | # Shows data of dragons with zipcodes between 100 and 99999
353 |
354 | # Display uniques (no duplication)
355 | > SELECT DISTINCT likes_dragons FROM dragonsurvey;
356 | # This one will just return two entries (at most), since there are only two unique entries for like_dragons
357 |
358 | #########################
359 | # ORDERING AND LIMITING #
360 | #########################
361 |
362 | # Order your displays
363 | > SELECT * FROM dragonsurvey ORDER BY name;
364 | # Orders the data displayed in alphabetical order (ascending)
365 | > SELECT * FROM dragonsurvey ORDER BY name DESC;
366 | # Orders the data displayed in alphabetical order (descending)
367 |
368 | # Order your displays, more precisely!
369 | > SELECT * FROM dragonsurvey ORDER BY name zip;
370 | # Orders first by name, then within equal names, by zip
371 |
372 | # Limit the results
373 | > SELECT * FROM dragonsurvey LIMIT 5;
374 | # Shows the first 5 results
375 | > SELECT * FROM dragonsurvey LIMIT 5, 10;
376 | # Shows the 6-10th result
377 |
378 | #########################
379 | # MANIPULATING DISPLAYS #
380 | #########################
381 |
382 | # Rename your displayed data columns
383 | > SELECT name AS "Dragon" FROM dragonsurvey;
384 |
385 | # Concatenate results
386 | > SELECT CONCAT(name, " ", id) AS "Name_ID" FROM dragonsurvey;
387 | # This will combine the name and id properties, and list it as NAME_ID
388 |
389 | # Count entries
390 | > SELECT COUNT(DISTINCT likes_dragons) FROM dragonsurvey;
391 | # Doesn't list the uniques, just counts them
392 | > SELECT COUNT(*);
393 | # Shows the number of data entries in the entire table
394 |
395 | # Group entries
396 | > SELECT likes_dragons, COUNT(*) FROM dragonsurvey GROUP BY likes_dragons;
397 | # This will display two categories, people who like dragons and people who don't. Then there'll be a count for each
398 |
399 | # MATH
400 | # Some commonly used ones: MIN(), MAX(), -, +, /, %, SUM(), AVG()
401 | # There's a lot more numeric functions
402 | ```
403 |
404 | Function list: https://www.w3schools.com/sql/sql_ref_mysql.asp
405 |
406 |
407 |
408 | ### 2.10 Displaying Table Values (With Data Conditionals!)
409 |
410 | [go to top](#top)
411 |
412 | ```mysql
413 | # Conditional operators:
414 | # = , > , < , >= , <= , !
415 | # Logical operators:
416 | # OR , || , AND , && , NOT , !
417 |
418 | # CONDITIONALS!
419 | > SELECT , FROM dragonsurvey WHERE zip > 100;
420 | # You'll display all dragonsurvey participants who have zip greater than 100;
421 |
422 | # LOGIC!
423 | > SELECT , FROM dragonsurvey WHERE zip > 100 OR name="methylDragon";
424 | # You'll display all dragonsurvey participants who have zip greater than 100 OR who are "methylDragon"
425 |
426 | # FUNCTIONS!
427 | > SELECT , FROM sometable WHERE month(date) > 02;
428 | # Filters out every entry with date of month Jan or Feb (01 and 02)
429 | # (Other functions are similarly callable!)
430 |
431 | # FORMATS!
432 | > SELECT name, id FROM dragonsurvey WHERE name LIKE 'm%' OR id LIKE '%8';
433 | # % matches any sequence of characters
434 | # _ matches any SINGLE character
435 | # This one displays entries where 'name' starts with m OR id ends with 8
436 | ```
437 |
438 |
439 |
440 | ### 2.11 Altering Tables
441 |
442 | [go to top](#top)
443 |
444 | ```mysql
445 | # To begin altering a table (adding, deleting, changing column names), use the ALTER keyword to open a prompt
446 | > ALTER TABLE dragonsurvey;
447 |
448 | # You can ADD:
449 | -> ADD colour VARCHAR(30) NOT NULL AFTER name;
450 | # The AFTER states that you want to have the property be inserted after the property called 'name'
451 |
452 | # You can CHANGE column names:
453 | > ALTER TABLE dragonsurvey CHANGE colour breath
454 | # Which will create a prompt for the new property's datatype
455 | -> ENUM('fire','ice','earth','lightning') NOT NULL;
456 |
457 | # You can MODIFY COLUMN name types
458 | > ALTER TABLE dragonsurvey MODIFY COLUMN breath VARCHAR(30) NOT NULL;
459 |
460 | # You can DROP (delete) entire TABLEs:
461 | > ALTER TABLE dragonsurvey DROP TABLE IF EXISTS dragonsurvey;
462 | # NOOOOOOO
463 | # PS: You can use IF EXISTS just to make sure it's only done if the table exists
464 |
465 | # Or, just DROP a COLUMN
466 | > ALTER TABLE dragonsurvey DROP COLUMN zip;
467 | # Why would dragons need zipcodes anyway..?
468 | ```
469 |
470 |
471 |
472 | ### 2.12 Renaming Tables
473 |
474 | [go to top](#top)
475 |
476 | ```mysql
477 | # Use the RENAME TABLE keyword to do this! It'll open a prompt
478 | > RENAME TABLE
479 | -> dragonsurvey to dragons;
480 | # You can rename multiple tables this way, just use the ',' in place of the ';' until you're done.
481 | ```
482 |
483 |
484 |
485 | ### 2.13 Joins
486 |
487 | [go to top](#top)
488 |
489 | You can JOIN two tables when you're pulling data!
490 |
491 | You have to find commonalities between tables in order to join them though!
492 |
493 | ```mysql
494 | # JOINING tables by common ID using =
495 | > SELECT * FROM table1, table2 WHERE table1.id = table2.id;
496 |
497 | # Notice, you can call specific table column names by using the .
498 | # Eg: table1.name, table2.date, etc.
499 |
500 | # You can join THREE TABLES TOO! Just use AND
501 | # Just use table1.id = table2.id AND table2.id = table3.id
502 |
503 | # All the filtering and grouping stuff mentioned in the previous tutorial catagories can be applied here as well!
504 |
505 |
506 | ```
507 |
508 |
509 |
510 | ### 2.14 Advanced Joins (Inner and Left/Right)
511 |
512 | [go to top](#top)
513 |
514 | ```mysql
515 | # LEFT JOINs return all relevant data from the first table, even if the relevant data in the second table is null
516 | > SELECT * FROM table1 LEFT JOIN table2 ON table1.id = table2.id;
517 | # The RIGHT (second) table in this case is table2
518 |
519 | # RIGHT JOINs do the opposite, prioritising the second table
520 | > SELECT * FROM table1 RIGHT JOIN table2 ON table.id = table2.id;
521 | # table2 is still the RIGHT table
522 |
523 | # INNER JOINs return all relevant data, provided no relevant data from both tables are NULL
524 | > SELECT * FROM table1 INNER JOIN table2 ON table.id = table2.id;
525 | ```
526 |
527 | Confused? No worries, someone wrote a better tutorial: https://www.sitepoint.com/understanding-sql-joins-mysql-database/
528 |
529 | ## Reference Links
530 |
531 | [go to top](#top)
532 |
533 | https://www.ntu.edu.sg/home/ehchua/programming/sql/MySQL_Beginner.html (Oh, cool, NTU has its own MySQL tutorial haha!)
534 |
535 | https://www.w3schools.com/sql/sql_ref_mysql.asp (Function list)
536 | https://www.w3schools.com/sql/sql_datatypes.asp (Data type list)
537 | https://www.techonthenet.com/mysql/datatypes.php (Also a data type list)
538 | https://www.sitepoint.com/understanding-sql-joins-mysql-database/ (Join list)
539 |
540 |
541 |
542 | ------
543 |
544 | [.png)](https://www.buymeacoffee.com/methylDragon)
--------------------------------------------------------------------------------
/MySQL/assets/MySQL Table.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/methylDragon/coding-notes/b9dcabff04e0a29160728aeaaad18f1364067493/MySQL/assets/MySQL Table.png
--------------------------------------------------------------------------------
/MySQL/assets/Student Schemas.PNG:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/methylDragon/coding-notes/b9dcabff04e0a29160728aeaaad18f1364067493/MySQL/assets/Student Schemas.PNG
--------------------------------------------------------------------------------
/MySQL/assets/Student Table.PNG:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/methylDragon/coding-notes/b9dcabff04e0a29160728aeaaad18f1364067493/MySQL/assets/Student Table.PNG
--------------------------------------------------------------------------------
/PHP/02 PHP - Object-Oriented Syntax.md:
--------------------------------------------------------------------------------
1 | # Object-Oriented PHP Syntax Reference
2 |
3 | Author: methylDragon
4 | Contains a syntax reference for Object-Oriented PHP
5 | I'll be adapting it from the ever amazing Derek Banas: https://www.youtube.com/watch?v=5YaF8xTmxs4
6 |
7 | ---
8 |
9 | ## Pre-Requisites
10 |
11 | ### Assumed knowledge (This is a syntax reference, not a basic coding tutorial)
12 |
13 | - How **variables, loops, conditionals, etc**. work
14 | - Basic **HTML**
15 | - Completed the **PHP** syntax tutorial
16 |
17 |
18 |
19 | ## Table Of Contents
20 |
21 | 1. [Introduction](#1)
22 | 1.1 [Objects and Classes](#1.1)
23 | 1.2 [Inheritance](#1.2)
24 | 1.3 [Polymorphisms](#1.3)
25 | 1.4 [Interfaces](#1.4)
26 | 2. [OOP Syntax Reference](#2)
27 | 2.1 [Visibility (Access Levels)](#2.1)
28 | 2.2 [Class Declaration](#2.2)
29 | 2.3 [Child Class Declaration](#2.3)
30 | 2.4 [Object Construction](#2.4)
31 | 2.5 [Method Polymorphisms via Child Classes](#2.5)
32 | 2.6 [A note on :: and ->](#2.6)
33 | 2.7 [A note on self and $this](#2.7)
34 | 2.8 [Interface Declaration](#2.8)
35 | 2.9 [Method Polymorphisms via Interfaces](#2.9)
36 | 2.10 [Some more useful functions](#2.10)
37 | 2.11 [Abstract Classes and Methods](#2.11)
38 | 3. [Reference Links](#3)
39 |
40 |
41 |
42 | ## 1. Introduction
43 |
44 | Let's do a refresher for some basic Object Oriented Programming (OOP) concepts!
45 |
46 | > The basis for all object oriented programming languages is the manipulation of **objects**.
47 | >
48 | > **Objects** contain **Attributes** and **Methods**. These two can be referred to collectively as the **Members** of the **Object's Class**.
49 |
50 |
51 |
52 | ### 1.1 Objects and Classes
53 |
54 | [go to top](#top)
55 |
56 | **Objects** act a lot like real-world objects. They:
57 |
58 | - Can be **created** or **destroyed**
59 | - Are instances of **Classes**
60 | - Have manipulable **Properties/Attributes**
61 | - Have callable **Methods** (it's like calling functions!)
62 |
63 | **Classes** define the **Attributes** and **Methods** of objects that belong to them! Attributes and Methods are referred collectively as the class' **Members**.
64 |
65 | So for example, you can have a class that defines an object with the property: "Colour", but the instance of the class (the object), can have any value within that property (Red, Black, etc.) **You can also state the default value of the class otherwise!**
66 |
67 | > **Example:** **methylDragon** is an object that belongs to the **Dragon** class. This gives him default attributes like:
68 | >
69 | > Color: Red
70 | > Sound: ["Rawr"] (This is an array because the object might make multiple sounds)
71 | > Breath: Fire
72 | >
73 | > And methods like:
74 | >
75 | > Sound()
76 | > Talk()
77 | > Walk()
78 | > Eat()
79 | > Fly()
80 | >
81 | > **Note:** When constructing an object belonging to a class, you **can** override the default values defined by the class. So when defining **methylDragon**, you can give him alternative attribute values! Like the **Color: Black**!
82 |
83 |
84 |
85 | ### 1.2 Inheritance
86 |
87 | [go to top](#top)
88 |
89 | Notably, **you can nest classes!** Sub-classes will then **inherit** or **overriding** the attributes and methods of their parent classes as a **polymorphism**.
90 |
91 | > **Example:** The class **Dragon** has a child class (sub-class) **Music_Dragon** that **methylDragon** belongs to!
92 | >
93 | > This can confer new methods or attributes (Like... A stage-name, and music making ability) **in addition** to any attributes and methods the **Dragon** class conferred.
94 | >
95 | > It can also override any pre-existing methods or attributes the defined objects would have had. So for example, Sound could be re-defined as containing ["Rawr", "~♪~♫~♪~♪"] by default instead!
96 | >
97 | > So now **methylDragon** has the following:
98 | >
99 | > Attributes:
100 | >
101 | > Color: Black | (Custom defined)
102 | > Sound: ["Rawr", "~♪~♫~♪~♪"] | (Overridden)
103 | > Breath: Fire | (Inherited)
104 | >
105 | > Methods:
106 | >
107 | > Sound() | (Overridden)
108 | > Talk() | (Inherited)
109 | > Walk() | (Inherited)
110 | > Eat() | (Inherited)
111 | > Fly() | (Inherited)
112 |
113 |
114 |
115 | ### 1.3 Polymorphisms
116 |
117 | [go to top](#top)
118 |
119 | You can override pre-existing methods defined by a parent class. This means that when the method is called, the child class' method definition will be used instead of the parent class'.
120 |
121 | > **Example:** The **Music_Dragon** class defines an alternate version of the Sound() method that allows objects belonging it to also make music!
122 | >
123 | > So **methylDragon** can make music! :musical_note:
124 |
125 |
126 |
127 | ### 1.4 Interfaces
128 |
129 | [go to top](#top)
130 |
131 | http://php.net/manual/en/language.oop5.interfaces.php
132 |
133 | > Object interfaces allow you to create code which specifies which methods a class must implement, without having to define how these methods are handled.
134 | >
135 | > Interfaces are defined in the same way as a class, but with the *interface* keyword replacing the *class* keyword and without any of the methods having their contents defined.
136 | >
137 | > All methods declared in an interface must be public; this is the nature of an interface.
138 |
139 | > Imagine that I make cars, and you drive them.
140 | >
141 | > Me, as the car manufacturer, don't want you to be messing around with it's internals (motor, ECU, etc), but I do want you to drive it.
142 | >
143 | > So I create the interface, wheel, buttons, etc. So you just need to learn the interface. However, nothing stops you to pop up the hood and see what's in it, right?
144 | >
145 | > Today I manufacture cars, tomorrow it can be a van, but I'll keep the same interface, and maybe add some options, so that you can still drive it without learning every little detail about cars, vans, trucks, motorcycles and so on. (r/eli5)
146 |
147 | In short, implementing an interface is like having an object sign a contract to implement any method defined in the interface.
148 |
149 |
150 |
151 | ## 2. OOP Syntax Reference
152 |
153 | ### 2.1 Visibility (Access Levels)
154 |
155 | [go to top](#top)
156 |
157 | You can restrict the visibility of an object's methods and attributes for debugging, and security purposes!
158 |
159 | The most commonly used visibility levels are: **`public`, `private`**, and **`protected`**.
160 |
161 | **If you don't declare any visibility levels, the default is public. But it's good to be explicit about it.**
162 |
163 | ```php
164 | public:
165 | // Public methods and attributes can be accessed and changed by
166 | # any class
167 |
168 | private:
169 | // Private methods and attributes can only be accessed and changed by
170 | # the same class that declared it
171 |
172 | protected:
173 | // Protected methods and attributes can be accessed and changed by
174 | # the same class that declared it
175 | # any child classes (that inherit from the class the protected data is declared in)
176 |
177 | # NOTE: Visibility affects inheritance as well! Private attributes and methods are NOT inherited
178 | ```
179 |
180 |
181 |
182 | ### 2.2 Class Declaration
183 |
184 | [go to top](#top)
185 |
186 | **Let's define an Animal class**
187 |
188 | ```php
189 | class Animal {
190 | ```
191 | **Now we can start defining attributes**
192 |
193 | ```php
194 | // In this case, there are no default values
195 | protected $name;
196 | protected $sound;
197 | protected $id;
198 |
199 | public static $number_of_animals = 0;
200 | # Static means that every object of class Animal will share this attribute and its value.
201 | # If we increment this, every object of class Animal will reflect the change. Its default
202 | # value is 0.
203 |
204 | // You can also define constants! ... If you want to.. For some reason.
205 | # You can access this particular one using Animal::e
206 | const e = "2.71828";
207 | ```
208 |
209 | **Now we can define methods!**
210 |
211 | ```php
212 | // Animals must be able to move! Let's make a function for that!
213 | public function move() {
214 | echo $this->name . " runs
";
215 | // $this refers to the object the method is called from
216 | // $this->name: "Access the data stored in $name from $this object"
217 | }
218 | ```
219 | **And a `final` method**
220 | ```php
221 | // Let's define a method that allows us to access the private attribute $name
222 | // Now you can access it by calling it from any Animal object!
223 | # The "final" keyword prevents child classes from overriding them!
224 | final public function getName() {
225 | return $this->name;
226 | }
227 | ```
228 | **And a `static` method**
229 |
230 | ```php
231 | // Static methods are defined using the "static" keyword
232 | # Static methods can be called without the need to instantiate/create an object
233 | # You call them using ClassName::method()
234 | static function add_these($num1, $num2) {
235 | return ($num1 + $num2) . "
";
236 | }
237 | ```
238 |
239 | **We're defining constructors and destructors here**
240 |
241 | ```php
242 | // We can also define special methods with __
243 | # They're called Magic Methods! Google it!
244 | # The double underscores __ denote that the method is a special method. There are others!
245 |
246 | // Now let's write a constructor method!
247 | // Class constructor methods are called each time an object/instance of the class is created
248 | public function __construct() {
249 | $this->id = $number_of_animals + 1; // Set the instance's $id
250 |
251 | echo $this->id . " has been assigned
"; // Echo out a notice
252 |
253 | // Now let's increment the static attribute $number_of_animals
254 | # You can access this using Animal::$number_of_animals
255 | Animal::$number_of_animals++; // We're incrementing it once here
256 | }
257 |
258 | // Destructor methods called each time an object/instance of the class is destroyed/unset
259 | public function __destruct() {
260 | echo $this->name . " is being destroyed
" // Echo out a notice
261 | }
262 | ```
263 | **Magic methods**
264 |
265 | ```php
266 | // PHP has some magic methods that allow us to create Getters and Setters easily
267 | # Note: These are slower than using direct method calls
268 |
269 | // Getters are functions that access and get inaccessible data
270 | public function __get($attribute) {
271 | echo "Asked for " . $attribute . "
";
272 | return $this->$attribute;
273 | }
274 |
275 | // Setters are methods that set inaccessible data
276 | public function __set($attribute, $value) {
277 | switch($attribute) {
278 | case "name" :
279 | $this->name = $value;
280 | break;
281 | case "sound" :
282 | $this->sound = $value;
283 | break;
284 | default :
285 | echo $attribute . "Not Found";
286 | die();
287 | }
288 | echo "Set " . $attribute . " to " . $value . "
";
289 | }
290 |
291 | // The __toString() method runs each time a class instance is echoed and prints whatever is returned
292 | // example: echo $object;
293 | public function __toString() {
294 | return $this->name . " is an Animal that says " . $this->sound;
295 | }
296 | }
297 | ```
298 |
299 |
300 |
301 | ### 2.3 Child Class Declaration
302 |
303 | [go to top](#top)
304 |
305 | **Now let's make a sub-class!** Remember that child classes inherit every attribute and method **except for private ones!**
306 |
307 | Let's just remake the Dragon class. (Forget anything you knew about the class from the introduction section.)
308 |
309 | ```php
310 | // The "extends" keyword is how you declare a child class
311 | class Dragon extends Animal {
312 | // Dragons fly! So let's override the move() method
313 | # Note: You cannot ovveride methods declared as "final"
314 | public function move() {
315 | echo $this-> name . " flies
";
316 | }
317 | }
318 | ```
319 |
320 |
321 |
322 | ### 2.4 Object Construction
323 |
324 | [go to top](#top)
325 |
326 | Now let's make some objects!
327 |
328 | **Let's create an Animal called Smaug**
329 |
330 | ```php
331 | // Create new instances of classes (objects) using the "new" keyword!
332 | $animal_one = new Animal();
333 |
334 | // Set attributes by accessing them using ->
335 | $animal_one->name = "Smaug";
336 | $animal_one->sound = "I am Fire. I am Death.";
337 |
338 | // Now you can use these attributes as variables!
339 | echo $animal_one->name . " says " . $animal_one->sound . "
";
340 | echo $animal_one->name . "'s ID is " . $animal_one->id . "
";
341 | echo "Total Animals: " . Animal::$number_of_animals . "
";
342 |
343 | // Get the class name of an object using get_class()
344 | echo $animal_one->name . " is a/an " . get_class($animal_one) . ".
";
345 | # This will echo "Smaug is a/an Animal."
346 |
347 | // And if you remember, we defined a static function
348 | echo "3 + 5 = " . Animal::add_these(3,5);
349 | # This will print "3 + 5 = 8"
350 | ```
351 |
352 |
353 |
354 | ### 2.5 Method Polymorphisms via Child Classes
355 |
356 | [go to top](#top)
357 |
358 | **Now let's construct a Dragon called methylDragon** (because of course)
359 |
360 | Let's see how calling move() differs between `$Smaug` and `$methylDragon`
361 |
362 | ```php
363 | $toothless = new Dragon();
364 |
365 | $toothless->name = "Toothless";
366 | $toothless->sound = "Raa"
367 |
368 | // Call an object's class method using $object->method()
369 | $toothless->move();
370 | // This will result in "Toothless flies" being printed
371 | $animal_one->move();
372 | // This will result in "Smaug runs" being printed
373 |
374 | # The polymorphism worked!
375 | ```
376 |
377 |
378 |
379 | ### 2.6 A note on `::` and `->`
380 |
381 | [go to top](#top)
382 |
383 | https://stackoverflow.com/questions/1245121/difference-between-and-in-php-mysqli-oop
384 | https://stackoverflow.com/questions/7524503/php-difference-between-and
385 |
386 | > Use `->` to access **static or non-static** members of an **object**
387 |
388 | > Use `::` to access **ONLY static** members of an **object** or **class**
389 |
390 |
391 |
392 | ### 2.7 A note on `self` and `$this`
393 |
394 | [go to top](#top)
395 |
396 | https://stackoverflow.com/questions/151969/when-to-use-self-over-this
397 |
398 | > Use `$this` to refer to the **current object.**
399 | > In other words, use `$this->member` for non-static members
400 |
401 | > Use `self` to refer to the **current class.**
402 | > In other words, use `self::$member for static members
403 |
404 | ```php
405 | // Here's a correct implementation!
406 | class myClass {
407 | private $non_static_member = 1;
408 | private static $static_member = 2;
409 |
410 | function __construct() {
411 | echo 'Non-Static: ' . $this->non_static_member . ' Static: ' . self::$static_member;
412 | }
413 | }
414 | ```
415 |
416 |
417 |
418 | ### 2.8 Interface Declaration
419 |
420 | [go to top](#top)
421 |
422 | ```php
423 | // Declare interfaces using the "interface" keyword
424 | interface Singable {
425 | public function sing();
426 | }
427 |
428 | # Note: You don't actually say what the method sing() does here. Interfaces are a way for you to help with method polymorphisms!
429 | # Interfaces are better than child classes because you can only "extend" an object once, but you can append a neverending array of interfaces.
430 | ```
431 |
432 | **NOTE: Interfaces** will **force** you to define the required methods within the classes you implement them in!
433 |
434 | **Let's implement the Singable interface now!**
435 |
436 | ```php
437 | // You let a class implement an interface using the "implements" keyword
438 | class Music_Dragon extends Dragon implements Singable {
439 | function sing() {
440 | echo $this->name . " sings '~♪~♫~♪~♪'
";
441 | }
442 | }
443 |
444 | class Human extends Animal implements Singable {
445 | function sing() {
446 | echo $this->name . " sings 'Ohhh~♪~♫'
";
447 | }
448 | }
449 | ```
450 |
451 |
452 |
453 | ### 2.9 Method Polymorphisms via Interfaces
454 |
455 | [go to top](#top)
456 |
457 | You can define functions that accept classes that **extend** a certain class or implements a certain **interface**.
458 |
459 | ```php
460 | // Let's make some objects now
461 | $methylDragon = new Music_Dragon();
462 | $bob = new Human();
463 |
464 | // And we'll give them some names
465 | $methylDragon->name = "methylDragon";
466 | $bob->name = "Bob the human";
467 |
468 | // Let's make a function that accepts classes that implement Singable
469 | function make_them_sing(Singable $singing_animal) {
470 | $singing_animal->sing();
471 | }
472 |
473 | // Now we'll call them!
474 | make_them_sing($methylDragon);
475 | // Prints "methylDragon sings '~♪~♫~♪~♪'"
476 | make_them_sing($bob);
477 | // Prints "Bob the human sings 'Ohhh~♪~♫'"
478 | ```
479 |
480 |
481 |
482 | ### 2.10 Some more useful functions
483 |
484 | [go to top](#top)
485 |
486 | ```php
487 | // Ternary operator refresher: ($var > 2) ? true : false
488 | // "Is $var greater than 2? If yes, return true, if no, return false
489 |
490 | // You can check if an object is an instance of a class using "instanceof"
491 | $is_it_an_animal = ($methylDragon instanceof Animal) ? "True" : "False";
492 | echo "It is " . $is_it_an_animal . " that $methylDragon is an Animal
"
493 | # In this case, this will echo "It is True that $methylDragon is an Animal"
494 | # Because remember, $methylDragon is a Music_Dragon, which is has Dragon, and hence Animal as a parent class
495 |
496 | // Clone objects using the "clone" keyword!
497 | $smaug_clone = clone $animal_one;
498 | # The magic method __clone() will be called everytime a object is cloned
499 |
500 | ```
501 |
502 |
503 |
504 | ### 2.11 Abstract Classes and Methods
505 |
506 | [go to top](#top)
507 |
508 | Abstract classes cannot be instantiated, but it **forces** classes that implement it to **override** any abstract methods that are members of the abstract class.
509 |
510 | ```php
511 | // Define an abstract class or method using the "abstract" keyword
512 | abstract class RandomClass {
513 | abstract function RandomFunction($attribute);
514 | }
515 | ```
516 |
517 |
518 |
519 | ## 3. Reference Links
520 |
521 | https://www.youtube.com/watch?v=5YaF8xTmxs4 (Heavily adapted)
522 | http://www.logicbig.com/tutorials/misc/php/php-oop-cheat-sheet/ (Oh look! A more in-depth cheat sheet!)
523 |
524 |
525 |
526 | ------
527 |
528 | [.png)](https://www.buymeacoffee.com/methylDragon)
--------------------------------------------------------------------------------
/Python 3/02 Python 3 - Functions and File IO.md:
--------------------------------------------------------------------------------
1 | # Functional Python 3 Crash Course
2 |
3 | Author: methylDragon
4 | Contains a syntax reference for Python 3
5 | This time, we'll be going through Functions and File I/O!
6 | I'll be adapting it from the ever amazing Derek Banas: https://www.youtube.com/watch?v=N4mEzFDjqtA
7 |
8 | ------
9 |
10 | ## Pre-Requisites
11 |
12 | ### Assumed knowledge
13 |
14 | - The previous section!
15 |
16 | ### Good to know
17 |
18 | - We're using Python 3 here! Python 2 has different syntax!
19 | - If you have knowledge of computation structures like variables, functions, OOP, etc. it'll be easier
20 | - But if not... https://www.youtube.com/playlist?list=PLGLfVvz_LVvTn3cK5e6LjhgGiSeVlIRwt
21 | - Or you can learn on the go!
22 |
23 |
24 |
25 | ## Table Of Contents
26 |
27 | 1. [Introduction](#1)
28 | 2. [Functional C++ Syntax Reference](#2)
29 | 2.1 [Functions](#2.1)
30 | 2.2 [Local and Global Variables](#2.2)
31 | 2.3 [Recursive Functions](#2.3)
32 | 2.4 [File I/O](#2.4)
33 |
34 |
35 |
36 | ## 1. Introduction
37 |
38 | We've gone through the basics of Python 3. Now let's throw in some functions and file interactions!
39 |
40 |
41 |
42 | ## 2. Functional Python 3 Syntax Reference
43 |
44 | ### 2.1 Functions
45 |
46 | [go to top](#top)
47 |
48 | Functions are chunks of code that can be called again after being declared!
49 |
50 | They're a handy way to chunk up your code so you don't have to repeat what you declared!
51 |
52 | ```python
53 | # Define a function using def
54 |
55 | def add_numbers(first_num, second_num):
56 | added_numbers = first_num + second_num
57 | return added_numbers # Stop the function and output the value stored in added_numbers
58 |
59 | # The function's name is add_numbers
60 | # And it takes two parameters, first_num and second_num
61 | # You can manipulate them inside the function, and return the result!
62 |
63 | add_numbers(1,2) # Gives 3
64 | add_numbers(4,5) # Gives 9
65 | ```
66 |
67 | #### **Optional Inputs**
68 |
69 | ```python
70 | # You can state OPTIONAL INPUTS as well!
71 |
72 | # third_num is an optional input with default value 0
73 | def add_more_numbers(first_num, second_num, third_num = 0):
74 | added_numbers = first_num + second_num + third_num
75 | return added_numbers
76 |
77 | add_more_numbers(1, 2) # Gives 3
78 | add_more_numbers(4, 5) # Gives 9
79 | add_more_numbers(4, 5, 1) # Gives 10! The optional value got overwritten with your input!
80 | ```
81 |
82 | #### **Docstrings**
83 |
84 | ```python
85 | # DOCSTRINGS
86 | def my_function(some_parameters):
87 | '''
88 | You can include what's called a docstring in python 3 functions!
89 | The first string declared after the function declaration statement is the docstring
90 |
91 | Docstrings are used to help clarify your function's purpose and arguments
92 | As well as to provide other necessary help. Think of it as a help document!
93 | Triple-quotes are generally the convention even if the docstring is one line
94 |
95 | Docstrings can be accessed using my_function.__doc__
96 | '''
97 |
98 | # Docstring conventions from the PEP
99 | # Multi-Line Docstring
100 | def complex(real=0.0, imag=0.0):
101 | """Form a complex number.
102 |
103 | Keyword arguments:
104 | real -- the real part (default 0.0)
105 | imag -- the imaginary part (default 0.0)
106 | """
107 | if imag == 0.0 and real == 0.0:
108 | return complex_zero
109 |
110 | # One-Line Docstring
111 | def function(a, b):
112 | """Do X and return a list."""
113 | ```
114 |
115 | #### **Yield**
116 |
117 | ```python
118 | # If you want to define a function to generate items instead of returning a single one
119 | # You can let the function have outputs without ending the function using Yield!
120 |
121 | # It works just like Return, but it doesn't end the function!
122 |
123 | def rawr():
124 | yield "raa"
125 | yield "rer"
126 | yield "rawr"
127 |
128 | for item in rawr():
129 | print(item)
130 |
131 | # Output:
132 | # "raa"
133 | # "rer"
134 | # "rawr"
135 |
136 | # Yield can do something cooler too!
137 | # Combine it with next() to create an INFINITE ITERATABLE! (Without killing your memory)
138 | # Yield computes only when it needs to!
139 |
140 | def infinity():
141 | x = 0
142 | while True:
143 | yield x
144 | x += 1
145 |
146 | infinity_forever = infinity()
147 | while True:
148 | print(next(infinity_forever, end=", "))
149 |
150 | # Prints
151 | # 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20 ......................
152 | # At least, until your computer runs out of memory I guess?
153 | ```
154 |
155 | #### **Default value pitfalls**
156 |
157 | ```python
158 | # Python 3 supports default argument values as well!
159 | # But there are pitfalls!
160 | # If you pass a mutable type like a list, the same list will get altered each time you run the function, which means its default value won't be default anymore.
161 |
162 | # If you really need to use a list
163 | def myfunc(value = None):
164 | if value is None:
165 | value = []
166 |
167 | # Read about it here: http://effbot.org/zone/default-values.htm
168 |
169 | # If you really want to use default arguments, a good rule of thumb is to KEEP THEM IMMUTABLE
170 | # None is a good one
171 |
172 | def function_name(parameter1 = None):
173 | # bla bla bla
174 |
175 | # The link I posted has this really good memoisation implementation
176 | # I'll talk about memoisation in the advanced section, not here
177 |
178 | def calculate(a, b, c, memo={}):
179 | try:
180 | value = memo[a, b, c] # return already calculated value
181 | except KeyError:
182 | value = heavy_calculation(a, b, c) # Running some expensive recursive function
183 | memo[a, b, c] = value # update the memo dictionary
184 | return value
185 | ```
186 |
187 | > Note: Python 3 does not support function overloading like in C++. This is a consequence of it being a loosely typed language.
188 |
189 |
190 |
191 | ### 2.2 Local and Global variables
192 |
193 | [go to top](#top)
194 |
195 | ```python
196 | # Let's look at the add_numbers function we had!
197 | def add_numbers(first_num, second_num):
198 | added_numbers = first_num + second_num
199 | return added_numbers
200 |
201 | # If you try to use the variable we defined inside the function outside of it, it won't work
202 | print(added_numbers) # Will give you an error!
203 | ```
204 |
205 | Variables declared inside a function are considered **local** and cannot be accessed outside of the function!
206 |
207 | Variables declared outside a function are considered **global** and can be accessed everywhere!
208 |
209 |
210 |
211 | ### 2.3 Recursive Functions
212 |
213 | [go to top](#top)
214 |
215 | Source: https://www.python-course.eu/recursive_functions.php
216 |
217 | These are functions that call THEMSELVES. Trippy.
218 |
219 | ```python
220 | # Let's calculate the nth Fibonacci number!
221 | # [0, 1, 1, 2, 3, 5, 8, 13, 21, 34 ...]
222 | # n = 0 returns 0
223 | # Here, we're counting downwards, until we get n = 0 or n = 1 for each function call of fib()
224 |
225 | def fib(n):
226 | if n == 0:
227 | return 0
228 | elif n == 1:
229 | return 1
230 | else:
231 | return fib(n-1) + fib(n-2) # The function calls itself here!
232 | ```
233 |
234 | The last function calls to go on the stack are resolved first! USE THE STACK! Play some Magic: The Gathering! You'll understand!
235 |
236 | > Note! An iterative version of this will be orders of magnitude faster the higher n is because the recursive version repeats a lot of work! UNLESS MEMOISATION IS USED! To be talked about in the advanced section!
237 |
238 | ```python
239 | # FYI: This is the iterative version
240 | # Here, we're counting upwards
241 |
242 | def fibi(n):
243 | a, b = 0, 1
244 | for i in range(n):
245 | a, b = b, a + b
246 | return a
247 | ```
248 |
249 |
250 |
251 | ### 2.4 File I/O
252 |
253 | [go to top](#top)
254 |
255 | File input output.
256 |
257 | #### **Create, Open, and Write to a file!**
258 |
259 | ```python
260 | # Create and Open a file!
261 |
262 | # wb stands for file-mode: write in binary mode
263 | my_file = open("rawr.txt", "wb") # Use "ab+" to Read and Append to file
264 |
265 | # Fetch file mode
266 | print(my_file.mode) # Returns wb
267 |
268 | # Fetch file name
269 | print(my_file.name) # Returns rawr.txt in this case
270 |
271 | # Write to file
272 | my_file.write(bytes("I'm Rawring inside this file!\n", 'UTF-8')) # UTF-8 is the encoding
273 |
274 | # Close the file
275 | my_file.close()
276 | my_file.closed # Checks if a file is closed (returns True if yes, False if no)
277 | ```
278 |
279 | #### **Read from the file!**
280 |
281 | ```python
282 | import os # This is so we can delete the file later
283 |
284 | # Open the file!
285 | # r+ stands for file-mode: Read and Write
286 | my_file = open("rawr.txt", "r+")
287 |
288 | # Read entire file contents
289 | text_in_my_file = my_file.read()
290 |
291 | # Read line by line iteratively! Each call reads successive lines
292 | # If you've reached the end of file, nothing is returned
293 | # If it's a blank line, \n is returned
294 | my_file.readline() # Course, rawr.txt only has one line though...
295 |
296 | # You can also loop over the entire file!
297 | for line in my_file:
298 | print(line, end="")
299 |
300 | # Print contents
301 | print(text_in_my_file) # Returns I'm Rawring inside this file!\n
302 |
303 | # Delete a file!
304 | os.remove("rawr.txt")
305 | ```
306 |
307 | #### **tell() and seek()**
308 |
309 | `tell()` returns an integer giving the current position of the cursor in the file (in bytes when in mode `b` or as a number otherwise)
310 |
311 | `seek()` lets you change the position of the cursor! It takes two arguments, the second is optional
312 |
313 | - `my_file.seek(offset[, whence])`
314 |
315 | ```python
316 | # tell() returns an integer giving the current position of the cursor in the file
317 | # (in bytes when in mode b or as a number otherwise)
318 | my_file.tell()
319 |
320 | # seek() lets you change the position of the cursor! It takes two arguments, the second is optional
321 | # my_file.seek(offset[, whence])
322 | # Whence = 0 is default, which means absolute file positioning
323 | # Whence = 1 means seek from current position
324 | # Whence = 2 means seek from end of file
325 | # Offset is how far to move
326 | my_file.seek(0,0) # Returns you to the beginning of file
327 | ```
328 |
329 | ```python
330 | # This is pretty nifty!
331 | # You can use this to append to the end of a file in write mode!
332 | # Course, you could always just use a+ ...
333 |
334 | f = open("rawr.txt", "r+")
335 |
336 | # Bring cursor to EOF
337 | f.seek(0,2)
338 |
339 | # Write!
340 | f.write("\nRawr")
341 |
342 | # Bring cursor to beginning of file
343 | f.seek(0,0)
344 |
345 | # Print the results!
346 | print(f.read())
347 |
348 | f.close()
349 | ```
350 |
351 |
352 |
353 | #### **File Modes**
354 |
355 | > - `r` for reading
356 | > - `w` for writing
357 | > - `r+` opens for reading and writing (cannot truncate a file)
358 | > - `w+` for writing and reading (can truncate a file)
359 | > - `rb+` reading or writing a binary file
360 | > - `wb+` writing a binary file
361 | > - `a+` opens for appending (All writes will occur at end of file regardless of cursor position)
362 | >
363 | > https://stackoverflow.com/questions/41406116/what-is-the-difference-between-rw-and-r
364 |
365 | #### **Good to know**
366 |
367 | ```python
368 | # It's good practice to open files using "with"
369 | # This way, if you get any errors, the file will still close instead of you having to rely on garbage disposal
370 |
371 | with open('rawr.txt', 'r+') as f:
372 | read_data = f.read()
373 |
374 | # Other handy os module commands
375 |
376 | # Rename()
377 | os.rename(file_name, new_name)
378 |
379 | # Mkdir()
380 | os.mkdir("dir_name") # Like linux! Makes a directory
381 |
382 | # Rmdir()
383 | os.rmdir("dir_name") # Deletes the directory
384 |
385 | # Change directory
386 | os.chdir("dir_name") # Not like linux! :( But this is basically cd
387 |
388 | # Get working directory
389 | os.getcwd() # OS's version of linux's pwd
390 | ```
391 |
392 | #### **For extra stuff**
393 |
394 | Like.. say you want to read delimited data with json or something, or do more advanced writing,
395 |
396 | Check: https://docs.python.org/3/tutorial/inputoutput.html
397 |
398 |
399 |
400 | ```
401 | . .
402 | . |\-^-/| .
403 | /| } O.=.O { |\
404 | ```
405 |
406 |
407 |
408 | ------
409 |
410 | [.png)](https://www.buymeacoffee.com/methylDragon)
--------------------------------------------------------------------------------
/Python 3/assets/1563086409015.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/methylDragon/coding-notes/b9dcabff04e0a29160728aeaaad18f1364067493/Python 3/assets/1563086409015.png
--------------------------------------------------------------------------------
/Python 3/assets/1563125439057.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/methylDragon/coding-notes/b9dcabff04e0a29160728aeaaad18f1364067493/Python 3/assets/1563125439057.png
--------------------------------------------------------------------------------
/Python 3/assets/1_PTC18sgXqar4aS-_C_uzRQ.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/methylDragon/coding-notes/b9dcabff04e0a29160728aeaaad18f1364067493/Python 3/assets/1_PTC18sgXqar4aS-_C_uzRQ.png
--------------------------------------------------------------------------------
/Python 3/assets/1_YUMW7F-pm3bXmSnr1owcMg.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/methylDragon/coding-notes/b9dcabff04e0a29160728aeaaad18f1364067493/Python 3/assets/1_YUMW7F-pm3bXmSnr1owcMg.png
--------------------------------------------------------------------------------
/Python 3/assets/1_kvOnNBfiEn-WdiQbcElpEA.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/methylDragon/coding-notes/b9dcabff04e0a29160728aeaaad18f1364067493/Python 3/assets/1_kvOnNBfiEn-WdiQbcElpEA.png
--------------------------------------------------------------------------------
/Python 3/assets/memory-management-in-python-the-basics-75-638.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/methylDragon/coding-notes/b9dcabff04e0a29160728aeaaad18f1364067493/Python 3/assets/memory-management-in-python-the-basics-75-638.jpg
--------------------------------------------------------------------------------
/Python 3/assets/priority_queue.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/methylDragon/coding-notes/b9dcabff04e0a29160728aeaaad18f1364067493/Python 3/assets/priority_queue.png
--------------------------------------------------------------------------------
/Python 3/assets/probing.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/methylDragon/coding-notes/b9dcabff04e0a29160728aeaaad18f1364067493/Python 3/assets/probing.png
--------------------------------------------------------------------------------
/Python 3/assets/py_memory1.2b6e5f8e5bc9.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/methylDragon/coding-notes/b9dcabff04e0a29160728aeaaad18f1364067493/Python 3/assets/py_memory1.2b6e5f8e5bc9.png
--------------------------------------------------------------------------------
/Python 3/assets/py_memory3_1.ea43471d3bf6.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/methylDragon/coding-notes/b9dcabff04e0a29160728aeaaad18f1364067493/Python 3/assets/py_memory3_1.ea43471d3bf6.png
--------------------------------------------------------------------------------
/Python 3/assets/queue.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/methylDragon/coding-notes/b9dcabff04e0a29160728aeaaad18f1364067493/Python 3/assets/queue.png
--------------------------------------------------------------------------------
/Python 3/assets/singly-ll.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/methylDragon/coding-notes/b9dcabff04e0a29160728aeaaad18f1364067493/Python 3/assets/singly-ll.png
--------------------------------------------------------------------------------
/Python 3/assets/stack.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/methylDragon/coding-notes/b9dcabff04e0a29160728aeaaad18f1364067493/Python 3/assets/stack.jpg
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # Coding Notes and Tutorials
2 |
3 | I've compiled a whole bunch of tutorials and references for different **coding languages** and **frameworks!**
4 |
5 |
6 |
7 | Most of these can be read through in under an hour, and they're pitched at the beginner to intermediate level. But most importantly, they're **designed to be CTRL-F-able!**
8 |
9 |
10 |
11 | ## Support my efforts!
12 |
13 | [.png)](https://www.buymeacoffee.com/methylDragon)
14 |
15 | [Or leave a tip! ヾ(°∇°*)](https://www.paypal.me/methylDragon)
16 |
17 |
18 |
19 | ## So far, I've covered:
20 |
21 | - [C++](#C++)
22 |
23 | - [CMake](#CMake)
24 |
25 | - [OpenSplice DDS](#OpenSplice%20DDS)
26 |
27 | - [MATLAB](#MATLAB)
28 |
29 | - [MySQL](#MySQL)
30 |
31 | - [PHP](#PHP)
32 |
33 | - [Python 3](#Python%203)
34 |
35 | - [WordPress](#WordPress)
36 |
37 |
38 |
39 | ## Tutorial Directory
40 |
41 | ### C++
42 |
43 | [go to top](#top)
44 |
45 | - [Introduction and Basic Syntax](./C++/01%20C++%20-%20Introduction.md)
46 | - [Functions and File IO](./C++/02%20C++%20-%20Functions%20and%20File%20IO.md)
47 | - [Object-Oriented Syntax](./C++/03%20C++%20-%20Object-Oriented%20Syntax.md)
48 | - [Pointers and Memory](./C++/04%20C++%20-%20Pointers%20and%20Memory.md)
49 | - [Data Structures (Containers)](./C++/05%20C++%20-%20Data%20Structures%20(Containers).md)
50 | - [Templates](./C++/06%20C++%20-%20Templates.md)
51 | - [Threading and Concurrency](./C++/07%20C++%20-%20Threading%20and%20Concurrency.md)
52 | - [Linkages and Preprocessor Directives](./C++/08%20C++%20-%20Linkages%20and%20Preprocessor%20Directives.md)
53 | - [Tips and Tricks](./C++/09%20C++%20-%20Tips%20and%20Tricks.md)
54 | - [(Bonus) Headers](./C++/Bonus%20Notes/BONUS%20C++%20-%20Headers.md)
55 |
56 |
57 |
58 | ### CMake
59 |
60 | [go to top](#top)
61 |
62 | - [Basics and Scripting](./CMake/01%20CMake%20-%20Basics%20and%20Scripting.md)
63 | - [Building with CMake](./CMake/02%20CMake%20-%20Building%20with%20CMake.md)
64 | - [Advanced Scripting and Modules](./CMake/03%20CMake%20-%20Advanced%20Scripting%20and%20Modules.md)
65 |
66 |
67 |
68 | ### OpenSplice DDS
69 |
70 | [go to top](#top)
71 |
72 | - [Introduction and Basic Syntax](./DDS/OpenSplice%20DDS%20(C++%20API)/01%20DDS%20-%20Introduction.md)
73 |
74 |
75 |
76 | ### MATLAB
77 |
78 | [go to top](#top)
79 |
80 | - [Crash Course](./MATLAB/MATLAB%20Crash%20Course.md)
81 |
82 |
83 |
84 | ### MySQL
85 |
86 | [go to top](#top)
87 |
88 | - [Introduction and Basic Syntax](./MySQL/01%20MySQL%20-%20Introduction.md)
89 |
90 |
91 |
92 | ### PHP
93 |
94 | [go to top](#top)
95 |
96 | - [Syntax and Database Interactions](./PHP/01%20PHP%20-%20Syntax%20and%20DB%20Interactions.md)
97 | - [Object-Oriented Syntax](./PHP/02%20PHP%20-%20Object-Oriented%20Syntax.md)
98 |
99 |
100 |
101 | ### Python 3
102 |
103 | [go to top](#top)
104 |
105 | - [Introduction and Basic Syntax](./Python%203/01%20Python%203%20-%20Introduction.md)
106 | - [Functions and File IO](./Python%203/02%20Python%203%20-%20Functions%20and%20File%20IO.md)
107 | - [Object-Oriented Syntax](./Python%203/03%20Python%203%20-%20Object-Oriented%20Syntax.md)
108 | - [Advanced Concepts](./Python%203/04%20Python%203%20-%20Advanced%20Concepts.md)
109 | - [Data Structures](./Python%203/05%20Python%203%20-%20Data%20Structures.md)
110 |
111 |
112 |
113 | ### WordPress
114 |
115 | [go to top](#top)
116 |
117 | - [Introduction and Basic Syntax](./WordPress/01%20WordPress%20-%20Introduction.md)
118 |
119 |
120 |
121 | ## Credits
122 |
123 | All credits and sources are listed inside the tutorials and references themselves.
124 |
125 |
126 |
127 | ```
128 | . .
129 | . |\-^-/| .
130 | /| } O.=.O { |\
131 | ```
132 |
--------------------------------------------------------------------------------
/Regular Expressions/Regex Cheatsheets.md:
--------------------------------------------------------------------------------
1 | 
2 |
3 | 
--------------------------------------------------------------------------------
/Regular Expressions/assets/Another Cheat Sheet.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/methylDragon/coding-notes/b9dcabff04e0a29160728aeaaad18f1364067493/Regular Expressions/assets/Another Cheat Sheet.png
--------------------------------------------------------------------------------
/Regular Expressions/assets/Cheat Sheet.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/methylDragon/coding-notes/b9dcabff04e0a29160728aeaaad18f1364067493/Regular Expressions/assets/Cheat Sheet.jpg
--------------------------------------------------------------------------------
/Rust (WIP)/02 Rust - Loops, Custom Types, and Errors.md:
--------------------------------------------------------------------------------
1 | # Rust Crash Course (Loops, Custom Types, and Errors)
2 |
3 | Author: methylDragon
4 | Contains a syntax reference for Rust!
5 | I'll be adapting it from several sources that will be credited in the introduction
6 |
7 | ------
8 |
9 | ## Pre-Requisites
10 |
11 | **Assumed knowledge (This is a Rust crash course, not a basic coding tutorial)**
12 |
13 | - How **variables, loops, conditionals, etc**. work (Basic coding fundamentals will help a lot!)
14 | - Linux (**Terminal/Console proficiency**) (We're going to need to compile our stuff)
15 | - Gone through the all preceding parts of the tutorial
16 |
17 | ### Good to know
18 |
19 | - Other systems programming language knowledge (e.g. C++)
20 | - It'll help with appreciating the benefits of Rust!
21 |
22 | - If you have knowledge of computation structures like variables, functions, OOP, etc. it'll be easier
23 |
24 |
25 |
26 | ## Introduction
27 |
28 | Now that we know what types are, and what tools Rust affords us, we can start getting funky with the next few steps:
29 |
30 | - Loops (`for`, `while`, etc.)
31 | - Custom Types (`structs`, `enums`, type aliases)
32 | - Error handling
33 |
34 |
35 |
36 | ## Rust Syntax Reference
37 |
38 | ### Loops (`loop`, `while`, `for`)
39 |
40 |
41 |
42 |
43 |
44 |
45 | ```
46 | . .
47 | . |\-^-/| .
48 | /| } O.=.O { |\
49 | ```
50 |
51 |
52 |
53 | ------
54 |
55 | [.png)](https://www.buymeacoffee.com/methylDragon)
56 |
57 |
--------------------------------------------------------------------------------
/Rust (WIP)/TODOS:
--------------------------------------------------------------------------------
1 | 02 - Loops, Custom Types, and Errors
2 | 03 - Functions, Generics, and IO
3 | - Include local vs global
4 | - Include user input
5 | - Include paths
6 | 04 - Traits and OOP
7 | 05 - Scope, Memory, and The Borrow Checker
8 | - Generalize scope
9 | 06 - Modules, Crates, and Cargo
10 | 07 - Concurrency
11 | 08 - Collections
12 |
13 | BONUS - Macros
14 | BONUS - Testing and Documentation
15 | BONUS - Dark Arts, FFI, and Unsafe Rust
16 | BONUS - Performance
17 |
--------------------------------------------------------------------------------
/Rust (WIP)/assets/01 Rust - Introduction/ferris.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/methylDragon/coding-notes/b9dcabff04e0a29160728aeaaad18f1364067493/Rust (WIP)/assets/01 Rust - Introduction/ferris.gif
--------------------------------------------------------------------------------
/WordPress/01 WordPress - Introduction.md:
--------------------------------------------------------------------------------
1 | # WordPress Notes
2 |
3 | Author: methylDragon
4 | Contains notes on WordPress in general, plugin development, and a code reference for actions and filters
5 |
6 | ***
7 |
8 | ## Pre-Requisites
9 |
10 | ### Good to know
11 |
12 | - **PHP** (read my PHP syntax reference!)
13 |
14 |
15 |
16 | ## Table Of Contents
17 |
18 | 1. [Introduction](#1)
19 | 2. [Plugin Development](#2)
20 | 2.1 [Introduction](#2.1)
21 | 2.2 [Boilerplate Code](#2.2)
22 | 2.3 [Actions, Filters, and Hooks](#2.3)
23 | 2.4 [A Refresher on PHP Functions](#2.4)
24 | 2.5 [Hooks](#2.5)
25 | 2.6 [Actions](#2.6)
26 | 2.7 [do_action() and do_action_ref_array()](#2.7)
27 | 2.8 [add_action()](#2.8)
28 | 2.9 [Unhooking actions](#2.9)
29 | 2.10 [Miscellaneous action related functions](#2.10)
30 | 2.11 [Filters](#2.11)
31 | 2.12 [apply_filters()](#2.12)
32 | 2.13 [add_filter()](#2.13)
33 | 2.14 [Unhooking filters](#2.14)
34 | 2.15 [Miscellaneous filter related functions](#2.15)
35 | 3. [Relevant Links](#3)
36 |
37 |
38 |
39 | ## 1. Introduction
40 |
41 | WordPress (WP) is a content management system that uses PHP to dynamically generate pages from its MySQL database.
42 |
43 | Since it was started as a blogging platform, WordPress sites are organized into **pages** (eg. activity, about page, etc.) and **posts** (blog posts.) WP provides an easy backend console to deal with this and create pages and posts, but its true value comes in its extendibility with plugins and customization with code.
44 |
45 |
46 |
47 | # 2. Plugin Development
48 |
49 | ### 2.1 Introduction
50 |
51 | [go to top](#top)
52 |
53 | The main bulk of plugin development will deal with introducing new **actions** and **functions** hooked onto the WP core, as well as coding in custom PHP and MySQL queries to interact with, and modifying the MySQL database that WP comes packed in with. **Plugins are written in PHP.** Wrap them in `` tags!
54 |
55 |
56 |
57 | ### 2.2 Boilerplate Code
58 |
59 | [go to top](#top)
60 |
61 | In order for WP to recognize that a .PHP file is a plugin, you need to ensure that you include a comment detailing the description and other metadata for the plugin as a whole!
62 |
63 | ```php
64 | /*
65 | Plugin Name:
66 | Plugin URI:
67 | Description:
68 | Version:
69 | Text Domain:
70 | Domain Path:
71 | Author: methylDragon
72 | Author URI: methylDragon.com
73 | License:
74 | */
75 | ```
76 |
77 | Also, **FYI**, whenever you open a parenthesis, make sure you add a space after it, otherwise WP will reject the code...
78 |
79 | `some_function( 'see_the_parentheses?' );`
80 |
81 |
82 |
83 | ### 2.3 Actions, Filters, and Hooks
84 |
85 | [go to top](#top)
86 |
87 | In order to deal with constant WP updates while maintaining plugin compatibility, WP has implemented a system called **Actions, Filters, and Hooks** to do this. This will form the bulk of any plugin development.
88 |
89 |
90 |
91 | ### 2.4 A Refresher on PHP Functions
92 |
93 | [go to top](#top)
94 |
95 | Here's a PHP function prototype refresher!
96 |
97 | ```php
98 | function functionName() {
99 | code to be executed;
100 | }
101 | ```
102 |
103 | You can call functions directly on WP using functionName(); , or call them via an action, or filter! You'll see why this is useful later on.
104 |
105 |
106 |
107 | ### 2.5 Hooks
108 |
109 | [go to top](#top)
110 |
111 | > Hooks are provided by WordPress to allow your plugin to 'hook into' the rest of WordPress; that is, to call functions in your plugin at specific times, and thereby set your plugin in motion. (From WP codex)
112 |
113 | These hooks exist in two forms, Actions, and Filters.
114 |
115 |
116 |
117 | ### 2.6 Actions: Call PHP functions that are supposed to do something
118 |
119 | [go to top](#top)
120 |
121 | Actions are places where WP or other plugins call certain functions. You *can* write your own actions, and call them either alone, or *as a callback* alongside another action! The latter is the reason why an action can be a hook, since an action that you write can be hooked onto another action!
122 |
123 | * The difference between calling a function directly and using an action, is that when you call a function using an action, any other actions that are hooked onto that action you just called will also end up being called.
124 |
125 |
126 |
127 |
128 | ### 2.7 do_action() and do_action_ref_array()
129 |
130 | [go to top](#top)
131 |
132 | ```php
133 | /* Use do_action() to call a function anywhere you want
134 |
135 | do_action( string $tag, $arg = '' )
136 |
137 | OPTIONAL: $arg (mixed) You can pass arguments to the action!
138 | */
139 |
140 | do_action( 'function_name' );
141 |
142 | /* Use do_action_ref_array() to call a function anywhere you want, while passing an array as an argument!
143 | */
144 |
145 | $args = array( 'arg_1', true, 'foo', 'arg_4' );
146 | do_action_ref_array( 'function_name', $args );
147 |
148 | //Is equivalent to
149 |
150 | do_action( 'function_name', 'arg_1', true, 'foo', 'arg_4' );
151 | ```
152 |
153 |
154 | ### 2.8 add_action()
155 |
156 | [go to top](#top)
157 |
158 | ```php
159 | /* Use add_action() to hook an action onto another existing action
160 | It will call your hooked action whenever the first action is called
161 |
162 | add_action( string $tag, callable $function_to_add, int $priority = 10, int $accepted_args = 1 )
163 |
164 | OPTIONAL: $priority (int) Used to specify the order in which functions associated with a particular action are executed. Lower number means higher priority. Functions with the same priority number are executed in the order in which they were added to the action. Default = 10
165 |
166 | OPTIONAL: $accepted_args (int) The number of arguments the function accepts. . Default = 1
167 |
168 | NOTE: The arguments passed to the $tag action will be the ones passed to the $function_to_add
169 | */
170 | add_action( 'some_hook', 'callback_function_for_some_hook' );
171 |
172 | // Or if calling a function from within a class
173 | add_action( 'some_hook', array( 'some_class', 'callback_function_in_some_class' ) );
174 | ```
175 |
176 |
177 |
178 | ### 2.9 Unhooking actions
179 |
180 | [go to top](#top)
181 |
182 | ```php
183 | /* Use remove_action() to unhook an action
184 | Note: You cannot call this directly, it has to be done from within a function!
185 |
186 | This returns true when finished
187 | */
188 | function remove_my_action() {
189 | remove_action( 'some_hook', 'function_being_removed' );
190 | }
191 | do_action( 'remove_my_action' );
192 |
193 | // Or if the action was hooked from within a class, eg. by a plugin
194 | function remove_my_class_action(){
195 | global $my_class;
196 | remove_action( 'some_hook', array( $my_class, 'class_function_being_removed' ) );
197 | do_action( 'remove_my_class_action');
198 | }
199 |
200 | /* Use remove_all_actions() to unhook everything hooked to an action
201 |
202 | This returns true when finished
203 |
204 | Note: Becareful when using this, because it might cause issues with nested hooks!
205 | */
206 | remove_all_actions( 'some_hook' );
207 | ```
208 |
209 |
210 |
211 | ### 2.10 Miscellaneous action related functions
212 |
213 | [go to top](#top)
214 |
215 | ```php
216 | /* Use has_action() to check if an action has been registered for a hook.
217 | It returns a boolean value, or an integer, if the action has a priority value associated with it
218 | */
219 | has_action( 'hook_name', 'function_to_check' );
220 |
221 | // Use did_action() to see how many times an action has fired
222 | did_action( 'action_name' )
223 | ```
224 |
225 |
226 |
227 | ### 2.11 Filters: Call PHP functions that receive and returns values
228 |
229 | [go to top](#top)
230 |
231 | Note: They might potentially modify the received value, but they **must** return a value
232 |
233 | Otherwise, filters act a lot like actions, you can add, and do them just like actions, but with a few small differences. Just **make sure your functions defined to be called by filters take in and RETURN values!**
234 |
235 | I'll add less detail for the filter functions because a lot of them are aliases for the action functions
236 |
237 |
238 |
239 | ### 2.12 apply_filters()
240 |
241 | [go to top](#top)
242 |
243 | ```php
244 | /* An analog is do_action()
245 |
246 | apply_filters( string $tag, mixed $value )
247 |
248 | You must supply a parameter!
249 | */
250 | apply_filters( 'filter_to_use', 'value_to_filter', 'potentially_more_values' );
251 | ```
252 |
253 |
254 |
255 | ### 2.13 add_filter()
256 |
257 | [go to top](#top)
258 |
259 | ```php
260 | /* So let's say you might want to add additional filters onto filter_to_use. You use add_filter to hook an additional filter function to an existing filter, much like add_action!
261 |
262 | add_filter( string $tag, callable $function_to_add, int $priority = 10, int $accepted_args = 1 )
263 |
264 | Same thing with priority and accepted args for add_action
265 |
266 | Note: Don't forget to define your callback function!
267 | */
268 | function additional_filter( $example ) {
269 | // Maybe modify $example in some way.
270 | return $example;
271 | }
272 |
273 | add_filter( 'filter_to_use', 'additional_filter' );
274 | ```
275 |
276 |
277 |
278 | ### 2.14 Unhooking filters
279 |
280 | [go to top](#top)
281 |
282 | ```php
283 | /* remove_filter(): Same thing with actions, self explanatory
284 | Returns true when done
285 | */
286 | function remove_my_filter() {
287 | remove_filter( 'some_hook', 'function_being_removed' );
288 | }
289 | do_action( 'remove_my_filter' );
290 |
291 | // Or if the filter was hooked from within a class, eg. by a plugin
292 | function remove_my_class_filter(){
293 | global $my_class;
294 | remove_filter( 'some_hook', array( $my_class, 'class_function_being_removed' ) );
295 | do_action( 'remove_my_class_filter' );
296 | }
297 |
298 | // remove_all_filters() does exactly what you think it does
299 | remove_all_filters( 'some_hook' );
300 | ```
301 |
302 |
303 |
304 | ### 2.15 Miscellaneous filter related functions
305 |
306 | [go to top](#top)
307 |
308 | ```php
309 | // current_filter() retrieves the name of the current filter or action
310 |
311 | //Retrieving filter name
312 | function my_filter() {
313 | echo current_filter(); // 'the_content'
314 | }
315 | add_filter( 'the_content', 'my_filter' );
316 |
317 | //Retrieving action name
318 | function my_init_function() {
319 | echo current_filter(); // 'init'
320 | }
321 | add_action( 'init', 'my_init_function' );
322 |
323 | // has_filter() works like has_action(), returns true if a hook has the passed function hooked onto it
324 | has_filter( 'hook_name', 'function_to_check' )
325 | ```
326 |
327 |
328 |
329 | ## 3. Relevant links:
330 |
331 | https://codex.wordpress.org/Plugin_API
332 | https://www.youtube.com/watch?v=AQrXcsc4CIw (Actions, Filters, and Hooks)
333 | https://www.youtube.com/watch?v=w257tYZtL8Y (WordPress Plugin Development)
334 | https://wordpress.stackexchange.com/questions/1007/difference-between-filter-and-action-hooks (Filters vs Actions)
335 |
336 |
337 |
338 | ------
339 |
340 | [.png)](https://www.buymeacoffee.com/methylDragon)
--------------------------------------------------------------------------------
/_assets/COFFEE BUTTON ヾ(°∇°^).png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/methylDragon/coding-notes/b9dcabff04e0a29160728aeaaad18f1364067493/_assets/COFFEE BUTTON ヾ(°∇°^).png
--------------------------------------------------------------------------------