Dictionary

I really want to test this code myself, but sadly I do not have access to a Cortex that I cant blow up! So… If anyone wants to give this a try then by all means go for it, its a dictionary which is linked in memory, I do not know if it works, its just something I wrote to upgrade my dictionary code from inefficient structures.


// ClassExtension.cpp
// This class is designed to extend the functions available.

// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// ~~~~ START OF DICTIONARY ~~~~
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

// NOTE: Dictionary is CORTEX only because it requires string support;

#ifdef VEX2

struct sNode;
struct StrDictionary;

struct {
  sNode *previous;
  string Identifier;
  int Value;
  sNode *next;
} sNode;

struct
{
  // Do Not Edit!!!
  sNode root;
  int NumberOfEntries;
  sNode *LastEntry;
} StrDictionary;

typedef struct
{
  void New(StrDictionary &memDictionary);
  void Add(string Identifier, int Value, StrDictionary &memDictionary);
  int Get(string Identifier, StrDictionary &memDictionary);
  bool Get(string Identifier, int &Value, StrDictionary &memDictionary);
  bool Set(string Identifier, int Value, StrDictionary &memDictionary);
  bool Remove(string Identifier, StrDictionary &memDictionary);

  void New(StrDictionary &memDictionary)
  {
    memDictionary.root.previous = 0;
    memDictionary.root.next = 0;
    memDictionary.root.Identifier = "DICTIONARY_ROOT";
    memDictionary.root.Value = -1;
    memDictionary.NumberOfEntries = 0;
    memDictionary.LastEntry = memDictionary.root;
  }
  
  void Add(string Identifier, int Value, StrDictionary &memDictionary)
  {
    // Create a new node
    sNode memNode;
    memNode.Identifier = Identifier;
    memNode.Value = Value;
    memNode.next = 0;
    
    // Find the last node
    sNode conductor = memDictionary.LastEntry;
    
    // Now add another node
    memNode.previous = conductor;
    conductor.next = memNode;
  }
  
  int Get(string Identifier, StrDictionary &memDictionary)
  {
    // Get the root
    sNode conductor = memDictionary.root;
    
    // Find the node
    while ((conductor.next != 0) && (conductor != Identifier))
    {
      conductor = conductor.next;
    }
    
    // Return value if node found, otherwise return negative zero
    if (conductor.Identifier == Identifier)
    {
      return conductor.Value;
    }
    return -0;
  }
  
  bool Get(string Identifier, int &Value, StrDictionary &memDictionary)
  {
    // Get the root
    sNode conductor = memDictionary.root;
    
    // Find the node
    while ((conductor.next != 0) && (conductor != Identifier))
    {
      conductor = conductor.next;
    }
    
    // Return value if node found, otherwise return nothing
    if (conductor.Identifier == Identifier)
    {
      Value = conductor.Value;
      return true;
    }
    return false;
  }
  
  bool Set(string Identifier, int Value, StrDictionary &memDictionary)
  {
    // Get the root
    sNode conductor = memDictionary.root;
    
    // Find the node
    while ((conductor.next != 0) && (conductor != Identifier))
    {
      conductor = conductor.next;
    }
    
    // Set the value if node found, otherwise set nothing
    if (conductor.Identifier == Identifier)
    {
      conductor.Value = Value;
      return true;
    }
    return false;
  }
  
  bool Remove(string Identifier, StrDictionary &memDictionary)
  {
    // Get the root
    sNode conductor = memDictionary.root;
    
    // Find the node
    while ((conductor.next != 0) && (conductor != Identifier))
    {
      conductor = conductor.next;
    }
    
    // Remove if node found, otherwise do nothing
    if (conductor.Identifier == Identifier)
    {
      // Get the nodes on either side
      sNode memPrevious = conductor.previous;
      sNode memNext = conductor.next;
      
      // Then remove the link and link the nodes on either side together
      memPrevious.next = memNext;
      memNext.previous = memPrevious;
      
      return true;
    }
    return false;
  }
} Dictionary;

#endif
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// ~~~~  END OF DICTIONARY  ~~~~
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

Example of how to use it:


// Example use:

// First create a new dictionary
StrDictionary tempDictionary;

// Now Initiate it
Dictionary.Init(tempDictionary);

// Now lets add a motor value
Dictionary.Add("MOTOR1", motor[port1], tempDictionary);

// Now lets change that value
Dictionary.Set("MOTOR1", 90, tempDictionary);

// Now lets give the motor the new value
// There is two ways of doing this
Dictionary.Get("MOTOR1", motor[port1], tempDictionary);
// or
motor[port1] = Dictionary.Get("MOTOR1", tempDictionary);

// Finally, lets get rid of it
Dictionary.Del("MOTOR1", tempDictionary);

NOW! I have doubts that it will work, but I also believe that there is 99% chance that there will no damage to your Cortex, as this is memory based and should have worse case scenario of the Cortex freezing.

USE AT YOUR OWN RISK! UNTESTED!

What compiler did you use to check for syntax errors?
RobotC/ EasyC/ Unix Gcc with some vex lib ?

Can you add some sales pitch about why it would be useful?
Your example shows something like “named access to motor ports”,
and being able to read the current value of a motor port.

Its not clear to me how your setting a motor port actually takes effect,
but maybe that is just my unfamiliarity with the library you are using.

My framework is for RobotC, so I developed this for RobotC and if it works, I will include it in my Final release of IT 2.0 ReAmped (cheesy name).

Anyway, you are not setting the motor port, you are setting the speed on that motor port. heres whats in the example


// Now lets give the motor the new value
// There is two ways of doing this
Dictionary.Get("MOTOR1", motor[port1], tempDictionary);
// or
motor[port1] = Dictionary.Get("MOTOR1", tempDictionary);

Now the first way, you are passing a pointer to the function and the function just assigns the variable that has been pointed to, the new value. in this case you are pointing to the variable for motor speed on port 1, this function will assign the dictionaries’ value of the node “MOTOR1” to the motor speed variable.
Now the second way is a standard return method, the function is just getting the value from the node “MOTOR1” and is returning it, so you are basically assigning the value to the variable motor speed port 1.

The first way can be used to check whether or not the node existed and the value was assigned to the variable.
The second way can be used in statements, for example:


if (Dictionary.Get("MOTOR1", tempDictionary) == 127)
{
    motor[port1] = 127;
}

This example is saying that if the node’s value is 127 then set motor speed port 1 to 127.

Now, for the use of this. Well currently there is no practical use for it because I actually start using it once I know it works, and I don’t know if it works yet soooo… Yea I’ll get back to you on that one.

Doesn’t RobotC already incorporate “naming” motor ports? (That seems to be the main function of this program, but I’m not sure.)

Yes! Yes it does. But I was just using it as an example for how to use the dictionary, as I said, since I don’t know whether it works or not, I havent bothered creating uses for it. When I know it works then I will come up with some uses, and you can also find a use for it, you could use it to store data then at the end of the program you could attach the debug cable and press a button on the joystick then dump the dictionary data through serial on to the terminal.