Jump to content
  • Advertisement


  • Content Count

  • Joined

  • Last visited

Community Reputation

533 Good

About Nit

  • Rank
  1. Nit

    Unnecessary Challenges

    This happened to me a few years back, and I know how frustrating this situation must be for you. I'm currently using Amazon cloud (5 GB free storage) to back up my critical data (svn repository dump files mainly). If possible, i'd recommend that you identify the stuff you can't live without and get it down to a small amount that fits in the free cloud storage plans (or maybe use a few services that are free).
  2. Nit

    Standalone SVN Repository

    It's funny you say that, as I've been moving Git up on my priority list. Posts from promit and suprpig really brought my attention to some of SVNs limitations. That said, SVN does not current hold me back; it does everything I need it to do right now (which is to manage the evolution of my codebase, and allow me to diff between past versions). I'm the only developer adding to the repository, so a simple solution seems acceptable for now. Switching to Git is mostly motivated by its learning experience.
  3. By request, I'm attaching some sample source code that demonstrates the topics covered in my last two postings. This is a basic solution for calling into Python from C++. I've also included in the attached zipfile, notes on how to configure a Visual Studio 2008 solution to use Python26. I expect it is straightforward to translate these steps to work with a different compiler, or another version of Python. For completeness, these notes are included here: Notes for creating the Project in Visual Studio 2008 Assumes Python26 is installed at C:\Python26, so be sure to update the paths listed below if you are using a different version of python.Create a New Project --> Win32 Console Application, No precompiled Headers, Empty ProjectAdd main.cpp, pythonCallbacks.h, pythonCallbacks.cpp files to solutionRight click on PythonCppExample --> PropertiesC/C++ --> General --> Additional Include Directories = C:\Python26\includeLinker --> General --> Additional Library Directories = C:\Python26\libs(NOTE: Notice it is the libs directory, not the Lib directory)Linker --> Input --> Additional Dependencies = python26.lib
  4. Nit

    Interfacing C++ and Python (Part 2)

    Sure. I'll try to get an example uploaded this weekend.
  5. This is the second posting that deals with interfacing C++ with a Python scripting layer. Part 1 can be found here. The focus in this post relates to the design I chose to follow for wrapping Python callback functions in C++. The design objective here is to ensure that a callback function can be quickly defined in python, while also not requiring any recompilation of the c++ UI library. This last feature is important, because in theory the user interface should be configurable and extendable by advanced end users of the game engine. A lot of my inspiration of this train of thought can be attributed to World of Warcraft's extremely customizable user interface. To setup this example, consider the following xml file that defines a simple GUI, with a window containing a button. The button defines a callback to be executed when the button is pressed, that links to a function defined in Python. When constructing this class, a generic interface must be defined that are components of GUI elements. In my codebase, currently all Python standalone functions like this inherit from this callback process. class PythonCallback { public: PythonCallback(const std::string& module, const std::string& callback); virtual ~PythonCallback(); protected: PyObject* _module; PyObject* _callback; }; Notice _module and _callback are PyObjects. To rehash from my earlier entry, I personally prefer to forward declare this PyObjects rather than use a #include to ensure that python.h is not included unless it is absolutely necessary (e.g., in the cpp implementation file!). // forward declare PyObject // as suggested on the python mailing list // http://mail.python.org/pipermail/python-dev/2003-August/037601.html #ifndef PyObject_HEAD struct _object; typedef _object PyObject; #endif Much of the Python C API setup is done in the constructor of this abstract class. The guts of this is largely derived from the Python C API documentation, particularly in the following tutorial: http://docs.python.o.../embedding.html The primary function here is to create the _callback and _module instances and maintain proper memory management of our PyObject references. PythonCallback::PythonCallback(const std::string &module, const std::string &callback) { PyObject *pyName; pyName = PyString_FromString(module.c_str()); _module = PyImport_Import(pyName); Py_DECREF(pyName); if (_module) { _callback = PyObject_GetAttrString(_module, callback.c_str()); /* _callback is a new reference */ if (_callback && PyCallable_Check(_callback)) { // success } else { if (PyErr_Occurred()) PyErr_Print(); std::cout
  6. I've recently decided it was time to gain a bit more flexibility in my c++ codebase by adding support for a scripting interface. My initial use case was to enable my homegrown gui system (in c++) to offload callbacks and general customization to a scripting layer, rather than having to hard code a user interface in C++. I chose Python as my scripting language, due to my years of experience with this language. With the GUI/addon system use case in mind, I need my C++ code to call into a Python script/module and I also need my Python scripts to interact with C++ objects. Here's a simple example that I've got in mind for this process: # import the pyd that interfaces python with my c++ library from az_gui import * ... def onCancelButton(self, event): ''' Event handler for cancel button. ''' window = self.getWindow() window.close() return True I've decided to split this topic into several postings. This first post covers the ground work necessary for calling into Python scripts. The second posting will review a PythonCallback wrapper class that is designed to encapsulate the Python C API code for calling function callbacks in python modules. After that I'll have a post or two on my Boost.Python experiences that expose my C++ libraries to Python (e.g., allowing for Python code to call the C++ class, Window as shown in the example above). C++ calls into Python scripts: Went with the Python C API for communication in this direction, since it was a manageable process. I'm resistant to adding 3rdParty dependencies to my project, so this seemed like the best I could do. On a side note, my original goal was to write my own Python C API wrappers to also exposing my c++ classes to Python scripts, but that panned out to be an enormous undertaking that I'm not ready to tackle yet. (this discussion is saved for another post). There were a few catches along the way that made the implementation less straightfoward. For starters, a standard install of Python does not have a debug library. As such, some macro magic needs to be performed to include Python.h header file. //Note // Since Python may define some pre-processor definitions which affect // the standard headers on some systems, you must include Python.h before // any standard headers are included. #ifdef _DEBUG #undef _DEBUG #include "Python.h" #define _DEBUG #else #include "Python.h" #endif It is my preference to keep this Python.h ugliness inside the cpp files, so my next trick involved forward declaring PyObject: // forward declare PyObject // as suggested on the python mailing list // http://mail.python.org/pipermail/python-dev/2003-August/037601.html #ifndef PyObject_HEAD struct _object; typedef _object PyObject; #endif Pulling it all together: To manage the Python C API, I created a PythonManager class to encapsulate the Python interpreter session used within my codebase. PythonManager.h ... class PythonManager { public: PythonManager(); virtual ~PythonManager(); void initialize(); void uninitialize(); // add directories to the python interpreter's sys.path // to allow for Python scripts to locate script directories. bool addSysPath(const std::string& relativePath); protected: }; PythonManger.cpp: ... PythonManager::PythonManager() { } PythonManager::~PythonManager() { uninitialize(); } bool PythonManager::addSysPath(const std::string& relativePath) { std::ostringstream ss; ss
  7. Since I'm the sole programmer on my own personal game engine, I didn't feel much pressure in using configuration management software. I had at one point been reliant on regular backups by simply zipping the entire solution directory and timestamping the zip file. I keep a changelog that summarizes the changes made to the code base in order to hint at the state of the code snapshot in case I ever needed to roll back to that version. I've was never thrilled with solution; 95% (buttpull number) of each zip contained code that had not changed, rolling back could result in lots of snooping around to find the correct version, the backup process was time consuming, no diff mechanism to verify that I actually wanted to keep all changes made for this version snapshot. A while back, I found a good opportunity to switch over to subversion for all of my revision needs. I had setup a svn repository on a remote ubuntu server in the past, but I hardly keep that old clunker running so it was a pain to power up a machine each time I wanted to check in some code. My newer approach was to create a repository on my development laptop and check in code locally. The plan is regularly backup this repository onto another machine for redundancy purposes. Since the repository is stored on my local development machine, I know it will always be online for code checkins. If the machine happens to be powered down, I certainly won't be coding. To setup this standalone svn repository, I used Tortoise SVN (http://tortoisesvn.tigris.org/). This was the only download needed. After installing and rebooting, I created my repository by creating a folder named "svn_repository", right clicking on that new folder, and selecting TortoiseSVN->"Create Repository Here". The next step required is setup the structure of the svn repository. I prefer to use the trunk, braches, tags structure for my repository. To do this, I created a temporary directory (C:\svn_temp) and placed three empty subfolders here, svn_temp\trunk, svn_temp\branches, and svn_temp\tags. Right click on svn_temp and select "Tortoise SVN -> Import ...". For the comment, I just said something along the lines of "Repository folder structure". The URL of the repository in my case was "file:///c:/projects/svn_repository", which was the top directory for my repository. The final step involves the importing of my current code base. Since the trunk is the active (and sometimes unstable) HEAD of the repository, I wanted to import my first batch of code into the trunk. I didn't see this code base as being at any major version, so that is why I chose a checkin into the trunk rather than the tags directory. First I created a directory called svn_workingcopies. I right clicked on this new folder and selected Checkout. For the repository URL, I specified ""file:///c:/projects/svn_repository/trunk", since I was planning on working on the trunk. The operation should complete successfully, and there won't be any new contents added to this svn_workingcopies directory since the trunk is currently empty. I copied and pasted my entire code base from the old location (that was archived with zip files), to the new svn_workingcopies directory. To add this codebase to svn, I right clicked on the top level directory of my newly copied project ("c:\projects\svn_workingcopies\azrial") and selected "Tortoise SVN -> Add". From here I weeded out (unchecked) any file that was generated (game log files, Debug directory contents, Release Directory contents, etc). I didn't want stuff in the repository that would change each time I ran my project. Now that everything is added, it is ready to be committed to the repository. This was done by right clicking on the project and selecting "SVN Commit". After double checking that I was checking in only the essential files, I hit ok and was left with a full code base in the trunk directory of my repository. With all of this in place, I will be creating tags at major code milestones, creating branches when I plan to do some experimentation on the codebase, and performing diffs on files before doing commits to verify that no "test code" sneaks into the repository.
  8. Nit

    Crash Recovery

    I recently suffered a terrible HD crash on my coding laptop, which resulted in a loss of about 2 months of coding work. Needless to say, losing any amount of work that you are proud of certainly does suck. However, I've been able to collect a list of tasks that vanished as a result of this event and I should be back on track within a week or so. There is something positive that came out of this crash, as I have been reminded of the importance of backup up my work. For a while I was doing pretty good, using a svn repository in addition to performing full archives of the code base with a zip file. That backup regiment has slowly tapered off, and lately I've been only zipping the code base without copying the zip up to a thumb drive or external. In response, I've written the following script that I wanted to share that performs the backup for me. If you're really bad about backing up your work, you may want to do what I did: place the script directly on your external storage device and integrate it into the autorun. Directions on doing this are included in the scripts comments: ## ## file: backup.py ## author: Alex Wood ## date: 2008-06-04 ## desc: Archives all files in each specified directory into a specific zip file. ## ## ## Place this script in the toplevel of a thumb drive or external harddrive ## to enable autobackup of directories, as described below. ## ## Copy and paste the following text into your autorun.inf text file: ## ## [autorun] ## open=launch.bat ## ACTION = Launch portable workspace ## ## Create launch.bat and add the following line: ## python backup.py ## import os import zipfile import datetime dirList = [ ('C:\\foo', 'foo'), # directory, zip name ('C:\\bar', 'bar'), # directory, zip name ] copyDest = os.getcwd() numFiles = 0 for src in dirList: currentPath = src[0] # verify the source directory exists if not os.path.isdir(currentPath): print '%s not found' % currentPath continue # zipfile name is the concatenation of the zip name (defined in dirList) and a timestamp zipname = src[1] zipfilename = "%s_%s.zip" % (zipname, datetime.datetime.now().strftime("%Y%m%d%H%M%S")) file = zipfile.ZipFile(zipfilename , "w") for (path, dirs, files) in os.walk(currentPath): numFiles += len(files) currentPath = path for name in files: print name archiveName = str(os.path.join(path, name)) # the archive name must be relative to the root of the archive # so strip off the C:\foo part of the path archiveName = archiveName[len(src[0]):] file.write(os.path.join(path, name), archiveName, zipfile.ZIP_DEFLATED) print '%d files archived into %s' % (numFiles, zipfilename)
  9. Nit

    Urban Empires - January 13, 2008 Update

    Hey Dan, I just caught you post on January 2nd that showcased some new animations. I knew you've been a Milkshape guy (as am I) and I noticed that your screenshots are not from Milkshape. Are you using a separate technique/tool for character modeling or are those screenshots out of a homegrown tool? Things look great! I've been watching this project grow for many years on this site.
  10. Nit


    Haha. Nice job on the Keen Klone! Good to see that more work is being done on SO. Its unfortunate that I haven't been around for testing. What time I have available I try to allocate it to Azrial (yes i still work on that, just haven't been posting!). First year of college is very exciting! The course work usually sucks because its usually intro material for some course and poorly taught by grad students to weed out the people that don't belong in major X. In the first year, it isn't about the course work though. Keep the grades up and have a good time!
  11. Nit

    Looking for: Evolution vs Religion-rants

    I think Will Wright's "Spore" will prove Evolution. You've got a tough case on your hands.
  12. Nit

    MAU Invasion!

    Wow! You really need to post some of those screenshots in your journal. The artwork is fantastic and the screenshots look amazing. Very cool stuff. Out of curiosity, how did you make the artwork on your home page (with the blotty ink and such). Nice touch. Anway, as Stompy already said, ++Welcome to Journal Land!
  13. Nit

    Grad School Applications, round 2

    Yay PSU! Great school. In addition to their computer science department, their School of Information Science and Technology does a lot of computer science-cognitive science research (check out Dr. Frank Ritter). NC State is also a good choice, Dr. Chris Healy does some cool graphics work. UNC also has an outstanding graphics program and should also be considered. If you get into PSU, all your football ticket are belong to me.
  14. Nit

    Optimization Day!

    Congratz on hitting 60 fps! The game is looking good as always.
  15. Nit


    Naruto and Bleach have my vote. You should check them out if you haven't already.
  • Advertisement

Important Information

By using GameDev.net, you agree to our community Guidelines, Terms of Use, and Privacy Policy.

GameDev.net is your game development community. Create an account for your GameDev Portfolio and participate in the largest developer community in the games industry.

Sign me up!