Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #16 from leapmotion/feature-examples
Basic Examples
- Loading branch information
Showing
7 changed files
with
321 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,8 @@ | ||
// Copyright (C) 2012-2014 Leap Motion, Inc. All rights reserved. | ||
#include <autowiring/Autowired.h> | ||
#include <iostream> | ||
#include <memory> | ||
|
||
int main() { | ||
std::cout << "Hello World" << std::endl; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,15 @@ | ||
add_executable(ContextExample ContextExample.cpp) | ||
target_link_libraries(ContextExample Autowiring) | ||
set_property(TARGET ContextExample PROPERTY FOLDER "Examples") | ||
|
||
add_executable(ThreadExample ThreadExample.cpp) | ||
target_link_libraries(ThreadExample Autowiring) | ||
set_property(TARGET ThreadExample PROPERTY FOLDER "Examples") | ||
|
||
add_executable(EventExample EventExample.cpp) | ||
target_link_libraries(EventExample Autowiring) | ||
set_property(TARGET EventExample PROPERTY FOLDER "Examples") | ||
|
||
add_executable(AutoFilterExample AutoFilterExample.cpp) | ||
target_link_libraries(AutoFilterExample Autowiring) | ||
set_property(TARGET AutoFilterExample PROPERTY FOLDER "Examples") |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,131 @@ | ||
// Copyright (C) 2012-2014 Leap Motion, Inc. All rights reserved. | ||
#include <autowiring/Autowired.h> | ||
#include <iostream> | ||
#include <memory> | ||
|
||
// pretty print boolean with desciption | ||
#define check(desc,val) std::cout << desc << (val ? ": True" : ": False") << std::endl | ||
|
||
// dummy classes | ||
class Foo { | ||
public: | ||
int x; | ||
}; | ||
|
||
class Bar{ | ||
public: | ||
Autowired<Foo> foo; | ||
}; | ||
|
||
int main() { | ||
/////////////////////////// | ||
// // | ||
// GlobalCoreContext // | ||
// // | ||
/////////////////////////// | ||
{ | ||
// The CoreContext is the basic unit of organization in Autowriring. They are organized | ||
// in a tree structure, the root of which is the GlobalCoreContext. Each thread | ||
// keeps track of its current context, which defaults to GlobalCoreContext | ||
|
||
// This creates a shared_ptr to the global context | ||
AutoGlobalContext global; | ||
|
||
// This is the a shared_ptr to the current context | ||
AutoCurrentContext ctxt; | ||
|
||
// Since we default to the current context, they should be the same | ||
check("Current context is global", global==ctxt); | ||
} | ||
|
||
///////////////////////////////////////////////// | ||
// // | ||
// Context Creation and Switching Contexts // | ||
// // | ||
///////////////////////////////////////////////// | ||
{ | ||
// New contexts can be created using the 'Create' factory method on a context. | ||
// The factory will create a child context to 'this' context. | ||
// A helper type 'AutoCreateContext' will call Create on the current context | ||
// automatically | ||
|
||
AutoGlobalContext global; //same as AutoCurrentContext here | ||
|
||
// Create's a chile of the current context | ||
AutoCreateContext childCtxt; // Same as childCtxt = AutoCurrentContext()->Create<void>(); | ||
|
||
// Even though we've created a child context, we're still in the global context | ||
check("Are we in the GlobalCoreContext", AutoCurrentContext()->IsGlobalContext()); | ||
|
||
// CurrentContextPusher can be used to switch contexts using RAII patterns | ||
{ | ||
CurrentContextPusher pshr(childCtxt); | ||
check("Now in child context", AutoCurrentContext() == childCtxt); | ||
} | ||
// Back in global context | ||
} | ||
|
||
/////////////////////////////////////////////////////// | ||
// // | ||
// Adding members to a context with AutoRequired // | ||
// // | ||
/////////////////////////////////////////////////////// | ||
{ | ||
// Switch to a child context | ||
AutoCreateContext ctxt; | ||
CurrentContextPusher pshr(ctxt); | ||
|
||
// A single instance of any type can be injected into a context | ||
// This is done using AutoRequied | ||
AutoRequired<Foo> foo; // We now have a std::shared_ptr<Foo> | ||
|
||
// AutoRequired will return an instance of the requested type from | ||
// the current context. If that type doesn't exist in the current | ||
// context, it will create an instace | ||
foo->x = 5; | ||
|
||
// If we try to AutoRequire a second Foo, we'll get a pointer to | ||
// the same instance | ||
AutoRequired<Foo> foo2; | ||
check("foo2 is the same instance as foo", foo==foo2); | ||
std::cout << "foo2 value of 'x': " << foo2->x << std::endl; | ||
|
||
} // 'ctxt' and all members a destroyed when the context goes out of scope | ||
|
||
////////////////////// | ||
// // | ||
// Autowired // | ||
// // | ||
////////////////////// | ||
{ | ||
{ | ||
AutoCreateContext ctxt; | ||
CurrentContextPusher pshr(ctxt); | ||
|
||
// Autowired is similar to AutoRequied, except it doesn't create the | ||
// object if it doesn't already exist. It also searches up the tree | ||
// if the object isn't found in the current context | ||
Autowired<Foo> foo; | ||
check("foo is an empty pointer", !foo); | ||
|
||
// If we inject to type Foo later, foo will automatically point to that instance | ||
AutoRequired<Foo>(); | ||
check("foo now contains an instance of Foo", foo); | ||
} | ||
|
||
// This delayed satisfaction also works for class members. | ||
{ | ||
AutoCreateContext ctxt; | ||
CurrentContextPusher pshr(ctxt); | ||
|
||
// Bar has an Autowrired<Foo> classmember | ||
AutoRequired<Bar> bar; | ||
|
||
check("Foo member of bar is satisfied before AutoRequired", bar->foo); | ||
|
||
// If we inject Foo into the context, the Autowired<Foo> member of Bar will be satisfied | ||
AutoRequired<Foo>(); | ||
check("Foo member of bar is satisfied after AutoRequired", bar->foo); | ||
} | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,87 @@ | ||
// Copyright (C) 2012-2014 Leap Motion, Inc. All rights reserved. | ||
#include <autowiring/Autowired.h> | ||
#include <iostream> | ||
#include <memory> | ||
|
||
///////////////////////////////////////////////////////////////////// | ||
// // | ||
// Autowiring Events // | ||
// // | ||
///////////////////////////////////////////////////////////////////// | ||
|
||
// Autowiring events are just function calls on member functions in a context. | ||
// All context members that implement function pointer you "fire" will be called | ||
|
||
class MyEvent: | ||
public EventReceiver | ||
{ | ||
public: | ||
virtual void myFunction(int) = 0; | ||
}; | ||
|
||
// Will receive MyEvent::myFunction or FooEvent::myFunction events | ||
class FooEvent: | ||
public MyEvent | ||
{ | ||
public: | ||
FooEvent(): | ||
m_secret(0) | ||
{} | ||
|
||
void myFunction(int i) override { | ||
m_secret = i; | ||
} | ||
|
||
int getSecret(){ | ||
return m_secret; | ||
} | ||
private: | ||
int m_secret; | ||
}; | ||
|
||
// Will receive MyEvent::myFunction or BarEvent::myFunction events | ||
class BarEvent: | ||
public MyEvent | ||
{ | ||
public: | ||
BarEvent(): | ||
m_secret(0) | ||
{} | ||
|
||
void myFunction(int i) override { | ||
m_secret = i; | ||
} | ||
|
||
int getSecret(){ | ||
return m_secret; | ||
} | ||
private: | ||
int m_secret; | ||
}; | ||
|
||
int main(){ | ||
AutoCurrentContext ctxt; | ||
|
||
// A context must be initiated before events can be received. Similar to CoreThread | ||
ctxt->Initiate(); | ||
|
||
// This creates an proxy object that can fire MyEvent::* events | ||
AutoFired<MyEvent> eventFirer; | ||
|
||
// Inject receiver types into current context | ||
AutoRequired<FooEvent> foo; | ||
AutoRequired<BarEvent> bar; | ||
std::cout << "Foo should be 0: " << foo->getSecret() << std::endl; | ||
std::cout << "Bar Should be 0: " << bar->getSecret() << std::endl; | ||
|
||
// Fire event, this should set m_secret on both foo and bar | ||
eventFirer(&MyEvent::myFunction)(42); | ||
std::cout << "Foo should be 42: " << foo->getSecret() << std::endl; | ||
std::cout << "Bar should be 42: " << bar->getSecret() << std::endl; | ||
|
||
// You can also manually fire events on a context with `Invoke` | ||
// Since the function pointer is to `BarEvent`, `FooEvent` won't receive the event | ||
//ctxt->Invoke(&BarEvent::myFunction)(77); | ||
//std::cout << "Foo should be 42: " << foo->getSecret() << std::endl; | ||
//std::cout << "Bar should be 77: " << bar->getSecret() << std::endl; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,65 @@ | ||
// Copyright (C) 2012-2014 Leap Motion, Inc. All rights reserved. | ||
#include <autowiring/Autowired.h> | ||
#include <autowiring/CoreThread.h> | ||
#include <iostream> | ||
#include <memory> | ||
#include <thread> | ||
#include <chrono> | ||
|
||
class MyBasicThread: | ||
public BasicThread | ||
{ | ||
public: | ||
virtual void Run() override { | ||
for (auto x : {0, 1, 2 ,3}) { | ||
std::cout << "MyBasicThread: " << x << "\n"; | ||
} | ||
} | ||
}; | ||
|
||
class MyCoreThread: | ||
public CoreThread | ||
{ | ||
public: | ||
void AddToQueue(int x) { | ||
*this += [x] { | ||
std::cout << "MyCoreThread: " << x << "\n"; | ||
std::this_thread::sleep_for(std::chrono::milliseconds(500)); | ||
}; | ||
} | ||
}; | ||
|
||
int main(){ | ||
|
||
// The 2 main thread classes in Autowiring are the BasicThread and CoreThread. | ||
// Classes that inherit from these types will have thread capabilities | ||
// Both start when their enclosing context is 'initiated'. Threads injected | ||
// after the context is initiated will start immediatly | ||
|
||
AutoRequired<MyBasicThread> myBasic; | ||
|
||
AutoCurrentContext ctxt; | ||
ctxt->Initiate(); // myBasic->Run() starts now in its own thread | ||
|
||
std::this_thread::sleep_for(std::chrono::milliseconds(250)); | ||
|
||
std::cout << "injecting a CoreThread" << std::endl; | ||
|
||
// Types inheriting from CoreThread implement a dispatch queue in their 'run()' | ||
// function. Lambdas can be appended with operator+= | ||
|
||
AutoRequired<MyCoreThread> myCore; | ||
myCore->AddToQueue(42); | ||
myCore->AddToQueue(1337); | ||
|
||
*myCore += []{ | ||
std::cout << "This gets run after '1337'" << std::endl; | ||
}; | ||
|
||
// This should be run before 'myCore' is finished | ||
std::cout << "This thread is faster\n"; | ||
|
||
// This will wait for all outstanding threads to finish before terminating the context | ||
ctxt->SignalShutdown(true); | ||
} | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters