From cd725fd3385e2763beb4ba081c89a059a2712e5b Mon Sep 17 00:00:00 2001 From: Adam Preble Date: Thu, 21 May 2009 10:04:35 -0400 Subject: [PATCH 1/5] Documentation enhancements. --- include/pinproc.h | 144 +++++++++++++++++++++++++++++++--------------- 1 file changed, 98 insertions(+), 46 deletions(-) diff --git a/include/pinproc.h b/include/pinproc.h index 923aece..5c0914d 100644 --- a/include/pinproc.h +++ b/include/pinproc.h @@ -56,9 +56,7 @@ #define PR_EXTERN_C_END #endif #endif -/** @endcond */ -/** @cond */ PR_EXTERN_C_BEGIN /** @endcond */ @@ -76,6 +74,11 @@ typedef void * PRHandle; /**< Opaque type used to reference an individual P- typedef void (*PRLogCallback)(const char *text); /**< Function pointer type for a custom logging callback. See: PRLogSetCallback(). */ PR_EXPORT void PRLogSetCallback(PRLogCallback callback); /**< Replaces the default logging handler with the given callback function. */ +/** + * @defgroup device Device Creation & Deletion + * @{ + */ + typedef enum PRMachineType { kPRMachineInvalid = 0, kPRMachineCustom = 1, @@ -88,29 +91,12 @@ typedef enum PRMachineType { PR_EXPORT PRHandle PRCreate(PRMachineType machineType); /**< Create a new P-ROC device handle. Only one handle per device may be created. This handle must be destroyed with PRDelete() when it is no longer needed. Returns #kPRHandleInvalid if an error occurred. */ PR_EXPORT void PRDelete(PRHandle handle); /**< Destroys an existing P-ROC device handle. */ - -// Events -// Closed == 0, Open == 1 -typedef enum PREventType { - kPREventTypeInvalid = 0, - kPREventTypeSwitchClosedDebounced = 1, /**< The switch has gone from open to closed and the signal has been debounced. */ - kPREventTypeSwitchOpenDebounced = 2, /**< The switch has gone from closed to open and the signal has been debounced. */ - kPREventTypeSwitchClosedNondebounced = 3, /**< The switch has gone from open to closed and the signal has not been debounced. */ - kPREventTypeSwitchOpenNondebounced = 4, /**< The switch has gone from closed to open and the signal has not been debounced. */ - kPREventTypetLast = kPREventTypeSwitchOpenNondebounced -} PREventType; - -typedef struct PREvent { - PREventType type; /**< The type of event that has occurred. Usually a switch event at this point. */ - uint32_t value; /**< For switch events, the switch number that has changed. */ - uint32_t time; /**< Time (in milliseconds) that this event occurred. */ -} PREvent; - -/** Get all of the available events that have been received. */ -PR_EXPORT int PRGetEvents(PRHandle handle, PREvent *eventsOut, int maxEvents); - +/** @} */ // End of Device Creation & Deletion // Drivers +/** @defgroup drivers Driver Manipulation + * @{ + */ typedef struct PRDriverGlobalConfig { bool_t enableOutputs; // Formerly enable_direct_outputs @@ -160,43 +146,95 @@ PR_EXPORT PRResult PRDriverGetGroupConfig(PRHandle handle, uint8_t groupNum, PRD PR_EXPORT PRResult PRDriverUpdateGroupConfig(PRHandle handle, PRDriverGroupConfig *driverGroupConfig); PR_EXPORT PRResult PRDriverGetState(PRHandle handle, uint8_t driverNum, PRDriverState *driverState); -/** Sets the state of the given driver (lamp, coil, etc.). */ +/** + * @brief Sets the state of the given driver (lamp or coil). + */ PR_EXPORT PRResult PRDriverUpdateState(PRHandle handle, PRDriverState *driverState); // Driver Helper functions: -/** Disables (turns off) the given driver. */ +/** + * Disables (turns off) the given driver. + * This function is provided for convenience. See PRDriverStateDisable() for a full description. + */ PR_EXPORT PRResult PRDriverDisable(PRHandle handle, uint16_t driverNum); -/** Pulses the given driver for a number of milliseconds. */ +/** + * Pulses the given driver for a number of milliseconds. + * This function is provided for convenience. See PRDriverStatePulse() for a full description. + */ PR_EXPORT PRResult PRDriverPulse(PRHandle handle, uint16_t driverNum, int milliseconds); -/** Assigns a repeating schedule to the given driver. */ +/** + * Assigns a repeating schedule to the given driver. + * This function is provided for convenience. See PRDriverStateSchedule() for a full description. + */ PR_EXPORT PRResult PRDriverSchedule(PRHandle handle, uint16_t driverNum, uint32_t schedule, uint8_t cycleSeconds, bool_t now); -/** Assigns a pitter-patter schedule (repeating on/off) to the given driver. */ +/** + * Assigns a pitter-patter schedule (repeating on/off) to the given driver. + * This function is provided for convenience. See PRDriverStatePatter() for a full description. + */ PR_EXPORT PRResult PRDriverPatter(PRHandle handle, uint16_t driverNum, uint16_t millisecondsOn, uint16_t millisecondsOff, uint16_t originalOnTime); /** Tickle the watchdog timer. */ PR_EXPORT PRResult PRDriverWatchdogTickle(PRHandle handle); -/** Disables (turns off) the given driver. */ +/** + * Changes the given #PRDriverState to reflect a disabled state. + * @note The driver state structure must be applied using PRDriverUpdateState() or linked to a switch rule using PRSwitchesUpdateRule() to have any effect. + */ PR_EXPORT void PRDriverStateDisable(PRDriverState *driverState); -/** Pulses the given driver for a number of milliseconds. */ +/** + * Changes the given #PRDriverState to reflect a pulse state. + * @param milliseconds Number of milliseconds to pulse the driver for. + * @note The driver state structure must be applied using PRDriverUpdateState() or linked to a switch rule using PRSwitchesUpdateRule() to have any effect. + */ PR_EXPORT void PRDriverStatePulse(PRDriverState *driverState, int milliseconds); -/** Assigns a repeating schedule to the given driver. */ +/** + * Changes the given #PRDriverState to reflect a scheduled state. + * Assigns a repeating schedule to the given driver. + * @note The driver state structure must be applied using PRDriverUpdateState() or linked to a switch rule using PRSwitchesUpdateRule() to have any effect. + */ PR_EXPORT void PRDriverStateSchedule(PRDriverState *driverState, uint32_t schedule, uint8_t cycleSeconds, bool_t now); -/** Assigns a pitter-patter schedule (repeating on/off) to the given driver. */ +/** + * @brief Changes the given #PRDriverState to reflect a pitter-patter schedule state. + * Assigns a pitter-patter schedule (repeating on/off) to the given driver. + * @note The driver state structure must be applied using PRDriverUpdateState() or linked to a switch rule using PRSwitchesUpdateRule() to have any effect. + * + * Use originalOnTime to pulse the driver for a number of milliseconds before the pitter-patter schedule begins. + */ PR_EXPORT void PRDriverStatePatter(PRDriverState *driverState, uint16_t millisecondsOn, uint16_t millisecondsOff, uint16_t originalOnTime); - +/** @} */ // End of Drivers // Switches -/** @defgroup switchconsts Switch Constants +/** @defgroup switches Switches and Events * @{ */ + +// Events +// Closed == 0, Open == 1 +typedef enum PREventType { + kPREventTypeInvalid = 0, + kPREventTypeSwitchClosedDebounced = 1, /**< The switch has gone from open to closed and the signal has been debounced. */ + kPREventTypeSwitchOpenDebounced = 2, /**< The switch has gone from closed to open and the signal has been debounced. */ + kPREventTypeSwitchClosedNondebounced = 3, /**< The switch has gone from open to closed and the signal has not been debounced. */ + kPREventTypeSwitchOpenNondebounced = 4, /**< The switch has gone from closed to open and the signal has not been debounced. */ + kPREventTypetLast = kPREventTypeSwitchOpenNondebounced +} PREventType; + +typedef struct PREvent { + PREventType type; /**< The type of event that has occurred. Usually a switch event at this point. */ + uint32_t value; /**< For switch events, the switch number that has changed. */ + uint32_t time; /**< Time (in milliseconds) that this event occurred. */ +} PREvent; + +/** Get all of the available events that have been received. */ +PR_EXPORT int PRGetEvents(PRHandle handle, PREvent *eventsOut, int maxEvents); + + #define kPRSwitchPhysicalFirst (0) /**< Switch number of the first physical switch. */ #define kPRSwitchPhysicalLast (223) /**< Switch number of the last physical switch. */ #define kPRSwitchVirtualFirst (224) /**< Switch number of the first virtual switch. */ #define kPRSwitchVirtualLast (255) /**< Switch number of the last virtual switch. */ -/** @} */ typedef struct PRSwitchRule { bool_t notifyHost; /**< If true this switch change event will provided to the user via PRGetEvents(). */ @@ -205,13 +243,16 @@ typedef struct PRSwitchRule { /** * @brief Configures the handling of switch rules within P-ROC. * - * P-ROC's switch event system allows the user to receive and act upon events specific to the individual switch's application. - * For example, P-ROC can provide debounced switch events to software by means of the PRGetEvents() call (to create - * a lane change behavior). The same switch can also be configured with a non-debounced rule to fire a flipper coil. + * P-ROC's switch rule system allows the user to decide which switch events are returned to software, + * as well as optionally linking one or more driver state changes to rules to create immediate feedback (such as in pop bumpers). + * + * For instance, P-ROC can provide debounced switch events for a flipper button so software can apply lange change behavior. + * This is accomplished by configuring the P-ROC with a switch rule for the flipper button and then receiving the events via the PRGetEvents() call. + * The same switch can also be configured with a non-debounced rule to fire a flipper coil. * Multiple driver changes can be tied to a single switch state transition to create more complicated effects: a slingshot * switch that fires the slingshot coil, a flash lamp, and a score event. * - * P-ROC holds four different switch rules for each switch: closed to open and open to closed, each with a debounced and non-debounced versions: + * P-ROC holds four different switch rules for each switch: closed to open, open to closed, and each with a debounced and non-debounced versions: * - #kPREventTypeSwitchOpenDebounced * - #kPREventTypeSwitchClosedDebounced * - #kPREventTypeSwitchOpenNondebounced @@ -219,14 +260,14 @@ typedef struct PRSwitchRule { * * @section Examples * - * Configuring a basic switch rule with no driver state changes that will appear in PRGetEvents(): + * Configuring a basic switch rule to simply notify software via PRGetEvents() without affecting any coil/lamp drivers: * @code * PRSwitchRule rule; * rule.notifyHost = true; * PRSwitchesUpdateRule(handle, switchNum, kPREventTypeSwitchOpenDebounced, &rule, NULL, 0); * @endcode * - * Configuring a pop bumper switch to pulse the coil and a flash lamp: + * Configuring a pop bumper switch to pulse the coil and a flash lamp for 50ms each: * @code * // Configure a switch rule to fire the coil and flash lamp: * PRSwitchRule rule; @@ -236,11 +277,11 @@ typedef struct PRSwitchRule { * PRDriverGetState(handle, drvFlashLamp1, &drivers[1]); * PRDriverStatePulse(&drivers[0], 50); * PRDriverStatePulse(&drivers[1], 50); - * PRSwitchesUpdateRule(handle, drvSwPopBumper1, kPREventTypeSwitchClosedNondebounced, + * PRSwitchesUpdateRule(handle, swPopBumper1, kPREventTypeSwitchClosedNondebounced, * &rule, drivers, 2); * // Now configure a switch rule to process scoring in software: - * rule.notifyHost = false; - * PRSwitchesUpdateRule(handle, drvSwPopBumper1, kPREventTypeSwitchClosedDebounced, + * rule.notifyHost = true; + * PRSwitchesUpdateRule(handle, swPopBumper1, kPREventTypeSwitchClosedDebounced, * &rule, NULL, 0); * @endcode * @@ -253,10 +294,13 @@ typedef struct PRSwitchRule { */ PR_EXPORT PRResult PRSwitchesUpdateRule(PRHandle handle, uint8_t switchNum, PREventType eventType, PRSwitchRule *rule, PRDriverState *linkedDrivers, int numDrivers); - +/** @} */ // End of Switches & Events // DMD - +/** + * @defgroup dmd DMD Control + * @{ + */ typedef struct PRDMDGlobalConfig { uint8_t numRows; uint16_t numColumns; @@ -274,8 +318,16 @@ PR_EXPORT int32_t PRDMDUpdateGlobalConfig(PRHandle handle, PRDMDGlobalConfig *dm /** Updates the DMD frame buffer with the given data. */ PR_EXPORT PRResult PRDMDDraw(PRHandle handle, uint8_t * dots, uint16_t columns, uint8_t rows, uint8_t numSubFrames); +/** @} */ // End of DMD + /** @cond */ PR_EXTERN_C_END /** @endcond */ +/** + * @mainpage libpinproc API Documentation + * + * This is the documentation for libpinproc, the P-ROC Layer 1 API. + */ + #endif // _PINPROC_H_ From b96905f5caa55d6f2b7d69d15f5416be29fdc9fc Mon Sep 17 00:00:00 2001 From: Adam Preble Date: Thu, 21 May 2009 20:13:29 -0400 Subject: [PATCH 2/5] Reverted minor doc wording change. --- include/pinproc.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/include/pinproc.h b/include/pinproc.h index 5c0914d..17b7879 100644 --- a/include/pinproc.h +++ b/include/pinproc.h @@ -252,7 +252,7 @@ typedef struct PRSwitchRule { * Multiple driver changes can be tied to a single switch state transition to create more complicated effects: a slingshot * switch that fires the slingshot coil, a flash lamp, and a score event. * - * P-ROC holds four different switch rules for each switch: closed to open, open to closed, and each with a debounced and non-debounced versions: + * P-ROC holds four different switch rules for each switch: closed to open and open to closed, each with a debounced and non-debounced versions: * - #kPREventTypeSwitchOpenDebounced * - #kPREventTypeSwitchClosedDebounced * - #kPREventTypeSwitchOpenNondebounced From cd1b0462c53739887b418e949ec968d4961c6d05 Mon Sep 17 00:00:00 2001 From: Adam Preble Date: Fri, 22 May 2009 01:51:52 -0400 Subject: [PATCH 3/5] Added excruciatingly rough implementation of PRLoadDefaultsFromYAML() and related items. --- .gitignore | 1 + Makefile | 3 +- README.markdown | 8 +++ examples/pinproctest/Example.yaml | 7 +++ examples/pinproctest/Makefile | 4 +- examples/pinproctest/pinproctest.cpp | 1 + include/pinproc.h | 2 + libpinproc.xcodeproj/project.pbxproj | 22 +++++-- src/PRDevice.cpp | 87 ++++++++++++++++++++++++++++ src/PRDevice.h | 1 + src/pinproc.cpp | 4 ++ 11 files changed, 133 insertions(+), 7 deletions(-) create mode 100644 examples/pinproctest/Example.yaml diff --git a/.gitignore b/.gitignore index 8248aa2..83e29ab 100644 --- a/.gitignore +++ b/.gitignore @@ -1,3 +1,4 @@ build/ */*.pbxuser */*.perspectivev3 +*.o diff --git a/Makefile b/Makefile index ceabe44..c03269e 100644 --- a/Makefile +++ b/Makefile @@ -9,7 +9,8 @@ LIBSRC=src/pinproc.cpp src/PRDevice.cpp src/PRHardware.cpp LIBOBJ=$(LIBSRC:.cpp=.o) -#CXXFLAGS=-I/usr/local/lib -lusb -lftdi +#CXXFLAGS=-I/usr/local/lib -lusb -lftdi +CXXFLAGS=-I../../yaml-cpp/include $(LIB): $(LIBOBJ) @echo lib Makefile - archiving $(LIB) diff --git a/README.markdown b/README.markdown index d27d016..7e5b248 100644 --- a/README.markdown +++ b/README.markdown @@ -2,6 +2,14 @@ Library for Gerry Stellenberg's [P-ROC](http://pinballcontrollers.com/) (Pinball Remote Operations Controller). +### Compiling + +libpinproc requires: + +- [libusb-0.1.12](http://libusb.wiki.sourceforge.net/): Install with the default /usr/local prefix. +- [libftdi-0.16](http://www.intra2net.com/en/developer/libftdi/): Install with the default /usr/local prefix. +- [yaml-cpp](http://code.google.com/p/yaml-cpp/): Should be checked out in the directory two levels below libpinproc in the full source tree (at the same level as ./P-ROC) in a directory named yaml-cpp. Follow the build instructions, creating the build subdirectory. The Makefiles and other project files expect to find libyaml-cpp.a in the yaml-cpp/build/bin directory. + ### License #### The MIT License diff --git a/examples/pinproctest/Example.yaml b/examples/pinproctest/Example.yaml new file mode 100644 index 0000000..f99a700 --- /dev/null +++ b/examples/pinproctest/Example.yaml @@ -0,0 +1,7 @@ +PRGameName: My Great Pin +PRDrivers: + 1: driver one + 2: driver two +PRSwitches: + 1: switch one + 2: switch two diff --git a/examples/pinproctest/Makefile b/examples/pinproctest/Makefile index db31cb6..99244bc 100644 --- a/examples/pinproctest/Makefile +++ b/examples/pinproctest/Makefile @@ -2,8 +2,8 @@ # File: Makefile for application # CC=g++ -LDFLAGS=-L../.. -L/usr/local/lib -LIBS=-lpinproc -lusb -lftdi +LDFLAGS=-L../.. -L/usr/local/lib -L../../../../yaml-cpp/build/bin +LIBS=-lpinproc -lusb -lftdi -lyaml-cpp SRC=pinproctest.cpp diff --git a/examples/pinproctest/pinproctest.cpp b/examples/pinproctest/pinproctest.cpp index 1a489b2..ce7b117 100644 --- a/examples/pinproctest/pinproctest.cpp +++ b/examples/pinproctest/pinproctest.cpp @@ -162,6 +162,7 @@ int main(const char **argv, int argc) return 1; printf("Configuring P-ROC...\n"); + PRLoadDefaultsFromYAML(proc, "../../examples/pinproctest/Example.yaml"); ConfigureSwitches(proc); // Make Drivers the last thing to configure so watchdog doesn't expire diff --git a/include/pinproc.h b/include/pinproc.h index 17b7879..b9b45eb 100644 --- a/include/pinproc.h +++ b/include/pinproc.h @@ -91,6 +91,8 @@ typedef enum PRMachineType { PR_EXPORT PRHandle PRCreate(PRMachineType machineType); /**< Create a new P-ROC device handle. Only one handle per device may be created. This handle must be destroyed with PRDelete() when it is no longer needed. Returns #kPRHandleInvalid if an error occurred. */ PR_EXPORT void PRDelete(PRHandle handle); /**< Destroys an existing P-ROC device handle. */ +PR_EXPORT PRResult PRLoadDefaultsFromYAML(PRHandle handle, const char *yamlFilePath); + /** @} */ // End of Device Creation & Deletion // Drivers diff --git a/libpinproc.xcodeproj/project.pbxproj b/libpinproc.xcodeproj/project.pbxproj index 98001c9..65642bf 100644 --- a/libpinproc.xcodeproj/project.pbxproj +++ b/libpinproc.xcodeproj/project.pbxproj @@ -221,7 +221,10 @@ GCC_ENABLE_FIX_AND_CONTINUE = YES; GCC_MODEL_TUNING = G5; GCC_OPTIMIZATION_LEVEL = 0; - HEADER_SEARCH_PATHS = /usr/local/include; + HEADER_SEARCH_PATHS = ( + /usr/local/include, + "../../yaml-cpp/include", + ); INSTALL_PATH = /usr/local/lib; PRODUCT_NAME = pinproc; }; @@ -233,7 +236,10 @@ ALWAYS_SEARCH_USER_PATHS = NO; DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; GCC_MODEL_TUNING = G5; - HEADER_SEARCH_PATHS = /usr/local/include; + HEADER_SEARCH_PATHS = ( + /usr/local/include, + "../../yaml-cpp/include", + ); INSTALL_PATH = /usr/local/lib; PRODUCT_NAME = pinproc; }; @@ -275,7 +281,11 @@ GCC_MODEL_TUNING = G5; GCC_OPTIMIZATION_LEVEL = 0; INSTALL_PATH = /usr/local/bin; - OTHER_LDFLAGS = "-lftdi"; + OTHER_LDFLAGS = ( + "-L../../yaml-cpp/build/bin", + "-lyaml-cpp", + "-lftdi", + ); PREBINDING = NO; PRODUCT_NAME = pinproctest; }; @@ -290,7 +300,11 @@ GCC_ENABLE_FIX_AND_CONTINUE = NO; GCC_MODEL_TUNING = G5; INSTALL_PATH = /usr/local/bin; - OTHER_LDFLAGS = "-lftdi"; + OTHER_LDFLAGS = ( + "-L../../yaml-cpp/build/bin", + "-lyaml-cpp", + "-lftdi", + ); PREBINDING = NO; PRODUCT_NAME = pinproctest; ZERO_LINK = NO; diff --git a/src/PRDevice.cpp b/src/PRDevice.cpp index db14858..5b70b7b 100644 --- a/src/PRDevice.cpp +++ b/src/PRDevice.cpp @@ -99,6 +99,93 @@ void PRDevice::Reset() // TODO: Assign defaults based on machineType. Some may have already been done above. } +#include +#include "yaml.h" + +PRResult PRDevice::LoadDefaultsFromYAML(const char *yamlFilePath) +{ + try + { + std::ifstream fin(yamlFilePath); + if (fin.is_open() == false) + { + DEBUG(PRLog("YAML file not found: %s\n", yamlFilePath)); + return kPRFailure; + } + YAML::Parser parser(fin); + + while(parser) { + YAML::Node doc; + parser.GetNextDocument(doc); + + for(YAML::Iterator it=doc.begin();it!=doc.end();++it) { + std::string key; + it.first() >> key; + DEBUG(PRLog("Parsing key %s...\n", key.c_str())); + if (key.compare("PRGameName") == 0) + { + std::string name; + it.second() >> name; + DEBUG(PRLog(" Machine name: %s\n", name.c_str())); + } + else if (key.compare("PRDriverGlobalConfig") == 0) + { + //const YAML::Node& dict = it.second(); + } + else if (key.compare("PRDriverGroupConfigs") == 0) + { + const YAML::Node& groups = it.second(); + for(YAML::Iterator it=groups.begin();it!=groups.end();++it) + { + std::string key; + it.first() >> key; + } + } + else if (key.compare("PRDrivers") == 0) + { + const YAML::Node& dict = it.second(); + for(YAML::Iterator dictIt=dict.begin(); dictIt != dict.end(); ++dictIt) + { + std::string driverKey; + std::string driverName; + dictIt.first() >> driverKey; + dictIt.second() >> driverName; + DEBUG(PRLog(" Driver: %s -> %s\n", driverKey.c_str(), driverName.c_str())); + } + } + else if (key.compare("PRSwitches") == 0) + { + const YAML::Node& dict = it.second(); + for(YAML::Iterator dictIt=dict.begin(); dictIt != dict.end(); ++dictIt) + { + std::string driverKey; + std::string driverName; + dictIt.first() >> driverKey; + dictIt.second() >> driverName; + DEBUG(PRLog(" Switch: %s -> %s\n", driverKey.c_str(), driverName.c_str())); + } + } + } + } + } + catch (YAML::ParserException& ex) + { + DEBUG(PRLog("YAML parse error at line=%d col=%d: %s\n", ex.line, ex.column, ex.msg.c_str())); + return kPRFailure; + } + catch (YAML::RepresentationException& ex) + { + DEBUG(PRLog("YAML representation error at line=%d col=%d: %s\n", ex.line, ex.column, ex.msg.c_str())); + return kPRFailure; + } + catch (...) + { + DEBUG(PRLog("Unexpected exception while parsing YAML config.\n")); + return kPRFailure; + } + return kPRSuccess; +} + int PRDevice::GetEvents(PREvent *events, int maxEvents) { diff --git a/src/PRDevice.h b/src/PRDevice.h index a181458..04b9018 100644 --- a/src/PRDevice.h +++ b/src/PRDevice.h @@ -56,6 +56,7 @@ protected: public: // public libpinproc API: + PRResult LoadDefaultsFromYAML(const char *yamlFilePath); int GetEvents(PREvent *events, int maxEvents); PRResult DriverUpdateGlobalConfig(PRDriverGlobalConfig *driverGlobalConfig); diff --git a/src/pinproc.cpp b/src/pinproc.cpp index e223f6f..a078067 100644 --- a/src/pinproc.cpp +++ b/src/pinproc.cpp @@ -72,6 +72,10 @@ PR_EXPORT void PRDelete(PRHandle handle) delete (PRDevice*)handle; } +PR_EXPORT PRResult PRLoadDefaultsFromYAML(PRHandle handle, const char *yamlFilePath) +{ + return handleAsDevice->LoadDefaultsFromYAML(yamlFilePath); +} // Events From 8b0eeecee308417bf7f30e77bc26e4795bdb717b Mon Sep 17 00:00:00 2001 From: Adam Preble Date: Fri, 22 May 2009 11:35:31 -0400 Subject: [PATCH 4/5] Moved YAML code to new PRConfig.cpp. --- libpinproc.xcodeproj/project.pbxproj | 4 + src/PRConfig.cpp | 120 +++++++++++++++++++++++++++ src/PRDevice.cpp | 87 ------------------- 3 files changed, 124 insertions(+), 87 deletions(-) create mode 100644 src/PRConfig.cpp diff --git a/libpinproc.xcodeproj/project.pbxproj b/libpinproc.xcodeproj/project.pbxproj index 65642bf..252f07f 100644 --- a/libpinproc.xcodeproj/project.pbxproj +++ b/libpinproc.xcodeproj/project.pbxproj @@ -15,6 +15,7 @@ 668249E30FC0A3960051560E /* pinproctest.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 668249E20FC0A3960051560E /* pinproctest.cpp */; }; 668249EA0FC0A4280051560E /* libpinproc.a in Frameworks */ = {isa = PBXBuildFile; fileRef = D2AAC046055464E500DB518D /* libpinproc.a */; }; 668249ED0FC0A4CD0051560E /* PRHardware.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 668249EC0FC0A4CD0051560E /* PRHardware.cpp */; }; + 66824DAE0FC6FC690051560E /* PRConfig.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 66824DAD0FC6FC690051560E /* PRConfig.cpp */; }; /* End PBXBuildFile section */ /* Begin PBXContainerItemProxy section */ @@ -36,6 +37,7 @@ 668249D90FC0A30A0051560E /* pinproctest */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.executable"; includeInIndex = 0; path = pinproctest; sourceTree = BUILT_PRODUCTS_DIR; }; 668249E20FC0A3960051560E /* pinproctest.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = pinproctest.cpp; path = examples/pinproctest/pinproctest.cpp; sourceTree = ""; }; 668249EC0FC0A4CD0051560E /* PRHardware.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = PRHardware.cpp; path = src/PRHardware.cpp; sourceTree = ""; }; + 66824DAD0FC6FC690051560E /* PRConfig.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = PRConfig.cpp; path = src/PRConfig.cpp; sourceTree = ""; }; D2AAC046055464E500DB518D /* libpinproc.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = libpinproc.a; sourceTree = BUILT_PRODUCTS_DIR; }; /* End PBXFileReference section */ @@ -93,6 +95,7 @@ 668249390FC07B2A0051560E /* pinproc.cpp */, 668249400FC07D900051560E /* PRDevice.h */, 668249410FC07D900051560E /* PRDevice.cpp */, + 66824DAD0FC6FC690051560E /* PRConfig.cpp */, 6682494A0FC0870B0051560E /* PRHardware.h */, 668249EC0FC0A4CD0051560E /* PRHardware.cpp */, ); @@ -198,6 +201,7 @@ 6682493A0FC07B2A0051560E /* pinproc.cpp in Sources */, 668249430FC07D900051560E /* PRDevice.cpp in Sources */, 668249ED0FC0A4CD0051560E /* PRHardware.cpp in Sources */, + 66824DAE0FC6FC690051560E /* PRConfig.cpp in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; diff --git a/src/PRConfig.cpp b/src/PRConfig.cpp new file mode 100644 index 0000000..17b34bb --- /dev/null +++ b/src/PRConfig.cpp @@ -0,0 +1,120 @@ +/* + * The MIT License + * Copyright (c) 2009 Gerry Stellenberg, Adam Preble + * + * Permission is hereby granted, free of charge, to any person + * obtaining a copy of this software and associated documentation + * files (the "Software"), to deal in the Software without + * restriction, including without limitation the rights to use, + * copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following + * conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT + * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR + * OTHER DEALINGS IN THE SOFTWARE. + */ +/* + * PRConfig.cpp + * libpinproc + * + */ + + +#include "PRDevice.h" + +#include +#include "yaml.h" + +PRResult PRDevice::LoadDefaultsFromYAML(const char *yamlFilePath) +{ + try + { + std::ifstream fin(yamlFilePath); + if (fin.is_open() == false) + { + DEBUG(PRLog("YAML file not found: %s\n", yamlFilePath)); + return kPRFailure; + } + YAML::Parser parser(fin); + + while(parser) { + YAML::Node doc; + parser.GetNextDocument(doc); + + for(YAML::Iterator it=doc.begin();it!=doc.end();++it) { + std::string key; + it.first() >> key; + DEBUG(PRLog("Parsing key %s...\n", key.c_str())); + if (key.compare("PRGameName") == 0) + { + std::string name; + it.second() >> name; + DEBUG(PRLog(" Machine name: %s\n", name.c_str())); + } + else if (key.compare("PRDriverGlobalConfig") == 0) + { + //const YAML::Node& dict = it.second(); + } + else if (key.compare("PRDriverGroupConfigs") == 0) + { + const YAML::Node& groups = it.second(); + for(YAML::Iterator it=groups.begin();it!=groups.end();++it) + { + std::string key; + it.first() >> key; + } + } + else if (key.compare("PRDrivers") == 0) + { + const YAML::Node& dict = it.second(); + for(YAML::Iterator dictIt=dict.begin(); dictIt != dict.end(); ++dictIt) + { + std::string driverKey; + std::string driverName; + dictIt.first() >> driverKey; + dictIt.second() >> driverName; + DEBUG(PRLog(" Driver: %s -> %s\n", driverKey.c_str(), driverName.c_str())); + } + } + else if (key.compare("PRSwitches") == 0) + { + const YAML::Node& dict = it.second(); + for(YAML::Iterator dictIt=dict.begin(); dictIt != dict.end(); ++dictIt) + { + std::string driverKey; + std::string driverName; + dictIt.first() >> driverKey; + dictIt.second() >> driverName; + DEBUG(PRLog(" Switch: %s -> %s\n", driverKey.c_str(), driverName.c_str())); + } + } + } + } + } + catch (YAML::ParserException& ex) + { + DEBUG(PRLog("YAML parse error at line=%d col=%d: %s\n", ex.line, ex.column, ex.msg.c_str())); + return kPRFailure; + } + catch (YAML::RepresentationException& ex) + { + DEBUG(PRLog("YAML representation error at line=%d col=%d: %s\n", ex.line, ex.column, ex.msg.c_str())); + return kPRFailure; + } + catch (...) + { + DEBUG(PRLog("Unexpected exception while parsing YAML config.\n")); + return kPRFailure; + } + return kPRSuccess; +} diff --git a/src/PRDevice.cpp b/src/PRDevice.cpp index 5b70b7b..db14858 100644 --- a/src/PRDevice.cpp +++ b/src/PRDevice.cpp @@ -99,93 +99,6 @@ void PRDevice::Reset() // TODO: Assign defaults based on machineType. Some may have already been done above. } -#include -#include "yaml.h" - -PRResult PRDevice::LoadDefaultsFromYAML(const char *yamlFilePath) -{ - try - { - std::ifstream fin(yamlFilePath); - if (fin.is_open() == false) - { - DEBUG(PRLog("YAML file not found: %s\n", yamlFilePath)); - return kPRFailure; - } - YAML::Parser parser(fin); - - while(parser) { - YAML::Node doc; - parser.GetNextDocument(doc); - - for(YAML::Iterator it=doc.begin();it!=doc.end();++it) { - std::string key; - it.first() >> key; - DEBUG(PRLog("Parsing key %s...\n", key.c_str())); - if (key.compare("PRGameName") == 0) - { - std::string name; - it.second() >> name; - DEBUG(PRLog(" Machine name: %s\n", name.c_str())); - } - else if (key.compare("PRDriverGlobalConfig") == 0) - { - //const YAML::Node& dict = it.second(); - } - else if (key.compare("PRDriverGroupConfigs") == 0) - { - const YAML::Node& groups = it.second(); - for(YAML::Iterator it=groups.begin();it!=groups.end();++it) - { - std::string key; - it.first() >> key; - } - } - else if (key.compare("PRDrivers") == 0) - { - const YAML::Node& dict = it.second(); - for(YAML::Iterator dictIt=dict.begin(); dictIt != dict.end(); ++dictIt) - { - std::string driverKey; - std::string driverName; - dictIt.first() >> driverKey; - dictIt.second() >> driverName; - DEBUG(PRLog(" Driver: %s -> %s\n", driverKey.c_str(), driverName.c_str())); - } - } - else if (key.compare("PRSwitches") == 0) - { - const YAML::Node& dict = it.second(); - for(YAML::Iterator dictIt=dict.begin(); dictIt != dict.end(); ++dictIt) - { - std::string driverKey; - std::string driverName; - dictIt.first() >> driverKey; - dictIt.second() >> driverName; - DEBUG(PRLog(" Switch: %s -> %s\n", driverKey.c_str(), driverName.c_str())); - } - } - } - } - } - catch (YAML::ParserException& ex) - { - DEBUG(PRLog("YAML parse error at line=%d col=%d: %s\n", ex.line, ex.column, ex.msg.c_str())); - return kPRFailure; - } - catch (YAML::RepresentationException& ex) - { - DEBUG(PRLog("YAML representation error at line=%d col=%d: %s\n", ex.line, ex.column, ex.msg.c_str())); - return kPRFailure; - } - catch (...) - { - DEBUG(PRLog("Unexpected exception while parsing YAML config.\n")); - return kPRFailure; - } - return kPRSuccess; -} - int PRDevice::GetEvents(PREvent *events, int maxEvents) { From 5f934a58f75b1f56b9baea4c7cf47de5306ab6ab Mon Sep 17 00:00:00 2001 From: Adam Preble Date: Fri, 22 May 2009 12:41:10 -0400 Subject: [PATCH 5/5] Changed PRLoadConfigFromYAML() to use much clearer style. --- src/PRConfig.cpp | 74 ++++++++++++++++++++---------------------------- 1 file changed, 31 insertions(+), 43 deletions(-) diff --git a/src/PRConfig.cpp b/src/PRConfig.cpp index 17b34bb..ac0a0e5 100644 --- a/src/PRConfig.cpp +++ b/src/PRConfig.cpp @@ -51,54 +51,42 @@ PRResult PRDevice::LoadDefaultsFromYAML(const char *yamlFilePath) YAML::Node doc; parser.GetNextDocument(doc); - for(YAML::Iterator it=doc.begin();it!=doc.end();++it) { - std::string key; - it.first() >> key; - DEBUG(PRLog("Parsing key %s...\n", key.c_str())); - if (key.compare("PRGameName") == 0) + try + { + const YAML::Node& node = doc["PRGameName"]; + std::string name; node >> name; + DEBUG(PRLog(" Game Name: %s\n", name.c_str())); + } + catch (YAML::KeyNotFound& ex) {} + + try + { + const YAML::Node& dict = doc["PRSwitches"]; + for(YAML::Iterator dictIt = dict.begin(); dictIt != dict.end(); ++dictIt) { + std::string key; std::string name; - it.second() >> name; - DEBUG(PRLog(" Machine name: %s\n", name.c_str())); + dictIt.first() >> key; + dictIt.second() >> name; + DEBUG(PRLog(" Switch: %s -> %s\n", key.c_str(), name.c_str())); } - else if (key.compare("PRDriverGlobalConfig") == 0) + } + catch (YAML::KeyNotFound& ex) {} + + try + { + const YAML::Node& dict = doc["PRDrivers"]; + for(YAML::Iterator dictIt = dict.begin(); dictIt != dict.end(); ++dictIt) { - //const YAML::Node& dict = it.second(); + std::string key; + std::string name; + dictIt.first() >> key; + dictIt.second() >> name; + DEBUG(PRLog(" Driver: %s -> %s\n", key.c_str(), name.c_str())); } - else if (key.compare("PRDriverGroupConfigs") == 0) - { - const YAML::Node& groups = it.second(); - for(YAML::Iterator it=groups.begin();it!=groups.end();++it) - { - std::string key; - it.first() >> key; - } - } - else if (key.compare("PRDrivers") == 0) - { - const YAML::Node& dict = it.second(); - for(YAML::Iterator dictIt=dict.begin(); dictIt != dict.end(); ++dictIt) - { - std::string driverKey; - std::string driverName; - dictIt.first() >> driverKey; - dictIt.second() >> driverName; - DEBUG(PRLog(" Driver: %s -> %s\n", driverKey.c_str(), driverName.c_str())); - } - } - else if (key.compare("PRSwitches") == 0) - { - const YAML::Node& dict = it.second(); - for(YAML::Iterator dictIt=dict.begin(); dictIt != dict.end(); ++dictIt) - { - std::string driverKey; - std::string driverName; - dictIt.first() >> driverKey; - dictIt.second() >> driverName; - DEBUG(PRLog(" Switch: %s -> %s\n", driverKey.c_str(), driverName.c_str())); - } - } - } + } + catch (YAML::KeyNotFound& ex) {} + } } catch (YAML::ParserException& ex)