Code: Select all
tValue::BasePtr myValue = tValueParser::parse(tString("1+2"));
std::cerr << myValue->GetInt() << std::endl;
Code: Select all
tValue::BasePtr myValue = tValueParser::parse(tString("1+2"));
std::cerr << myValue->GetInt() << std::endl;
Provide? No, Io is a minimalistic language, it provides only the basics. But it allows you to implement caching (not going into details about implementation possibilities). And the cached value can reside in some C++ wrapped object and can even be referenced freely in C++ for extremely fast access.Luke-Jr wrote:Does Io provide efficient caching of expressions?
Scripting exists and is working fine for me. ;)z-man wrote:It already exists, and it probably is faster than scripting will be. I'm unsure about the other questions as well, but it seems vValues can be strings, ints and floats.meriton wrote:Or, to ask bluntly: What can vValue do what scripting can not?
So, like I say, if Luke wants to still do it, that's his prerogative, so long as he doesn't mind terribly if we later discover it's not useful in light of where scripting went. If I were he, I'd wait and see how the Io thread works out.![]()
Code: Select all
cycle do(
rubber = 200
speed = 10
brake = -10
)
Code: Select all
cycle do(
speed = 10
relativeRubber := 20 // this introduces a new config item
rubber = speed * relativeRubber
)
Code: Select all
cycle speed = 10
cycle brake = -10
cycle rubber = 200
cycleClone := cycle clone
cycleOverlay := cycle overlay
cycle rubber = 0
cycleOverlay brake = 0
cycleClone brake = 0
Code: Select all
class ConfigTreeNode{
public: // standard tree navigation, throws exceptions when nodes don't exist
ConfigTreeNode & GetParent();
ConfigTreeNode & GetChild( char const * name );
};
Code: Select all
template<class T> class ConfigItem: public ConfigTreeNode{
public:
T const & Get();
void Set( T const & );
private:
T value_;
};
Code: Select all
template<class T> class ConfigItemProxy{
public:
ConfigItemProxy( char const * name );
// accessors
T const & Get();
operator T const &(){ return Get();}
void Set( T const & );
void Attach( ConfigTreeNode & node ); // attaches to the value in the config tree, provided it is a value of the right type. Exception thrown on failure.
private:
ConfigItem< T > * value_;
};
Code: Select all
struct CycleConfigItems: public ConfigItemProxySet<CycleConfigItems>{
ConfigItemProxy<float> rubber_, speed_, brake_;
CycleConfigItems(): rubber_("rubber"), speed_("speed"), brake_("brake"){ SetParent<RootConfigItems>("cycle"); }
};
Code: Select all
class ConfigItemProxySetBase{
public:
static ConfigTreeNode * CreatePrototypes( IoState * state, char const * rootNameInIo ); // initialize the config item tree, returns the root node
template<class P> void SetParent( char const * name ); // register with parent node under that name
void Attach( ConfigTreeNode & node ); // attaches to a node of the config tree; all setting proxies contained will be attached, too
// stuff used by the ConfigItemProxies to register
};
template<class DERIVED> class ConfigItemProxySet: public ConfigItemProxySetBase{
// only private stuff that guarantees that the use of a DERIVED object anywhere in C++ triggers the generation of the glue code
};
Code: Select all
// somewhere in the main program. Don't worry about the state argument, that's an Io internal.
ConfigTreeNode & rootNode = *ConfigItemProxySetBase::CreatePrototypes( state, "configuration" );
// in the game code:
ConfigTreeNode & cycleNode = rootNode.GetChild( "cycle" ); // fetch the node of the cylce settings
CycleConfigItems cycleConfig;
cycleConfig.Attach( cycleNode ); // attach the cycle settings to it
gCycle * cycle = SpawnCycle();
cycle->SetSettings( &cycleConfig ); // spawn cycle and give it its settings
// in gCycle:
CycleConfigItems * config; // passed from outside
float speed = config->speed_;
Code: Select all
struct CycleRubberConfigItems: public ConfigItemProxySet<CycleRubberConfigItems>
{
ConfigItemProxy<float> rubber_, speed_, minDistance_;
CycleRubberConfigItems(): rubber_(""), speed_("speed"), minDistance_("mindistance"){}
};
struct CycleConfigItems: public ConfigItemProxySet<CycleConfigItems>{
ConfigItemSubSet<CycleRubberConfigItems> rubber_;
ConfigItemProxy<float> speed_, brake_;
CycleConfigItems(): rubber_("rubber"), speed_("speed"), brake_("brake"){ SetParent<RootConfigItems>("cycle"); }
};
Code: Select all
cycle rubber value = 200
cycle rubber speed 40
autoUpdate looks easier to do and makes more sense to me:z-man wrote:So this is what I've come up with during the boring parts of the lecture. I'm assuming we'll be using Io and the Io parser for the configuration system, but things should translate easily to the other scripting languages.
For the user, if she wants to do the things she's doing with the current configuration system, not much will change. She'll have to throw in some equal signs and replace some underscores with spaces. For example, cycle_rubber 200 could become cycle rubber = 200. She'll be able to save some typing usingto access multiple settings in one node. To base one setting on another, it's a simple matter of writingCode: Select all
cycle do( rubber = 200 speed = 10 brake = -10 )
And from then on, changing speed or relativeRubber will also change rubber. If that's undesired and the formula should just be evaluated at the time of its first evaluation, writing "now" after it should suffice. Note: I only have some rough ideas how this could be possible. It should work with basic expressions, but I don't know about custom functions. Maybe it would be easier to turn the logic around, make the default the evaluation now and require to write "rubber = autoUpdate( relativeRubber * speed )" for auto-updating settings. This, and whether it will be indeed this easy to add new config items (looks possible in Io), strongly depends on the scripting language's capabilities.Code: Select all
cycle do( speed = 10 relativeRubber := 20 // this introduces a new config item rubber = speed * relativeRubber )
Code: Select all
autoUpdate := getSlot("block")
extractValue := method(o, if(o getSlot("call"), o call, o))
cycle := Object clone do(
speed := 10
relativeRubber := 20
rubber := autoUpdate(speed * relativeRubber)
)
extractValue(cycle rubber) println
cycle speed = 15
extractValue(cycle rubber) println
cycle rubber = 3
extractValue(cycle rubber) println
Code: Select all
cycle accell rim = 1000
Code: Select all
admin kick "Player 1"
Code: Select all
pathAppend cycle
pathPrepend admin
kick "Admin" // found in admin node
rubber = -1 // found in cycle node
pathClear