├── .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 | [![Yeah! Buy the DRAGON a COFFEE!](../_assets/COFFEE%20BUTTON%20%E3%83%BE(%C2%B0%E2%88%87%C2%B0%5E).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 | [![Yeah! Buy the DRAGON a COFFEE!](../_assets/COFFEE%20BUTTON%20%E3%83%BE(%C2%B0%E2%88%87%C2%B0%5E).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 | [![Yeah! Buy the DRAGON a COFFEE!](../../_assets/COFFEE%20BUTTON%20%E3%83%BE(%C2%B0%E2%88%87%C2%B0%5E).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 | [![Yeah! Buy the DRAGON a COFFEE!](../../_assets/COFFEE%20BUTTON%20%E3%83%BE(%C2%B0%E2%88%87%C2%B0%5E).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 | [![Yeah! Buy the DRAGON a COFFEE!](../../_assets/COFFEE%20BUTTON%20%E3%83%BE(%C2%B0%E2%88%87%C2%B0%5E).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 | ![MySQL Table](assets/MySQL Table.png) 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 | ![Student Table](assets/Student Table.PNG) 143 | 144 | Then eventually this will allow you to more easily see how to design your tables! 145 | 146 | ![Student Schemas](assets/Student Schemas.PNG) 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 | [![Yeah! Buy the DRAGON a COFFEE!](../_assets/COFFEE%20BUTTON%20%E3%83%BE(%C2%B0%E2%88%87%C2%B0%5E).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 | [![Yeah! Buy the DRAGON a COFFEE!](../_assets/COFFEE%20BUTTON%20%E3%83%BE(%C2%B0%E2%88%87%C2%B0%5E).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 | [![Yeah! Buy the DRAGON a COFFEE!](../_assets/COFFEE%20BUTTON%20%E3%83%BE(%C2%B0%E2%88%87%C2%B0%5E).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 | [![Yeah! Buy the DRAGON a COFFEE!](./_assets/COFFEE%20BUTTON%20%E3%83%BE(%C2%B0%E2%88%87%C2%B0%5E).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 | ![Another Cheat Sheet](assets/Another Cheat Sheet.png) 2 | 3 | ![Cheat Sheet](assets/Cheat Sheet.jpg) -------------------------------------------------------------------------------- /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 | [![Yeah! Buy the DRAGON a COFFEE!](../_assets/COFFEE%20BUTTON%20%E3%83%BE(%C2%B0%E2%88%87%C2%B0%5E).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 | [![Yeah! Buy the DRAGON a COFFEE!](../_assets/COFFEE%20BUTTON%20%E3%83%BE(%C2%B0%E2%88%87%C2%B0%5E).png)](https://www.buymeacoffee.com/methylDragon) -------------------------------------------------------------------------------- /_assets/COFFEE BUTTON ヾ(°∇°^).png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/methylDragon/coding-notes/b9dcabff04e0a29160728aeaaad18f1364067493/_assets/COFFEE BUTTON ヾ(°∇°^).png --------------------------------------------------------------------------------